Spin Operator Basis¶
Single Spin 1/2¶
In [1]:
Copied!
import numpy as np
np.set_printoptions(precision=2, suppress=True)
import numpy as np
np.set_printoptions(precision=2, suppress=True)
In [2]:
Copied!
Ix = 0.5 * np.array([[0, 1], [1, 0]])
Iy = 0.5 * np.array([[0, -1j], [1j, 0]])
Iz = 0.5 * np.array([[1, 0], [0, -1]])
Ix = 0.5 * np.array([[0, 1], [1, 0]])
Iy = 0.5 * np.array([[0, -1j], [1j, 0]])
Iz = 0.5 * np.array([[1, 0], [0, -1]])
In [3]:
Copied!
print(Ix)
print(Ix)
[[0. 0.5] [0.5 0. ]]
In [4]:
Copied!
from sympy import latex, Matrix
from IPython.display import display, Math
def pprint(obj, tex=False):
if tex:
print(latex(Matrix(obj)))
else:
display(Math(latex(Matrix(obj))))
from sympy import latex, Matrix
from IPython.display import display, Math
def pprint(obj, tex=False):
if tex:
print(latex(Matrix(obj)))
else:
display(Math(latex(Matrix(obj))))
In [5]:
Copied!
pprint(Ix)
pprint(Ix)
$\displaystyle \left[\begin{matrix}0.0 & 0.5\\0.5 & 0.0\end{matrix}\right]$
In [6]:
Copied!
def commutator(a, b):
return (a @ b) - (b @ a)
def commutator(a, b):
return (a @ b) - (b @ a)
Q1¶
- Check all the commutation Relations. Refer to Madhu's Lecture, Slide 14
In [7]:
Copied!
np.allclose(commutator(Ix, Iy), 1j * Iz)
np.allclose(commutator(Ix, Iy), 1j * Iz)
Out[7]:
True
In [8]:
Copied!
# your answers here
# your answers here
Multiple Spin System (Spin 1/2)¶
In [9]:
Copied!
E = np.array([[1, 0], [0, 1]])
E = np.array([[1, 0], [0, 1]])
In [10]:
Copied!
I1x, I1y, I1z = np.kron(Ix, E), np.kron(Iy, E), np.kron(Iz, E)
I2x, I2y, I2z = np.kron(E, Ix), np.kron(E, Iy), np.kron(E, Iz)
I1x, I1y, I1z = np.kron(Ix, E), np.kron(Iy, E), np.kron(Iz, E)
I2x, I2y, I2z = np.kron(E, Ix), np.kron(E, Iy), np.kron(E, Iz)
In [11]:
Copied!
pprint(I1z)
pprint(I2z)
pprint(I1z)
pprint(I2z)
$\displaystyle \left[\begin{matrix}0.5 & 0.0 & 0.0 & 0.0\\0.0 & 0.5 & 0.0 & 0.0\\0.0 & 0.0 & -0.5 & 0.0\\0.0 & 0.0 & 0.0 & -0.5\end{matrix}\right]$
$\displaystyle \left[\begin{matrix}0.5 & 0.0 & 0.0 & 0.0\\0.0 & -0.5 & 0.0 & 0.0\\0.0 & 0.0 & 0.5 & 0.0\\0.0 & 0.0 & 0.0 & -0.5\end{matrix}\right]$
Q2¶
- Check that the operators for different spins commute
In [12]:
Copied!
# your answers here
# your answers here
Spin > 1/2¶
In [13]:
Copied!
def spin_operators(s):
"""
Generate all single spin operators for a spin
"""
dim = int(2 * s) + 1
ms = np.linspace(s, -s, dim)
Sz = np.diag(ms)
S_plus = np.zeros((dim, dim))
for i in range(dim - 1):
m = ms[i+1]
S_plus[i, i+1] = np.sqrt(s*(s+1) - m*(m+1))
S_minus = S_plus.T.conj()
Sx = 0.5 * (S_plus + S_minus)
Sy = -0.5j * (S_plus - S_minus)
return {'x': Sx, 'y': Sy, 'z':Sz}
def spin_operators(s):
"""
Generate all single spin operators for a spin
"""
dim = int(2 * s) + 1
ms = np.linspace(s, -s, dim)
Sz = np.diag(ms)
S_plus = np.zeros((dim, dim))
for i in range(dim - 1):
m = ms[i+1]
S_plus[i, i+1] = np.sqrt(s*(s+1) - m*(m+1))
S_minus = S_plus.T.conj()
Sx = 0.5 * (S_plus + S_minus)
Sy = -0.5j * (S_plus - S_minus)
return {'x': Sx, 'y': Sy, 'z':Sz}
Q3¶
- Check the basis for spin = 1, 3/2, 2, 5/2, 3, 7/2, 4, 9/2
In [14]:
Copied!
# your answers here
# your answers here
Q4¶
- How do you generate an arbitrary spin system (different number of nuclei with different spins)
In [15]:
Copied!
# your answers here
# your answers here
In [16]:
Copied!
def spinsys(*spins):
"""Generate a multi-spin hilbert basis from each spin"""
dims = [int(2*s + 1) for s in spins]
nspins = len(spins)
if nspins == 1:
return spin_operators(spins[0])
else:
sso = []
for s in spins:
sso.append(spin_operators(s))
out = []
for i, (spin) in enumerate(sso):
out.append({})
for j, (direction, operator) in enumerate(spin.items()):
identities = [np.eye(dim) for dim in dims]
identities[i] = operator
out[i][direction] = identities[0]
for k in identities[1:]:
out[i][direction] = np.kron(out[i][direction], k)
return out
def spinsys(*spins):
"""Generate a multi-spin hilbert basis from each spin"""
dims = [int(2*s + 1) for s in spins]
nspins = len(spins)
if nspins == 1:
return spin_operators(spins[0])
else:
sso = []
for s in spins:
sso.append(spin_operators(s))
out = []
for i, (spin) in enumerate(sso):
out.append({})
for j, (direction, operator) in enumerate(spin.items()):
identities = [np.eye(dim) for dim in dims]
identities[i] = operator
out[i][direction] = identities[0]
for k in identities[1:]:
out[i][direction] = np.kron(out[i][direction], k)
return out
In [17]:
Copied!
I = spinsys(4)
print(I['z'].shape)
I = spinsys(4)
print(I['z'].shape)
(9, 9)
In [18]:
Copied!
I1, I2, I3 = spinsys(0.5, 0.5, 1)
I1, I2, I3 = spinsys(0.5, 0.5, 1)
In [19]:
Copied!
print(I3['z'], )
print(I3['z'], )
[[ 1. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.] [ 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.] [ 0. 0. -1. 0. 0. -0. 0. 0. -0. 0. 0. -0.] [ 0. 0. 0. 1. 0. 0. 0. 0. 0. 0. 0. 0.] [ 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.] [ 0. 0. -0. 0. 0. -1. 0. 0. -0. 0. 0. -0.] [ 0. 0. 0. 0. 0. 0. 1. 0. 0. 0. 0. 0.] [ 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.] [ 0. 0. -0. 0. 0. -0. 0. 0. -1. 0. 0. -0.] [ 0. 0. 0. 0. 0. 0. 0. 0. 0. 1. 0. 0.] [ 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.] [ 0. 0. -0. 0. 0. -0. 0. 0. -0. 0. 0. -1.]]
For Later Use¶
In [20]:
Copied!
import numpy as np
def spin_operators(s):
"""
Generate all single spin operators for a spin
"""
dim = int(2 * s) + 1
ms = np.linspace(s, -s, dim)
Sz = np.diag(ms)
S_plus = np.zeros((dim, dim))
for i in range(dim - 1):
m = ms[i+1]
S_plus[i, i+1] = np.sqrt(s*(s+1) - m*(m+1))
S_minus = S_plus.T.conj()
Sx = 0.5 * (S_plus + S_minus)
Sy = -0.5j * (S_plus - S_minus)
Sz = Sz.astype('complex128')
return {'x': Sx, 'y': Sy, 'z':Sz}
def spinsys(*spins):
"""Generate a multi-spin hilbert basis from each spin"""
dims = [int(2*s + 1) for s in spins]
nspins = len(spins)
if nspins == 1:
return Spin(spin_operators(spins[0]))
else:
sso = []
for s in spins:
sso.append(spin_operators(s))
out = []
for i, (spin) in enumerate(sso):
out.append({})
for j, (direction, operator) in enumerate(spin.items()):
identities = [np.eye(dim) for dim in dims]
identities[i] = operator
out[i][direction] = identities[0]
for k in identities[1:]:
out[i][direction] = np.kron(out[i][direction], k)
return [Spin(o) for o in out]
class Spin(dict):
def __init__(self, dict_):
super().__init__(dict_)
self['p'] = self['x'] + 1j * self['y']
self['m'] = self['x'] - 1j * self['y']
def __getattr__(self, key):
try:
return self[key]
except KeyError:
raise AttributeError(f"'Spin' object has no attribute '{key}'")
def __setattr__(self, key, value):
self[key] = value
import numpy as np
def spin_operators(s):
"""
Generate all single spin operators for a spin
"""
dim = int(2 * s) + 1
ms = np.linspace(s, -s, dim)
Sz = np.diag(ms)
S_plus = np.zeros((dim, dim))
for i in range(dim - 1):
m = ms[i+1]
S_plus[i, i+1] = np.sqrt(s*(s+1) - m*(m+1))
S_minus = S_plus.T.conj()
Sx = 0.5 * (S_plus + S_minus)
Sy = -0.5j * (S_plus - S_minus)
Sz = Sz.astype('complex128')
return {'x': Sx, 'y': Sy, 'z':Sz}
def spinsys(*spins):
"""Generate a multi-spin hilbert basis from each spin"""
dims = [int(2*s + 1) for s in spins]
nspins = len(spins)
if nspins == 1:
return Spin(spin_operators(spins[0]))
else:
sso = []
for s in spins:
sso.append(spin_operators(s))
out = []
for i, (spin) in enumerate(sso):
out.append({})
for j, (direction, operator) in enumerate(spin.items()):
identities = [np.eye(dim) for dim in dims]
identities[i] = operator
out[i][direction] = identities[0]
for k in identities[1:]:
out[i][direction] = np.kron(out[i][direction], k)
return [Spin(o) for o in out]
class Spin(dict):
def __init__(self, dict_):
super().__init__(dict_)
self['p'] = self['x'] + 1j * self['y']
self['m'] = self['x'] - 1j * self['y']
def __getattr__(self, key):
try:
return self[key]
except KeyError:
raise AttributeError(f"'Spin' object has no attribute '{key}'")
def __setattr__(self, key, value):
self[key] = value