
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 个评论
回答(3 个)
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 个评论
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
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
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.
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 Center 和 File Exchange 中查找有关 Calculus 的更多信息
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!