Buzi
Buzi

Reputation: 248

Differentiation using MATLAB

I'm trying to write a small program using MATLAB in which I try to differentiate a function that I created inside a different function, but I keep getting errors.

My files are:

newton.m:

function [ y, iter ] = newton( f, fp, x0 )

    iter = 0;
    xprev = x0;
    x = xprev - f(xprev)/fp(xprev);

    iter = iter + 1;

    while abs(x-xprev) > eps*abs(x)
        xprev = x;
        x = x - f(x)/fp(x);
        iter = iter + 1;
        y = x;
    end
end  

f.m:

function y = f(x)
    y = tan(x) - 2*x;
end  

fp.m:

function y = fp(f)
    y = diff(f);
end

I'm running the following:

[y, iter] = newton(@f, @fp, 1.4)  

and getting:

Error using /
Matrix dimensions must agree.

Error in newton (line 6) x = xprev - f(xprev)/fp(xprev);

When I'm checking the value of y in fp.m I keep getting [].

Upvotes: 0

Views: 1118

Answers (1)

rayryeng
rayryeng

Reputation: 104464

You are trying to use diff to differentiate a function. Out-of-the-box diff performs a difference operation between pairs of elements. You don't want this. Instead, make your f and fp as actual function handles. First create the symbolic definition of your function f, then differentiate this symbolic representation using the symbolic version of diff (which you can just call with diff itself), then create a MATLAB function with matlabFunction out of this:

%// Define symbolic variable
syms x;

%// Define function symbolically
y = tan(x) - 2*x;

%// Define function handles (numerical) to the original and derivative
f = matlabFunction(y); 
fp = matlabFunction(diff(y));

%// Now call Newton's Method
[y, iter] = newton(f, fp, 1.4);  

Take note that f and fp are already function handles. That's what matlabFunction returns, so there isn't a need to create a handle via @ as inputs into your Newton's Method function anymore.

Running this modification to your code, I get this for the root with the initial guess at x = 1.4 and the amount of iterations it took:

>> format long g
>> y

y =

          1.16556118520721

>> iter

iter =

     8

If the Symbolic Mathematics Toolbox is missing...

If, for some reason, you don't have the Symbolic Mathematics Toolbox, then what I suggested won't work. As such, you don't have a choice but to use the discrete approximation of the derivative to get this to work. However, we can still work with the code I wrote above, but fp will have to be defined differently.

If you recall, the definition of the derivative is such that:

To get this to work in the discrete case, you make Δx very small... something like 1e-10 for example.

As such, you would do this instead with anonymous functions:

%// Define function
f = @(x) tan(x) - 2*x;

%// Define derivative
h = 1e-10;
fp = @(x) (f(x + h) - f(x)) / h;

%// Now call Newton's Method
[y, iter] = newton(f, fp, 1.4); 

With this, I get:

>> format long g;
>> y

y =

          1.16556118520721

>> iter

iter =

     8

I'd say that's pretty darn close!

Upvotes: 1

Related Questions