how to solve non-linear transcendental equation with many roots

Hi All,
I have to solve the following equation
x-(2*(sinh(x)*((cos(x)).^2+cos(x)-1)+sin(x)*(cosh(x)-1)))/((1-cos(x)*cosh(x))) =0.
It is a nonlinear with many roots, so is there any function in matlab can do it? the function fzero only return a root near a initial root value, which is not a automatic task.
Thank you.

Answers (3)

I suspect not, but I do not have the Symbolic Toolbox to test with. Using a different symbolic package, I find that there are an infinite number of roots, some real and some imaginary. There is no nice analytic expression for the roots.
One of the basic items repeated over and over in the forms is the root of cos(x) = x, which has no analytic solution.
The generalized solution for reals has three forms; the overall solution is the union of {0} and these three forms and three forms for the imaginary solutions. The three real forms are:
.7429621155 + 1.655668423 * B + 6.283185308 * Z
-0.7429621155 + 4.627516885 * B + 6.283185308 * Z
3.141592654 * B + 6.283185308 * Z
where B must be either 0 or 1, and Z is any arbitrary integer.
The 6.28<etc> is obviously 2*Pi, and the 3.14<etc> is obviously Pi, but the other numeric values have no obvious interpretation.

4 Comments

right, 'solve' gives the triplet {0,0,0}
Yes, how i can take the numerical results? There are indeed infinite results. Here comes the code you can find the intersection point between y=x and y=f(x).
clear clc close all
xx=0:0.001:50; for i=1:length(xx) x=xx(i); fx(i)=(2*(sinh(x)*((cos(x)).^2+cos(x)-1)+sin(x)*(cosh(x)-1)))/((1-cos(x)*cosh(x))); flinerx(i)=x; end
plot(xx, fx); hold on plot(xx, flinerx, 'r') axis([0, max(xx), -max(xx), max(xx)])
xguess = [2, 5,12, 17.8, 23.97, 30, 37, 44]; for i=1:length(xguess) Root_results(i)=fzero(@myfun,xguess(i)); end
function fz = myfun(x) fz=x-(2*(sinh(x)*((cos(x)).^2+cos(x)-1)+sin(x)*(cosh(x)-1)))/((1-cos(x)*cosh(x)));
It is possible that the above solution is incorrect; I am working through some difficulties I found with the other package.
I have confirmed that the solution I showed in my Answer is incorrect, but I do not have anything worked out yet as to what the correct general solution should be.

Sign in to comment.

Hi, there many ways to get solution,
You use a function Handle :
>>f=@(x) x-(2*(sinh(x)*((cos(x))^2+cos(x)-1)+sin(x)*(cosh(x)-1)))/(1-cos(x)*cosh(x))
>>y=fsolve(f,10e-3)
'fsolve' starts at x0=10e-3 and tries to solve the equation , you can verify the solution :
>>f(y)
-2.0334e-009
This helps ?

3 Comments

The poster is hoping for the many roots. fsolve() will not do that.
What can be tried is
syms x
f = x-(2*(sinh(x)*((cos(x)).^2+cos(x)-1)+sin(x)*(cosh(x)-1)))/((1-cos(x)*cosh(x)));
feval(symengine, 'numeric::solve', f, x, 'AllRealRoots')
This might have a problem because of the fact that there are an infinite number of real roots.
Yes, it has infinite number of real roots. What i need is the first several results, such as the first 50 roots.
What Walter said are exactly the point.

Sign in to comment.

2nd answer :
You can use " solve" with symbolic variable :
syms x
y=x-(2*(sinh(x)*((cos(x))^2+cos(x)-1)+sin(x)*(cosh(x)-1)))/((1-cos(x)*cosh(x)))
z=solve(y) .

12 Comments

Will this return an expression for all roots, or only for a single root?
it returns three elements : {root1,root2,root3}
Three numeric roots, or expressions?
I guess the symbolic method cant give the analytical results, because the analytical results do not exist. How i can get the multiple roots? i find the function fzero is not good enough to be used.
Thank you very much.
correct david, the 2nd answer gives SYmbolic results but zeros :{0,0,0} !!
Addition : I tried to change the 2nd answer , by altering the first hyperbolic sinus with cosh, so it gives two symbolic solutions as numbers :
y=x-(2*(cosh(x)*((cos(x))^2+cos(x)-1)+sin(x)*(cosh(x)-1)))/((1-cos(x)*cosh(x)))
y =
x-(2*cosh(x)*(cos(x)^2+cos(x)-1)+2*sin(x)*(cosh(x)-1))/(1-cos(x)*cosh(x))
>> z=solve(y)
z =
-3.7334546196297311376767645164302
.52183972722849489951741775832884-1.2746296333498672112488371780214*i
abs(z)
ans =
3.7334546196297311376767645164302
1.3773152882065627025290631464461
whos z
Name Size Bytes Class Attributes
z 2x1 390 sym
Thank you, Youssef.
Yes, so i am wondering how i can automatically obtain the first several roots. For function Fzero or fsolve, it can only return one root near the initial value, and sometime it cant always give the correct answer.
clear clc close all
xx=0:0.001:50; for i=1:length(xx) x=xx(i); fx(i)=(2*(sinh(x)*((cos(x)).^2+cos(x)-1)+sin(x)*(cosh(x)-1)))/((1-cos(x)*cosh(x))); flinerx(i)=x; end
plot(xx, fx); hold on plot(xx, flinerx, 'r') axis([0, max(xx), -max(xx), max(xx)])
xguess = [2, 5,12, 17.8, 23.97, 30, 37, 44];
for i=1:length(xguess) Root_results(i)=fzero(@myfun,xguess(i)); end
function fz = myfun(x) fz=x-(2*(sinh(x)*((cos(x)).^2+cos(x)-1)+sin(x)*(cosh(x)-1)))/((1-cos(x)*cosh(x)));
---------------- for the above code, fzero cant give the exact roots for the intimal point. Sometimes, it may require the tentative setting of the initial roots, but this does not always give correct results. at 23.97, 30, 37, 44,
David, based on the code above, i tried to find indexes where zeros do exist, but the method failed, anyway i tried to plot the analytic function :
syms x
f = x-(2*(sinh(x)*((cos(x)).^2+cos(x)-1)+sin(x)*(cosh(x)-1)))/((1-cos(x)*cosh(x)));
>> ezplot(f,[1 1000])
So based on the reasoning above, the graph should cross Infinitely the x axis , but its not the case , so what do you think?
I guess i have got the results. pls see the following code,
clear clc close all
xx=0:0.001:100; for i=1:length(xx) x=xx(i); fx(i)=(2*(sinh(x)*((cos(x)).^2+cos(x)-1)+sin(x)*(cosh(x)-1)))/((1-cos(x)*cosh(x))); flinerx(i)=x; end
plot(xx, fx); hold on plot(xx, flinerx, 'r') axis([0, max(xx), -max(xx), max(xx)])
options=optimset('Display','iter','TolFun',1e-10); % Option to display output
xguess = [2, 5,12, 18, 24, 30, 37, 43, 49, 55.5, 62, 68, 75, 81, 87, 93.5, 99.5]; for i=1:length(xguess) % Root_results(i)=fzero(@myfun,xguess(i)); Root_results(i,1)=fsolve(@myfun,xguess(i),options); end
fsolve is much better than fzero in finding the root, so i finally use fsolve instead of fzero.

Sign in to comment.

Asked:

on 13 Feb 2013

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!