Search code examples
matlabnewtons-method

NOT CONVERGE: use Newton Raphson-Method to find root of nonlinear equations


I tried non-linear polynomial functions and this code works well. But for this one I tried several methods to solve the linear equation df0*X=f0 using backslash or bicg or lsqr, also tried several initial values but the result never converge.

% Define the given function
syms x1 x2 x3

x=[x1,x2,x3];

f(x)=[3*x1-cos(x2*x3)-1/2;x1^2+81*(x2+0.1)^2-sin(x3)+1.06;...
    exp(-x1*x2)+20*x3+1/3*(10*pi-3)];

% Define the stopping criteria based on Nither or relative errors

tol=10^-5; 
Niter=100;

df=jacobian(f,x);

x0=[0.1;0.1;-0.1];

% Setting starting values

error=1; 
i=0; 

% Start the Newton-Raphson Iteration

while(abs(error)>tol)

f0=eval(f(x0(1),x0(2),x0(3)));

df0=eval(df(x0(1),x0(2),x0(3))); 

xnew=x0-df0\f0; % also tried lsqr(df0,f0),bicg(df0,f0)

error=norm(xnew-x0);

x0=xnew;

i=i+1

if i>=Niter

    fprintf('Iteration times spill over Niter\n');

    return;

end

end

Solution

  • You'll need anonymous functions here to better do the job (we mentioned it in passing today!).

    First, let's get the function definition down. Anonymous functions are nice ways for you to call things in a manner similar to mathematical functions. For example,

    f = @(x) x^2;

    is a squaring function. To evaluate it, just write like you would on paper f(2) say. Since you have a multivariate function, you'll need to vectorize the definition as follows:

    f(x) = @(x) [3*x(1) - cos(x(2) * x(3)) - 1/2; ...

    For your Jacobian, you'll need to use another anonymous function (maybe call it grad_f) and compute it on paper, then code it in. The function jacobian uses finite differences and so the errors may pile up with the Jacobian is not stable in some regions.

    The key is to just be careful and use some good coding practices. See this document for more info on anonymous functions and other good MATLAB practices.