4 views (last 30 days)

Show older comments

I create a function handle:

syms x;

f = @(x) x.^2 - sin(x) - 0.5;

And I take it into my Newton's method function:

function [r, i, Xnew] = Newton(f,a,b,tolerancia,errorfun,maxiter)

syms x;

fprime = @(x) diff(f(x),x);

h = (f(a)/fprime(a));

end

And I get these error messages:

Error using diff

Difference order N must be a positive integer scalar.

Error in Newton>@(x)diff(f(x),x) (line 3)

fprime = @(x) diff(f(x),x);

Error in Newton (line 4)

h = (f(a)/fprime(a));

I've tried simply assigning fprime as diff(f(x),x) as per the answer here, but that also produces an error - 'Array indices must be positive integers or logical values.'

Walter Roberson
on 12 May 2021

There are two completely different diff() functions in MATLAB.

The main one works with numeric data, and for it, diff(x) is x(2:end,:) - x(1:end-1,:) . That is the one you are accidentally invoking, and it is complaining because the optional second parameter, which controls the number of times that kind of difference is applied, must be a positive integer, not the data.

The one you thought you were getting is the symbolic toolbox calculuas derivative function. For it to work, diff(f(x),x) would require that x is a symbolic variable and f(x) returns a symbolic expression or symbolic function.

You did define

syms x;

but you proceeded to

f = @(x) x.^2 - sin(x) - 0.5;

which "shadows" x -- inside the anonymous function, x refers to the first input parameter, as if you had written

f = @(varargin) varargin{1}.^2 - sin(varargin{1}) - 0.5

which has no symbolic x inside it.

Inside the function, you do syms x, but when you

fprime = @(x) diff(f(x),x);

again you are shadowing x, and the effect is as-if you had written

fprime = @(varargin) diff(f(varargin{1}), varargin{1})

with no knowledge of the symbolic x. And as indicated earlier, your f is not a symbolic calculation either.

Your code is passing a numeric value into fprime, which is passing the numeric value to x, which calculates x^2-sin(x)-0.5 numerically, and then tries to calculate diff(numeric_result_of_f, numeric_input) which fails

So what do you do instead? This:

fprime = matlabFunction( diff(f(x),x) )

That will invoke f(x) on symbolic x, creating a symbolic expression, and then it would be diff() applied to a symbolic expression, which gives a symbolic result, and then the symbolic result would be converted into an anonymous function.

It is generally suggested that you only calculate fprime once and then pass the handle in to functions that need it.

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!