您如何评估 python 中的导数?
How do you evaluate a derivative in python?
我是 python 的初学者。我最近了解了 Sympy 及其符号操作功能,尤其是微分功能。我正在尝试以最简单的方式执行以下操作:
- 定义 f(x,y) = x^2 + xy^2。
- 关于 x 对 f 求微分。所以 f'(x,y) = 2x + xy^2.
- 计算导数,例如 f'(1,1) = 2 + 1 = 3。
我知道如何执行 1 和 2。问题是,当我尝试在步骤 3 中计算导数时,出现 python 无法计算导数的错误。这是一个最小的工作示例:
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))
我希望最后一行打印 3。它没有打印任何内容,并显示 "can't calculate the 1st derivative wrt 1"。
当您在函数 fprime(x,y) 中调用 fprime(1,1) 时,您可以这样调用它 sym.diff(f(1,1),1)
您必须为 x 和 x 的值使用不同的变量
您的函数 fprime
不是导数。它是 returns 导数的函数(作为 Sympy 表达式)。要评估它,您可以使用 .subs
将值插入此表达式:
>>> fprime(x, y).evalf(subs={x: 1, y: 1})
3.00000000000000
如果你想让fprime
真正成为导数,你应该将导数表达式直接赋值给fprime
,而不是将它包装在一个函数中。那么就可以直接evalf
了:
>>> fprime = sym.diff(f(x,y),x)
>>> fprime.evalf(subs={x: 1, y: 1})
3.00000000000000
这个问题的答案很简单。当然,另一个答案中给出的 subs
选项适用于评估数字的导数,但如果你想绘制导数,它就不起作用。有一种方法可以解决此问题:lambdify,如下所述。
使用 lambdify 将所有 sympy 函数(可微分但不可求值)转换为对应的 numpy 函数(可求值、绘图等,但不可微分)。例如,sym.sin(x) 将替换为 np.sin(x)。这个想法是:使用 sympy 函数定义函数,根据需要区分,然后定义一个新函数,它是原始函数的 lambdified 版本。
如以下代码所示,sym.lambdify 采用以下输入:
sym.lambdify(variable, function(variable), "numpy")
第三个输入 "numpy" 是用对应的 numpy 函数替换 sympy 函数的。一个例子是:
def f(x):
return sym.cos(x)
def fprime(x):
return sym.diff(f(x),x)
fprimeLambdified = sym.lambdify(x,f(x),"numpy")
然后函数fprime(x)
returns -sym.sin(x)
,以及函数fprimeLambdified(x)
returns -np.sin(x)
。我们现在可以 "call"/评估 fprimeLambdified
在特定的输入值,而我们不能 "call"/评估 fprime
,因为前者由 numpy 表达式和后者的 sympy 表达式组成。换句话说,输入 fprimelambdified(math.pi)
是有意义的,这将 return 一个输出,而 fprime(math.pi)
将 return 一个错误。
下面是一个在多个变量中使用 sym.lambdify
的示例。
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))
我是 python 的初学者。我最近了解了 Sympy 及其符号操作功能,尤其是微分功能。我正在尝试以最简单的方式执行以下操作:
- 定义 f(x,y) = x^2 + xy^2。
- 关于 x 对 f 求微分。所以 f'(x,y) = 2x + xy^2.
- 计算导数,例如 f'(1,1) = 2 + 1 = 3。
我知道如何执行 1 和 2。问题是,当我尝试在步骤 3 中计算导数时,出现 python 无法计算导数的错误。这是一个最小的工作示例:
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))
我希望最后一行打印 3。它没有打印任何内容,并显示 "can't calculate the 1st derivative wrt 1"。
当您在函数 fprime(x,y) 中调用 fprime(1,1) 时,您可以这样调用它 sym.diff(f(1,1),1)
您必须为 x 和 x 的值使用不同的变量
您的函数 fprime
不是导数。它是 returns 导数的函数(作为 Sympy 表达式)。要评估它,您可以使用 .subs
将值插入此表达式:
>>> fprime(x, y).evalf(subs={x: 1, y: 1})
3.00000000000000
如果你想让fprime
真正成为导数,你应该将导数表达式直接赋值给fprime
,而不是将它包装在一个函数中。那么就可以直接evalf
了:
>>> fprime = sym.diff(f(x,y),x)
>>> fprime.evalf(subs={x: 1, y: 1})
3.00000000000000
这个问题的答案很简单。当然,另一个答案中给出的 subs
选项适用于评估数字的导数,但如果你想绘制导数,它就不起作用。有一种方法可以解决此问题:lambdify,如下所述。
使用 lambdify 将所有 sympy 函数(可微分但不可求值)转换为对应的 numpy 函数(可求值、绘图等,但不可微分)。例如,sym.sin(x) 将替换为 np.sin(x)。这个想法是:使用 sympy 函数定义函数,根据需要区分,然后定义一个新函数,它是原始函数的 lambdified 版本。
如以下代码所示,sym.lambdify 采用以下输入:
sym.lambdify(variable, function(variable), "numpy")
第三个输入 "numpy" 是用对应的 numpy 函数替换 sympy 函数的。一个例子是:
def f(x):
return sym.cos(x)
def fprime(x):
return sym.diff(f(x),x)
fprimeLambdified = sym.lambdify(x,f(x),"numpy")
然后函数fprime(x)
returns -sym.sin(x)
,以及函数fprimeLambdified(x)
returns -np.sin(x)
。我们现在可以 "call"/评估 fprimeLambdified
在特定的输入值,而我们不能 "call"/评估 fprime
,因为前者由 numpy 表达式和后者的 sympy 表达式组成。换句话说,输入 fprimelambdified(math.pi)
是有意义的,这将 return 一个输出,而 fprime(math.pi)
将 return 一个错误。
下面是一个在多个变量中使用 sym.lambdify
的示例。
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))