Reputation: 131
I am looking for a method to compute a derivative using a discrete and fast method. Since now I do not know the type of equation I have, I am looking for discrete methods analog to the ones that we can find for the integral such as, the Euler method.
Upvotes: 12
Views: 24885
Reputation: 8783
Automatic differentiation is the most accurate and conceptually awesome way of doing this kind of thing. Just a bit more complicated.
Upvotes: 2
Reputation: 20151
To do numerical differentiation, which is always an approximation, there are two common scenarios:
* Andrea's answer uses the forward difference operator {f(a+h) - f(a)}/h instead of the central difference operator {f(a+h) - f(a-h)}/2h, but the forward difference operator is less accurate in numerical solutions.
Upvotes: 4
Reputation: 39616
I think you are looking for the derivative calculated in a point. If this is the case, here there is a simple way to do that. You need to know the derivative in a point, say a. It is given by the limit of the difference quotient for h->0:
You actually need to implement the limit function. So you:
Now in a DO-WHILE loop:
1- divide h by 2 (or by 10, the important thing is to make it smaller)
2- calculate again the difference quotient with the new value of h, store this in f2
3- set diff = abs(f2-f1)
4- assign f1 = f2
5- repeat from point 1 while (diff>epsilon)
Remember: You are assuming the function is differentiable in a. Every result you will get will be wrong due of errors of the finite decimal digit your computer can handle, there is no escape from this.
Example in python:
def derive(f, a, h=0.01, epsilon = 1e-7):
f1 = (f(a+h)-f(a))/h
while True: # DO-WHILE
h /= 2.
f2 = (f(a+h)-f(a))/h
diff = abs(f2-f1)
f1 = f2
if diff<epsilon: break
return f2
print "derivatives in x=0"
print "x^2: \t\t %.6f" % derive(lambda x: x**2,0)
print "x:\t\t %.6f" % derive(lambda x: x,0)
print "(x-1)^2:\t %.6f" % derive(lambda x: (x-1)**2,0)
print "\n\nReal values:"
print derive(lambda x: x**2,0)
print derive(lambda x: x,0)
print derive(lambda x: (x-1)**2,0)
Output:
derivatives in x=0
x^2: 0.000000
x: 1.000000
(x-1)^2: -2.000000
Real values:
7.62939453125e-08
1.0
-1.99999992328
The first time I've got "precise" value" because of using only the first 6 digits of the result, note I used 1e-7 as epsilon. The REAL calculated values are printed after that, and they are obviously mathematically wrong. The choose of how small epsilon is depends on how precise you want your results to be.
Upvotes: 11
Reputation: 20928
Formally, no. Either you are describing the (partial) derivitives of discrete functions or you are asking for a numerical method to approximate the (partial) derivatives of continuous functions.
Discrete functions don't have derivatives. If you review the epsilon-delta definition of a derivative, you will see that you would need to be able to evaluate the function close to the point you want the derivative at. That doesn't make sense if the function only has values at integer values of x, y and z. So there is no way to find the derivative of a discrete function for any value of fast.
If you want a numerical method exactly calculate the derivatives of a continuous function, you're out of luck as well. Numerical methods for derivatives are heuristic, not algorithmic. There is no numerical method which guarantees an exact solution. Fortunately, there exist many good heuristics. Mathematica uses a specialized version of Brent's principle axis method by default. I would recommend you use the GNU Scientific Library, which has a very good implementation of Brent's method. I owe my entire grade in one of my math courses to the GSL. The ruby bindings are pretty good if that's your thing. If necessary, most numerical differentiation libraries have a handful of different methods available.
If you really want, I can whip out some sample code. Let me know.
Upvotes: 1
Reputation: 6649
If the function is linear as you have indicated then the derivatives are trivial. The derivative with respect to 'x' is 'a'; the derivative with respect to 'y' is 'b' and the derivative with respect to 'z' is 'c'. If the equation is of a more complex form and you need a formula representing the solution rather than an empirical solution, then please submit the more complex form of the equation.
Regards
Upvotes: -1
Reputation: 107774
There is quite a bit of theory (and established practice) in calculating numerical ("finite") derivatives. Getting all the details correct, such that you believe the result, is not trivial. If there's any way you can get the analytical derivative of the function (using pen and paper, or a computer algebra system such as Maple, Mathematica, Sage, or SymPy), this is by far the best option.
If you can't get the analytical form, or you don't know the function (just it's output), then numerical estimation are your only option. This chapter in Numerical Recipies in C is a good start.
Upvotes: 7
Reputation:
Short of using a symbolic math language, like Maple, the best you can do is to approximate the derivative at various points. (And then interpolate, if you need a function.)
If you've already got the function you want to use, then you should use the backward divided-difference forumla, and Richardson extrapolation to improve your error.
Also keep in mind that these methods work on functions of one variable. However, partial derivatives of each variable treat the other variables as constants.
Upvotes: 2
Reputation: 57188
A simple method is to compute the change in f over a small value for each point of the derivative you're interested in. For example, to compute ∂f/∂x, you could use this:
epsilon = 1e-8
∂f/∂x(x, y, z) = (f(x+epsilon,y,z) - f(x-epsilon, y, z))/(epsilon * 2);
The other partials would be similar in y and z.
The value chosen for epsilon depends on the contents of f, the precision required, the floating point type used, and probably other things. I suggest you experiment with values for it with functions you're interested in.
Upvotes: 4
Reputation: 309028
I'll assume that your function is more complex than the simple one you posted, because the closed-form solution is far too simple.
When you use the word "discrete" it makes me think you need "finite differences". You'll need some discretization to calculate the approximation.
Df/Dx ~ (f2-f1)/(x2-x1), etc.
Upvotes: 0