def coupling_(a, b): particle_types = [] for a_i in np.arange(-1 * a, a + 1, 1): for b_j in np.arange(-1 * b, b + 1, 1): c = abs(a_i + b_j) c2 = abs(abs(a_i) + abs(b_j)) if c != c2: particle_types.append(c2) particle_types.append(c) T = {} for particle in particle_types: particle_dict = {} if particle == 0: states = [] for a_i in np.arange(-1 * a, a + 1, 1): for b_j in np.arange(-1 * b, b + 1, 1): state = qt.clebsch(a, b, 0, a_i, b_j, 0)*\ qt.tensor(qt.spin_state(a, a_i), qt.spin_state(b, b_j)) states.append(state) STATE = sum(states) particle_dict[particle] = (qt.spin_state(0, 0), STATE) else: for c_m in np.arange(-1 * particle, particle + 1, 1): states = [] for a_i in np.arange(-1 * a, a + 1, 1): for b_j in np.arange(-1 * b, b + 1, 1): state = qt.clebsch(a, b, particle, a_i, b_j, c_m)*\ qt.tensor(qt.spin_state(a, a_i), qt.spin_state(b, b_j)) states.append(state) STATE = sum(states) particle_dict[c_m] = (qt.spin_state(particle, c_m), STATE) T[particle] = particle_dict return T
def _rho_kq(rho, j, k, q): v = 0j for m1 in arange(-j, j + 1): for m2 in arange(-j, j + 1): v += ((-1)**(j - m1 - q) * qutip.clebsch(j, j, k, m1, -m2, q) * rho.data[m1 + j, m2 + j]) return v
def _transitions(self, levels): self.Aops = {} for p, level_g in enumerate(levels): Jg = level_g.J states_g = level_g.states for q, level_e in enumerate(levels): if level_e.name != level_g.name: Je = level_e.J states_e = level_e.states if abs(Jg - Je) <= 1: name = level_g.name + level_e.name if level_g.J != 0: self.Aops[name] = [ sum([ states_g[i] * states_e[j].dag() * qu.clebsch(Jg, 1, Je, level_g.M[i], k, level_e.M[j]) for i in range(level_g.N) for j in range(level_e.N) ]) for k in [-1, 0, 1] ] else: self.Aops[name] = [ sum([ states_g[i] * states_e[j].dag() for i in range(level_g.N) for j in range(level_e.N) ]) ]
def _rho_kq(rho, j, k, q): """ This calculates the trace of the multipole operator T_kq and the density matrix rho for use in the spin Wigner quasiprobability distribution. Parameters ---------- rho : qobj A density matrix for a spin-j quantum system. j : float The spin length of the system. k : int Spherical harmonic degree q : int Spherical harmonic order Returns ------- v : float Overlap of state with multipole operator T_kq """ v = 0j for m1 in arange(-j, j + 1): for m2 in arange(-j, j + 1): v += ((-1)**(2 * j - k - m1 - m2) * np.sqrt( (2 * k + 1) / (2 * j + 1)) * qutip.clebsch(j, k, j, -m1, q, -m2) * rho.data[int(j - m1), int(j - m2)]) return v
def test_unit_clebsch_delta_m(j1, j2): """sum_j3 sum_m3 C(j1,j2,j3,m1,m2,m3)*C(j1,j2,j3,m1',m2',m3) = delta m1,m1' delta m2,m2'""" for _ in range(10): m1 = np.random.choice(np.arange(-j1, j1 + 1)) m1p = np.random.choice(np.arange(-j1, j1 + 1)) m2 = np.random.choice(np.arange(-j2, j2 + 1)) m2p = np.random.choice(np.arange(-j2, j2 + 1)) sum_match = 0 sum_differ = 0 for j3 in np.arange(abs(j1 - j2), j1 + j2 + 1): for m3 in np.arange(-j3, j3 + 1): c1 = clebsch(j1, j2, j3, m1, m2, m3) c2 = clebsch(j1, j2, j3, m1p, m2p, m3) sum_match += c1**2 sum_differ += c1 * c2 assert sum_match == pytest.approx(1) assert sum_differ == pytest.approx(int(m1 == m1p and m2 == m2p))
def test_unit_clebsch_delta_j(j1, j2): """sum_m1 sum_m2 C(j1,j2,j3,m1,m2,m3) * C(j1,j2,j3',m1,m2,m3') = delta j3,j3' delta m3,m3'""" for _ in range(10): j3 = np.random.choice(np.arange(abs(j1 - j2), j1 + j2 + 1)) j3p = np.random.choice(np.arange(abs(j1 - j2), j1 + j2 + 1)) m3 = np.random.choice(np.arange(-j3, j3 + 1)) m3p = np.random.choice(np.arange(-j3p, j3p + 1)) sum_match = 0 sum_differ = 0 for m1 in np.arange(-j1, j1 + 1): for m2 in np.arange(-j2, j2 + 1): c1 = clebsch(j1, j2, j3, m1, m2, m3) c2 = clebsch(j1, j2, j3p, m1, m2, m3p) sum_match += c1**2 sum_differ += c1 * c2 assert sum_match == pytest.approx(1) assert sum_differ == pytest.approx(int(j3 == j3p and m3 == m3p))
def murelj(Jg, Je): import numpy as np import qutip as qu intg = int(2 * Jg + 1) inte = int(2 * Je + 1) Mg = list(np.arange(-Jg, Jg + 1)) Me = list(np.arange(-Je, Je + 1)) Am = np.zeros([intg, inte]) A0 = np.zeros([intg, inte]) Ap = np.zeros([intg, inte]) if abs(Jg - Je) > 1: print('true') return Am, A0, Ap else: for k in np.arange(0, intg): m = Mg[k] if abs(m - 1) <= Je: Am[k, Me.index(m - 1)] = qu.clebsch(Jg, 1, Je, m, -1, m - 1) if abs(m) <= Je: A0[k, Me.index(m)] = qu.clebsch(Jg, 1, Je, m, 0, m) if abs(m + 1) <= Je: Ap[k, Me.index(m + 1)] = qu.clebsch(Jg, 1, Je, m, 1, m + 1) return Am, A0, Ap
def _parity(N, j): """Private function to calculate the parity of the quantum system. """ if j == 0.5: pi = np.identity(N) - np.sqrt((N - 1) * N * (N + 1) / 2) * _lambda_f(N) return pi / N elif j > 0.5: mult = np.int32(2 * j + 1) matrix = np.zeros((mult, mult)) foo = np.ones(mult) for n in np.arange(-j, j + 1, 1): for l in np.arange(0, mult, 1): foo[l] = (2 * l + 1) * qutip.clebsch(j, l, j, n, 0, n) matrix[np.int32(n + j), np.int32(n + j)] = np.sum(foo) return matrix / mult
def _parity(N, j): """Private function to calculate the parity of the quantum system. """ if j == 0.5: pi = np.identity(N) - np.sqrt((N - 1) * N * (N + 1) / 2) * _lambda_f(N) return pi / N elif j > 0.5: mult = np.int32(2 * j + 1) matrix = np.zeros((mult, mult)) foo = np.ones(mult) for n in np.arange(-j, j + 1, 1): for l in np.arange(0, mult, 1): foo[l] = (2 * l + 1) * qt.clebsch(j, l, j, n, 0, n) matrix[np.int32(n + j), np.int32(n + j)] = np.sum(foo) return matrix / mult
def tensor_clebsch(j1, j2): J3 = possible_j3s(j1, j2) states = [] labels = [] for j3 in J3: substates = [] sublabels = [] for m3 in np.arange(-j3, j3 + 1): terms = [] for m1 in np.arange(-j1, j1 + 1): for m2 in np.arange(-j2, j2 + 1): terms.append(\ qt.clebsch(j1, j2, j3, m1, m2, m3)*\ qt.tensor(qt.spin_state(j1, m1),\ qt.spin_state(j2, m2))) substates.append(sum(terms)) sublabels.append((j3, m3)) states.extend(substates[::-1]) labels.append(sublabels[::-1]) return qt.Qobj(np.array([state.full().T[0] for state in states])), labels
def threej(j1, j2, j, m1, m2, m): return (-1)**(j1-j2-m)/np.sqrt(2*j + 1) * qt.clebsch(j1, j2, j, m1, m2, -m)
def test_unit_clebsch(): "utilities: Clebsch–Gordan coefficients " N = 15 for _ in range(100): "sum_m1 sum_m2 C(j1,j2,j3,m1,m2,m3)*C(j1,j2,j3',m1,m2,m3') =" "delta j3,j3' delta m3,m3'" j1 = np.random.randint(0, N + 1) j2 = np.random.randint(0, N + 1) j3 = np.random.randint(abs(j1 - j2), j1 + j2 + 1) j3p = np.random.randint(abs(j1 - j2), j1 + j2 + 1) m3 = np.random.randint(-j3, j3 + 1) m3p = np.random.randint(-j3p, j3p + 1) if np.random.rand() < 0.25: j1 += 0.5 j3 += 0.5 j3p += 0.5 m3 += np.random.choice([-0.5, 0.5]) m3p += np.random.choice([-0.5, 0.5]) if np.random.rand() < 0.25: j2 += 0.5 j3 += 0.5 j3p += 0.5 m3 += np.random.choice([-0.5, 0.5]) m3p += np.random.choice([-0.5, 0.5]) sum_match = -1 sum_differ = -int(j3 == j3p and m3 == m3p) for m1 in np.arange(-j1, j1 + 1): for m2 in np.arange(-j2, j2 + 1): c1 = clebsch(j1, j2, j3, m1, m2, m3) c2 = clebsch(j1, j2, j3p, m1, m2, m3p) sum_match += c1**2 sum_differ += c1 * c2 assert_(abs(sum_match) < 1e-6) assert_(abs(sum_differ) < 1e-6) for _ in range(100): "sum_j3 sum_m3 C(j1,j2,j3,m1,m2,m3)*C(j1,j2,j3,m1',m2',m3) =" "delta m1,m1' delta m2,m2'" j1 = np.random.randint(0, N + 1) j2 = np.random.randint(0, N + 1) m1 = np.random.randint(-j1, j1 + 1) m1p = np.random.randint(-j1, j1 + 1) m2 = np.random.randint(-j2, j2 + 1) m2p = np.random.randint(-j2, j2 + 1) if np.random.rand() < 0.25: j1 += 0.5 m1 += np.random.choice([-0.5, 0.5]) m1p += np.random.choice([-0.5, 0.5]) if np.random.rand() < 0.25: j2 += 0.5 m2 += np.random.choice([-0.5, 0.5]) m2p += np.random.choice([-0.5, 0.5]) sum_match = -1 sum_differ = -int(m1 == m1p and m2 == m2p) for j3 in np.arange(abs(j1 - j2), j1 + j2 + 1): for m3 in np.arange(-j3, j3 + 1): c1 = clebsch(j1, j2, j3, m1, m2, m3) c2 = clebsch(j1, j2, j3, m1p, m2p, m3) sum_match += c1**2 sum_differ += c1 * c2 assert_(abs(sum_match) < 1e-6) assert_(abs(sum_differ) < 1e-6)