def test_heisenberg(self): J = np.array([[0, 1, 0, 0], [0, 0, 2, 0], [0, 0, 0, 3], [0, 0, 0, 0]], dtype=float) h = np.array([[0.3, 0, 0], [0, 0.4, 0], [0, 0, 0.5], [0, 0, 0]]) indices = [('a', 0), ('b', 1), ('c', 2), ('d', 3)] H1 = heisenberg(J) self.assertIsInstance(H1, ExpressionR) ref1 = - 0.5 * S_p(0) * S_m(1) \ - 0.5 * S_m(0) * S_p(1) \ - 1.0 * S_z(0) * S_z(1) \ - 1.0 * S_p(1) * S_m(2) \ - 1.0 * S_m(1) * S_p(2) \ - 2.0 * S_z(1) * S_z(2) \ - 1.5 * S_p(2) * S_m(3) \ - 1.5 * S_m(2) * S_p(3) \ - 3.0 * S_z(2) * S_z(3) self.assertEqual(H1, ref1) H2 = heisenberg(1j * J) self.assertIsInstance(H2, ExpressionC) ref2 = 1j * ref1 self.assertEqual(H2, ref2) H3 = heisenberg(J, h) self.assertIsInstance(H3, ExpressionC) ref3 = ref1 - 0.3 * S_x(0) - 0.4 * S_y(1) - 0.5 * S_z(2) self.assertEqual(H3, ref3) H4 = heisenberg(J, h, indices=indices) self.assertIsInstance(H4, ExpressionC) ref4 = - 0.5 * S_p('a', 0) * S_m('b', 1) \ - 0.5 * S_m('a', 0) * S_p('b', 1) \ - 1.0 * S_z('a', 0) * S_z('b', 1) \ - 1.0 * S_p('b', 1) * S_m('c', 2) \ - 1.0 * S_m('b', 1) * S_p('c', 2) \ - 2.0 * S_z('b', 1) * S_z('c', 2) \ - 1.5 * S_p('c', 2) * S_m('d', 3) \ - 1.5 * S_m('c', 2) * S_p('d', 3) \ - 3.0 * S_z('c', 2) * S_z('d', 3) \ - 0.3 * S_x('a', 0) - 0.4 * S_y('b', 1) - 0.5 * S_z('c', 2) self.assertEqual(H4, ref4) H5 = heisenberg(J, h, indices=indices, spin=1) self.assertIsInstance(H5, ExpressionC) ref5 = - 0.5 * S1_p('a', 0) * S1_m('b', 1) \ - 0.5 * S1_m('a', 0) * S1_p('b', 1) \ - 1.0 * S1_z('a', 0) * S1_z('b', 1) \ - 1.0 * S1_p('b', 1) * S1_m('c', 2) \ - 1.0 * S1_m('b', 1) * S1_p('c', 2) \ - 2.0 * S1_z('b', 1) * S1_z('c', 2) \ - 1.5 * S1_p('c', 2) * S1_m('d', 3) \ - 1.5 * S1_m('c', 2) * S1_p('d', 3) \ - 3.0 * S1_z('c', 2) * S1_z('d', 3) \ - 0.3 * S1_x('a', 0) - 0.4 * S1_y('b', 1) - 0.5 * S1_z('c', 2) self.assertEqual(H5, ref5)
def test_ising(self): J = np.array([[0, 1, 0, 0], [0, 0, 2, 0], [0, 0, 0, 3], [0, 0, 0, 0]], dtype=float) h_l = np.array([0.3, 0.4, 0.5, 0.0]) h_t = np.array([0.0, 0.6, 0.7, 0.8]) indices = [('a', 0), ('b', 1), ('c', 2), ('d', 3)] H1 = ising(J) self.assertIsInstance(H1, ExpressionR) ref1 = - 1.0 * S_z(0) * S_z(1) \ - 2.0 * S_z(1) * S_z(2) \ - 3.0 * S_z(2) * S_z(3) self.assertEqual(H1, ref1) H2 = ising(1j * J) self.assertIsInstance(H2, ExpressionC) ref2 = 1j * ref1 self.assertEqual(H2, ref2) H3 = ising(J, h_l=h_l) self.assertIsInstance(H3, ExpressionR) ref3 = ref1 - 0.3 * S_z(0) - 0.4 * S_z(1) - 0.5 * S_z(2) self.assertEqual(H3, ref3) H4 = ising(J, h_l=1j * h_l) self.assertIsInstance(H4, ExpressionC) ref4 = ref1 - 1j * (0.3 * S_z(0) + 0.4 * S_z(1) + 0.5 * S_z(2)) self.assertEqual(H4, ref4) H5 = ising(J, h_t=h_t) self.assertIsInstance(H5, ExpressionC) ref5 = ref1 - 0.6 * S_x(1) - 0.7 * S_x(2) - 0.8 * S_x(3) self.assertEqual(H5, ref5) H6 = ising(J, h_t=1j * h_t) self.assertIsInstance(H6, ExpressionC) ref6 = ref1 - 1j * (0.6 * S_x(1) + 0.7 * S_x(2) + 0.8 * S_x(3)) self.assertEqual(H6, ref6) H7 = ising(J, h_l, h_t, indices=indices) self.assertIsInstance(H7, ExpressionC) ref7 = - 1.0 * S_z('a', 0) * S_z('b', 1) \ - 2.0 * S_z('b', 1) * S_z('c', 2) \ - 3.0 * S_z('c', 2) * S_z('d', 3) \ - 0.3 * S_z('a', 0) - 0.4 * S_z('b', 1) - 0.5 * S_z('c', 2) \ - 0.6 * S_x('b', 1) - 0.7 * S_x('c', 2) - 0.8 * S_x('d', 3) self.assertEqual(H7, ref7) H8 = ising(J, h_l, h_t, indices=indices, spin=1) self.assertIsInstance(H8, ExpressionC) ref8 = - 1.0 * S1_z('a', 0) * S1_z('b', 1) \ - 2.0 * S1_z('b', 1) * S1_z('c', 2) \ - 3.0 * S1_z('c', 2) * S1_z('d', 3) \ - 0.3 * S1_z('a', 0) - 0.4 * S1_z('b', 1) - 0.5 * S1_z('c', 2)\ - 0.6 * S1_x('b', 1) - 0.7 * S1_x('c', 2) - 0.8 * S1_x('d', 3) self.assertEqual(H8, ref8)
def test_dzyaloshinskii_moriya(self): D = np.zeros((4, 4, 3), dtype=float) D[0, 1, :] = [1.0, 0, 0] D[1, 2, :] = [0, 2.0, 0] D[2, 3, :] = [0, 0, 3.0] indices = [('a', 0), ('b', 1), ('c', 2), ('d', 3)] H1 = dzyaloshinskii_moriya(D) self.assertIsInstance(H1, ExpressionC) ref1 = 1.0 * (S_y(0) * S_z(1) - S_z(0) * S_y(1)) \ + 2.0 * (S_z(1) * S_x(2) - S_x(1) * S_z(2)) \ + 3.0 * (S_x(2) * S_y(3) - S_y(2) * S_x(3)) self.assertEqual(H1, ref1) H2 = dzyaloshinskii_moriya(D, indices=indices) self.assertIsInstance(H2, ExpressionC) ref2 = 1.0 * (S_y('a', 0) * S_z('b', 1) - S_z('a', 0) * S_y('b', 1)) \ + 2.0 * (S_z('b', 1) * S_x('c', 2) - S_x('b', 1) * S_z('c', 2)) \ + 3.0 * (S_x('c', 2) * S_y('d', 3) - S_y('c', 2) * S_x('d', 3)) self.assertEqual(H2, ref2) H3 = dzyaloshinskii_moriya(D, spin=1) self.assertIsInstance(H3, ExpressionC) ref3 = 1.0 * (S1_y(0) * S1_z(1) - S1_z(0) * S1_y(1)) \ + 2.0 * (S1_z(1) * S1_x(2) - S1_x(1) * S1_z(2)) \ + 3.0 * (S1_x(2) * S1_y(3) - S1_y(2) * S1_x(3)) self.assertEqual(H3, ref3)
def test_Heisenberg(self): # Addition of 3D vectors def add(S1, S2): return (S1[0] + S2[0], S1[1] + S2[1], S1[2] + S2[2]) # Dot-product of 3D vectors def dot(S1, S2): return S1[0] * S2[0] + S1[1] * S2[1] + S1[2] * S2[2] # Cross-product of vectors def cross(S1, S2): return (S1[1] * S2[2] - S1[2] * S2[1], S1[2] * S2[0] - S1[0] * S2[2], S1[0] * S2[1] - S1[1] * S2[0]) N = 6 S = [(S_x(i), S_y(i), S_z(i)) for i in range(N)] H = sum(dot(S[i], S[(i + 1) % N]) for i in range(N)) S_tot = (ExpressionC(), ) * 3 for i in range(N): S_tot += add(S_tot, S[i]) # H must commute with the total spin self.assertEqual(len(H * S_tot[0] - S_tot[0] * H), 0) self.assertEqual(len(H * S_tot[1] - S_tot[1] * H), 0) self.assertEqual(len(H * S_tot[2] - S_tot[2] * H), 0) # Q3 is a higher-order integral of motion Q3 = sum( dot(cross(S[i], S[(i + 1) % N]), S[(i + 2) % N]) for i in range(N)) self.assertEqual(len(H * Q3 - Q3 * H), 0)
def test_spin_boson(self): eps = np.array([1, 2, 3], dtype=float) delta = np.array([4, 5, 6], dtype=float) delta_z = np.zeros((3, )) omega = np.array([7, 8], dtype=float) lambda_ = np.array([[0.1, 0.2], [0.3, 0.4], [0.5, 0.6]], dtype=float) indices_spin = [('a', 0), ('b', 1), ('c', 2)] indices_boson = [('x', 0), ('y', 1)] self.assertIsInstance(spin_boson(eps, delta, omega, lambda_), ExpressionC) self.assertIsInstance(spin_boson(eps, delta_z, omega, lambda_), ExpressionR) self.assertIsInstance(spin_boson(1j * eps, delta_z, omega, lambda_), ExpressionC) self.assertIsInstance(spin_boson(eps, delta_z, 1j * omega, lambda_), ExpressionC) self.assertIsInstance(spin_boson(eps, delta_z, omega, 1j * lambda_), ExpressionC) H1 = spin_boson(eps, delta, omega, 1j * lambda_) ref1 = -(S_z(0) + 2.0 * S_z(1) + 3.0 * S_z(2)) ref1 += (4.0 * S_x(0) + 5.0 * S_x(1) + 6.0 * S_x(2)) ref1 += 7.0 * a_dag(0) * a(0) + 8.0 * a_dag(1) * a(1) ref1 += S_z(0) * (0.1j * a_dag(0) - 0.1j * a(0)) ref1 += S_z(0) * (0.2j * a_dag(1) - 0.2j * a(1)) ref1 += S_z(1) * (0.3j * a_dag(0) - 0.3j * a(0)) ref1 += S_z(1) * (0.4j * a_dag(1) - 0.4j * a(1)) ref1 += S_z(2) * (0.5j * a_dag(0) - 0.5j * a(0)) ref1 += S_z(2) * (0.6j * a_dag(1) - 0.6j * a(1)) self.assertEqual(H1, ref1) H2 = spin_boson(eps, delta, omega, 1j * lambda_, indices_spin=indices_spin, indices_boson=indices_boson) ref2 = -(S_z('a', 0) + 2.0 * S_z('b', 1) + 3.0 * S_z('c', 2)) ref2 += (4.0 * S_x('a', 0) + 5.0 * S_x('b', 1) + 6.0 * S_x('c', 2)) ref2 += 7 * a_dag('x', 0) * a('x', 0) + 8 * a_dag('y', 1) * a('y', 1) ref2 += S_z('a', 0) * (0.1j * a_dag('x', 0) - 0.1j * a('x', 0)) ref2 += S_z('a', 0) * (0.2j * a_dag('y', 1) - 0.2j * a('y', 1)) ref2 += S_z('b', 1) * (0.3j * a_dag('x', 0) - 0.3j * a('x', 0)) ref2 += S_z('b', 1) * (0.4j * a_dag('y', 1) - 0.4j * a('y', 1)) ref2 += S_z('c', 2) * (0.5j * a_dag('x', 0) - 0.5j * a('x', 0)) ref2 += S_z('c', 2) * (0.6j * a_dag('y', 1) - 0.6j * a('y', 1)) self.assertEqual(H2, ref2) H3 = spin_boson(eps, delta, omega, 1j * lambda_, spin=1) ref3 = -(S1_z(0) + 2.0 * S1_z(1) + 3.0 * S1_z(2)) ref3 += (4.0 * S1_x(0) + 5.0 * S1_x(1) + 6.0 * S1_x(2)) ref3 += 7.0 * a_dag(0) * a(0) + 8.0 * a_dag(1) * a(1) ref3 += S1_z(0) * (0.1j * a_dag(0) - 0.1j * a(0)) ref3 += S1_z(0) * (0.2j * a_dag(1) - 0.2j * a(1)) ref3 += S1_z(1) * (0.3j * a_dag(0) - 0.3j * a(0)) ref3 += S1_z(1) * (0.4j * a_dag(1) - 0.4j * a(1)) ref3 += S1_z(2) * (0.5j * a_dag(0) - 0.5j * a(0)) ref3 += S1_z(2) * (0.6j * a_dag(1) - 0.6j * a(1)) self.assertEqual(H3, ref3)
def test_complex_only(self): # Spin 1/2 self.assertEqual(make_complex(S_p(0, "x")), S_x(0, "x") + 1j * S_y(0, "x")) self.assertEqual(make_complex(S_m(0, "x")), S_x(0, "x") - 1j * S_y(0, "x")) # Spin 1 self.assertEqual(make_complex(S_p(0, "x", spin=1)), S_x(0, "x", spin=1) + 1j * S_y(0, "x", spin=1)) self.assertEqual(make_complex(S_m(0, "x", spin=1)), S_x(0, "x", spin=1) - 1j * S_y(0, "x", spin=1)) # Spin 3/2 self.assertEqual( make_complex(S_p(0, "x", spin=3 / 2)), S_x(0, "x", spin=3 / 2) + 1j * S_y(0, "x", spin=3 / 2)) self.assertEqual( make_complex(S_m(0, "x", spin=3 / 2)), S_x(0, "x", spin=3 / 2) - 1j * S_y(0, "x", spin=3 / 2))
def test_rabi(self): eps = np.array([1, 2, 3], dtype=float) omega = np.array([4, 5], dtype=float) g = np.array([[0.1, 0.2], [0.3, 0.4], [0.5, 0.6]], dtype=float) indices_atom = [('a', 0), ('b', 1), ('c', 2)] indices_boson = [('x', 0), ('y', 1)] self.assertIsInstance(rabi(eps, omega, np.zeros((3, 2))), ExpressionR) self.assertIsInstance(rabi(eps, omega, g), ExpressionC) self.assertIsInstance(rabi(1j * eps, omega, g), ExpressionC) self.assertIsInstance(rabi(eps, 1j * omega, g), ExpressionC) self.assertIsInstance(rabi(eps, omega, 1j * g), ExpressionC) H1 = rabi(eps, omega, g) ref1 = S_z(0) + 2.0 * S_z(1) + 3.0 * S_z(2) ref1 += 4.0 * a_dag(0) * a(0) + 5.0 * a_dag(1) * a(1) ref1 += 0.1 * S_x(0) * (a_dag(0) + a(0)) ref1 += 0.2 * S_x(0) * (a_dag(1) + a(1)) ref1 += 0.3 * S_x(1) * (a_dag(0) + a(0)) ref1 += 0.4 * S_x(1) * (a_dag(1) + a(1)) ref1 += 0.5 * S_x(2) * (a_dag(0) + a(0)) ref1 += 0.6 * S_x(2) * (a_dag(1) + a(1)) self.assertEqual(H1, ref1) H2 = rabi(eps, omega, g, indices_atom=indices_atom, indices_boson=indices_boson) ref2 = S_z('a', 0) + 2.0 * S_z('b', 1) + 3.0 * S_z('c', 2) ref2 += 4 * a_dag('x', 0) * a('x', 0) + 5 * a_dag('y', 1) * a('y', 1) ref2 += 0.1 * S_x('a', 0) * (a_dag('x', 0) + a('x', 0)) ref2 += 0.2 * S_x('a', 0) * (a_dag('y', 1) + a('y', 1)) ref2 += 0.3 * S_x('b', 1) * (a_dag('x', 0) + a('x', 0)) ref2 += 0.4 * S_x('b', 1) * (a_dag('y', 1) + a('y', 1)) ref2 += 0.5 * S_x('c', 2) * (a_dag('x', 0) + a('x', 0)) ref2 += 0.6 * S_x('c', 2) * (a_dag('y', 1) + a('y', 1)) self.assertEqual(H2, ref2) H3 = rabi(eps, omega, g, spin=1) ref3 = S1_z(0) + 2.0 * S1_z(1) + 3.0 * S1_z(2) ref3 += 4.0 * a_dag(0) * a(0) + 5.0 * a_dag(1) * a(1) ref3 += 0.1 * S1_x(0) * (a_dag(0) + a(0)) ref3 += 0.2 * S1_x(0) * (a_dag(1) + a(1)) ref3 += 0.3 * S1_x(1) * (a_dag(0) + a(0)) ref3 += 0.4 * S1_x(1) * (a_dag(1) + a(1)) ref3 += 0.5 * S1_x(2) * (a_dag(0) + a(0)) ref3 += 0.6 * S1_x(2) * (a_dag(1) + a(1)) self.assertEqual(H3, ref3)
def test_anisotropic_heisenberg(self): Jx = np.array([[0, 1, 0, 0], [0, 0, 2, 0], [0, 0, 0, 3], [0, 0, 0, 0]], dtype=float) Jy = np.array([[0, 4, 0, 0], [0, 0, 5, 0], [0, 0, 0, 6], [0, 0, 0, 0]], dtype=float) Jz = np.array([[0, 7, 0, 0], [0, 0, 8, 0], [0, 0, 0, 9], [0, 0, 0, 0]], dtype=float) h = np.array([[0.3, 0, 0], [0, 0.4, 0], [0, 0, 0.5], [0, 0, 0]]) indices = [('a', 0), ('b', 1), ('c', 2), ('d', 3)] H1 = anisotropic_heisenberg((Jx, Jy, Jz)) self.assertIsInstance(H1, ExpressionC) ref1 = - 1.0 * S_x(0) * S_x(1) \ - 4.0 * S_y(0) * S_y(1) \ - 7.0 * S_z(0) * S_z(1) \ - 2.0 * S_x(1) * S_x(2) \ - 5.0 * S_y(1) * S_y(2) \ - 8.0 * S_z(1) * S_z(2) \ - 3.0 * S_x(2) * S_x(3) \ - 6.0 * S_y(2) * S_y(3) \ - 9.0 * S_z(2) * S_z(3) self.assertEqual(H1, ref1) H2 = anisotropic_heisenberg((Jx, Jy, Jz), h) self.assertIsInstance(H2, ExpressionC) ref2 = ref1 - 0.3 * S_x(0) - 0.4 * S_y(1) - 0.5 * S_z(2) self.assertEqual(H2, ref2) H3 = anisotropic_heisenberg((Jx, Jy, Jz), h, indices=indices) self.assertIsInstance(H3, ExpressionC) ref3 = - 1.0 * S_x('a', 0) * S_x('b', 1) \ - 4.0 * S_y('a', 0) * S_y('b', 1) \ - 7.0 * S_z('a', 0) * S_z('b', 1) \ - 2.0 * S_x('b', 1) * S_x('c', 2) \ - 5.0 * S_y('b', 1) * S_y('c', 2) \ - 8.0 * S_z('b', 1) * S_z('c', 2) \ - 3.0 * S_x('c', 2) * S_x('d', 3) \ - 6.0 * S_y('c', 2) * S_y('d', 3) \ - 9.0 * S_z('c', 2) * S_z('d', 3) \ - 0.3 * S_x('a', 0) - 0.4 * S_y('b', 1) - 0.5 * S_z('c', 2) self.assertEqual(H3, ref3) H4 = anisotropic_heisenberg((Jx, Jy, Jz), h, indices=indices, spin=1) self.assertIsInstance(H4, ExpressionC) ref4 = - 1.0 * S1_x('a', 0) * S1_x('b', 1) \ - 4.0 * S1_y('a', 0) * S1_y('b', 1) \ - 7.0 * S1_z('a', 0) * S1_z('b', 1) \ - 2.0 * S1_x('b', 1) * S1_x('c', 2) \ - 5.0 * S1_y('b', 1) * S1_y('c', 2) \ - 8.0 * S1_z('b', 1) * S1_z('c', 2) \ - 3.0 * S1_x('c', 2) * S1_x('d', 3) \ - 6.0 * S1_y('c', 2) * S1_y('d', 3) \ - 9.0 * S1_z('c', 2) * S1_z('d', 3) \ - 0.3 * S1_x('a', 0) - 0.4 * S1_y('b', 1) - 0.5 * S1_z('c', 2) self.assertEqual(H4, ref4)
# M. P. Grabowski and P. Mathieu # Mod. Phys. Lett. A, Vol. 09, No. 24, pp. 2197-2206 (1994), # https://doi.org/10.1142/S0217732394002057 # from numpy import array, zeros, dot, cross from pycommute.expression import S_x, S_y, S_z from pycommute.models import heisenberg # Number of spins in the chain N = 20 # Heisenberg exchange constant g = 2 # List of 3-component spin vectors {S_0, S_1, ..., S_{N-1}} S = [array([S_x(i), S_y(i), S_z(i)]) for i in range(N)] # Matrix of exchange constants between spins i and j exchange_matrix = zeros((N, N)) # Set elements corresponding to the nearest neighbors to -g # (index shift modulo N ensures periodic boundary conditions). for i in range(N): exchange_matrix[i, (i + 1) % N] = -g # Hamiltonian of the spin-1/2 Heisenberg chain. H = heisenberg(exchange_matrix) # Total spin of the chain. S_tot = array(sum(S)) # All three components of S commute with the Hamiltonian.