0

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 [].

Adriaan
  • 17,741
  • 7
  • 42
  • 75
Buzi
  • 248
  • 3
  • 12
  • The function `diff` returns the difference between elements in a vector. See diff>. You need to get at least two values in when calling `fp` – Jørgen Nov 20 '15 at 12:44

1 Answers1

1

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!

rayryeng
  • 102,964
  • 22
  • 184
  • 193
  • Thanks for the answer! Tho I guess I'm missing something. Do I need to create the symbolic definition of my function f in the command windows or as a new 'm' file? – Buzi Nov 22 '15 at 06:43
  • @Buzi No, you don't need to make a new M file for the original function and its derivative. You create your function handles directly in the code. Simply take the code I wrote above, put it in a new M file and run it. I got it to run and that's how I got my answer. BTW, when you get this to work, if you don't need any more help, consider accepting my answer to signify to the SO community that you don't need more help. Good luck! – rayryeng Nov 22 '15 at 07:13
  • Should I call the new M file with a specific name? And sure, I will mark your answer as helpful :) – Buzi Nov 22 '15 at 07:15
  • Yeah call it something like, `newtontest.m`, put the above code in this file, then run it. You'll get the root and iterations when you're done... and thanks! – rayryeng Nov 22 '15 at 07:16
  • I keep getting an error: Error in newtontest (line 2) syms x; – Buzi Nov 22 '15 at 07:19
  • To use 'syms', you might need: syms - Symbolic Math Toolbox Error in newtontest (line 2) syms x; – Buzi Nov 22 '15 at 07:21
  • oh boy... yeah you don't have that toolbox... so what I suggested won't work. I'll have to reformulate so you work with the discrete approximation to the derivative. You don't have a choice here. – rayryeng Nov 22 '15 at 07:21
  • Yes! Thank you very much! – Buzi Nov 22 '15 at 08:09