# Metropolis algorithm and thermal sine-Gordon model

I try to simulate thermal version of 1D $(x, t)$ sine-Gordon field model. I am interested in finding thermal static solution that minimizes functional of energy $E$:

$$E = \int dx \left( \frac{1}{2} \phi' ^2 + 1 - \cos \phi \right) \ ,$$

where $\phi' = \partial_x \phi$

What is very confusing that acceptance ratio of Metropolis algorithm is too high - more than $0.95$, so almost every new proposed configuration is accepted. On each Metropolis step I change field value at one spatial point and calculate difference in energy. To propose new configurations uniform sampling is used with step parameter $\delta = 0.5$, i.e.

$$\phi_{new} = \phi_{old} + r \ ,$$

where $r$ is random number from $\phi_{old} - \delta$ to $\phi_{old} + \delta$.

It seems to me that if acceptance ratio is too high then algorithm does not work correctly. However, such algorithm is perfectly applied to the ground state harmonic oscillator (via path integral Monte Carlo).

Here is my code:

double E_part(double dx, double phi, double phi_plus, double phi_minus) {
return dx * ( 0.5 * pow ( 0.5 * ( phi - phi_minus ), 2.0 ) + 0.5 * pow ( 0.5 * ( phi_plus - phi ), 2.0 ) + 1 - cos ( 0.5 * ( phi_minus + phi ) ) - cos ( 0.5 * (phi + phi_plus ) ) );
}

double Metropolis(int N, int Steps, double dx, double Temperature, double* dphi, double* phi, double delta, double* EnergyArray) {

double Beta = 1.0 / Temperature;

double Epart;

double Enewpart;

double phinew;

double phi_plus, phi_minus;

int AcceptanceCounter = 0;

//Initial energy

double r; //random number from 0 to 1;

for (int k=0; k<Steps; k++) {

for (int j=0; j<N; j++) {

int pos = RandomUniformInt(1 , N-2); //random position to change;

phinew = phi[pos] - delta + RandomUniform() * 2 * delta;

phi_plus = phi[pos + 1];
phi_minus = phi[pos - 1];

Epart = E_part(dx, phi[pos], phi_plus, phi_minus);
Enewpart = E_part(dx, phinew, phi_plus, phi_minus);

r = RandomUniform();

if ( Enewpart * Beta - Epart * Beta < 0.0 || exp( Epart * Beta - Enewpart * Beta ) >= r ) {
phi[pos] = phinew;
dphi[pos - 1] = 0.5 * ( phi[pos] - phi[pos - 1] );
dphi[pos] = 0.5 * ( phi[pos + 1] - phi[pos] );
AcceptanceCounter++;

}
}

EnergyArray[k] = Energy(N, dx, dphi, phi);

}
return ( AcceptanceCounter / static_cast<double>(Steps * N) );  //AcceptanceRatio is returned
}


I don't know what might be wrong.

• Should you not be checking exp( Epart * Beta - Enewpart * Beta ) < r instead of exp( Epart * Beta - Enewpart * Beta ) >= r ? – lemon Aug 24 '16 at 7:33
• @lemon No, of course, because in this case new energy is greater than the current one and (E - Enew) < 0 – newt Aug 24 '16 at 11:54
• Sorry, you're right. My only remaining guess is that your temperature is too high. If you only accept changes that decrease the energy then what is your acceptance ratio? – lemon Aug 24 '16 at 13:43
• @lemon It is very interesting, but energy tends to rise. I think it is quite normal because we have nonzero temperature, so the initial configuration becomes "noisy". Acceptance ratio is about 0.75 - 0.95 (depends on temperature and Metropolis step 'delta'). I think that probably the problem lies in high correlation between neighboring grid points. – newt Aug 24 '16 at 18:07