Spaces:
Sleeping
Sleeping
"""Bosonic quantum operators.""" | |
from sympy.core.mul import Mul | |
from sympy.core.numbers import Integer | |
from sympy.core.singleton import S | |
from sympy.functions.elementary.complexes import conjugate | |
from sympy.functions.elementary.exponential import exp | |
from sympy.functions.elementary.miscellaneous import sqrt | |
from sympy.physics.quantum import Operator | |
from sympy.physics.quantum import HilbertSpace, FockSpace, Ket, Bra, IdentityOperator | |
from sympy.functions.special.tensor_functions import KroneckerDelta | |
__all__ = [ | |
'BosonOp', | |
'BosonFockKet', | |
'BosonFockBra', | |
'BosonCoherentKet', | |
'BosonCoherentBra' | |
] | |
class BosonOp(Operator): | |
"""A bosonic operator that satisfies [a, Dagger(a)] == 1. | |
Parameters | |
========== | |
name : str | |
A string that labels the bosonic mode. | |
annihilation : bool | |
A bool that indicates if the bosonic operator is an annihilation (True, | |
default value) or creation operator (False) | |
Examples | |
======== | |
>>> from sympy.physics.quantum import Dagger, Commutator | |
>>> from sympy.physics.quantum.boson import BosonOp | |
>>> a = BosonOp("a") | |
>>> Commutator(a, Dagger(a)).doit() | |
1 | |
""" | |
def name(self): | |
return self.args[0] | |
def is_annihilation(self): | |
return bool(self.args[1]) | |
def default_args(self): | |
return ("a", True) | |
def __new__(cls, *args, **hints): | |
if not len(args) in [1, 2]: | |
raise ValueError('1 or 2 parameters expected, got %s' % args) | |
if len(args) == 1: | |
args = (args[0], S.One) | |
if len(args) == 2: | |
args = (args[0], Integer(args[1])) | |
return Operator.__new__(cls, *args) | |
def _eval_commutator_BosonOp(self, other, **hints): | |
if self.name == other.name: | |
# [a^\dagger, a] = -1 | |
if not self.is_annihilation and other.is_annihilation: | |
return S.NegativeOne | |
elif 'independent' in hints and hints['independent']: | |
# [a, b] = 0 | |
return S.Zero | |
return None | |
def _eval_commutator_FermionOp(self, other, **hints): | |
return S.Zero | |
def _eval_anticommutator_BosonOp(self, other, **hints): | |
if 'independent' in hints and hints['independent']: | |
# {a, b} = 2 * a * b, because [a, b] = 0 | |
return 2 * self * other | |
return None | |
def _eval_adjoint(self): | |
return BosonOp(str(self.name), not self.is_annihilation) | |
def __mul__(self, other): | |
if other == IdentityOperator(2): | |
return self | |
if isinstance(other, Mul): | |
args1 = tuple(arg for arg in other.args if arg.is_commutative) | |
args2 = tuple(arg for arg in other.args if not arg.is_commutative) | |
x = self | |
for y in args2: | |
x = x * y | |
return Mul(*args1) * x | |
return Mul(self, other) | |
def _print_contents_latex(self, printer, *args): | |
if self.is_annihilation: | |
return r'{%s}' % str(self.name) | |
else: | |
return r'{{%s}^\dagger}' % str(self.name) | |
def _print_contents(self, printer, *args): | |
if self.is_annihilation: | |
return r'%s' % str(self.name) | |
else: | |
return r'Dagger(%s)' % str(self.name) | |
def _print_contents_pretty(self, printer, *args): | |
from sympy.printing.pretty.stringpict import prettyForm | |
pform = printer._print(self.args[0], *args) | |
if self.is_annihilation: | |
return pform | |
else: | |
return pform**prettyForm('\N{DAGGER}') | |
class BosonFockKet(Ket): | |
"""Fock state ket for a bosonic mode. | |
Parameters | |
========== | |
n : Number | |
The Fock state number. | |
""" | |
def __new__(cls, n): | |
return Ket.__new__(cls, n) | |
def n(self): | |
return self.label[0] | |
def dual_class(self): | |
return BosonFockBra | |
def _eval_hilbert_space(cls, label): | |
return FockSpace() | |
def _eval_innerproduct_BosonFockBra(self, bra, **hints): | |
return KroneckerDelta(self.n, bra.n) | |
def _apply_from_right_to_BosonOp(self, op, **options): | |
if op.is_annihilation: | |
return sqrt(self.n) * BosonFockKet(self.n - 1) | |
else: | |
return sqrt(self.n + 1) * BosonFockKet(self.n + 1) | |
class BosonFockBra(Bra): | |
"""Fock state bra for a bosonic mode. | |
Parameters | |
========== | |
n : Number | |
The Fock state number. | |
""" | |
def __new__(cls, n): | |
return Bra.__new__(cls, n) | |
def n(self): | |
return self.label[0] | |
def dual_class(self): | |
return BosonFockKet | |
def _eval_hilbert_space(cls, label): | |
return FockSpace() | |
class BosonCoherentKet(Ket): | |
"""Coherent state ket for a bosonic mode. | |
Parameters | |
========== | |
alpha : Number, Symbol | |
The complex amplitude of the coherent state. | |
""" | |
def __new__(cls, alpha): | |
return Ket.__new__(cls, alpha) | |
def alpha(self): | |
return self.label[0] | |
def dual_class(self): | |
return BosonCoherentBra | |
def _eval_hilbert_space(cls, label): | |
return HilbertSpace() | |
def _eval_innerproduct_BosonCoherentBra(self, bra, **hints): | |
if self.alpha == bra.alpha: | |
return S.One | |
else: | |
return exp(-(abs(self.alpha)**2 + abs(bra.alpha)**2 - 2 * conjugate(bra.alpha) * self.alpha)/2) | |
def _apply_from_right_to_BosonOp(self, op, **options): | |
if op.is_annihilation: | |
return self.alpha * self | |
else: | |
return None | |
class BosonCoherentBra(Bra): | |
"""Coherent state bra for a bosonic mode. | |
Parameters | |
========== | |
alpha : Number, Symbol | |
The complex amplitude of the coherent state. | |
""" | |
def __new__(cls, alpha): | |
return Bra.__new__(cls, alpha) | |
def alpha(self): | |
return self.label[0] | |
def dual_class(self): | |
return BosonCoherentKet | |
def _apply_operator_BosonOp(self, op, **options): | |
if not op.is_annihilation: | |
return self.alpha * self | |
else: | |
return None | |