如何在SymPy中利用hints参数阻止doit()计算特定子表达式?
如何通过SymPy的doit() hints参数保留Commutator结构同时计算积分?
你遇到的问题是:调用expr.doit()时,积分被计算的同时Commutator也被展开了,但你希望保留Commutator的[A,B]形式,只计算积分部分。
解决方案
直接在doit()中传入commutator=False的hint参数即可实现需求,修改后的代码如下:
from sympy import * from sympy.physics.quantum import Commutator A,B = symbols('A B', commutative=False) x = symbols('x') expr = 1 + Integral(Commutator(A,B),(x,0,2)) # 传入commutator=False的hint result = expr.doit(commutator=False) print(result)
运行后会得到期望的输出:
1 + 2*[A, B]
原理说明
SymPy中不同类型的未求值对象(比如Integral、Commutator)的doit()方法会各自处理传入的hints参数:
- Commutator的doit逻辑:源码中Commutator类的
doit()方法会检查是否存在commutator这个hint,当该hint设为False时,会直接返回自身,不执行展开操作。 - Integral的doit逻辑:Integral的
doit()方法不受commutatorhint的影响,依然会正常计算积分结果。
为什么之前的尝试无效?
- 使用
deep=False:这个参数会让doit()不递归处理子表达式,导致积分也不会被计算,所以得到的是未求值的原表达式。 - 用
UnevaluatedExpr包裹Commutator:UnevaluatedExpr的doit()方法会自动解开包裹并触发内部对象的doit(),所以Commutator还是会被展开。
内容的提问来源于stack exchange,提问作者DeafIdiotGod
相关产品推荐
相关产品推荐

