1

I am a new user of MATLAB. I want to find the value that makes f(x) = 0, using the Newton-Raphson method. I have tried to write a code, but it seems that it's difficult to implement Newton-Raphson method. This is what I have so far:

function x = newton(x0, tolerance)
    tolerance = 1.e-10;
    format short e;
    Params = load('saved_data.mat');
    theta = pi/2;
    zeta = cos(theta);
    I = eye(Params.n,Params.n);
    Q = zeta*I-Params.p*Params.p';

    % T is a matrix(5,5)
    Mroot = Params.M.^(1/2);  %optimization
    T = Mroot*Q*Mroot;

    % Find the eigenvalues
    E = real(eig(T));

    % Find the negative eigenvalues
    % Find the smallest negative eigenvalue
    gamma = min(E);  

    % Now solve for lambda
    M_inv = inv(Params.M);  %optimization
    zm = Params.zm;

    x = x0;
    err = (x - xPrev)/x;

    while abs(err) > tolerance
        xPrev = x;
        x = xPrev - f(xPrev)./dfdx(xPrev);

        % stop criterion: (f(x) - 0) < tolerance
        err = f(x);
   end 

   % stop criterion: change of x < tolerance % err = x - xPrev;

end

The above function is used like so:

% Calculate the functions
Winv = inv(M_inv+x.*Q);

f = @(x)( zm'*M_inv*Winv*M_inv*zm);

dfdx = @(x)(-zm'*M_inv*Winv*Q*M_inv*zm);

x0 = (-1/gamma)/2;

xRoot = newton(x0,1e-10);
Chris
  • 44,602
  • 16
  • 137
  • 156
user1079331
  • 11
  • 1
  • 1
  • 6
  • 1
    So, what is th question? You just show your code... – Oli Dec 03 '11 at 20:24
  • I need to fix the code to make it work. – user1079331 Dec 04 '11 at 12:03
  • What sort of output are you getting? What are your functions that appear to not work with `fzero()`? – jblock Dec 04 '11 at 19:05
  • It gives the following error :??? Error using ==> fzero Function values at interval endpoints must be finite and real"".I think this is because there is complex entries in the equation. – user1079331 Dec 04 '11 at 19:13
  • @user1079331 can you show us what `Params.n`, `Params.p`, `Params.M` etc are? Then we are more likely to be able to help you debug your problem. – Chris Dec 05 '11 at 11:13

1 Answers1

3

The question isn't particularly clear. However, do you need to implement the root finding yourself? If not then just use Matlab's built in function fzero (not based on Newton-Raphson).

If you do need your own implementation of the Newton-Raphson method then I suggest using one of the answers to Newton Raphsons method in Matlab? as your starting point.

Edit: The following isn't answering your question, but is just a note on coding style.

It is useful to split your program up into reusable chunks. In this case your root finding should be separated from your function construction. I recommend writing your Newton-Raphson method in a separate file and call this from the script where you define your function and its derivative. Your source would then look some thing like:

% Define the function (and its derivative) to perform root finding on:
Params = load('saved_data.mat');
theta = pi/2;
zeta  = cos(theta);
I = eye(Params.n,Params.n);
Q = zeta*I-Params.p*Params.p';

Mroot = Params.M.^(1/2);
T = Mroot*Q*Mroot; %T is a matrix(5,5)

E = real(eig(T)); % Find the eigen-values

gamma = min(E);   % Find the smallest negative eigen value

% Now solve for lambda (what is lambda?)
M_inv = inv(Params.M);
zm = Params.zm;

Winv = inv(M_inv+x.*Q);

f = @(x)( zm'*M_inv*Winv*M_inv*zm);
dfdx = @(x)(-zm'*M_inv*Winv*Q*M_inv*zm);

x0 = (-1./gamma)/2.;

xRoot = newton(f, dfdx, x0, 1e-10);

In newton.m you would have your implementation of the Newton-Raphson method, which takes as arguments the function handles you define (f and dfdx). Using your code given in the question, this would look something like

function root = newton(f, df, x0, tol)

    root = x0; % Initial guess for the root

    MAXIT = 20; % Maximum number of iterations

    for j = 1:MAXIT;

        dx = f(root) / df(root);
        root = root - dx

        % Stop criterion:
        if abs(dx) < tolerance
            return
        end

    end

    % Raise error if maximum number of iterations reached.
    error('newton: maximum number of allowed iterations exceeded.')

end 

Notice that I avoided using an infinite loop.

Community
  • 1
  • 1
Chris
  • 44,602
  • 16
  • 137
  • 156
  • I have tried fzero but it doesn't work because there is a complex input in the equation.Also I had seen the answers of link you suggested ,but I need to fix this code. – user1079331 Dec 04 '11 at 12:12
  • @user1079331 Can you not just decompose your input equation into real and imaginary parts? Also, it may be helpful to spell out your problem (what equations you are using) and to clean up code code in the qeustion (for example, where is the `end` to your `while` loop?). – Chris Dec 04 '11 at 19:59
  • I don't decompose the input equation into real and imaginary parts. – user1079331 Dec 04 '11 at 20:14
  • I don't decompose the input equation into real and imaginary parts.The function is Winv = inv(M_inv+lambda.*Q); newton = zm'*M_inv*Winv*M_inv*zm; As you see Winv is a parameter in the equation just only and it contains the variable lambda that we should found it's value that make the derivative of the function above equals zero.The derivative is :Winv = inv(M_inv+lambda.*Q); newton = -zm'*M_inv*Winv*Q*M_inv*zm; – user1079331 Dec 04 '11 at 20:21