Hi Mi,
it is difficoult to give a precise answer without a deeper knowledge of the equation which has to be solved. Unfortunately, convergency issues are very often found with Newton-Raphson, or any other method to solve nonlinear equations.
Up to my (very limited) experience, I can give you a few advices:
- You could try to use Matlab fsolve function instead of writing a custom nonlinear solver.
- From your code, I see that the only convergency test is on the absolute variation of the candidate solution (abs(g-g0)<eps). Perhaps you ought to test also the residual. Kelley suggests to test
, where x = current iterate,
= initial quest, the equation to be solved is
, and
and
are respectivel the relative and absolute tolerances. - Most importantly, you could implement strategies like Armijo rule, also known as "backtracking". In practice, at each iteration compute the tentative direction (in your code -fin/dfun). Then, instead of just computing the next iterate g=g0-fun/dfun, an inner loop is added so as to ensure that the residual is reduced at the next iteration. This can greatly improve the convergency properties of Newton-Raphson method.
I can provide the following code, which is extremely simplistic and not at all optimized, which illustrate these concepts on a simple case. The (scalar) equation which is solved is:
, the solution of which is obviously
. It can be observed that the method diverges is Armijo rule is not used. x = linspace(-5, 5, 1024);
plot(x, f(x)) ; grid on ; hold on
xlabel('x') ; ylabel('f(x)');
while use_armijo && abs(f(x)) < abs(f(x+delta_x))
fprintf('x = %20.15f\n', x);
if abs(f(x)) < tau_r*(abs(f0)) + tau_a
disp('*** Convergence ***');
plot(x, f(x), 'r+', 'MarkerSize', 12);
end
x = 4.737878027780923
x = 1.820188841802746
x = 1.525092387763806
x = 1.556934889460351
x = 1.557407623013678
x = 1.557407724654897
I may suggest to read the book: C.T. Kelley, Solving nonlinear equations with Newton's method, SIAM (ISBN 0-89871-546-6). It contains many Matlab codes, and it is only 100 pages long.
I hope it helps.