Spaces:
Sleeping
Sleeping
"""Fermionic quantum operators.""" | |
from sympy.core.numbers import Integer | |
from sympy.core.singleton import S | |
from sympy.physics.quantum import Operator | |
from sympy.physics.quantum import HilbertSpace, Ket, Bra | |
from sympy.functions.special.tensor_functions import KroneckerDelta | |
__all__ = [ | |
'FermionOp', | |
'FermionFockKet', | |
'FermionFockBra' | |
] | |
class FermionOp(Operator): | |
"""A fermionic operator that satisfies {c, Dagger(c)} == 1. | |
Parameters | |
========== | |
name : str | |
A string that labels the fermionic mode. | |
annihilation : bool | |
A bool that indicates if the fermionic operator is an annihilation | |
(True, default value) or creation operator (False) | |
Examples | |
======== | |
>>> from sympy.physics.quantum import Dagger, AntiCommutator | |
>>> from sympy.physics.quantum.fermion import FermionOp | |
>>> c = FermionOp("c") | |
>>> AntiCommutator(c, Dagger(c)).doit() | |
1 | |
""" | |
def name(self): | |
return self.args[0] | |
def is_annihilation(self): | |
return bool(self.args[1]) | |
def default_args(self): | |
return ("c", 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_FermionOp(self, other, **hints): | |
if 'independent' in hints and hints['independent']: | |
# [c, d] = 0 | |
return S.Zero | |
return None | |
def _eval_anticommutator_FermionOp(self, other, **hints): | |
if self.name == other.name: | |
# {a^\dagger, a} = 1 | |
if not self.is_annihilation and other.is_annihilation: | |
return S.One | |
elif 'independent' in hints and hints['independent']: | |
# {c, d} = 2 * c * d, because [c, d] = 0 for independent operators | |
return 2 * self * other | |
return None | |
def _eval_anticommutator_BosonOp(self, other, **hints): | |
# because fermions and bosons commute | |
return 2 * self * other | |
def _eval_commutator_BosonOp(self, other, **hints): | |
return S.Zero | |
def _eval_adjoint(self): | |
return FermionOp(str(self.name), not self.is_annihilation) | |
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}') | |
def _eval_power(self, exp): | |
from sympy.core.singleton import S | |
if exp == 0: | |
return S.One | |
elif exp == 1: | |
return self | |
elif (exp > 1) == True and exp.is_integer == True: | |
return S.Zero | |
elif (exp < 0) == True or exp.is_integer == False: | |
raise ValueError("Fermionic operators can only be raised to a" | |
" positive integer power") | |
return Operator._eval_power(self, exp) | |
class FermionFockKet(Ket): | |
"""Fock state ket for a fermionic mode. | |
Parameters | |
========== | |
n : Number | |
The Fock state number. | |
""" | |
def __new__(cls, n): | |
if n not in (0, 1): | |
raise ValueError("n must be 0 or 1") | |
return Ket.__new__(cls, n) | |
def n(self): | |
return self.label[0] | |
def dual_class(self): | |
return FermionFockBra | |
def _eval_hilbert_space(cls, label): | |
return HilbertSpace() | |
def _eval_innerproduct_FermionFockBra(self, bra, **hints): | |
return KroneckerDelta(self.n, bra.n) | |
def _apply_from_right_to_FermionOp(self, op, **options): | |
if op.is_annihilation: | |
if self.n == 1: | |
return FermionFockKet(0) | |
else: | |
return S.Zero | |
else: | |
if self.n == 0: | |
return FermionFockKet(1) | |
else: | |
return S.Zero | |
class FermionFockBra(Bra): | |
"""Fock state bra for a fermionic mode. | |
Parameters | |
========== | |
n : Number | |
The Fock state number. | |
""" | |
def __new__(cls, n): | |
if n not in (0, 1): | |
raise ValueError("n must be 0 or 1") | |
return Bra.__new__(cls, n) | |
def n(self): | |
return self.label[0] | |
def dual_class(self): | |
return FermionFockKet | |