# Solving trigonometric equations in interval.

Hi I have a question. I am trying to find the values between a given inteval for a trigonometric equation ex.

sin(x) == 0.8, (0>x>2*pi)


If I solve the function like this

f = sin(x)
solve(f,x)


Then i only recieve the result for the first time f == 0.8. I found out that there are ways to get all the values for f== 0.8 if i type some command like

solve(f,x,to_poly_solve=True)


or

y = var('y')
solve([sin(x)==y,y==0.8],[x,y])


or

 solve(sin(x)==0.8, x, to_poly_solve = 'force')


But all these methods give me only some crazy outputs which i don't understand - and far out of the interval than i want.

I found out that I can move the function down and find the roots if i type

first = find_roots(0.8-f,0,1)
second = find_roots(0.8-f,0,2*pi)


And then i will get the result for the value of x when f == 0.8

But it seems like a pretty big work around just to get this result, and when i am working with bigger equations, then i will have to plot them first to find out which xmin and xmax values i should put in the "find_root" feature.

Are there an easier way to get the results or a tutorial or something how to make it simpler? Maybe i can define my own command somehow?

edit retag close merge delete

Sort by » oldest newest most voted

Root finding is a difficult subject. In general, you cannot expect an algorithm to yield all the solutions of a given equation $f(x)=0$. It is required some prior knowledge and analysis of the equation.

The solve function tries to obtain exact solutions, if any. For the equation you propose, that is, $\sin x=0.8$, you have already tested

solve(sin(x)==0.8,x)


which yields $x=\arcsin(4/5)$ and misses the other solution in $[0,2\pi]$, which is $x=\pi-\arcsin(4/5)$. You have also tried

solve(sin(x)==0.8, x, to_poly_solve = 'force')


and got something like

[x == pi + 2*pi*z103 - arctan(3602879701896397/7301667457314599911469129704407*sqrt(7301667457314599911469129704407)),
x == 2*pi*z105 + arctan(3602879701896397/7301667457314599911469129704407*sqrt(7301667457314599911469129704407))]


Here, z103 and z105 represent integer constants. Every time you evaluate such a function, you get different numbers after z. In a more mathematical notation, Sage proposes the solutions $$x=-\arctan\Bigl(\frac{a\sqrt{b}}{b}\Bigr)+\pi(2z_{103}+1)\quad\text{and}\quad x=\arctan\Bigl(\frac{a\sqrt{b}}{b}\Bigr)+2\pi z_{105},$$ where $$a=3602879701896397 \quad\text{and}\quad b=7301667457314599911469129704407.$$ Please, note that we have now an infinite number of solutions. If z103 and z105 are replaced by given integers, we get specific solutions. For example,

sol = solve(sin(x)==0.8, x, to_poly_solve = 'force')
print "First solution:", sol[0].rhs().subs(z103=0).n()
print "Second solution:",sol[1].rhs().subs(z105=0).n()


yields

First solution: 2.21429743558818
Second solution: 0.927295218001612


assuming, of course, that z103 and z105 still were the constants appearing in sol. These are the expected roots (up to an error of order $10^{-16}$) in $[0,2\pi]$, since

sage: print N(arcsin(4/5)), N(pi-arcsin(4/5))
0.927295218001612 2.21429743558818


The find_root function applies a numerical algorithm, essentially Brent's method. So each call to find_root will yield, if any, just one approximated root of the equation. Hence, to find all the zeros of a function, you need to know in advance how many they are and where they live and then use find_root as many times as needed, changing the corresponding intervals.

more

Just to complement my answer, you can also try the solve function given by Sympy, which provides both roots in $[0,2\pi]$:

sage: import sympy as sp
sage: sp.solve(sin(x)==0.8,x)
[0.927295218001612, 2.21429743558818]

( 2019-03-07 19:34:51 -0500 )edit