I asked a question yesterday regarding differentiating a python function and then when I found that none of the answers posted were satisfactory for my need of evaluating (in some variables) and then plotting the derivative, I was able to figure out my own solution.
Previous code:
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.
print(fprime(1,1))
New code:
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))
As you can see, I overcame the inability to evaluate the derivative fprime by creating a new function DerivativeOfF which was the "lambdified" version of fprime. From there, I was able to evaluate DerivativeOfF, and also plot it in one of the variables.
My question is: why did this work? What exactly have I done? And what are some downsides to this method? I have tried reading the lambdify documentation but it's extremely confusing to me (I'm a beginner in Python). My guess is that I converted the Python function fprime to a Sympy expression DerivativeOfF, or something like that. Any help explaining what happened and why, and what exactly lambdify does (in layman's terms), would be appreciated.
Let's see if I can illustrate this action. I known Python and
numpywell, but haven't usedsympymuch (but have used other symbolic algebra packages likemacsyma).In a ipython numpy session:
fis a python function; what it returns depends on how the inputs handle operations like*,**and+. Scalars and arrays work. Lists handle+and*(concatenate, replicate) but not**.Defining
symbolscreates a couple of new objects. They handle+etc in their own symbolic way.Calling
fwith these 2 symbol objects creates a new sym object. I can also call it with other combinations of symbols and numbers or even arrays.If I pass this
Addobject tosym.diffI get a newAddobjectNeither
fsymnorfprimeare callable. They are not Python functions.fsym(1,2)does not work.But
fsym.subscan be used to replacexor/andywith other values, whether numbers or other symbols:lambdifyis asympyfunction that takes a sympy object and returns a Python function, possiblynumpycompatible`.This
flfunction is similar to the originalf. It's not identical, for example it has ahelp/docexpression.lambdifyapplied tofprimedoes the same thing, but with a different symbolic expression:This transparency between python/numpy functions or expressions and sympy ones has limits. The other (deleted) answer tried to explore those. For example there's a difference between
math.sin,numpy.sinandsym.sin.In these examples, differentiation is done symbolically by the
sym.difffunction.sym.lambdifyis just a way of converting either of these sympy objects into a Python function.trig example
Picking up the example in the discussion for the other answer
Defining a function that uses the
symversions of sin/cos:I think that because
sym.sin(<array>)does not work; it would have to benp.sin(...), but that doesn't work with symbols.As before we can take symbolic derivatives:
Again none of these a functions. Evaluation has to be done with
subsorlambdify.I can evaluate
f2with array inputs, where as I couldn't withf1. Presumablysympyas substitutednp.sinforsym.sin.In fact when I try to evaluate
f2with a symbol,numpycomplains: