我尝试模拟一维正弦戈登场模型的热版本。我有兴趣找到使能量的函数最小化的热静态解决方案:
其中
令人困惑的是 Metropolis 算法的接受率太高——超过,因此几乎每一个新提议的配置都被接受。在每个 Metropolis 步骤中,我都会更改一个空间点的场值并计算能量差异。为了提出新的配置,统一采样与步骤参数一起使用,即
其中到 的随机数。
在我看来,如果接受率太高,那么算法就不能正常工作。然而,这种算法完美地应用于基态谐振子(通过路径积分蒙特卡罗)。
这是我的代码:
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
}
我不知道可能出了什么问题。