在SymPy 1.4中定义满足线性与莱布尼茨法则的导子函数
嘿,我懂你想要在SymPy 1.4里实现类似Mathematica那样的导子函数——满足线性性(d(f+g)=d(f)+d(g))和莱布尼茨乘积法则(d(f*g)=f*d(g)+d(f)*g)对吧?其实SymPy虽然没有Mathematica那种直接的模式匹配语法,但我们可以利用它的表达式类型系统和自定义函数来实现完全一样的效果,下面是具体的实现方案:
核心思路:利用SymPy的自定义函数+表达式类型判断
SymPy里所有的数学表达式都是对应类的实例(比如加法是Add,乘法是Mul),我们可以创建一个继承自Function的自定义函数d,然后在它的eval方法里根据表达式类型递归应用导子规则。
具体代码实现
from sympy import Function, Add, Mul, sympify, Symbol, Integer, Pow class d(Function): @classmethod def eval(cls, expr): # 先把输入转为SymPy表达式,确保兼容性 expr = sympify(expr) # 1. 处理加法:线性性规则 if isinstance(expr, Add): # 对每个加数递归应用d,再求和 return Add(*[cls(arg) for arg in expr.args]) # 2. 处理乘法:莱布尼茨法则 elif isinstance(expr, Mul): # 把乘积拆成两个部分(SymPy会自动处理多因子的情况,递归生效) f, g = expr.as_two_terms() return f * cls(g) + cls(f) * g # 3. 处理常数:常数的导子为0 elif isinstance(expr, Integer): return Integer(0) # 4. 处理单个变量:这里可以自定义变量的导子,比如d(x)=1 elif isinstance(expr, Symbol): # 你也可以改成其他表达式,比如如果是x就返回1,y返回某个函数之类的 return Integer(1) # 5. 可选:处理幂次(幂法则,其实是莱布尼茨法则的推论,直接写更高效) elif isinstance(expr, Pow): base, exp = expr.args return exp * base**(exp - 1) * cls(base) # 其他情况:返回原函数调用,留待后续扩展或者手动处理 return super().eval(expr)
测试一下效果
我们用几个例子验证规则是否生效:
# 定义变量 x, y = symbols('x y') # 测试加法:d(x+y) 应该返回 d(x)+d(y) = 1+1=2 print(d(x + y)) # 输出: 2 # 测试乘法:d(x*y) 应该返回 x*d(y)+d(x)*y = x*1 +1*y = x+y print(d(x * y)) # 输出: x + y # 测试混合表达式:d(x² + x*y) print(d(x**2 + x*y)) # 输出: 2*x + x + y = 3*x + y
扩展说明
- 如果你需要对特定变量或表达式自定义导子规则,只需要在
eval方法里添加对应的类型判断即可,比如对三角函数sin(x),可以加:from sympy import sin, cos elif isinstance(expr, sin): arg = expr.args[0] return cos(arg) * cls(arg) - SymPy 1.4的
Function.eval方法会自动在创建函数实例时尝试简化,所以递归调用会自动展开,和Mathematica的模式匹配效果一致。
内容的提问来源于stack exchange,提问作者physics_researcher
相关产品推荐
相关产品推荐

