/

# Source code for sympy.physics.quantum.cartesian

"""Operators and states for 1D cartesian position and momentum.

TODO:

* Add 3D classes to mappings in operatorset.py

"""

from __future__ import print_function, division

from sympy import DiracDelta, exp, I, Interval, pi, S, sqrt

from sympy.physics.quantum.constants import hbar
from sympy.physics.quantum.hilbert import L2
from sympy.physics.quantum.operator import DifferentialOperator, HermitianOperator
from sympy.physics.quantum.state import Ket, Bra, State

__all__ = [
'XOp',
'YOp',
'ZOp',
'PxOp',
'X',
'Y',
'Z',
'Px',
'XKet',
'XBra',
'PxKet',
'PxBra',
'PositionState3D',
'PositionKet3D',
'PositionBra3D'
]

#-------------------------------------------------------------------------
# Position operators
#-------------------------------------------------------------------------

[docs]class XOp(HermitianOperator):
"""1D cartesian position operator."""

@classmethod
def default_args(self):
return ("X",)

@classmethod
def _eval_hilbert_space(self, args):
return L2(Interval(S.NegativeInfinity, S.Infinity))

def _eval_commutator_PxOp(self, other):
return I*hbar

def _apply_operator_XKet(self, ket):
return ket.position*ket

def _apply_operator_PositionKet3D(self, ket):
return ket.position_x*ket

def _represent_PxKet(self, basis, **options):
index = options.pop("index", 1)

states = basis._enumerate_state(2, start_index=index)
coord1 = states[0].momentum
coord2 = states[1].momentum
d = DifferentialOperator(coord1)
delta = DiracDelta(coord1 - coord2)

return I*hbar*(d*delta)

[docs]class YOp(HermitianOperator):
""" Y cartesian coordinate operator (for 2D or 3D systems) """

@classmethod
def default_args(self):
return ("Y",)

@classmethod
def _eval_hilbert_space(self, args):
return L2(Interval(S.NegativeInfinity, S.Infinity))

def _apply_operator_PositionKet3D(self, ket):
return ket.position_y*ket

[docs]class ZOp(HermitianOperator):
""" Z cartesian coordinate operator (for 3D systems) """

@classmethod
def default_args(self):
return ("Z",)

@classmethod
def _eval_hilbert_space(self, args):
return L2(Interval(S.NegativeInfinity, S.Infinity))

def _apply_operator_PositionKet3D(self, ket):
return ket.position_z*ket

#-------------------------------------------------------------------------
# Momentum operators
#-------------------------------------------------------------------------

[docs]class PxOp(HermitianOperator):
"""1D cartesian momentum operator."""

@classmethod
def default_args(self):
return ("Px",)

@classmethod
def _eval_hilbert_space(self, args):
return L2(Interval(S.NegativeInfinity, S.Infinity))

def _apply_operator_PxKet(self, ket):
return ket.momentum*ket

def _represent_XKet(self, basis, **options):
index = options.pop("index", 1)

states = basis._enumerate_state(2, start_index=index)
coord1 = states[0].position
coord2 = states[1].position
d = DifferentialOperator(coord1)
delta = DiracDelta(coord1 - coord2)

return -I*hbar*(d*delta)

X = XOp('X')
Y = YOp('Y')
Z = ZOp('Z')
Px = PxOp('Px')

#-------------------------------------------------------------------------
# Position eigenstates
#-------------------------------------------------------------------------

[docs]class XKet(Ket):
"""1D cartesian position eigenket."""

@classmethod
def _operators_to_state(self, op, **options):
return self.__new__(self, *_lowercase_labels(op), **options)

def _state_to_operators(self, op_class, **options):
return op_class.__new__(op_class,
*_uppercase_labels(self), **options)

@classmethod
def default_args(self):
return ("x",)

@classmethod
def dual_class(self):
return XBra

@property
[docs]    def position(self):
"""The position of the state."""
return self.label[0]

def _enumerate_state(self, num_states, **options):
return _enumerate_continuous_1D(self, num_states, **options)

def _eval_innerproduct_XBra(self, bra, **hints):
return DiracDelta(self.position - bra.position)

def _eval_innerproduct_PxBra(self, bra, **hints):
return exp(-I*self.position*bra.momentum/hbar)/sqrt(2*pi*hbar)

[docs]class XBra(Bra):
"""1D cartesian position eigenbra."""

@classmethod
def default_args(self):
return ("x",)

@classmethod
def dual_class(self):
return XKet

@property
[docs]    def position(self):
"""The position of the state."""
return self.label[0]

[docs]class PositionState3D(State):
""" Base class for 3D cartesian position eigenstates """

@classmethod
def _operators_to_state(self, op, **options):
return self.__new__(self, *_lowercase_labels(op), **options)

def _state_to_operators(self, op_class, **options):
return op_class.__new__(op_class,
*_uppercase_labels(self), **options)

@classmethod
def default_args(self):
return ("x", "y", "z")

@property
[docs]    def position_x(self):
""" The x coordinate of the state """
return self.label[0]

@property
[docs]    def position_y(self):
""" The y coordinate of the state """
return self.label[1]

@property
[docs]    def position_z(self):
""" The z coordinate of the state """
return self.label[2]

[docs]class PositionKet3D(Ket, PositionState3D):
""" 3D cartesian position eigenket """

def _eval_innerproduct_PositionBra3D(self, bra, **options):
x_diff = self.position_x - bra.position_x
y_diff = self.position_y - bra.position_y
z_diff = self.position_z - bra.position_z

return DiracDelta(x_diff)*DiracDelta(y_diff)*DiracDelta(z_diff)

@classmethod
def dual_class(self):
return PositionBra3D

[docs]class PositionBra3D(Bra, PositionState3D):
""" 3D cartesian position eigenbra """

@classmethod
def dual_class(self):
return PositionKet3D

#-------------------------------------------------------------------------
# Momentum eigenstates
#-------------------------------------------------------------------------

[docs]class PxKet(Ket):
"""1D cartesian momentum eigenket."""

@classmethod
def _operators_to_state(self, op, **options):
return self.__new__(self, *_lowercase_labels(op), **options)

def _state_to_operators(self, op_class, **options):
return op_class.__new__(op_class,
*_uppercase_labels(self), **options)

@classmethod
def default_args(self):
return ("px",)

@classmethod
def dual_class(self):
return PxBra

@property
[docs]    def momentum(self):
"""The momentum of the state."""
return self.label[0]

def _enumerate_state(self, *args, **options):
return _enumerate_continuous_1D(self, *args, **options)

def _eval_innerproduct_XBra(self, bra, **hints):
return exp(I*self.momentum*bra.position/hbar)/sqrt(2*pi*hbar)

def _eval_innerproduct_PxBra(self, bra, **hints):
return DiracDelta(self.momentum - bra.momentum)

[docs]class PxBra(Bra):
"""1D cartesian momentum eigenbra."""

@classmethod
def default_args(self):
return ("px",)

@classmethod
def dual_class(self):
return PxKet

@property
[docs]    def momentum(self):
"""The momentum of the state."""
return self.label[0]

#-------------------------------------------------------------------------
# Global helper functions
#-------------------------------------------------------------------------

def _enumerate_continuous_1D(*args, **options):
state = args[0]
num_states = args[1]
state_class = state.__class__
index_list = options.pop('index_list', [])

if len(index_list) == 0:
start_index = options.pop('start_index', 1)
index_list = list(range(start_index, start_index + num_states))

enum_states = [0 for i in range(len(index_list))]

for i, ind in enumerate(index_list):
label = state.args[0]
enum_states[i] = state_class(str(label) + "_" + str(ind), **options)

return enum_states

def _lowercase_labels(ops):
if not isinstance(ops, set):
ops = [ops]

return [str(arg.label[0]).lower() for arg in ops]

def _uppercase_labels(ops):
if not isinstance(ops, set):
ops = [ops]

new_args = [str(arg.label[0])[0].upper() +
str(arg.label[0])[1:] for arg in ops]

return new_args