How to calculate a derivative of function numerically?
33 visualizaciones (últimos 30 días)
Mostrar comentarios más antiguos
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
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
Respuesta aceptada
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
0 comentarios
Más respuestas (1)
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.
0 comentarios
Ver también
Categorías
Más información sobre Symbolic Math Toolbox en Help Center y File Exchange.
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!