Borrar filtros
Borrar filtros

How to calculate a derivative of function numerically?

33 visualizaciones (últimos 30 días)
Denis Perotto
Denis Perotto el 22 de Sept. de 2018
Comentada: John D'Errico el 19 de Oct. de 2018
I have a continuous function of two variables:
f = @(x,y) x.^2 + (y-1).^2
How do I calculate a derivative of this function numerically? I tried two different ways and got errors:
% First try
df = @(x,y) diff(f(x,y),x)
df(1,2)
ans = []
% Second try
df = @(x,y) diff(f,x)
df(1,2)
Undefined function 'diff' for input arguments of type 'function_handle'
I must not set the derivative separately.
  7 comentarios
madhan ravi
madhan ravi el 19 de Oct. de 2018
ask a separate question @onur
John D'Errico
John D'Errico el 19 de Oct. de 2018
You can use higher order finite differences.
x = 2;
fun = @(x) sin(x);
-sin(x)
ans =
-0.909297426825682
dx = 1e-6;
(fun(x - dx) - 2*fun(x) + fun(x + dx))/dx^2
ans =
-0.909494701772928
dx = 1e-7;
(fun(x - dx) - 2*fun(x) + fun(x + dx))/dx^2
ans =
-0.899280649946377
But be careful, as if you use too small a delta, the scheme will go to hell quickly. Even derivest has difficulties for higher order derivatives, as things get unstable.
[df,errest] = derivest(fun,2,'deriv',2)
df =
-0.909297426825812
errest =
2.98009666234719e-12

Iniciar sesión para comentar.

Respuesta aceptada

Jan
Jan el 24 de Sept. de 2018
A numerical differentiation means a variation of the argument and a quotient of the differences:
df = (f(x + h) - f(x)) / h % one sided
df = (f(x + h) - f(x - h)) / (2*h) % two sided

Más respuestas (1)

John D'Errico
John D'Errico el 19 de Oct. de 2018
Editada: John D'Errico el 19 de Oct. de 2018
You can use symbolic tools to compute the derivative, if you have that toolbox. But if you wish todo so numerically, then you need to use numerical tools. They will never give a perfectly correct answer of course, since they at best use approximations to the result.
You can also use my derivest tools on the File Exchange. They use numerical approximations to compute the derivative, as well as estimate the error in that estimate.
For example, consider the function sin(x). We know the derivative of sin(x) is cos(x).
fun = @(x) sin(x);
We know that the derivative is defined in terms of a limit. Thus,
x = 1;
dx = 1e-12;
df = (fun(x + dx) - fun(x))/dx
df =
0.540345546085064
At x==1, we know the derivative is cos(1).
cos(1)
ans =
0.54030230586814
So the simple estimate, using dx == 1e-12 was not too terribly poor. Be careful though. Make dx too small, and things go to hell.
dx = eps
dx =
2.22044604925031e-16
df = (fun(x + dx) - fun(x))/dx
df =
0.5
which is clearly incorrect, even though MATLAB can compute the limit using symbolic tools.
syms x dx
limit((sin(x + dx) - sin(x))/dx,dx,0,'right')
ans =
cos(x)
Derivest is able to get itright, since it is designed to do just that.
[df,errest] = derivest(fun,1)
df =
0.54030230586814
errest =
1.47246694029184e-15
derivest nails it, and it tells you that it is confident of the result to within roughly 1.5e-15.
A better approximation comes from a higher order estimate.
dx = 1e-12;
df = (fun(x + dx) - fun(x - dx))/(2*dx)
df =
0.540290034933832
Again, in the limit, as x gets too small, things will get bad here too.
dx = eps
dx =
2.22044604925031e-16
df = (fun(x + dx) - fun(x - dx))/(2*dx)
df =
0.5
Limits don't always work that well when you push them in term of numerical computations. Derivest succeeds because it uses an extrapolatory scheme.

Categorías

Más información sobre Symbolic Math Toolbox en Help Center y File Exchange.

Productos


Versión

R2016b

Community Treasure Hunt

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

Start Hunting!

Translated by