Evaluate inner product of bra and ket in Sympy Quantum

In sympy I have defined a two kets and a corresponding bra, when I apply the bra to the kets...

from sympy import sqrt
from sympy.physics.quantum import Bra,Ket,qapply
superpos = (Ket('Dead')+Ket('Alive'))/sqrt(2)
d = qapply(Bra('Dead')*superpos)

...I get this result:

sqrt(2)*<Dead|Alive>/2 + sqrt(2)*<Dead|Dead>/2

How do I set 'Dead' and 'Alive' as orthogonal states, so that d.doit() gives sqrt(2)/2?

So far I've only been able to substitute the brakets by hand:

d.subs(Bra('Dead')*Ket('Dead'),1).subs(Bra('Dead')*Ket('Alive'),0)

But how do I make the brakets evaluate automatically? Why doesn't the InnerProduct result to 1 for identical brakets and 0 for brakets with different labels?

Your problem is that InnerProduct doesn't know how to evaluate these values and so leaves the unsimplified expression instead. Looking at the source, I see that it tries to call _eval_innerproduct() on the Ket, which says this.

def _eval_innerproduct(self, bra, **hints):
    """Evaluate the inner product betweeen this ket and a bra.

    This is called to compute <bra|ket>, where the ket is ``self``.

    This method will dispatch to sub-methods having the format::

        ``def _eval_innerproduct_BraClass(self, **hints):``

    Subclasses should define these methods (one for each BraClass) to
    teach the ket how to take inner products with bras.
    """

You should therefore be able to solve your problem by creating 2 new Bra classes and a new Ket class that implements 2 methods - one to evaluate each of the inner products (using the naming convention mandated above).

For completeness you probably also want to implement the other Ket for your orthogonal state and to make sure that dual_class returns the right class in each case.

Inner Product — SymPy 1.6.1 documentation, from sympy.physics.quantum import Ket, Bra The inner product of two states with different labels will give zero, states with the same label will� Inner Product¶ Symbolic inner product. class sympy.physics.quantum.innerproduct.InnerProduct (bra, ket) [source] ¶ An unevaluated inner product between a Bra and a Ket [1]. Parameters. bra: BraBase or subclass

As Peter points out in his answer, you need to implement a new Bra and Ket class yourself. This is a nice general implementation for orthogonal states that you can use.

Example usage:

>>> OrthogonalBra(n)*OrthogonalKet(n)
1
>>> OrthogonalBra(n)*OrthogonalKet(n+1)
0
>>> OrthogonalBra(n)*OrthogonalKet(m)
<n|m>

Implementation:

class OrthogonalKet(Ket):

    @classmethod
    def dual_class(self):
        return OrthogonalBra

    def _eval_innerproduct(self, bra, **hints):

        if len(self.args) != len(bra.args):
            raise ValueError('Cannot multiply a ket that has a different number of labels.')

        for i in range(len(self.args)):
            diff = self.args[i] - bra.args[i]
            diff.simplify()

            if diff.is_nonzero:
                return 0

            if not diff.is_zero:
                return None

        return 1


class OrthogonalBra(Bra):

    @classmethod
    def dual_class(self):
        return OrthogonalKet

sympy.physics.quantum.state, ip_doit : call .doit() in inner products when they are encountered (default: True). Returns from sympy.physics.quantum import qapply, Ket, Bra. Inner product and bra-ket identification on Hilbert space Main article: Inner product The bra-ket notation is particularly useful in Hilbert spaces which have an inner product [6] that allows Hermitian conjugation and identifying a vector with a linear functional, i.e. a ket with a bra, and vice versa (see Riesz representation theorem ).

This isn't exactly what you're looking for, but you can use Qubit to create orthogonal states.

from sympy import sqrt
from sympy.physics.quantum import Dagger, qapply
from sympy.physics.quantum.qubit import Qubit

dead = Qubit(0)
alive = Qubit(1)

These create Ket(0) and Ket(1). To make the Bra, you can use the Dagger function.

print(Dagger(dead) * dead)
<0|0>

When applied to your problem:

superpos = (dead + alive) / sqrt(2)
d = qapply(Dagger(dead) * superpos)

print(d)
sqrt(2)/2

Qapply — SymPy 1.6.1 documentation, from sympy.physics.quantum.represent import enumerate_states Attempts to calculate inner product with a bra from the specified basis. Should only be passed an Here we subclass Operator and Ket to create the z-spin operator and its spin 1/2 up eigenstate. By defining the Evaluate, Copy. Dock to� Orthogonal Bra in quantum mechanics. class sympy.physics.quantum.state.OrthogonalKet (* args, ** kwargs) [source] ¶ Orthogonal Ket in quantum mechanics. The inner product of two states with different labels will give zero, states with the same label will give one.

Maybe expression.xreplace() is what you are looking for? According to this book the xreplace function can take a dictionary where sympy-symbols or expressions are hashable keys. This would still be clunky like this:

from sympy import sqrt
from sympy.physics.quantum import Bra,Ket,qapply
superpos = (Ket('Dead')+Ket('Alive'))/sqrt(2)
d = qapply(Bra('Dead')*superpos)

mySubs = {Bra('Dead')*Ket('Dead'): 1,  Bra('Dead')*Ket('Alive'): 0} ##plus other bindings
d.xreplace(mySubs)

(caution: did not yet test it...)

This at least gives you the option to define all the desired substitutions in one place and "reuse" them wherever you like.

Represent — SymPy 1.6.1 documentation, Doctests and documentation of special methods for InnerProduct, Commutator, with which the function in the specified arbitrary expression is evaluated from sympy.physics.quantum import Ket, Bra, OuterProduct, Dagger. been using. It is also widely although not universally used. It all begins by writing the inner product differently. The rule is to turn inner products into bra-ket pairs as follows ( u,v ) −→ (u| v) . (1.1) Instead of the inner product comma we simply put a vertical bar! We can translate our earlier

An answer in Fock space:

>>> from sympy import sqrt
>>> from sympy.physics.quantum import Dagger,qapply
>>> from sympy.physics.quantum.boson import BosonFockKet
>>> ket_Dead = BosonFockKet(0)
>>> ket_Alive = BosonFockKet(1)
>>> superpos = (ket_Dead+ket_Alive)/sqrt(2)
>>> bra_Dead = Dagger(ket_Dead)
>>> qapply(bra_Dead*superpos).doit()
sqrt(2)/2

Is the same thing possible in Hilbert space ?

Operator — SymPy 1.6.1 documentation, Evaluate inner product of bra and ket in Sympy Quantum. In sympy I have defined a two kets and a corresponding bra, when I apply the bra to the kets from� def _eval_innerproduct(self, bra, **hints): """Evaluate the inner product betweeen this ket and a bra. This is called to compute <bra|ket>, where the ket is ``self``. This method will dispatch to sub-methods having the format:: ``def _eval_innerproduct_BraClass(self, **hints):`` Subclasses should define these methods (one for each BraClass) to

python, from __future__ import print_function, division from sympy import Expr, its properties: >>> from sympy.physics.quantum import Bra, Ket, InnerProduct >>> b � def _eval_innerproduct (self, bra, ** hints): """Evaluate the inner product betweeen this ket and a bra. This is called to compute <bra|ket>, where the ket is ``self``. This method will dispatch to sub-methods having the format:: ``def _eval_innerproduct_BraClass(self, **hints):`` Subclasses should define these methods (one for each BraClass

sympy.physics.quantum.innerproduct — SymPy 1.4 documentation, Your problem is that InnerProduct doesn't know how to evaluate these values and like this: from sympy import sqrt from sympy.physics.quantum import Bra, Ket� 0 Evaluate inner product of bra and ket in Sympy Quantum Apr 12 '17 0 Extracting elements from 2d list Dec 4 '18 View all questions and answers →

simplify quantum expression with sympy.physics.quantum, from sympy.physics.quantum import Bra, Ket, qapply, Dagger e0 The scalar product can be actually computed with the doit() method. The inner product is an operation that takes two vectors and produces a number. It satisfies several axioms. A vector is normalized if its inner product with itself is 1.

Comments
  • That's it ! I copy/paste boson.py rename it to OrthogonalBra/OrthogonalKet and change innerproduct to ` def _eval_innerproduct_OrthogonalBra(self, bra, **hints): if self.n == bra.n: return 1 else: return 0`
  • Relevant PR on the sympy project here.
  • Thanks, this looks wonderful! But I guess there hasn't been a release which includes it yet. I could get this working by copy pasting the definition into my own code, but I had to include a .doit() call to get it to actually evaluate the inner products. Without that I was still getting the <n|n> notation.
  • Yes, you can call either expr.doit() or qapply(expr) on the expression, similar to some other operations in the QM module.
  • Thank you for your effort. Unfortunately, I am looking for a more general solution : N-dimension basis as with qutip (for instance: from qutip import * ket_i=basis(N,i) )
  • This is basically the same kind of substitution as in the question. I want to perform the innerproduct automatically as with: sympy.Matrix([1,0,0]).dot(sympy.Matrix([0,1,0]))