# Implementation of neural network quantum states of the anti-ferromagnetic Heisenberg model

I'm studying this Science paper "Solving the quantum many-body problem with artificial neural networks" and looking into the implementation of the Anti-ferromagnetic Heisenberg model. The Hamiltonian is given as

$$$$\sum _ { \langle i , j \rangle } J _ { i j } \vec { S } _ { i } \vec { S } _ { j } = \sum _ { \langle i , j \rangle } J _ { i j } \left[ S _ { i } ^ { z } S _ { j } ^ { z } + \frac { 1 } { 2 } \left( S _ { i } ^ { + } S _ { j } ^ { - } + S _ { i } ^ { - } S _ { j } ^ { + } \right) \right]$$$$,

where $$S^{\pm}$$ are raising and lowering operators.

From this I understand how to derive the Hamiltonian in matrix form for a 2 particle system, which is given as

$$\left( \begin{array} { c c c c } { J _ { i j } / 4 } & { 0 } & { 0 } & { 0 } \\ { 0 } & { - J _ { i j } / 4 } & { J _ { i j } / 2 } & { 0 } \\ { 0 } & { J _ { i j } / 2 } & { - J _ { i j } / 4 } & { 0 } \\ { 0 } & { 0 } & { 0 } & { J _ { i j } / 4 } \end{array} \right)$$

in the basis $$\{ | \uparrow \uparrow \rangle , | \uparrow \downarrow \rangle , | \downarrow \uparrow \rangle , | \downarrow \downarrow \rangle \}$$.

However, in the code given in the paper, a $$-2$$ was used instead of $$2$$ for off-diagonal elements.
Here's the excerpt of part of the code (from the source code file named heisenberg1d.cc). The first for loop implements the $$S^{z}_{i}S^{z}_{j}$$ interaction while the second one for the raising and lowering operators.

//Finds the non-zero matrix elements of the hamiltonian
//on the given state
//i.e. all the state' such that <state'|H|state> = mel(state') \neq 0
//state' is encoded as the sequence of spin flips to be performed on state

//computing interaction part Sz*Sz
mel[0]=0.;

for(int i=0;i<(nspins_-1);i++){
mel[0]+=double(state[i]*state[i+1]);
}

//Looks for possible spin flips
for(int i=0;i<(nspins_-1);i++){
if(state[i]!=state[i+1]){
mel.push_back(-2);
flipsh.push_back(std::vector<int>({i,i+1}));
}
}


These matrix elements mel are used to compute the local energy in a step of the Variational Monte Carlo scheme, i.e.,

$$E_\text{local} = H_{ss'}\frac{\Psi(s')}{\Psi({s})}$$,

where $$H_{ss'}$$ are the matrix elements in mel, and $$\Psi$$ is the variational wavefunction represented by a Restricted Boltzmann Machine.

Thus my question is why is there a negative sign in the code implementation in the second for loop which implements the off-diagonal elements of the Hamiltonian?

PS. I have also verified that by using $$-2$$, it converges to the exact ground state energy of $$0.25 - \ln(2) = -0.44315$$.

• do you mean the part that goes mel[0]+=double(state[i]*state[i+1])? note that if state[i] and state[i+1] are of opposite direction this is negative, just as in your matrix. – user245141 Feb 24 '20 at 11:50
• no, I mean the off-diagonal term as in if(state[i]!=state[i+1]){ mel.push_back(-2);` – jackie_gamma Feb 24 '20 at 11:51
• ok. as i see it, the diagonal terms are negative (this is the mel.push_back(-2) line) and the off-diagonal terms, which represent spin-flips, are positive (this is the flipsh.push_back line). Note that for $|\uparrow,\downarrow\rangle$. I could miss something, though – user245141 Feb 24 '20 at 11:58
• I mean why is it "mel.push_back(-2)" instead of "mel.push_back(2)" since in the matrix form of the Hamiltonian, the off-diagonal terms are positive. Btw, the "flipsh.push_back" line is to store the positions of spins flips in the state vector – jackie_gamma Feb 24 '20 at 12:17
• ok. then I apologize, as I clearly don't understand the code. But one last thing, there are 4 spins you have to consider, not just two: spin[i] and spin[i+1] in $|\rm{state}\rangle$ and spin[i] and spin[i+1] in $\langle \rm{state}'|$. Your off-diagonal terms relate to a situation where $\rm{spin}[i](\rm{state})\neq \rm{spin}[i+1](\rm{state})=\rm{spin}[i](\rm{state}')\neq \rm{spin}[i+1](\rm{state}')$. It seems from the code you put here that only two spins are considered and compared? – user245141 Feb 24 '20 at 12:44

The sign difference would not matter. On any bipartite lattice, the Hamiltonians $$H_\pm = \sum_{\langle i ,j \rangle} \left( S^z_i S^z_j \pm \frac{1}{2} \left( S^+_i S^-_j + S^-_i S^+_j \right) \right)$$ are unitarily equivalent. In particular, if we label one sublattice as A, then the unitary $$U = \prod_{i \in A} \exp\left( i \pi S^z_i \right)$$ toggles this choice of sign: $$U H_\pm U^\dagger = H_\mp .$$

• Thanks for your answer. I get what you mean but I have 2 further questions. 1) Would this unitary transform change anything, such as the orthornormal basis? 2) Why do you think the author choose the negative instead of positive? I've tried with +2 in the code and it doesn't work. Is it because of the nature of the wavefunction ansatz used in this case? – jackie_gamma Feb 26 '20 at 16:27
• @jackie_gamma yes the unitary changes the eigenstates. What do you mean when you say the code doesn't work? Does the algorithm get stuck? One reason people sometimes flip these signs is to avoid sign issues, which is important for Monte Carlo. In particular, if we forget the SzSz term for the moment, then the advantage of choosing the minus is that it makes the model ferromagnetic. – Ruben Verresen Feb 26 '20 at 21:37
• I mean when I use +2, it will converge to a different energy value, around -0.25 which is closer to the classical result; while using -2, it converges to the correct result of -0.44. Also, the paper did clearly mention that the model studied is the anti-ferromagnetic one. That's why I'm confused... – jackie_gamma Feb 27 '20 at 1:45