Ising Model C++ Metropolis Algorithm - Page 2
CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Page 2 of 4 FirstFirst 1234 LastLast
Results 16 to 30 of 48

Thread: Ising Model C++ Metropolis Algorithm

  1. #16
    Join Date
    Dec 2012
    Location
    England
    Posts
    2,389

    Re: Ising Model C++ Metropolis Algorithm

    Quote Originally Posted by D_Drmmr View Post
    That's horrible. Why would you advice someone to use a macro for this? A simple text-replace can solve this without obfuscating the code.

    @OP Using two different names for the same variable will make your code harder to understand. When you read your code, every time you see 'spin' you need to think "right, that actually just means matrix". If you just use a single name, you'll save yourself a lot of unnecessary thinking, freeing up your brain capacity to understand the code you're writing/debugging/reading/whatever. If spin better describes the values in the matrix, then go ahead and rename your matrix variable to spin (it's a simple search-and-replace). But don't use different names for the same thing unless you want to make your code harder to understand.
    I agree - that's why I said in my post #10 that the easiest way would be to do text-replace. I only offered the #define as an option to try to get the code posted by the OP to compile as I suspect that the part of the code using spin() was obtained elsewhere and I not sure of the expertise of the OP based upon the postings.
    All advice is offered in good faith only. You are ultimately responsible for effects of your programs and the integrity of the machines they run on.

  2. #17
    Join Date
    Dec 2012
    Location
    England
    Posts
    2,389

    Re: Ising Model C++ Metropolis Algorithm

    Code:
    int x = int (rand()*LatSize);
    int y = int (rand()*LatSize);
    What's with the '*' ? It should be % (modulo) as per my post #2!

    Code:
    int x = int (rand()%LatSize);
    int y = int (rand()%LatSize);
    Also, you don't need #include <stdlib.h> as you have #include <cstdlib>.

    As D_Drmmr said in his post #15, you need to use the debugger to find out why things don't work as expected.
    Before coding a program, it should first be designed (stating in English or other natural language how the program is going to work
    Code:
    define input requirements
    define output requirements
    define required algorithms
    do {
         design program
         code program
         test program
         debug program
    } while program_not_correct
    Before you continue writing 'ad hoc' code I suggest that you first produce a program design and then code the program from this design.

    What os/compiler are you using and what's your level of expertise with c++?
    Last edited by 2kaud; April 11th, 2014 at 06:12 AM.
    All advice is offered in good faith only. You are ultimately responsible for effects of your programs and the integrity of the machines they run on.

  3. #18
    Join Date
    Apr 2014
    Posts
    24

    Re: Ising Model C++ Metropolis Algorithm

    Quote Originally Posted by D_Drmmr View Post
    That's horrible. Why would you advice someone to use a macro for this? A simple text-replace can solve this without obfuscating the code.

    @OP Using two different names for the same variable will make your code harder to understand. When you read your code, every time you see 'spin' you need to think "right, that actually just means matrix". If you just use a single name, you'll save yourself a lot of unnecessary thinking, freeing up your brain capacity to understand the code you're writing/debugging/reading/whatever. If spin better describes the values in the matrix, then go ahead and rename your matrix variable to spin (it's a simple search-and-replace). But don't use different names for the same thing unless you want to make your code harder to understand.
    I think it's more meaningful to use spin(x ,y) instead of matrix (x,y). This shouldn't screw up the code, right?

  4. #19
    Join Date
    Apr 2014
    Posts
    24

    Re: Ising Model C++ Metropolis Algorithm

    Quote Originally Posted by 2kaud View Post
    Code:
    int x = int (rand()*LatSize);
    int y = int (rand()*LatSize);
    What's with the '*' ? It should be % (modulo) as per my post #2!

    Code:
    int x = int (rand()%LatSize);
    int y = int (rand()%LatSize);
    Also, you don't need #include <stdlib.h> as you have #include <cstdlib>.

    As D_Drmmr said in his post #15, you need to use the debugger to find out why things don't work as expected.
    Before coding a program, it should first be designed (stating in English or other natural language how the program is going to work
    Code:
    define input requirements
    define output requirements
    define required algorithms
    do {
         design program
         code program
         test program
         debug program
    } while program_not_correct
    Before you continue writing 'ad hoc' code I suggest that you first produce a program design and then code the program from this design.

    What os/compiler are you using and what's your level of expertise with c++?
    I'm using an online compiler: http://www.compileonline.com/compile_cpp_online.php

    Code:
    //Generate NxN lattice with -1 or +1 at each site randomly.
    
    #include <stdlib.h>
    #include <stdio.h>
    #include <iostream>
    #include <cstdlib>
    #include <ctime>
    using namespace std;
    
    #define spin(a, b) (matrix[(a)][(b)])
    
    int main()
    {
    
    const int LatSize = 5;
    const int L = LatSize * LatSize;
    int matrix[LatSize][LatSize];
    
    
    srand ( static_cast<unsigned> ( time ( 0 ) ) );
    for ( int i = 0; i < LatSize; i++ ) 
    {
    for ( int j = 0; j < LatSize; j++ )
    {
    matrix[i][j] = rand () % 2 *2-1;
    }
    }
    
    //End of Generating matrix
    
     // Displaying the matrix on the screen
        for(int i=0;i<LatSize;i++)  // loop 3 times for three lines
        {
            for(int j=0;j<LatSize;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
        }
     
     //End of Displaying Matrix
     
    
     //Boundary conditions
    
    int x = int (rand() %LatSize); 
    int y = int (rand() %LatSize);
    if(x<0) x += LatSize;      
    if(x>=LatSize) x -= LatSize;
    if(y<0) y += LatSize;
    if(y>=LatSize) y -= LatSize;
    
    //End of Boundary Conditions
     
     //Extracting value of a site at location (x,y)
    
    printf ("The site chosen is at (x,y) = %x, %y", x, y);
    cout << spin(x, y);
    cout<<endl;
    
    
    int delta_M = -2*spin(x, y); //change in magnetization energy
    
    int delta_neighbour = spin(x-1, y) + spin(x+1, y)+ spin(x, y-1) + spin(x, y+1); 
    delta_neighbour = -2*spin(x,y)* delta_neighbour; //change in neighbour product energy
    
    cout << delta_neighbour;
    
    //End of extracting value of site at (x, y)
    
    return 0;
    }

  5. #20
    Join Date
    Dec 2012
    Location
    England
    Posts
    2,389

    Re: Ising Model C++ Metropolis Algorithm

    Code:
    if(x<0) x += LatSize;      
    if(x>=LatSize) x -= LatSize;
    if(y<0) y += LatSize;
    if(y>=LatSize) y -= LatSize;
    these statements are not needed as x and y will always satisfy the condition >= 0 and < LatSize due to how these values are generated.

    As you are using c++ and cout, why use printf instead of cout? The formating used is incorrect anyhow. Use
    Code:
    cout << "The site chosen is at (" << x << ", " << y << ") = " << spin(x, y) << endl;
    Code:
    int delta_neighbour = spin(x-1, y) + spin(x+1, y)+ spin(x, y-1) + spin(x, y+1);
    Note that this statement would cause the bounds of matrix to be exceeded if x or y is either 0 or LatSize -1. If x or y is either of these values, what element of matrix do you want to be used?
    All advice is offered in good faith only. You are ultimately responsible for effects of your programs and the integrity of the machines they run on.

  6. #21
    Join Date
    Apr 2014
    Posts
    24

    Re: Ising Model C++ Metropolis Algorithm

    Quote Originally Posted by 2kaud View Post
    Code:
    if(x<0) x += LatSize;      
    if(x>=LatSize) x -= LatSize;
    if(y<0) y += LatSize;
    if(y>=LatSize) y -= LatSize;
    these statements are not needed as x and y will always satisfy the condition >= 0 and < LatSize due to how these values are generated.

    As you are using c++ and cout, why use printf instead of cout? The formating used is incorrect anyhow. Use
    Code:
    cout << "The site chosen is at (" << x << ", " << y << ") = " << spin(x, y) << endl;

    Code:
    int delta_neighbour = spin(x-1, y) + spin(x+1, y)+ spin(x, y-1) + spin(x, y+1);
    Note that this statement would cause the bounds of matrix to be exceeded if x or y is either 0 or LatSize -1. If x or y is either of these values, what element of matrix do you want to be used?
    I'm implying boundary conditions on this part:

    Code:
    int delta_neighbour = spin(x-1, y) + spin(x+1, y)+ spin(x, y-1) + spin(x, y+1);
    by using:

    Code:
    if(x<0) x += LatSize;      
    if(x>=LatSize) x -= LatSize;
    if(y<0) y += LatSize;
    if(y>=LatSize) y -= LatSize;
    So if you choose a site that's along the sides, it ensures continuity. For example, if Site (0,0) top most left is chosen, the right neighbour would be (0,1), the left neighbour would be (0,4), the top neighbour would be (4,0), the bottom neighbour would be (1,0).

    However, when I run the code, it doesn't work, and sometimes it shows absurd values like the left neighbour having value of 25!

    Code:
    //Generate NxN lattice with -1 or +1 at each site randomly.
    
    #include <stdlib.h>
    #include <stdio.h>
    #include <iostream>
    #include <cstdlib>
    #include <ctime>
    using namespace std;
    
    #define spin(a, b) (matrix[(a)][(b)])
    
    int main()
    {
    
    const int LatSize = 5;
    const int L = LatSize * LatSize;
    int matrix[LatSize][LatSize];
    
    
    srand ( static_cast<unsigned> ( time ( 0 ) ) );
    for ( int i = 0; i < LatSize; i++ ) 
    {
    for ( int j = 0; j < LatSize; j++ )
    {
    matrix[i][j] = rand () % 2 *2-1;
    }
    }
    
    //End of Generating matrix
    
     // Displaying the matrix on the screen
        for(int i=0;i<LatSize;i++)  // loop 3 times for three lines
        {
            for(int j=0;j<LatSize;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
        }
     
     //End of Displaying Matrix
     
    
     //Boundary conditions
    
    int x = int (rand() %LatSize); 
    int y = int (rand() %LatSize);
    if(x<0) {x += LatSize;}   
    if(x>=LatSize) {x -= LatSize;}
    if(y<0) {y += LatSize;}
    if(y>=LatSize) {y -= LatSize;}
    
    
    //End of Boundary Conditions
     
     //Extracting value of a site at location (x,y)
    
    int delta_M = -2*matrix[x][y]; //change in magnetization energy
    
    int delta_neighbour = matrix[x-1][y] + matrix[x+1][y]+ matrix[x][y-1] + matrix[x][y+1]; 
    delta_neighbour = -2*matrix[x][y]* delta_neighbour; //change in neighbour product energy
    
    printf ("The site chosen is at (x,y) = (%d, %d)", x, y);
    cout<<endl;
    printf ("The spin at this site is:"); cout << matrix[x][y];
    cout<<endl;
    printf ("The left neighbour has spin :"); cout<< matrix[x][y-1];
    cout<<endl;
    printf ("The right neighbour has spin:"); cout<<matrix[x][y+1];
    cout<<endl;
    printf ("The above neighbour has spin:"); cout<<matrix[x-1][y];
    cout<<endl;
    printf ("The below neighbour has spin:"); cout<<matrix[x+1][y-1];
    cout<<endl;
    printf ("The change in neighbour energy is:"); cout << delta_neighbour;
    
    //End of extracting value of site at (x, y)
    
    return 0;
    }

  7. #22
    Join Date
    Apr 2014
    Posts
    24

    Re: Ising Model C++ Metropolis Algorithm

    Here's my latest code, updated with improved cout, and with printf gone! Everything works fine except the boundary conditions..

    Code:
    //Generate NxN lattice with -1 or +1 at each site randomly.
    
    #include <stdlib.h>
    #include <stdio.h>
    #include <iostream>
    #include <cstdlib>
    #include <ctime>
    using namespace std;
    #define spin(a, b) (matrix[(a)][(b)])
    
    
    int main()
    {
    
    
    const int LatSize = 5;
    const int L = LatSize * LatSize;
    int matrix[LatSize][LatSize];
    
    
    srand ( static_cast<unsigned> ( time ( 0 ) ) );
    for ( int i = 0; i < LatSize; i++ ) 
    {
    for ( int j = 0; j < LatSize; j++ )
    {
    matrix[i][j] = rand () % 2 *2-1;
    }
    }
    
    //End of Generating matrix
    
     // Displaying the matrix on the screen
        for(int i=0;i<LatSize;i++)  // loop 3 times for three lines
        {
            for(int j=0;j<LatSize;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
        }
     
     //End of Displaying Matrix
     
    
     //Boundary conditions
    
    int x = int (rand() %LatSize); 
    int y = int (rand() %LatSize);
    if(x<0) {x += LatSize;}   
    if(x>=LatSize) {x -= LatSize;}
    if(y<0) {y += LatSize;}
    if(y>=LatSize) {y -= LatSize;}
    
    
    //End of Boundary Conditions
     
     //Extracting value of a site at location (x,y)
    
    int delta_M = -2 * spin(x,y); //change in magnetization energy
    
    int delta_neighbour = spin(x-1, y) + spin(x+1, y)+ spin(x, y-1) + spin(x, y+1); 
    delta_neighbour = -2*spin(x, y)* delta_neighbour; //change in neighbour product energy
    
    cout << "The site chosen is at (" << x << ", " << y << ") = " << spin(x, y) << endl;
    cout << "The left neighbour has spin = " << spin(x, y-1) << endl;
    cout << "The right neighbour has spin = " << spin(x, y+1) << endl;
    cout << "The above neighbour has spin = " << spin(x-1, y) << endl;
    cout << "The below neighbour has spin = " << spin(x+1, y) << endl;
    cout << "The change in neighbour energy = " << delta_neighbour << endl;
    
    //End of extracting value of site at (x, y)
    
    return 0;
    }

  8. #23
    Join Date
    Dec 2012
    Location
    England
    Posts
    2,389

    Re: Ising Model C++ Metropolis Algorithm

    I'm implying boundary conditions on this part:

    Code:

    int delta_neighbour = spin(x-1, y) + spin(x+1, y)+ spin(x, y-1) + spin(x, y+1);

    by using:

    Code:

    if(x<0) x += LatSize;
    if(x>=LatSize) x -= LatSize;
    if(y<0) y += LatSize;
    if(y>=LatSize) y -= LatSize;

    So if you choose a site that's along the sides, it ensures continuity. For example, if Site (0,0) top most left is chosen, the right neighbour would be (0,1), the left neighbour would be (0,4), the top neighbour would be (4,0), the bottom neighbour would be (1,0).

    However, when I run the code, it doesn't work, and sometimes it shows absurd values like the left neighbour having value of 25!
    No. There is no implied boundary conditions in your code. That is why you are getting absurd values. The boundary conditions need to be part of spin() - so spin() needs to be function instead of just a define.

    I've re-worked your code to base it upon a class.

    Code:
    #include <iostream>
    #include <iomanip>
    #include <cstdlib>
    #include <ctime>
    using namespace std;
    
    const int LatSize = 5;
    
    class cSpin
    {
    public:
    	int operator()(int x, int y)
    	{
    		if (x < 0)
    			x += LatSize;
    
    		if (x >= LatSize) 
    			x -= LatSize;
    
    		if (y < 0) 
    			y += LatSize;
    
    		if (y >= LatSize)
    			y -= LatSize;
    
    		return matrix[x][y];
    	}
    
    	void generate()
    	{
    		for (int i = 0; i < LatSize; i++) 
    			for (int j = 0; j < LatSize; j++)
    				matrix[i][j] = (rand() % 2) * 2 - 1;
    	}
    
    
    	void display()
    	{
    	    for (int i = 0; i < LatSize; i++)  // loop 3 times for three lines
    	    {
    		for (int j = 0; j < LatSize; j++)  // loop for the three elements on the line
    			cout << setw(2) << matrix[i][j] << " ";  // display the current element out of the array
    
    		cout << endl;  // when the inner loop is done, go to a new line
    	    }
            }
    
    private:
    	int matrix[LatSize][LatSize];
    };
    
    int main()
    {
    cSpin	spin;
    
    	srand (static_cast<unsigned> (time(0)));
    
    	spin.generate();
    	spin.display();
    
    int x = int (rand() % LatSize); 
    int y = int (rand() % LatSize);
    
    int delta_M = -2 * spin(x, y); //change in magnetization energy
    
    int delta_neighbour = delta_M * (spin(x - 1, y) + spin(x + 1, y) + spin(x, y - 1) + spin(x, y + 1)); 
    
    	cout << "The site chosen is at (" << x << ", " << y << ") = " << spin(x, y) << endl;
    	cout << "The left neighbour has spin = " << spin(x, y - 1) << endl;
    	cout << "The right neighbour has spin = " << spin(x, y + 1) << endl;
    	cout << "The above neighbour has spin = " << spin(x - 1, y) << endl;
    	cout << "The below neighbour has spin = " << spin(x + 1, y) << endl;
    	cout << "The change in neighbour energy = " << delta_neighbour << endl;
    
    	return 0;
    }
    Last edited by 2kaud; April 11th, 2014 at 12:19 PM.
    All advice is offered in good faith only. You are ultimately responsible for effects of your programs and the integrity of the machines they run on.

  9. #24
    Join Date
    Apr 2014
    Posts
    24

    Re: Ising Model C++ Metropolis Algorithm

    Quote Originally Posted by 2kaud View Post
    No. There is no implied boundary conditions in your code. That is why you are getting absurd values. The boundary conditions need to be part of spin() - so spin() needs to be function instead of just a define.

    I've re-worked your code to base it upon a class.

    Code:
    #include <iostream>
    #include <iomanip>
    #include <cstdlib>
    #include <ctime>
    using namespace std;
    
    const int LatSize = 5;
    
    class cSpin
    {
    public:
    	int operator()(int x, int y)
    	{
    		if (x < 0)
    			x += LatSize;
    
    		if (x >= LatSize) 
    			x -= LatSize;
    
    		if (y < 0) 
    			y += LatSize;
    
    		if (y >= LatSize)
    			y -= LatSize;
    
    		return matrix[x][y];
    	}
    
    	void generate()
    	{
    		for (int i = 0; i < LatSize; i++) 
    			for (int j = 0; j < LatSize; j++)
    				matrix[i][j] = (rand() % 2) * 2 - 1;
    	}
    
    
    	void display()
    	{
    	    for (int i = 0; i < LatSize; i++)  // loop 3 times for three lines
    	    {
    		for (int j = 0; j < LatSize; j++)  // loop for the three elements on the line
    			cout << setw(2) << matrix[i][j] << " ";  // display the current element out of the array
    
    		cout << endl;  // when the inner loop is done, go to a new line
    	    }
            }
    
    private:
    	int matrix[LatSize][LatSize];
    };
    
    int main()
    {
    cSpin	spin;
    
    	srand (static_cast<unsigned> (time(0)));
    
    	spin.generate();
    	spin.display();
    
    int x = int (rand() % LatSize); 
    int y = int (rand() % LatSize);
    
    int delta_M = -2 * spin(x, y); //change in magnetization energy
    
    int delta_neighbour = delta_M * (spin(x - 1, y) + spin(x + 1, y) + spin(x, y - 1) + spin(x, y + 1)); 
    
    	cout << "The site chosen is at (" << x << ", " << y << ") = " << spin(x, y) << endl;
    	cout << "The left neighbour has spin = " << spin(x, y - 1) << endl;
    	cout << "The right neighbour has spin = " << spin(x, y + 1) << endl;
    	cout << "The above neighbour has spin = " << spin(x - 1, y) << endl;
    	cout << "The below neighbour has spin = " << spin(x + 1, y) << endl;
    	cout << "The change in neighbour energy = " << delta_neighbour << endl;
    
    	return 0;
    }
    It works, although this level of coding is too high for me. Let's see if I can work out some form of understanding:

    1. Starting with an entire class called 'cSpin' allows us to do interesting things within the class and later the statement 'cSpin spin' makes the function 'spin' possess all the conditions, follow any iteration, tasks that are defined within that class. And those tasks may or may not be called out to perform in future.

    2. sections within the class like 'void generate()' and 'void display()' are some of the tasks the computer might be doing. I'm guessing in the statement 'void generate()', generate is the 'callsign' for that set of tasks and void means you can define a function later on that uses the callsign to do those tasks.

    3. Not sure what the difference between public and private is. It seems like public is where you chuck in all the things (iteration, tasks, conditions) you want the class to possess. As for private, I'm not sure what it is used for.

    4. It seems the class is defined before the main program 'int main()'. I'm guessing you need to sort out the details before you execute the main program?

    4. spin.generate() and spin.display() uses the callsigns 'generate' and 'display' to tell the function 'spin' to do all those tasks.

    Is my understanding right?

    Questions that bug me
    1. What does the statement 'int operator()(int x, int y)' mean?
    2. What's the difference between private and public within a class?
    Last edited by unscientific; April 11th, 2014 at 12:44 PM.

  10. #25
    Join Date
    Dec 2012
    Location
    England
    Posts
    2,389

    Re: Ising Model C++ Metropolis Algorithm

    If you haven't met c++ classes before, you need a crash course in them.
    See
    http://www.learncpp.com/cpp-tutorial...class-members/
    http://www.cplusplus.com/doc/tutorial/classes/
    http://www.tutorialspoint.com/cplusp...es_objects.htm

    What book/resource are you currently using from which to learn c++?

    Very simply,
    1) cSpin is the class (ie type) and the variable spin is an instance of this class.

    2) generate and display are class functions (methods). They take the same format as 'normal' functions. So void generate() is a function of class cSpin that has a return type of void - ie doesn't return a value.

    3) private definitions can only be accessed within the class. Public ones can be accessed outside of the class. If you try to access spin.matrix[x][y] in main() you'll get a compilation error as matrix is defined private so can't be accessed outside of the cSpin class.

    4) classes (like functions, struct etc) need to be defined/declared before they are used. With more complex classes it it usual for the class to be declared in a header file which is included in the main program and for the class functions to be defined in a seperate compilation unit.

    5) spin.generate() and spin.display() call the class cSpin functions generate() and display() for the class instance variable spin.


    Questions
    1) int operator()(int x, int y) overloads the () operator for the class cSpin so that variables of the class can be used as if they are functions. So a = spin(1, 2) calls the operator() function for the spin instance of the cSpin class and returns a value of type int.

    2) see 3) above.

    I hope this of help. You really need to learn about classes and the Standard Template Library if you are using c++.
    Last edited by 2kaud; April 11th, 2014 at 02:05 PM.
    All advice is offered in good faith only. You are ultimately responsible for effects of your programs and the integrity of the machines they run on.

  11. #26
    Join Date
    Apr 2014
    Posts
    24

    Re: Ising Model C++ Metropolis Algorithm

    Quote Originally Posted by 2kaud View Post
    If you haven't met c++ classes before, you need a crash course in them.
    See
    http://www.learncpp.com/cpp-tutorial...class-members/
    http://www.cplusplus.com/doc/tutorial/classes/
    http://www.tutorialspoint.com/cplusp...es_objects.htm

    What book/resource are you currently using from which to learn c++?

    Very simply,
    1) cSpin is the class (ie type) and the variable spin is an instance of this class.

    2) generate and display are class functions (methods). They take the same format as 'normal' functions. So void generate() is a function of class cSpin that has a return type of void - ie doesn't return a value.

    3) private definitions can only be accessed within the class. Public ones can be accessed outside of the class. If you try to access spin.matrix[x][y] in main() you'll get a compilation error as matrix is defined private so can't be accessed outside of the cSpin class.

    4) classes (like functions, struct etc) need to be defined/declared before they are used. With more complex classes it it usual for the class to be declared in a header file which is included in the main program and for the class functions to be defined in a seperate compilation unit.

    5) spin.generate() and spin.display() call the class cSpin functions generate() and display() for the class instance variable spin.


    Questions
    1) int operator()(int x, int y) overloads the () operator for the class cSpin so that variables of the class can be used as if they are functions. So a = spin(1, 2) calls the operator() function for the spin instance of the cSpin class and returns a value of type int.

    2) see 3) above.

    I hope this of help. You really need to learn about classes and the Standard Template Library if you are using c++.
    Ok, here comes the interesting part. Of each spin (x,y) randomly chosen, we need to decide whether to flip it or not.
    If delta_E < 0, flip. If delta_E > 0, flip with acceptance probability w = exp(-delta_E).

    I think the code would be something like:
    Code:
    if (delta_E<=0)
    	{  spin(x, y) *= -1;     // flip spin
               M += delta_M;        // New Magnetization energy of flipped configuration
               E += delta_E;         // New total energy of flipped configuration
               int flip_counter++;      // Total number of sites chosen up till this point
               int sweep_counter = flip_counter/(LatSize*LatSize)   //Total number of sweeps till this point
    
               return 1;
            }
    
    if (delta_E>0)
    {
    if flipped, M and E is updated. If not flipped, M and E is unchanged.
    }
    Points of concern:
    1. How to ensure the same site is never picked twice in a sweep? And how do we tell when one sweep is done? For example in a 5x5 lattice, 25 different picks = 1 sweep.

  12. #27
    Join Date
    Oct 2008
    Posts
    1,135

    Re: Ising Model C++ Metropolis Algorithm

    Quote Originally Posted by unscientific View Post
    How to ensure the same site is never picked twice in a sweep?
    you can't ( you can't choose spins randomly and indipendently *and* at the same time enforce non repetitions as this will define a dependency between spins ) why do you have such a requirement ? it's fine ( and physically sensible too ) to have repetitions as long as you realize the relationship between the simulation time and the iterations count ...

  13. #28
    Join Date
    Dec 2012
    Location
    England
    Posts
    2,389

    Re: Ising Model C++ Metropolis Algorithm

    Code:
    spin(x, y) *= -1;     // flip spin
    As the class is currently coded, you can't do this as operator() returns a value not a reference. You need to change operator() to
    Code:
    	int& operator()(int x, int y)
    	{
    		if (x < 0)
    			x += LatSize;
    
    		if (x >= LatSize) 
    			x -= LatSize;
    
    		if (y < 0) 
    			y += LatSize;
    
    		if (y >= LatSize)
    			y -= LatSize;
    
    		return matrix[y][x];
    	}
    From your first program
    Code:
    double delta_E = -J*delta_neighbour -B*delta_M;
    what are J and B? What are M and E?

    Code:
    int flip_counter++;      // Total number of sites chosen up till this point
    int sweep_counter = flip_counter/(LatSize*LatSize)   //Total number of sweeps till this point
    No! flip_counter and sweep_counter are defined inside the block so their scope is only for the duration of the block. You can't post increment a variable that hasn't been initialised. This is basic c++ stuff. Before you go much further I would recommend that you get a good book on c++ and produce a design for your program.

    Why? What os are you using?
    Last edited by 2kaud; April 12th, 2014 at 04:43 AM.
    All advice is offered in good faith only. You are ultimately responsible for effects of your programs and the integrity of the machines they run on.

  14. #29
    Join Date
    Apr 2014
    Posts
    24

    Re: Ising Model C++ Metropolis Algorithm

    Quote Originally Posted by 2kaud View Post
    Code:
    spin(x, y) *= -1;     // flip spin
    As the class is currently coded, you can't do this as operator() returns a value not a reference. You need to change operator() to
    Code:
    	int& operator()(int x, int y)
    	{
    		if (x < 0)
    			x += LatSize;
    
    		if (x >= LatSize) 
    			x -= LatSize;
    
    		if (y < 0) 
    			y += LatSize;
    
    		if (y >= LatSize)
    			y -= LatSize;
    
    		return matrix[y][x];
    	}
    By changing the operator to 'int & operator()(int x, int y)' would this fix it?


    Quote Originally Posted by 2kaud View Post
    From your first program
    Code:
    double delta_E = -J*delta_neighbour -B*delta_M;
    what are J and B? What are M and E?
    J is a constant defined to be 1. M is a sum of all spins, so it starts from 0. I will define 'int M=0' before the public class section and as the NxN lattice is generated randomly I would insert in a line M+= matrix[i][j] here:

    Code:
    int M=0;
    void generate()
    	{
    		for (int i = 0; i < LatSize; i++) 
    			for (int j = 0; j < LatSize; j++)
    				matrix[i][j] = (rand() % 2) * 2 - 1;
    	                        for (i < LatSize) {M+= matrix[i][j];}
    }

    Quote Originally Posted by 2kaud View Post
    Code:
    int flip_counter++;      // Total number of sites chosen up till this point
    int sweep_counter = flip_counter/(LatSize*LatSize)   //Total number of sweeps till this point
    No! flip_counter and sweep_counter are defined inside the block so their scope is only for the duration of the block. You can't post increment a variable that hasn't been initialised. This is basic c++ stuff. Before you go much further I would recommend that you get a good book on c++ and produce a design for your program.



    Why? What os are you using?
    Does 'int flip_counter' and 'int sweep_counter' go into the public class then?
    At school I usually do this at the computer labs, where they use Mac OS X. But now I'm using windows 7.
    Last edited by unscientific; April 12th, 2014 at 09:55 AM.

  15. #30
    Join Date
    Dec 2012
    Location
    England
    Posts
    2,389

    Re: Ising Model C++ Metropolis Algorithm

    If you are using Windows 7 why don't you use the free Microsoft Visual Studio Express 2013?
    See http://www.visualstudio.com/download...sual-studio-vs
    You want Visual Studio Express 2013 for Windows Desktop.

    As I suggested in my post #17, before you continue with 'ad hoc coding' of the program, I recommend that you take a step back and design the program before you try to code it.
    Code:
    for (i < LatSize) {M+= matrix[i][j];}
    This is not valid c++ code. You also can't initialise a variable when it is defined within a class definiton (unless it is static of an integral type). If you want M to be the sum of the matrix values then you could code it as below. From your original code, B should also defined as 1?

    Based upon what I understand from your postings, this is a possible program so far
    Code:
    #include <iostream>
    #include <iomanip>
    #include <cstdlib>
    #include <ctime>
    using namespace std;
    
    const int LatSize = 5;
    
    class cSpin
    {
    public:
    	cSpin() : M(0)
    	{
    		for (int i = 0; i < LatSize; i++) 
    			for (int j = 0; j < LatSize; j++)
    				M += matrix[i][j] = (rand() % 2) * 2 - 1;
    	}
    
    	int& operator()(int x, int y)
    	{
    		if (x < 0)
    			x += LatSize;
    
    		if (x >= LatSize) 
    			x -= LatSize;
    
    		if (y < 0) 
    			y += LatSize;
    
    		if (y >= LatSize)
    			y -= LatSize;
    
    		return matrix[y][x];
    	}
    
    	void display()
    	{
    		for (int i = 0; i < LatSize; i++)  // loop 3 times for three lines
    		{
    			for (int j = 0; j < LatSize; j++)  // loop for the three elements on the line
    				cout << setw(2) << matrix[i][j] << " ";  // display the current element out of the array
    
    			cout << endl;  // when the inner loop is done, go to a new line
    		}
    	}
    
    	int SpinSum()
    	{
    		return M;
    	}
    
    private:
    	int matrix[LatSize][LatSize];
    	int M;
    };
    
    int main()
    {
    const int J = 1;
    const int B = 1;
    
    cSpin	spin;
    
    	srand (static_cast<unsigned> (time(0)));
    
    	spin.display();
    
    int M = spin.SpinSum();
    
    int x = int (rand() % LatSize); 
    int y = int (rand() % LatSize);
    
    int neighbour = 0;    // nearest neighbour count
    int flip_counter = 0;
    double sweep_counter = 0.0;
    
    	for (int i = 0; i < LatSize; i++)
    		for (int j = 0; j < LatSize; j++)
    		{
    			neighbour += (spin(i, j) == spin(i + 1, j)) ? 1 : -1;
    			neighbour += (spin(i, j) == spin(i, j + 1)) ? 1 : -1;
                    }
    
    int E = -J * neighbour - B * M;
    
    int delta_M = -2 * spin(x, y);	//change in magnetization energy
    
    int delta_neighbour = delta_M * (spin(x - 1, y) + spin(x + 1, y) + spin(x, y - 1) + spin(x, y + 1)); 
    
    int delta_E = -J * delta_neighbour - B * delta_M;
    
    	if (delta_E <= 0)
    	{
    		spin(x, y) *= -1;											// flip spin
    		M += delta_M;												// New Magnetization energy of flipped configuration
    		E += delta_E;												// New total energy of flipped configuration
    		flip_counter++;												// Total number of sites chosen up till this point
    		sweep_counter = (double)flip_counter / (LatSize * LatSize);	//Total number of sweeps till this point
    	}
    	else
    	{
    		//if flipped, M and E is updated. If not flipped, M and E is unchanged.
    	}
    
    	cout << "The site chosen is at (" << x << ", " << y << ") = " << spin(x, y) << endl;
    	cout << "The left neighbour has spin = " << spin(x, y - 1) << endl;
    	cout << "The right neighbour has spin = " << spin(x, y + 1) << endl;
    	cout << "The above neighbour has spin = " << spin(x - 1, y) << endl;
    	cout << "The below neighbour has spin = " << spin(x + 1, y) << endl;
    	cout << "The change in neighbour energy = " << delta_neighbour << endl;
    
    	return 0;
    }
    I hope this helps. But you really need to do some design work for the program before you continue coding. Also I would suggest that you become more familar with the c++ language. What book(s) are you using from which to learn c++?
    All advice is offered in good faith only. You are ultimately responsible for effects of your programs and the integrity of the machines they run on.

Page 2 of 4 FirstFirst 1234 LastLast

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  


Windows Mobile Development Center


Click Here to Expand Forum to Full Width

This is a CodeGuru survey question.


Featured


HTML5 Development Center