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 | |