Find all roots of non linear equation

15 次查看(过去 30 天)
Hi,
i want to find the all roots of an non linear equation without using the symbolic toolbox because of runtime issues. So i tried to use fzero and i found this helpful thread: https://de.mathworks.com/matlabcentral/answers/160117-how-to-use-fzero-and-choose-correctly-initial-guess
So i added my equation to it. The problem is that it doesn't fin initial guesses because of the step size. if i am using x = linspace(-1,1); it finds the root but not if i have a bigger intervall. And the problem is that normally i don't know the intervall that exactly.
1. Has sb an idea how i could improve the code to make it work for me ? Or has sb any idea how i could solve this problem with another method ? I cannot use roots() or sth else for polynoms because the equation is no polynom.
if true
b1=0
b2=0
v1=0
v2=0
s1=0
s2=0.175
j2=0.28
tau =300
x = linspace(-10,10); % Interval To Evaluate Over
f = @(x)-s2 + s1 + (v1 + (b1 - j2.*x).^2/(2.*j2) + (j2.*x.^2)/2 - (b1.*(b1 - j2.*x))/j2).*(tau - x - (2.*b2 - 2.^(1/2).*(2.*j2.*v1 - 2.*j2.*v2 - b1.^2 + b2.^2 + 2.*j2.^2.*x.^2).^(1/2))/(2.*j2) + (b1 - j2.*x)/j2 + (2.^(1/2).*(2.*j2.*v1 - 2.*j2.*v2 - b1.^2 + b2.^2 + 2.*j2.^2.*x.^2).^(1/2))/(2.*j2)) + (2.*b2 - 2.^(1/2).*(2.*j2.*v1 - 2.*j2.*v2 - b1.^2 + b2.^2 + 2.*j2.^2.*x.^2).^(1/2)).^3/(48.*j2.^2) - (b1 - j2.*x).^3/(6.*j2.^2) + (j2.*x.^3)/3 + x.*(v1 + (b1 - j2.*x).^2/(2.*j2) - (b1.*(b1 - j2.*x))/j2) - (v1.*(b1 - j2.*x))/j2 + (2.^(1/2).*(2.*j2.*v1 - 2.*j2.*v2 - b1.^2 + b2.^2 + 2.*j2.^2.*x.^2).^(3/2))/(24.*j2.^2) + (b1.*(b1 - j2.*x).^2)/(2.*j2.^2) + ((2.*b2 - 2.^(1/2).*(2.*j2.*v1 - 2.*j2.*v2 - b1.^2 + b2.^2 + 2.*j2.^2.*x.^2).^(1/2)).*(v1 - (j2.*v1 - j2.*v2 - b1.^2/2 + b2.^2/2 + j2.^2.*x.^2)/(2.*j2) + (b1 - j2.*x).^2/(2.*j2) + (j2.*x.^2)/2 - (b1.*(b1 - j2.*x))/j2))/(2.*j2) + (2.^(1/2).*(2.*b2 - 2.^(1/2).*(2.*j2.*v1 - 2.*j2.*v2 - b1.^2 + b2.^2 + 2.*j2.^2.*x.^2).^(1/2)).^2.*(2.*j2.*v1 - 2.*j2.*v2 - b1.^2 + b2.^2 + 2.*j2.^2.*x.^2).^(1/2))/(16.*j2.^2) - (2.^(1/2).*(v1 + (b1 - j2.*x).^2/(2.*j2) + (j2.*x.^2)/2 - (b1.*(b1 - j2.*x))/j2).*(2.*j2.*v1 - 2.*j2.*v2 - b1.^2 + b2.^2 + 2.*j2.^2.*x.^2).^(1/2))/(2.*j2);
fplot(f)
fx = f(x); % Function Evaluated Over ‘x’
cs = fx.*circshift(fx,-1,2); % Product Negative At Zero-Crossings
xc = x(cs <= 0); % Values Of ‘x’ Near Zero Crossings
for k1 = 1:length(xc)
fz(k1) = fzero(f, xc(k1)); % Use ‘xc’ As Initial Zero Estimate
end
syms x
f = -s2 + s1 + (v1 + (b1 - j2.*x).^2/(2.*j2) + (j2.*x.^2)/2 - (b1.*(b1 - j2.*x))/j2).*(tau - x - (2.*b2 - 2.^(1/2).*(2.*j2.*v1 - 2.*j2.*v2 - b1.^2 + b2.^2 + 2.*j2.^2.*x.^2).^(1/2))/(2.*j2) + (b1 - j2.*x)/j2 + (2.^(1/2).*(2.*j2.*v1 - 2.*j2.*v2 - b1.^2 + b2.^2 + 2.*j2.^2.*x.^2).^(1/2))/(2.*j2)) + (2.*b2 - 2.^(1/2).*(2.*j2.*v1 - 2.*j2.*v2 - b1.^2 + b2.^2 + 2.*j2.^2.*x.^2).^(1/2)).^3/(48.*j2.^2) - (b1 - j2.*x).^3/(6.*j2.^2) + (j2.*x.^3)/3 + x.*(v1 + (b1 - j2.*x).^2/(2.*j2) - (b1.*(b1 - j2.*x))/j2) - (v1.*(b1 - j2.*x))/j2 + (2.^(1/2).*(2.*j2.*v1 - 2.*j2.*v2 - b1.^2 + b2.^2 + 2.*j2.^2.*x.^2).^(3/2))/(24.*j2.^2) + (b1.*(b1 - j2.*x).^2)/(2.*j2.^2) + ((2.*b2 - 2.^(1/2).*(2.*j2.*v1 - 2.*j2.*v2 - b1.^2 + b2.^2 + 2.*j2.^2.*x.^2).^(1/2)).*(v1 - (j2.*v1 - j2.*v2 - b1.^2/2 + b2.^2/2 + j2.^2.*x.^2)/(2.*j2) + (b1 - j2.*x).^2/(2.*j2) + (j2.*x.^2)/2 - (b1.*(b1 - j2.*x))/j2))/(2.*j2) + (2.^(1/2).*(2.*b2 - 2.^(1/2).*(2.*j2.*v1 - 2.*j2.*v2 - b1.^2 + b2.^2 + 2.*j2.^2.*x.^2).^(1/2)).^2.*(2.*j2.*v1 - 2.*j2.*v2 - b1.^2 + b2.^2 + 2.*j2.^2.*x.^2).^(1/2))/(16.*j2.^2) - (2.^(1/2).*(v1 + (b1 - j2.*x).^2/(2.*j2) + (j2.*x.^2)/2 - (b1.*(b1 - j2.*x))/j2).*(2.*j2.*v1 - 2.*j2.*v2 - b1.^2 + b2.^2 + 2.*j2.^2.*x.^2).^(1/2))/(2.*j2);
vpa(solve(f,x))
end
  6 个评论
IlPadrino
IlPadrino 2018-7-19
编辑:IlPadrino 2018-7-19
b1 b2 v1 v2 s1 s2 j2 tau. The parameters which are in the equation

请先登录,再进行评论。

回答(3 个)

Star Strider
Star Strider 2018-7-18
That algorithm will work when the increment in your ‘x’ vector is small enough to detect the sign change.
The solution is to simply add more points to increase the resolution of the vector:
x = linspace(-10,10,1000); % Interval To Evaluate Over
that then produces:
fz =
-0.045636604654443 0.045643546458764
as desired, and acceptably close to the symbolic result.
  6 个评论
IlPadrino
IlPadrino 2018-7-19
But how do you decide how many roots he has to search? Because right now you set k1 to 2. But this cozld be changing.
Star Strider
Star Strider 2018-7-19
It could change. To search for more roots, increase the ‘k1’ limit, and provide new initial estimates:
for k1 = 1:4
[xv(k1,:),fxval(k1,:)] = fsolve(f, (-1/k1)*((-1)^k1)/tau); % Find Both Roots, Scale Initial Estimate By ‘1/tau’
end
xroots =
-0.010218893299935 + 0.395164734474393i
0.002137898025294 - 0.395703760614642i
-0.010218911868143 + 0.395164745783536i
0.002137898022517 - 0.395703760622581i
These (using your most recent set of constants) are acceptably close to the symbolic solve results.
The initial estimates are calculated as ‘(-1/k1)*((-1)^k1)/tau’.

请先登录,再进行评论。


Dimitris Kalogiros
Dimitris Kalogiros 2018-7-18
Dear IlPadrino
Your equation is not a "nonlinear" equation. If you try to search its roots fist at the interval [0, +inf) and then at (-inf, 0) , you can rid of this annoying square root.
Have a look at the following piece of code :
clear all;
clc;
% Initial problem
b1=0;
b2=0;
v1=0;
v2=0;
s1=0;
s2=0.175;
j2=0.28;
tau =300;
syms x
% initial form of f
f = -s2 + s1 + (v1 + (b1 - j2.*x).^2/(2.*j2) + (j2.*x.^2)/2 - (b1.*(b1 - j2.*x))/j2).*(tau - x - (2.*b2 - 2.^(1/2).*(2.*j2.*v1 - 2.*j2.*v2 - b1.^2 + b2.^2 + 2.*j2.^2.*x.^2).^(1/2))/(2.*j2) + (b1 - j2.*x)/j2 + (2.^(1/2).*(2.*j2.*v1 - 2.*j2.*v2 - b1.^2 + b2.^2 + 2.*j2.^2.*x.^2).^(1/2))/(2.*j2)) + (2.*b2 - 2.^(1/2).*(2.*j2.*v1 - 2.*j2.*v2 - b1.^2 + b2.^2 + 2.*j2.^2.*x.^2).^(1/2)).^3/(48.*j2.^2) - (b1 - j2.*x).^3/(6.*j2.^2) + (j2.*x.^3)/3 + x.*(v1 + (b1 - j2.*x).^2/(2.*j2) - (b1.*(b1 - j2.*x))/j2) - (v1.*(b1 - j2.*x))/j2 + (2.^(1/2).*(2.*j2.*v1 - 2.*j2.*v2 - b1.^2 + b2.^2 + 2.*j2.^2.*x.^2).^(3/2))/(24.*j2.^2) + (b1.*(b1 - j2.*x).^2)/(2.*j2.^2) + ((2.*b2 - 2.^(1/2).*(2.*j2.*v1 - 2.*j2.*v2 - b1.^2 + b2.^2 + 2.*j2.^2.*x.^2).^(1/2)).*(v1 - (j2.*v1 - j2.*v2 - b1.^2/2 + b2.^2/2 + j2.^2.*x.^2)/(2.*j2) + (b1 - j2.*x).^2/(2.*j2) + (j2.*x.^2)/2 - (b1.*(b1 - j2.*x))/j2))/(2.*j2) + (2.^(1/2).*(2.*b2 - 2.^(1/2).*(2.*j2.*v1 - 2.*j2.*v2 - b1.^2 + b2.^2 + 2.*j2.^2.*x.^2).^(1/2)).^2.*(2.*j2.*v1 - 2.*j2.*v2 - b1.^2 + b2.^2 + 2.*j2.^2.*x.^2).^(1/2))/(16.*j2.^2) - (2.^(1/2).*(v1 + (b1 - j2.*x).^2/(2.*j2) + (j2.*x.^2)/2 - (b1.*(b1 - j2.*x))/j2).*(2.*j2.*v1 - 2.*j2.*v2 - b1.^2 + b2.^2 + 2.*j2.^2.*x.^2).^(1/2))/(2.*j2)
%simplify f
f=expand(f)
% searching for roots at interval [0 +inf)
assume(x>=0);
f1=simplify(f)
sol_Right=solve(f1==0)
%searching for roots at (-inf , 0)
assume(x<0)
f2=simplify(f)
sol_left=vpasolve(f2==0)
% Graphical demonstration
fplot(f,[-.1 .1]); grid on; hold on; fplot(0,[-.1, .1]);
I've run this , and you can find results of it, inside the file I've attached.
  2 个评论
James Tursa
James Tursa 2018-7-18
It certainly is nonlinear. I think what you meant to write is that with the proper interpretation it can be reduced to a polynomial.
IlPadrino
IlPadrino 2018-7-19
Hi Dimitris Kalogiros big thanks for your Help I really appreciate it. But the problem is that the parameter are inserted at the very end of my process. So that means i need general expression of the polynom where i just insert the parameters and then calculate my x variable with an numerical approximation (without symbolic Toolbox) Tha's why i can't do it that way. I tried it with the symbolic expression of my non linear equation to simplyfy and then expand it to generate a polynom but without success. In Conclusion if i want to create an polynom i have to create it with the parameters in it.

请先登录,再进行评论。


Walter Roberson
Walter Roberson 2018-7-19
The solution involves the roots of a quartic.
P4 = -9*sqrt(2)*(-2*j2^2*tau^2+((-4*b1+4*b2)*tau-6*v1+6*v2)*j2+(b1+5*b2)*(b1-b2));
P3 = (72*tau*v2+72*s1-72*s2)*j2^2+((-72*v1+72*v2)*b1-36*b2^2*tau)*j2+24*b1^3-36*b1*b2^2+12*b2^3;
P2 = -(3*(-24*tau*(tau*v2+s1-s2)*j2^3+(((24*v1-48*v2)*tau-24*s1+24*s2)*b1+12*b2^2*tau^2+(24*tau*v2+24*s1-24*s2)*b2+36*(v1-v2)^2)*j2^2-(8*(tau*b1^2+(b2*tau+3*v1*(1/2)-3*v2*(1/2))*b1-(2*(b2*tau-9*v1*(1/4)+9*v2*(1/4)))*b2))*(b1-b2)*j2+(b1^2+10*b1*b2+13*b2^2)*(b1-b2)^2))*sqrt(2);
P1 = 0;
P0 = -sqrt(2)*(-72*(tau*v2+s1-s2)^2*j2^4+((144*(v1-v2))*(tau*v2+s1-s2)*b1+72*tau*(tau*v2+s1-s2)*b2^2-72*(v1-v2)^3)*j2^3+((-48*tau*v2-48*s1+48*s2)*b1^3+36*(v1-v2)^2*b1^2+72*b2^2*(-tau*v1+2*tau*v2+s1-s2)*b1-(18*(b2^2*tau^2+(4*v2*tau*(1/3)+4*s1*(1/3)-4*s2*(1/3))*b2+6*(v1-v2)^2))*b2^2)*j2^2-(6*(b1-b2))*((v1-v2)*b1^3-4*b2*(b2*tau-(1/4)*v1+(1/4)*v2)*b1^2-(4*(b2*tau+5*v1*(1/4)-5*v2*(1/4)))*b2^2*b1+(2*(b2*tau-9*v1*(1/2)+9*v2*(1/2)))*b2^3)*j2+(b1^4+2*b1^3*b2-10*b1*b2^3-11*b2^4)*(b1-b2)^2);
RRR = roots([P4, P3, P2, P1, P0]);
xroots = (3*RRR.^3*sqrt(2) + (12*tau*v2+12*s1-12*s2)*j2^2 + ((-12*v1+12*v2)*b1 - 6*b2^2*tau + 6*RRR.^2*tau)*j2 + 4*b1^3 + (6*RRR.^2-6*b2^2)*b1 + 2*b2^3 - 6*RRR.^2*b2) ./ (6*j2*((-2*v1+2*v2)*j2 + b1^2 - b2^2 + RRR.^2));
These are not guaranteed to be real-valued, and are not guaranteed to be unique.
  9 个评论

请先登录,再进行评论。

类别

Help CenterFile Exchange 中查找有关 Calculus 的更多信息

Community Treasure Hunt

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

Start Hunting!

Translated by