Effacer les filtres
Effacer les filtres

How to calculate a derivative of function numerically?

57 vues (au cours des 30 derniers jours)
Denis Perotto
Denis Perotto le 22 Sep 2018
Commenté : John D'Errico le 19 Oct 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 commentaires
madhan ravi
madhan ravi le 19 Oct 2018
ask a separate question @onur
John D'Errico
John D'Errico le 19 Oct 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

Connectez-vous pour commenter.

Réponse acceptée

Jan
Jan le 24 Sep 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

Plus de réponses (1)

John D'Errico
John D'Errico le 19 Oct 2018
Modifié(e) : John D'Errico le 19 Oct 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.

Catégories

En savoir plus sur Symbolic Math Toolbox dans Help Center et File Exchange

Produits


Version

R2016b

Community Treasure Hunt

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

Start Hunting!

Translated by