views:

1375

answers:

8

How is derivative of a f(x) is typically calculated programmatically to ensure maximum accuracy? I am implementing the Newton-Raphson method and it requires taking of the derivative of a function.

thanks

+4  A: 
fprime(x) = (f(x+dx) - f(x-dx)) / (2*dx)

for some small dx.

erikkallen
How small? thanks
vehomzzz
Mark
+7  A: 

Newton_Raphson assumes that you can have two functions f(x) and its derivative f'(x). If you do not have the derivative available as a function and have to estimate the derivative from the original function then you should use another root finding algorithm.

Wikipedia root finding gives several suggestions as would any numerical analysis text.

Mark
+24  A: 

I agree with erikkallen that (f(x + h) - f(x - h))/2h is the usual approach for numerically approximating derivatives. However, getting the right step size h is a little subtle.

The approximation error in (f(x + h) - f(x - h))/2h decreases as h gets smaller, which says you should take h as small as possible. But as h gets smaller, the error from floating point subtraction increases since the numerator requires subtracting nearly equal numbers. If h is too small, you can loose a lot of precision in the subtraction. So in practice you have to pick a not-too-small value of h that minimizes the combination of approximation error and numerical error.

As a rule of thumb, you can try h = SQRT(DBL_EPSILON) where DBL_EPSILON is the smallest double precision number e such that 1 + e != e in machine precision. DBL_EPSILON is about 10^-15 so you could use h = 10^-7 or 10^-8.

For more details, see these notes on picking the step size for differential equations.

John D. Cook
+1 Very interesting, looking into it.
vehomzzz
+1 for mentioning and explaining the stepsize dilemma
sellibitze
I think your rule of thumb assumes you use a first-order rule to approximate the derivative. However, the central difference rule you mention is second order, and the corresponding rule of thumb is h = EPSILON^(1/3) which is approximately 10^(-5) when using double precision.
Jitse Niesen
+1 excellent answer.
Stephen Canon
I think the accuracy can be improved a little by dividing by (x+h)-(x-h) instead of 2h. It's mathematically equivalent but not numerically.
sellibitze
+1 Great discussion of the tradeoff involved in choosing h
Martin B
Whould you mean instead "DBL_EPSILON is the smallest double precision number e such that **1 + e != 1** in machine precision."
yves Baumes
Choosing h depends on the derivative f'''(x).
Alexey Malistov
+1 great answer. I would surely have overlooked that very small sizes of h magnifies floating point errors. Thanks, I learned something today.
MAK
+5  A: 

What do you know about f(x)? If you only have f as a black box the only thing you can do is to numerically approximate the derivative. But the accuracy is usually not that good.

You can do much better if you can touch the code that computes f. Try "automatic differentiation". There some nice libraries for that available. With a bit of library magic you can convert your function easily to something that computes the derivative automatically. For a simple C++ example, see the source code in this German discussion.

sellibitze
+1  A: 

In addition to John D. Cooks answer above it is important not only to take into account the floating point precision, but also the robustness of the function f(x). For instance, in finance, it is a common case that f(x) is actually a Monte Carlo-simulation and the value of f(x) has some noise. Using a very small step size can in these cases severely degrade the accuracy of the derivative.

Rickard
+2  A: 
Alexey Malistov
epsilon should be 2^-53 for double, and 2^-24 for float (which is about 10^-16 and 10^-7, respectively).
Stephen Canon
epsilon is **relative** rounding error (not absolute). It is always about 10^{-16} for double and 10^-7 for float
Alexey Malistov
Yes, I know. In your answer, you say "epsilon -- relative rounding error, about 2^{-16} for double and 2^{-7} for float," which is plainly incorrect. The relative (forward) rounding error is also **not** always on that scale, but rather the backwards error. The forward error can be much, much larger when cancellation occurs, as is likely to happen here.
Stephen Canon
+3  A: 

You definitely want to take into account John Cook's suggestion for picking h, but you typically don't want to use a centered difference to approximate the derivative. The main reason is that it costs an extra function evaluation, if you use a forward difference, ie,

f'(x) = (f(x+h) - f(x))/h

Then you'll get value of f(x) for free because you need to compute it already for Newton's method. This isn't such a big deal when you have a scalar equation, but if x is a vector, then f'(x) is a matrix (the Jacobian), and you'll need to do n extra function evaluations to approximate it using the centered difference approach.

MikeT
A: 

Typically signal noise impacts the derivative quality more that anything else. If you do have noise in your f(x), Savtizky-Golay is a excellent smoothing algorithm that is often used to compute good derivatives. In a nutshell, SG fits a polynomial locally to your data, the then this polynomial can be used to compute the derivative.

Paul

Paul