// PROGRAM conduct // イジング鎖における複数デーモン・アルゴリズム #include "TrueBASIC.h" int main(); void initial(int *N, int spin[], int *nmcs, int *nvisit); void change(int N, int spin[], double Ed[], double *accept); void heat(int N, int spin[], double Edsum[]); void data(int N, int spin[], double Ed[], double Edsum[], double Msum[]); void output(int N, double Edsum[], double Msum[], int nmcs, double accept); int main() { int N, imcs, nmcs, nvisit, spin[1001], Itmp1_; double Ed[1001], Edsum[1001], Msum[1001], accept = 0; for(Itmp1_ = 0; Itmp1_ <= 1000; ++Itmp1_) { Ed[Itmp1_] = 0; Edsum[Itmp1_] = 0; Msum[Itmp1_] = 0; } // 熱はスピン 1 に加えられ,スピン N から取り除かれる initial(&N, spin, &nmcs, &nvisit); for(imcs = 1; imcs <= nmcs; ++imcs) { change(N, spin, Ed, &accept); if((imcs & nvisit) == 0) heat(N, spin, Edsum); data(N, spin, Ed, Edsum, Msum); } output(N, Edsum, Msum, nmcs, accept); return 0; } void initial(int *N, int spin[], int *nmcs, int *nvisit) { int i; char Stmp1_[_LBUFF_]; rnd(-1); printf("number of spins = "); fgets(Stmp1_, _LBUFF_, stdin); sscanf(Stmp1_, "%d", N); printf("number of MC steps per spin = "); fgets(Stmp1_, _LBUFF_, stdin); sscanf(Stmp1_, "%d", nmcs); printf("MC steps between updates of end spins = "); fgets(Stmp1_, _LBUFF_, stdin); sscanf(Stmp1_, "%d", nvisit); // 初期のランダムな配置 for(i = 1; i <= (*N); ++i) { if(rnd(0) > 0.5) spin[i] = 1; else spin[i] = -1; } } void change(int N, int spin[], double Ed[], double *accept) // スピン反転動力学 { int isite, i; double de; // 1 モンテカルロ・ステップを実行する for(i = 2; i <= N - 1; ++i) { // スピン 2 より N - 1 までの中から1つをランダムに取り出す isite = (int)(rnd(0)*(N - 2) + 2); // 試行エネルギー変化 de = 2*spin[isite]*(spin[isite - 1] + spin[isite + 1]); if(de <= Ed[isite]) { spin[isite] *= - 1; ++(*accept); Ed[isite] -= de; } } } void heat(int N, int spin[], double Edsum[]) { // エネルギーをスピン 1 に加えてスピン N から取り除くことを試みる // 許されるのはスピン 1 と 2 の向きが揃っていて, // スピン N と N - 1 が揃っていないときだけである if((spin[1]*spin[2] == 1) && (spin[N]*spin[N - 1] == -1)) { Edsum[1] += 2; Edsum[N] -= 2; spin[1] *= -1; spin[N] *= -1; } } void data(int N, int spin[], double Ed[], double Edsum[], double Msum[]) { int i; for(i = 2; i <= N - 1; ++i) { Edsum[i] += Ed[i]; Msum[i] += spin[i]; } } void output(int N, double Edsum[], double Msum[], int nmcs, double accept) { int i; double Edave, M, accept_prob, norm, temperature; norm = 1.0/nmcs; accept_prob = accept*norm/(N - 2); printf("acceptance probability = %f\n", accept_prob); printf("\n"); printf(" i Ed(i) T M(i)\n"); printf("\n"); for(i = 2; i <= N-1; ++i) { Edave = Edsum[i]*norm; temperature = 0; if(Edave != 0) if((1 + 4/Edave) > 0) temperature = 4/log(1 + 4/Edave); M = Msum[i]*norm; printf("%12d %12f %12f %12f\n", i, Edave, temperature, M); } }