为什么在将矩阵替换到sympy嵌套交换子中存在问题?

huangapple go评论46阅读模式
英文:

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)

huangapple
  • 本文由 发表于 2023年6月12日 00:19:54
  • 转载请务必保留本文链接:https://go.coder-hub.com/76451390.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定