MATLAB: For fsolve. Is it true that for a system with unique solution, by supplying analytical Jacobian and Hessian, the fsolve procedure would always converge

fsolveMATLAB

Is it true that for a system with unique solution, by supplying analytical Jacobian and Hessian, the fsolve procedure would always converge?

Best Answer

Nope. That is NOT a true statement. In fact, it is trivial to give a counter-example. One dimension is all that is needed, where fsolve would diverge to a point at infinity that is not a solution, yet the function has only a single real root. Whether analytical derivatives are provided or not, it can fail.
Of course, this depends on the start point. But you asked for assured convergence, so that means it must converge for ANY starting value.
If you think about it, I am sure you can construct a counter-example like that which I have in mind. If not, try this:
syms x
fs = sqrt(erfc(x)).*log(x) + 0.25;
vpasolve(fs)
ans =
0.65658394845178285500588834242862
There is a root, as vpasolve has found. Plot it.
f = @(x) sqrt(erfc(x)).*log(x) + 0.25;
ezplot(f,[.1,5])
grid on
Now try solving it, using fsolve. I'm too lazy to provide an analytical derivative, but that would prove no different. Fsolve is not that intelligent that it would matter.
fsolve(f,.5)
Equation solved.
fsolve completed because the vector of function values is near zero
as measured by the default value of the function tolerance, and
the problem appears regular as measured by the gradient.
<stopping criteria details>
ans =
0.656583948443698
But try it from a point above the hump, and fsolve will generally diverge. In practice, it will give up before it goes too far, at least on this function.
fsolve(f,2)
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
default value of the function tolerance.
<stopping criteria details>
ans =
6
If you insist, here is the first derivative:
diff(fs)
ans =
erfc(x)^(1 / 2)/x - (exp(-x^2)*log(x))/(pi^(1 / 2)*erfc(x)^(1 / 2))
I'm too lazy to actually run it though.