Search code examples
sympyquantum-computing

sympy: substitution of expressions with Braket-notation


I am using sympy (in sagemath). I would like to do a substitution, with Braket-notation (for quantum mechanical problem). Below there is a minimalistic code, in order to reproduce the problem.

from sympy.physics.quantum import Bra, Ket
from sympy import *
theta=symbols('theta',commutative=True)
pi, mu= symbols("pi mu",commutative=False)
W=2*pi*mu
print(W.subs(pi*mu,theta))
V=Bra(pi)*Ket(mu)
print(V.subs(Bra(pi)*Ket(mu),theta))
U=2*Bra(pi)*Ket(mu)
print(U.subs(Bra(pi)*Ket(mu),theta))

The output is:

2*theta
theta
2*<pi|*|mu>

If there is no leading scalar multiplier, the substitution works finely. I am stuck with a more complicated expression.


Solution

  • In these occasions srepr can shed some light:

    srepr(U)
    # out: "Mul(Integer(2), Bra(Symbol('pi', commutative=False)), Ket(Symbol('mu', commutative=False)))"
    
    srepr(Bra(pi)*Ket(mu))
    # out: "InnerProduct(Bra(Symbol('pi', commutative=False)),Ket(Symbol('mu', commutative=False)))"
    

    Note that the first output is a multiplication, object of type Mul, whereas the second output is an object of type InnerProduct. With the command U.subs(Bra(pi)*Ket(mu),theta) you are asking to search for an object of type InnerProduct into U, but there is none, hence no substitution has been done.

    In this case, you have to do:

    U.subs(Mul(Bra(pi), Ket(mu)),theta)
    # out: 2*theta
    

    Edit: or as @Oscar Benjamin pointed out, you do:

    from sympy.physics.quantum import qapply
    U = qapply(U)
    srepr(U)
    # out: "Mul(Integer(2), InnerProduct(Bra(Symbol('pi', commutative=False)),Ket(Symbol('mu', commutative=False))))"
    

    Now you can see an InnerProduct as an argument of Mul. FInally:

    U.subs(Bra(pi)*Ket(mu), theta)
    # out: 2*theta