How to measure the spin-spin correlation in a Monte Carlo simulation of the Ising model?

I'm simulating the Ising Model in 2D up to 5D and I want to calculate the spin-spin correlation, correlation length, and critical exponent of the system. What is a good way to go about doing this?

Generally, I know I need:

$$<s_os_r> \cong \frac{1}{N}\sum_i^N s_os_r$$

Where $N$ is the number of Monte Carlo trials run.

What is a good way to actually calculate $s_os_r$? And how does this help me with calculating the correlation length $\xi$ and the critical exponent $\nu$

• No, you don't need to store the history of a cell in order to calculate the spin-spin correlation function. The history is only needed if you look a the autocorrelation of an observable in time, but what is asked here is the correlation between the direction of two spins at the same time. @alvarezcl: Have a look at this question. Let me know if that helps. – Robert Rüger Mar 10 '15 at 10:39
• Thanks for your help, all. @RobertRüger The link you put up did help but I'm having trouble on a first principles basis. As I run through each MC iteration, what's a reasonable procedure to run through and estimate $$<s_os_r>$$ from all the spins I have? – alvarezcl Mar 11 '15 at 8:04
• @RobertRüger, your github code talks about observables where you calculate the spin-spin correlation. I'm having trouble mapping your README to the actual files. Is there a system there? – alvarezcl Mar 11 '15 at 21:25
• @RobertRüger, I find your spin-spin correlation function, namely, vector<double> IsingModel2d::ss_corr() in model_ising2dsqrmet.cpp Would you mind telling me what it does? I'll be going over your code but straight from the source is best, in my opinion. – alvarezcl Mar 11 '15 at 21:28
• Yes, there is kind of a system in the source code, though it was my first C++ project and I would do many things differently today ... I'll post an answer describing how it works for the 2d IsingModel. Generalizing it to more than 2 dimensions should not be hard then. – Robert Rüger Mar 12 '15 at 9:35

I will explain how I measured the spin-spin correlation function for the 2d Ising model. Generalization to more than 2 dimensions should be straightforward as long as you have hypercubic lattices.

Just to get the notation straight: Let's use the name $\sigma_{(i,j)}$ for the spin at position $\vec r_{(i,j)} = \begin{pmatrix} i \\ j \end{pmatrix}$. Let's assume our Ising model has $L \times L$ spins, so we have $1 \leq i,j \leq L$.

The first thing to note is that I assume that the spin-spin correlation function - lets call it $\chi_{(i,j)(k,l)}$ - only depends on the absolute distance between the two spins $\sigma_{(i,j)}$ and $\sigma_{(k,l)}$.

$$\chi_{(i,j)(k,l)} = \chi( | \vec r_{(i,j)} - \vec r_{(k,l)} | ) = \chi(r)$$

I'm not sure if this is true in general, but there is a proof that it is true for the 2d Ising model at the critical temperature. (A rotationally symmetric spin-spin correlation function is proven, and that is just another way of saying that it depends on the distance only.) Don't take my word for it, but for now I wouldn't worry about this assumption ...

Knowing this, it is easy to see that at every step in your Markov chain you don't have to look at all possible $L^2$ pairs of spins. Instead you can only look at a subset of pairs, where you have all distances $r$ you are interested in within this subset.

For my implementation I chose to use all spins $\sigma_{(i,i)}$ along the diagonal of the lattice and to only measure the correlation along the two directions of the lattice vectors. So I only consider the correlation between $\sigma_{(i,i)}$ and all $\sigma_{(i,j)}$ (horizontally) and $\sigma_{(j,i)}$ (vertically). Remember that the spin-spin correlation function is rotationally symmetric, so you don't gain anything by considering pairs of spins along any other direction. Measuring along the axes makes your life much easier as you will only have integer distances $r$, meaning that you can use a plain $L-1$ element array with the distance as an index to accumulate the terms of your sum. This is what you should calculate at every Monte Carlo step:

$$\text{sum}(r) = \sum_{i=1}^L \sum_{j=1}^L \left( \sigma_{(i,i)} \sigma_{(i,j)} + \sigma_{(i,i)} \sigma_{(j,i)} \right) \; \text{ with } \; r = |i-j|$$

$$\text{samples}(r) = \sum_{i=1}^L \sum_{j=1}^L 2 \; \text{ with } \; r = |i-j|$$

$$\chi_n(r) = \frac{\text{sum}(r)}{\text{samples}(r)}$$

This is exactly what this function IsingModel2d::ss_corr() in my code does. (Keeping track of the samples is only needed because you make a different number of measurements for different values of $r$. Consider as an example the extreme cases: All but two spins $\sigma_{(i,i)}$ on the diagonal have 4 nearest neighbors at distance $r=1$, but only $\sigma_{(1,1)}$ and $\sigma_{(L,L)}$ have two partners each at distance $r = L-1$. So you have to compensate for the fact that you measure the correlation between close spins more often than between far away spins.)

Note that you will get a different $\chi_n(r)$ at every Monte Carlo step, depending on your current configuration. In the end you should average them (just like you do with any other observable) to get your final result for the spin-spin correlation function:

$$\chi(r) = \frac{1}{N-1} \sum_{n=1}^N \chi_n(r)$$

Once you have this, you can fit $\chi(r) = r^{-\beta}$ where you should hopefully find $\beta = 0.25$. Check out this other question on details regarding the fit.

Hope this helps!

• Thanks for your help, I have been struggling with this for a while. Perhaps you can help elucidate on some of my results here: link – alvarezcl Mar 12 '15 at 16:52
• Should the sums be up to $r$, not $L$? – alvarezcl Mar 12 '15 at 18:50
• I see, so your $sum(r)$ is explicitly an array, where each index at r corresponds to the samples. I was confused initially but now I seem to understand it. – alvarezcl Mar 12 '15 at 19:12
• In fact, for any r, you can write that $$sum(r) = \sum_i^L\sigma_{(i,i)}(\sigma_{(i,i-r)} + \sigma_{(i-r,i)} + \sigma_{(i,i+r)} \sigma_{(i+r,i)})$$ This gives the 4 coupled values for each diagonal. One would then divide by 4L, since L diagonal values were sampled. This is what I was initially asking for; this would be just the value at one index $r$ of the array? This is assuming periodic boundary conditions. – alvarezcl Mar 12 '15 at 19:31
• Would you also know or have a resource on how to compute the correlation length given the spin-spin function? – alvarezcl Mar 13 '15 at 5:45