英文:
Why is there an issue with substituting matrices into sympy nested commutators?
问题
我正在使用sympy.physics.quantum中的Commutator类,并遇到了计算矩阵的嵌套对易子的问题。出于某种原因,我发现将矩阵代替符号,然后使用```expression.doit()```计算对易子表达式会产生一个零矩阵(这是错误的)。另一方面,如果我展开对易子表达式,然后将矩阵代替符号,我会得到正确的答案。为什么会发生这种情况?
以下代码复现了这个错误:
```python
import sympy as sp
tau_1, tau_2, tau_3 = sp.symbols('tau_1 tau_2 tau_3')
A = sp.symbols("A", commutative=False, cls=sp.Function)(tau_1)
B = sp.symbols("B", commutative=False, cls=sp.Function)(tau_2)
C = sp.symbols("C", commutative=False, cls=sp.Function)(tau_3)
matrix_from_symbol = {
A: sp.Matrix([[sp.sin(tau_1),sp.sin(tau_1)],[sp.sin(tau_1),1+sp.sin(tau_1)]]),
B: sp.Matrix([[sp.sin(tau_2),sp.sin(tau_2)],[sp.sin(tau_2),1+sp.sin(tau_2)]]),
C: sp.Matrix([[sp.sin(tau_3),sp.sin(tau_3)],[sp.sin(tau_3),1+sp.sin(tau_3)]]),
}
from sympy.physics.quantum import Commutator
expression = Commutator(A,Commutator(B,C))
doit_then_subs = expression.doit().subs(matrix_from_symbol,simultaneous=True).simplify()
sp.pprint(doit_then_subs) #给出一个非零矩阵;正确答案
subs_then_doit = expression.subs(matrix_from_symbol,simultaneous=True).doit()
sp.pprint(subs_then_doit) #给出一个零矩阵
英文:
I am using the Commutator class from sympy.physics.quantum and ran into an issue calculating nested commutators of matrices. For some reason, I find that substituting matrices for symbols and then evaluating the commutator expression with expression.doit()
produces a zero matrix (which is incorrect). On the other hand, if I expand the commutator expressions and then substitute matrices for the symbols, I get the correct answer. Why does this occur?
The following code reproduces the error:
import sympy as sp
tau_1, tau_2, tau_3 = sp.symbols('tau_1 tau_2 tau_3')
A = sp.symbols("A", commutative=False, cls=sp.Function)(tau_1)
B = sp.symbols("B", commutative=False, cls=sp.Function)(tau_2)
C = sp.symbols("C", commutative=False, cls=sp.Function)(tau_3)
matrix_from_symbol = {
A: sp.Matrix([[sp.sin(tau_1),sp.sin(tau_1)],[sp.sin(tau_1),1+sp.sin(tau_1)]]),
B: sp.Matrix([[sp.sin(tau_2),sp.sin(tau_2)],[sp.sin(tau_2),1+sp.sin(tau_2)]]),
C: sp.Matrix([[sp.sin(tau_3),sp.sin(tau_3)],[sp.sin(tau_3),1+sp.sin(tau_3)]])
}
from sympy.physics.quantum import Commutator
expression = Commutator(A,Commutator(B,C))
doit_then_subs = expression.doit().subs(matrix_from_symbol,simultaneous=True).simplify()
sp.pprint(doit_then_subs) #gives a non-zero matrix; correct answer
subs_then_doit = expression.subs(matrix_from_symbol,simultaneous=True).doit()
sp.pprint(subs_then_doit) #gives a zero matrix
答案1
得分: 0
问题是,sympy 在评估 A.subs(matrix_from_symbols, simultaneous=True) * Commutator(B, C).subs(matrix_from_symbol, simultaneous=True)
时不执行矩阵乘法。相反,它似乎将 Commutator(B, C)
视为标量,产生以下结果:
⎡⎡sin(τ₂) sin(τ₂) ⎤ ⎡sin(τ₃) sin(τ₃) ⎤⎤ ⎡⎡sin(τ₂)
⎢⎢ ⎥,⎢ ⎥⎥ sin(τ₁)⋅⎢⎢
⎣⎣sin(τ₂) sin(τ₂) + 1⎦ ⎣sin(τ₃) sin(τ₃) + 1⎦⎦ ⎣⎣sin(τ₂)
⎡⎡sin(τ₂) sin(τ₂) ⎤ ⎡sin(τ₃) sin(τ₃) ⎤⎤ ⎡⎡sin(
⎢⎢ ⎥,⎢ ⎥⎥ (sin(τ₁) + 1)⋅⎢⎢
⎣⎣sin(τ₂) sin(τ₂) + 1⎦ ⎣sin(τ₃) sin(τ₃) + 1⎦⎦ ⎣⎣sin(
sin(τ₂) ⎤ ⎡sin(τ₃) sin(τ₃) ⎤⎤ ⎤
⎥,⎢ ⎥⎥ ⎥
sin(τ₂) + 1⎦ ⎣sin(τ₃) sin(τ₃) + 1⎦⎦ ⎥
⎥
τ₂) sin(τ₂) ⎤ ⎡sin(τ₃) sin(τ₃) ⎤⎤⎥
⎥,⎢ ⎥⎥⎥
τ₂) sin(τ₂) + 1⎦ ⎣sin(τ₃) sin(τ₃) + 1⎦⎦⎦
要看到这一点,我还尝试了sp.Matmul(A.subs(matrix_from_symbol, simultaneous=True), Commutator(B, C).subs(matrix_from_symbol, simultaneous=True))
,但会引发错误消息:"MatMul 中的非可交换标量不受支持"
。
在Commutator类更新以支持矩阵之前,一个解决方法是在交换子中使用非可交换符号,然后使用 .doit()
评估交换子,最后将矩阵代入最终表达式。
感谢 @hpaulj 提供的有用评论和建议(特别是关于查看源代码的建议)。
英文:
The issue is that sympy does not perform matrix multiplication when evaluating A.subs(matrix_from_symbols,simultaneous=True) * Commutator(B,C).subs(matrix_from_symbol,simultaneous=True).
Instead, it appears to treat the Commutator(B,C)
as a scalar, producing the following result:
⎡ ⎡⎡sin(τ₂) sin(τ₂) ⎤ ⎡sin(τ₃) sin(τ₃) ⎤⎤ ⎡⎡sin(τ₂)
⎢sin(τ₁)⋅⎢⎢ ⎥,⎢ ⎥⎥ sin(τ₁)⋅⎢⎢
⎢ ⎣⎣sin(τ₂) sin(τ₂) + 1⎦ ⎣sin(τ₃) sin(τ₃) + 1⎦⎦ ⎣⎣sin(τ₂)
⎢
⎢ ⎡⎡sin(τ₂) sin(τ₂) ⎤ ⎡sin(τ₃) sin(τ₃) ⎤⎤ ⎡⎡sin(
⎢sin(τ₁)⋅⎢⎢ ⎥,⎢ ⎥⎥ (sin(τ₁) + 1)⋅⎢⎢
⎣ ⎣⎣sin(τ₂) sin(τ₂) + 1⎦ ⎣sin(τ₃) sin(τ₃) + 1⎦⎦ ⎣⎣sin(
sin(τ₂) ⎤ ⎡sin(τ₃) sin(τ₃) ⎤⎤ ⎤
⎥,⎢ ⎥⎥ ⎥
sin(τ₂) + 1⎦ ⎣sin(τ₃) sin(τ₃) + 1⎦⎦ ⎥
⎥
τ₂) sin(τ₂) ⎤ ⎡sin(τ₃) sin(τ₃) ⎤⎤⎥
⎥,⎢ ⎥⎥⎥
τ₂) sin(τ₂) + 1⎦ ⎣sin(τ₃) sin(τ₃) + 1⎦⎦⎦
To see that this is the case, I also tried sp.Matmul(A.subs(matrix_from_symbol,simultaneous=True),Commutator(B,C).subs(matrix_from_symbol,simultaneous=True))
which throws the error message: "noncommutative scalars in MatMul are not supported"
Until the Commutator class is updated to work with matrices, one workaround is to use noncommutative symbols in commutators, evaluate the commutators with .doit()
, then substitute matrices into the final expression.
Thanks to @hpaulj for helpful comments and suggestions (especially regarding looking at the source code)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论