[英]Returning automatic derivatives with Sympy
I'm trying to build a class whose goal is returning the derivative of a function f
also as a function. 我正在尝试建立一个类,其目标是将函数f
的派生也作为函数返回。 I've read about Sympy and I started to try it with this package. 我已经阅读了有关Sympy的文章,并开始尝试使用此软件包。
Let's suppose that I have a simple function with only one parameter, like this: 假设我有一个只有一个参数的简单函数,如下所示:
def f1p(x):
return x**2 + 5**x * 2*x + 1
Now, I have a method that ensures the funcion has one only paramether and then calculates the derivative (only as expression): 现在,我有一种方法可以确保函数只有一个参数,然后计算导数(仅作为表达式):
from sympy import *
import inspect
def get_derivative(fun):
parameters=inspect.getargspec(f).args
if(len(parameters)>1):
raise ValueError('Function has more than one parameter.')
fdiff=fun(Symbol(parameters[0])).diff()
print(fdiff)
Let's say that fdiff
contains the main expression of derivative function, so, the problem I want to solve is returning a function in order to evaluate it, for example: 假设fdiff
包含派生函数的主要表达式,因此,我要解决的问题是返回一个函数以对其求值,例如:
f_deriv=get_derivative(f1p) #f_deriv is a callable function
print(f_deriv(a)) #Prints derivative value of f1p in a
Note: I've try return eval/exec(diff)
but is a bad idea, because declaring parameters is needed. 注意:我已经尝试return eval/exec(diff)
但这是一个坏主意,因为需要声明参数。 Also I tried to wrap the expresion with: 我也尝试用以下方式包装表达式:
eval('def foo('+parameters[0]+'):\n\treturn '+diff)
And it still is not a good idea. 这仍然不是一个好主意。
Suppose now we use (for example) logarithms in our base function, so, we implement it this way 假设现在我们在基本函数中使用(例如)对数,因此我们以这种方式实现
import math
def f1p(x):
return x**2 + 5**x * 2*x + 1 + math.log(x)
When I apply the previous function to this, I get the following error: 当我对此应用上一个函数时,出现以下错误:
TypeError: can't convert expression to float
This is due to Sympy is not capable of understand math.log(x)
. 这是由于Sympy无法理解math.log(x)
。 So, my questions are: 因此,我的问题是:
get_derivative
function? 解决主要问题:有什么方法可以从get_derivative
函数返回可调用函数? Thanks in advance. 提前致谢。
You could use lambdify to return callable from your get_derivative
: 您可以使用lambdify从get_derivative
返回callable:
import inspect
from sympy import symbols, diff
from sympy.utilities.lambdify import lambdify
def get_derivative(function):
if len(inspect.getfullargspec(function).args) > 1:
raise ValueError('Function has more than one parameter.')
x = symbols('x')
return lambdify(x, diff(f1p(x), x))
Checking result for your first f1p
version: 您的第一个f1p
版本的检查结果:
def f1p(x):
return x**2 + 5**x * 2*x + 1
derivative = get_derivative(f1p)
derivative(1)
This will give 28.094379124341003
. 这将给28.094379124341003
。 It's a correct result. 这是正确的结果。
Now, if you want to use logarithm, then you should use the one from sympy , not from math : 现在,如果要使用对数,则应该使用sympy而不是math的对数 :
from sympy import log
def f1p(x):
return x**2 + 5**x * 2*x + 1 + log(x)
derivative = get_derivative(f1p)
derivative(1)
This will give 29.094379124341003
. 这将给29.094379124341003
。 Also correct. 也正确。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.