Evaluate inner product of bra and ket in Sympy Quantum
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
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.