Reputation: 248
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
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, 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