fsolve no solution found system of two equations
7 views (last 30 days)
Show older comments
hello,
I have a strange problem when trying to solve a very simple system with fsolve:
--------------------
x0=[1e17 1e19]
[x,FVAL,EXITFLAG] = fsolve(@ nested_solver_straight_wg , x0,options);
function F = nested_solver_straight_wg(x)
C=5.4e-22;
D=1.53e-18;
A=8.88e-21;
B=5.84e-20;
ne = x(1) ;
pe = x(2);
F(1) = A*ne.^1.16+B*pe.^1.109-7.24;
F(2) = C*ne.^1.011+D*pe.^0.838-2.7687e-04;
end
----------------------
When i run what i get is:
No solution found.
fsolve stopped because the problem appears regular as measured by the gradient,
but the vector of function values is not near zero as measured by the
value of the function tolerance.
<stopping criteria details>
-------------------------
I tried changing tolerances but I wasn't able to proceed further.
I tried also to solve just the equation
F(1) = A*ne.^1.16+B*pe.^1.109-7.24;
with pe=7e17 but even in this very simple case the solver isn't able to find a solution (ne) which we know it must have one in the simple case of a single equation even with different starting point and tolerances.
What am I missing?
0 Comments
Accepted Answer
Torsten
on 27 Mar 2022
A=8.88e-21;
B=5.84e-20;
C=5.4e-22;
D=1.53e-18;
A=A*(1e18)^1.16
B=B*(1e19)^1.109
C=C*(1e18)^1.011
D=D*(1e19)^0.838
x1=linspace(0,(7.24/B)^(1/1.109),100)
x2=linspace(0,(2.7687e-4/D)^(1/0.838),100)
y1=((7.24-B*x1.^1.109)/A).^(1/1.16);
y2=((2.7687e-4-D*x2.^0.838)/C).^(1/1.011)
plot(x1,y1)
hold on
plot(x2,y2)
As you can see: The two equations don't have a point in common.
0 Comments
More Answers (1)
Matt J
on 27 Mar 2022
Your function is not differentiable for x(2)<0, so we must impose a lower bound to make it positive. But when we do that as below, the result is that x(2)=0. So, the solver probably thinks that an exact solution might lie at x(2)<0, but we cannot let it got there, because of non-differentiability.
s=[1e8;1e10];
x0=[5.8787e+17, 7e17];
tol=1e-15;
options=optimoptions('lsqnonlin','SpecifyObjectiveGradient',true,...
'StepTolerance',tol,'OptimalityTolerance',tol,'FunctionTolerance',tol,'Display','iter',...
'MaxFunEvals',1e5,'MaxIter',2e3);
[x,~,FVAL,EXITFLAG,out,~,Jf] = lsqnonlin(@(x) nested_solver_straight_wg(x,s) , x0,[-inf,0],[],options);
x
FVAL=FVAL./s
function [F,J] = nested_solver_straight_wg(x,s)
C=5.4e-22 ;
D=1.53e-18 ;
A=8.88e-21 ;
B=5.84e-20 ;
ne = x(1) ;
pe = x(2);
F(1) = A*ne.^1.16+B*pe.^1.109-7.24;
F(2) = C*ne.^1.011+D*pe.^0.838-2.7687e-04;
F=s.*F(:);
if nargout>1
J(1,1) = A*ne.^0.16*1.16; J(1,2)=B*1.109*pe.^0.109;
J(2,1) = C*ne.^0.011*1.011; J(2,2)=D*pe.^(0.838-1)*0.838;
J=s.*J;
end
end
2 Comments
Matt J
on 27 Mar 2022
Edited: Matt J
on 27 Mar 2022
What is the meaning of
That is the Jacobian of F. You should provide it, using the SpecifyObjectiveGradient, whenver possible, since otherwise fsolve/lsqnonlin must approximate it using finite differences.
So with this version the solver is not able to solve the second equation:
The second equation doesn't appear to be providing very much additional information. If we do a surface plot of your objective function, we can see that there is a long trench of essentially equivalent least squares solutions:
fsurf(@(x,y) nested_solver_straight_wg(x,y),[1e18,1.1e18,0, 5e16])
xlabel ne;
ylabel pe;
zlim([0,.1]);
view(43,50)
function F = nested_solver_straight_wg(ne,pe)
C=5.4e-22 ;
D=1.53e-18 ;
A=8.88e-21 ;
B=5.84e-20 ;
F1 = A*ne.^1.16+B*pe.^1.109-7.24;
F2 = C*ne.^1.011+D*pe.^0.838-2.7687e-04;
F=F1.^2+F2.^2;
end
See Also
Categories
Find more on Ordinary Differential Equations in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!