Hint: Use a recursive routine. If an operation is unary plus or minus, leave the plus or minus sign alone and continue with the operand. (That means, recursively call the derivative routine on the operand.) If an operation is addition or subtraction, leave the plus or minus sign alone and recursively find the derivative of each operand. If the operation is multiplication, use the product rule. If the operation is division, use the quotient rule. If the operation is exponentiation, use the generalized power rule. (Do you know that rule, for u ^ v? It is not given in most first-year calculus books but is easy to find using logarithmic differentiation.) (Now that you have clarified in a comment that there will be no variable in the exponent, you can use the regular power rule (u^n)' = n * u^(n-1) * u' where n is a constant.) And at the base of the recursion, the derivative of x is 1 and the derivative of a constant is zero.
The result of such an algorithm would be very un-simplified but it would meet your stated requirements. Since this algorithm looks at an operation then looks at the operands, having the expression in Polish notation may be simpler than reverse Polish or "regular expression." But you could still do it for the expression in those forms.
If you need more detail, show us more of your work.
Answer from Rory Daulton on Stack OverflowVideos
Im currently a student and I'm trying to use python to make a program to calculate basic derivatives, but i've hit a bit of a wall and am looking for any ideas to help me out. The only thing i have to work off of is the basic equation (F(x-h)-F(x))/h. I can't get python to let me leave x or as a variable until after its done the operation. Is there anyway i can have x and h inputed after this has been done?
You have four options
- Finite Differences
- Automatic Derivatives
- Symbolic Differentiation
- Compute derivatives by hand.
Finite differences require no external tools but are prone to numerical error and, if you're in a multivariate situation, can take a while.
Symbolic differentiation is ideal if your problem is simple enough. Symbolic methods are getting quite robust these days. SymPy is an excellent project for this that integrates well with NumPy. Look at the autowrap or lambdify functions or check out Jensen's blogpost about a similar question.
Automatic derivatives are very cool, aren't prone to numeric errors, but do require some additional libraries (google for this, there are a few good options). This is the most robust but also the most sophisticated/difficult to set up choice. If you're fine restricting yourself to numpy syntax then Theano might be a good choice.
Here is an example using SymPy
In [1]: from sympy import *
In [2]: import numpy as np
In [3]: x = Symbol('x')
In [4]: y = x**2 + 1
In [5]: yprime = y.diff(x)
In [6]: yprime
Out[6]: 2⋅x
In [7]: f = lambdify(x, yprime, 'numpy')
In [8]: f(np.ones(5))
Out[8]: [ 2. 2. 2. 2. 2.]
The most straight-forward way I can think of is using numpy's gradient function:
x = numpy.linspace(0,10,1000)
dx = x[1]-x[0]
y = x**2 + 1
dydx = numpy.gradient(y, dx)
This way, dydx will be computed using central differences and will have the same length as y, unlike numpy.diff, which uses forward differences and will return (n-1) size vector.
Your function fprime is not the derivative. It is a function that returns the derivative (as a Sympy expression). To evaluate it, you can use .subs to plug values into this expression:
>>> fprime(x, y).evalf(subs={x: 1, y: 1})
3.00000000000000
If you want fprime to actually be the derivative, you should assign the derivative expression directly to fprime, rather than wrapping it in a function. Then you can evalf it directly:
>>> fprime = sym.diff(f(x,y),x)
>>> fprime.evalf(subs={x: 1, y: 1})
3.00000000000000
The answer to this question is pretty simple. Sure, the subs option given in the other answer works for evaluating the derivative at a number, but it doesn't work if you want to plot the derivative. There is a way to fix this: lambdify, as explained below.
Use lambdify to convert all of the sympy functions (which can be differentiated but not evaluated) to their numpy counterparts (which can be evaluated, plotted, etc., but not differentiated). For example, sym.sin(x) will be replaced with np.sin(x). The idea is: define the function using sympy functions, differentiate as needed, and then define a new function which is the lambdified version of the original function.
As in the code below, sym.lambdify takes the following inputs:
sym.lambdify(variable, function(variable), "numpy")
The third input, "numpy", is what replaces sympy functions with their numpy counterparts. An example is:
def f(x):
return sym.cos(x)
def fprime(x):
return sym.diff(f(x),x)
fprimeLambdified = sym.lambdify(x,f(x),"numpy")
Then the function fprime(x) returns -sym.sin(x), and the function fprimeLambdified(x) returns -np.sin(x). We can "call"/evaluate fprimeLambdified at specific input values now, whereas we cannot "call"/evaluate fprime, since the former is composed of numpy expressions and the latter sympy expressions. In other words, it makes sense to input fprimelambdified(math.pi), and this will return an output, while fprime(math.pi) will return an error.
An example of using sym.lambdify in more than one variable is seen below.
import sympy as sym
import math
def f(x,y):
return x**2 + x*y**2
x, y = sym.symbols('x y')
def fprime(x,y):
return sym.diff(f(x,y),x)
print(fprime(x,y)) #This works.
DerivativeOfF = sym.lambdify((x,y),fprime(x,y),"numpy")
print(DerivativeOfF(1,1))
diff is a "wrapper" method that it is going to instantiate the Derivative class. So, doing this:
from sympy import *
expr = x**2
expr.diff(x)
# out: 2*x
is equivalent to do:
Derivative(expr, x).doit()
# out: 2*x
However, the Derivative class might be useful to delay the evaluation of a derivative. For example:
Derivative(expr, x)
# out: Derivative(x**2, x)
But the same thing can also be achieved with:
expr.diff(x, evaluate=False)
# out: Derivative(x**2, x)
So, to answer your question, in the example you provided there is absolutely no difference in using diff vs Derivative.
If expr.diff(variable) can be evaluated, it will return an instance of Expr (either a symbol, a number, multiplication, addition, power operation, depending on expr). Otherwise, it will return an object of type Derivative.
The Derivative object represents an unevaluated derivative. It will never evaluate, for example:
>>> Derivative(x**2, x)
Derivative(x**2, x)
diff is a function which always tries to evaluate the derivative. If the derivative in question cannot be evaluated, it just returns an unevaluated Derivative object.
>>> diff(x**2, x)
2*x
Since undefined functions are always things whose derivatives won't be evaluated, Derivative and diff are the same.
>>> diff(f(x), x)
Derivative(f(x), x)
>>> Derivative(f(x), x)
Derivative(f(x), x)
There's only a difference between the two in cases where the derivative can be evaluated. For ODEs, this means that it generally doesn't matter, except maybe if you have something like the following that you don't want expanded
>>> diff(x*f(x), x)
x*Derivative(f(x), x) + f(x)
>>> Derivative(x*f(x), x)
Derivative(x*f(x), x)