forked from sympy/sympy
-
Notifications
You must be signed in to change notification settings - Fork 1
/
paulialgebra.py
67 lines (56 loc) · 1.54 KB
/
paulialgebra.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
from sympy import Symbol,I,Integer
"""
This module implements Pauli algebra by subclassing Symbol. Only aglebraic
properties of Pauli matrices are used (we don't use the Matrix class).
See the documentation to the class Pauli for examples.
See also:
http://en.wikipedia.org/wiki/Pauli_matrices
"""
def delta(i,j):
if i==j:
return 1
else:
return 0
def epsilon(i,j,k):
if (i,j,k) in [(1,2,3), (2,3,1), (3,1,2)]:
return 1
elif (i,j,k) in [(1,3,2), (3,2,1), (2,1,3)]:
return -1
else:
return 0
class Pauli(Symbol):
"""
>>> from sympy import *
>>> Pauli(1)
sigma1
>>> Pauli(1)*Pauli(2)
I*sigma3
>>> Pauli(1)*Pauli(1)
1
>>> Pauli(3)**4
1
>>> Pauli(1)*Pauli(2)*Pauli(3)
I
"""
__slots__ = ["i"]
def __new__(cls, i):
if not i in [1,2,3]:
raise IndexError("Invalid Pauli index")
obj = Symbol.__new__(cls, "sigma%d"%i, commutative=False)
obj.i=i
return obj
def __getnewargs__(self):
return (self.i,)
# FIXME don't work for -I*Pauli(2)*Pauli(3)
def __mul__(self, other):
if isinstance(other, Pauli):
j=self.i
k=other.i
return delta(j,k) \
+I*epsilon(j,k,1)*Pauli(1) \
+I*epsilon(j,k,2)*Pauli(2) \
+I*epsilon(j,k,3)*Pauli(3)
return super(Pauli, self).__mul__(other)
def _eval_power(b, e):
if e.is_Integer and e.is_positive:
return super(Pauli, b).__pow__(int(e) % 2)