c++ - C++ 中的伊辛模型

标签 c++ algorithm boolean

我正在用 C++ 为二维伊辛模型编写代码。以下是代码应该执行的操作:

  1. 生成随机 NxN 晶格,每个位点的值为 +1 或 -1。
  2. 随机选择一个站点
  3. 如果位点在翻转时(+1 到 -1 或 -1 到 +1)处于较低能量状态,翻转状态即。如果 dE < 0,翻转状态。如果翻转状态具有更高的能量,则以接受率 w = e^{-b(dE)} 翻转。如果状态翻转,dE 是能量的变化。 4.对所有 NxN 站点执行此操作,不要重复。这被认为是一次扫荡。
  4. 喜欢扫 100 次。

我在执行第 1、2 和 3 步时遇到问题,非常感谢任何帮助!对于第 1 步,我设法创建并显示了一个格子,但我似乎无法提取位置 (x, y) 处的站点值。第 2 步和第 3 步,如何使用某种 boolean 表达式根据接受概率进行翻转?

 #include <cstdlib>
#include <ctime>
using namespace std;
#include <iostream>
int main() //random generation of spin configuration
{
int L;              //Total number of spins L = NxN
int N = 30          //A square lattice of length 30
double B=1;         //magnetic field
double M;           //Total Magnetization = Sum Si
double E;           //Total Energy
int T = 1.0;
int nsweeps = 100;      //number of sweeps
int de;             //change in energy when flipped
double Boltzmann;       //Boltzmann factor
int x,y;            //randomly chosen lattice site
int i,j,a,c;            //counters
  int ROWS = 5;
  int COLS = 5;
  int matrix[ROWS][COLS];
  srand ( static_cast<unsigned> ( time ( 0 ) ) );
  for ( int i = 0; i < ROWS; i++ ) 
  {
    for ( int j = 0; j < COLS; j++ )
    {
      matrix[i][j] = rand () % 2 *2-1;
    }
  }

 // showing the matrix on the screen
    for(int i=0;i<ROWS;i++)  // loop 3 times for three lines
    {
        for(int j=0;j<COLS;j++)  // loop for the three elements on the line
        {
            cout<<matrix[i][j];  // display the current element out of the array
        }
    cout<<endl;  // when the inner loop is done, go to a new line
    }
    return 0;  // return 0 to the OS.

//boundary conditions and range
if(x<0) x += N;      
if(x>=L) x -= N;
if(y<0) y += N;
if(y>=L) y -= N;

//counting total energy of configuration
{  int neighbour = 0;    // nearest neighbour count

   for(int i=0; i<L; i++)
      for(int j=0; j<L; j++)
    {  if(spin(i,j)==spin(i+1, j))     // count from each spin to the right and above 
              neighbour++;
           else 
              neighbour--;
           if(spin(i, j)==spin(i, j+1))
              neighbour++;
           else
              neighbour--;
    }

    E = -J*neighbour - B*M;

//flipping spin
int x = int(srand48()*L);   //retrieves spin from randomly choosen site
int y = int(srand48()*L);

int delta_M = -2*spin(x, y);    //calculate change in Magnetization M
int delta_neighbour = spin(spinx-1, y) + spin(x+1, y)+ spin(x, y-1) + spin(x, y+1);
int delta_neighbour = -2*spin(x,y)* int delta_neighbour;

double delta_E = -J*delta_neighbour -B*delta_M;


//flip or not
if (delta_E<=0)
    {  (x, y) *= -1;     // flip spin and update values
           M += delta_M;
           E += delta_E;

        }



}

最佳答案

跟进我的评论:

There are too many issues with your code for a single answer. Try to build your program step by step. Use functions which perform one thing, and this they do well. Test each function individually and if necessary try to find out why it does not work. Then post specific questions again.

入门指南:

  • 将您的网格存储为 std::vector<int> lattice(N*N)
  • 访问元素 (x,y)data[x+N*y] .

例子:

#include <vector>

struct IsingModel
{ 
    unsigned size_;

    std::vector<int> lattice_;

    // access element (x,y)
    int& at(int x, int y) {
        return lattice_[x + y*size_];
    }
    int at(int x, int y) const {
        return lattice_[x + y*size_];
    }

    // generate size x size lattice
    IsingModel(unsigned size)
    : size_(size), lattice_(size*size, +1) {
    }

    static int BoolToSpin(bool v) {
        return v ? +1 : -1;
    }

    // initialize spin randomly
    void initializeRandom() {
        for(int y=0; y<size_; y++) {
            for(int x=0; x<size_; x++) {
                at(x,y) = BoolToSpin(rand()%2);
            }
        }
    }

    static int Energy(int a, int b) {
        return (a == b) ? +1 : -1;
    }

    // compute total energy
    unsigned computeTotalEnergy() const {
        unsigned energy = 0;
        for(int y=1; y<size_-1; y++) {
            for(int x=1; x<size_-1; x++) {
                energy += Energy(at(x,y), at(x+1,y));
                energy += Energy(at(x,y), at(x,y+1));
            }
        }
        return energy ;
    }

 };

 #include <iostream>     
 #include <cstdlib>
 #include <ctime>

 int main() {
     srand(static_cast<unsigned>(time(0))); // intialize random number generator
     IsingModel im(10);
     im.initializeRandom();
     unsigned energy = im.computeTotalEnergy();
     std::cout << energy << std::endl; // print energy
 }

关于c++ - C++ 中的伊辛模型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22973658/

相关文章:

pandas - 如何对 pandas 进行取模查询

c++ - 为什么这不是函数模板的部分特化?

c++ - 从基类实例调用派生类方法而无需强制转换

c++ - 奇怪的 C++ 类输出

c++ - if(!pointer) 和 if(!*pointer) 有什么区别?

algorithm - 合并排序最坏情况下的字典排序运行时间?

arrays - 计算乘积不能被 k 整除的子数组的个数

php - 检查一组数字中的数字 n 是否等于其子集的总和

javascript - "value === false"更优雅的替代方案?

python - 为 Python 中的任何表达式创建真值表