Spin-1/2 Heisenberg chain and its integrals of motion

The spin-1/2 Heisenberg chain is a textbook example of an integrable quantum system. Its Hamiltonian

\[\hat H = g \sum_i \mathbf{S}_i \cdot \mathbf{S}_{i+1}\]

conserves three projections of the total spin

\[\mathbf{S} = \sum_i \mathbf{S}_i\]

as well as a series of higher order charges \(Q_n\). Existence of these charges can be derived from the transfer matrix theory. Explicit expressions for \(Q_n\) were obtained in [GM94]. The following program constructs Hamiltonian of the Heisenberg chain with periodic boundary conditions and checks that \([\hat H, \mathbf{S}] = 0\), \([\hat H, Q_n] = 0\) and \([Q_n, Q_m] = 0\) for \(m,n = 3,4,5\).

  1#include <array>
  2#include <iostream>
  3#include <vector>
  4
  5#include <libcommute/libcommute.hpp>
  6
  7using namespace libcommute;
  8
  9// Type of the spin-1/2 Heisenberg Hamiltonian and its charges.
 10// All spin operators are going to carry one integer index - the site index.
 11using expr_t = static_indices::expr_complex<int>;
 12
 13// Spins S_i are operator-valued 3-dimensional vectors. Here, we use std::array
 14// as a simplistic implementation of such vectors.
 15using vector_expr_t = std::array<expr_t, 3>;
 16
 17// Addition of two vectors.
 18vector_expr_t operator+(vector_expr_t const& S1, vector_expr_t const& S2) {
 19  return {S1[0] + S2[0], S1[1] + S2[1], S1[2] + S2[2]};
 20}
 21
 22// Scalar product of two vectors.
 23expr_t dot(vector_expr_t const& S1, vector_expr_t const& S2) {
 24  return S1[0] * S2[0] + S1[1] * S2[1] + S1[2] * S2[2];
 25}
 26
 27// Cross product of two vectors
 28vector_expr_t cross(vector_expr_t const& S1, vector_expr_t const& S2) {
 29  return {S1[1] * S2[2] - S1[2] * S2[1],
 30          S1[2] * S2[0] - S1[0] * S2[2],
 31          S1[0] * S2[1] - S1[1] * S2[0]};
 32}
 33
 34int main() {
 35
 36  // For functions S_x(), S_y() and S_z().
 37  // Note that the x/y functions exist only for the complex expressions.
 38  using namespace static_indices;
 39
 40  // Number of spins in the chain
 41  int const N = 20;
 42  // Heisenberg exchange constant
 43  double const g = 2;
 44
 45  // List of spin operators {S_0, S_1, ..., S_{N-1}}
 46  std::vector<vector_expr_t> S;
 47  S.reserve(N);
 48  for(int i = 0; i < N; ++i)
 49    S.push_back({S_x(i), S_y(i), S_z(i)});
 50
 51  // Hamiltonian of the spin-1/2 Heisenberg chain.
 52  expr_t H;
 53  for(int i = 0; i < N; ++i) {
 54    // Index shift modulo N ensures periodic boundary conditions.
 55    H += g * dot(S[i], S[(i + 1) % N]);
 56  }
 57
 58  // Total spin of the chain
 59  vector_expr_t S_tot;
 60  for(int i = 0; i < N; ++i)
 61    S_tot = S_tot + S[i];
 62
 63  // All three components of S commute with the Hamiltonian.
 64  std::cout << "[H, S_x] = " << (H * S_tot[0] - S_tot[0] * H) << '\n';
 65  std::cout << "[H, S_y] = " << (H * S_tot[1] - S_tot[1] * H) << '\n';
 66  std::cout << "[H, S_z] = " << (H * S_tot[2] - S_tot[2] * H) << '\n';
 67
 68  // Higher charge Q_3 (1st line of Eq. (10)).
 69  expr_t Q3;
 70  for(int i = 0; i < N; ++i) {
 71    Q3 += dot(cross(S[i], S[(i + 1) % N]), S[(i + 2) % N]);
 72  }
 73  std::cout << "[H, Q3] = " << (H * Q3 - Q3 * H) << '\n';
 74
 75  // Higher charge Q_4 (2nd line of Eq. (10)).
 76  expr_t Q4;
 77  for(int i = 0; i < N; ++i) {
 78    Q4 += 4.0 * dot(cross(cross(S[i], S[(i + 1) % N]), S[(i + 2) % N]),
 79                    S[(i + 3) % N]);
 80    Q4 += dot(S[i], S[(i + 2) % N]);
 81  }
 82  std::cout << "[H, Q4] = " << (H * Q4 - Q4 * H) << '\n';
 83
 84  // Higher charge Q_5 (3rd line of Eq. (10)).
 85  expr_t Q5;
 86  for(int i = 0; i < N; ++i) {
 87    Q5 += 4.0 * dot(cross(cross(cross(S[i], S[(i + 1) % N]), S[(i + 2) % N]),
 88                          S[(i + 3) % N]),
 89                    S[(i + 4) % N]);
 90    Q5 += dot(cross(S[i], S[(i + 2) % N]), S[(i + 3) % N]);
 91    Q5 += dot(cross(S[i], S[(i + 1) % N]), S[(i + 3) % N]);
 92  }
 93  std::cout << "[H, Q5] = " << (H * Q5 - Q5 * H) << '\n';
 94
 95  // Check that the higher charges pairwise commute.
 96  std::cout << "[Q3, Q4] = " << (Q3 * Q4 - Q4 * Q3) << '\n';
 97  std::cout << "[Q3, Q5] = " << (Q3 * Q5 - Q5 * Q3) << '\n';
 98  std::cout << "[Q4, Q5] = " << (Q4 * Q5 - Q5 * Q4) << '\n';
 99
100  return 0;
101}
[GM94]

“Quantum Integrals of Motion for the Heisenberg Spin Chain”, M. P. Grabowski and P. Mathieu, Mod. Phys. Lett. A, Vol. 09, No. 24, pp. 2197-2206 (1994), https://doi.org/10.1142/S0217732394002057