├── LICENSE ├── README.md ├── README中文版.md ├── deltaenergy.m ├── down.m ├── generategrid.m ├── ising.m ├── ising_.m ├── left.m ├── metropolisrule.m ├── randompick.m ├── right.m ├── totalenergy.m ├── totalmagnetization.m ├── unitenergy.m └── up.m /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Bill 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 2D-Ising-Model-Matlab 2 | 3 | ## Description 4 | 5 | Simulating 2D Ising model with Monte Carlo Method in Matlab. 6 | 7 | -Bill in Chengdu 8 | 9 | ## Tutorial 10 | 11 | The program is used to simulate 2D Ising model with the primary application of Matlab. I choose the simple method of Single-spin-flip dymanics to deal with this task. 12 | 13 | Before running the program, you should add all the files into Matlab path. You'd better run the program in ising.m unless you want to improve my code. 14 | 15 | You can change temperature range and repeat times in ising.m and adjust paramaters in ising_.m simply by changing the default values. 16 | 17 | Enjoy your time with Ising and Matlab! Suggestions and adjustments (as well as STARs) are welcomed. 18 | 19 | GOOD NEWS! A detailed introduction of Simulating 2D Ising Model has been uploaded on ZHIHU. It is a Chinese version, [click here](https://zhuanlan.zhihu.com/p/42629484) to view. 20 | 21 | Created 25/8/2018 by Bill in Chengdu 22 | -------------------------------------------------------------------------------- /README中文版.md: -------------------------------------------------------------------------------- 1 | # 二维伊辛模型-Matlab 2 | 3 | ## 简介 4 | 5 | 本程序在Matlab中利用蒙特卡洛方法模拟二维伊辛模型。 6 | 7 | ## 使用说明 8 | 9 | 本程序利用最基础的Matlab操作来模拟二维伊辛模型。对此我选取了一种相对简单的思路:单分子翻转法。 10 | 11 | 在运行本程序之前,你应该将所有文件添加到Matlab的路径下。除非是你想帮我改进代码,你最好在ising.m这个文件里运行本程序。 12 | 13 | 你可以在ising.m中改变温度范围和重复次数,并可以在ising_.m中设置参数。对此你所需要做的仅仅只是调整一下默认参数就行了。 14 | 15 | 享受伊辛和Matlab给你带来的快乐吧!欢迎建议和指正(以及STAR)。 16 | 17 | 好消息!我将一个关于模拟伊辛模型的详细介绍上传到了知乎,[猛戳这里](https://zhuanlan.zhihu.com/p/42629484)以查看。 18 | 19 | Bill于8/9/2018创建于北京 20 | -------------------------------------------------------------------------------- /deltaenergy.m: -------------------------------------------------------------------------------- 1 | % The function is used to calculate the energy change if grid(i , j) is flipped. 2 | function out = deltaenergy(i , j , J , H , grid) 3 | out1 = 4 * J * grid(i,j) * (left(i,j,grid) + right(i,j,grid) + up(i,j,grid) + down(i,j,grid)); 4 | out2 = 2 * H * grid(i,j); 5 | out = out1 + out2; 6 | end -------------------------------------------------------------------------------- /down.m: -------------------------------------------------------------------------------- 1 | % The function gives the down-side neighbor of grid(i , j) 2 | function out = down(i , j , grid) 3 | if i < 1 || i > size(grid , 1) || j < 1 || j > size(grid , 2) 4 | out = 'incorrect inputs'; 5 | else 6 | if i == size(grid , 1) 7 | out = grid(1 , j); 8 | else 9 | out = grid(i + 1 , j); 10 | end 11 | end 12 | end -------------------------------------------------------------------------------- /generategrid.m: -------------------------------------------------------------------------------- 1 | % The function is used to generate a size-by-size grid. 2 | % If tis0 == 1, gird will be generated orderly otherwise randomly. 3 | function grid = generategrid(size , tis0) 4 | if tis0 5 | grid = ones(size); 6 | else 7 | grid = rand(size); 8 | grid = grid > 0.5; 9 | grid = 2 * grid - ones(size); 10 | end 11 | end 12 | 13 | -------------------------------------------------------------------------------- /ising.m: -------------------------------------------------------------------------------- 1 | % b records all energy data. 2 | % mb records all magnetization data. 3 | % a records average energy data. 4 | % ma records average magnetization data. 5 | % c and mc record temporary data. 6 | a = []; 7 | b = []; 8 | c = []; 9 | ma = []; 10 | mb = []; 11 | mc = []; 12 | 13 | % The program will repeat 10 times before changing the temporature. 14 | times = 10; 15 | 16 | for w = 1 : 30 17 | % The program will sweep the temperature from 1 to 10. 18 | T = 1 + (0.3 * w); 19 | 20 | for u = 1 : times 21 | % The program will run for a long time. You can estimate the remaining time by counting T and u. 22 | % The program ends when [T , u] reaches [10 , 10]. 23 | [T , u] 24 | ising_; 25 | b(times * (w-1) + u , 1) = T; 26 | b(times * (w-1) + u , 2) = et; 27 | mb(times * (w-1) + u , 1) = T; 28 | mb(times * (w-1) + u , 2) = mt; 29 | 30 | c(u) = et; 31 | mc(u) = mt; 32 | end 33 | a(w , 1) = T; 34 | a(w , 2) = sum(c) / times; 35 | ma(w , 1) = T; 36 | ma(w , 2) = sum(mc) / times; 37 | end 38 | 39 | % Plot data. 40 | % Plot left figure: energy-temperature 41 | subplot(1 , 2 , 1); 42 | plot(a(: , 1) , a(: , 2)); 43 | hold on 44 | % Plot right figure: magnetization-temperature 45 | subplot(1 , 2 , 2); 46 | plot(ma(: , 1) , ma(: , 2)); 47 | 48 | % Output data as .txt files. 49 | %dlmwrite('a.txt' , a , '\t'); 50 | %dlmwrite('b.txt' , b , '\t'); 51 | %dlmwrite('ma.txt' , ma , '\t'); 52 | %dlmwrite('mb.txt' , mb , '\t'); 53 | -------------------------------------------------------------------------------- /ising_.m: -------------------------------------------------------------------------------- 1 | % Initialize all parameters 2 | size = 8; 3 | J = 1; 4 | H = 0; 5 | steps = 100; 6 | ist0 = 0; 7 | 8 | g = generategrid(size , ist0); 9 | e = totalenergy(J , H , g); 10 | m = totalmagnetization(g); 11 | 12 | % The average energy/magnetization of spins. 13 | energy = [e / size^2]; 14 | magnetization = [m / size^2]; 15 | 16 | for i = 1 : steps * size^2 17 | x = randompick(g); 18 | isflip = metropolisrule(x(1) , x(2) , J , H , T , g); 19 | if isflip 20 | e = e + deltaenergy(x(1) , x(2) , J , H , g); 21 | m = m - 2 * g(x(1) , x(2)); 22 | g(x(1) , x(2)) = -g(x(1) , x(2)); 23 | end 24 | energy(i + 1) = e / size^2; 25 | magnetization(i + 1) = m / size^2; 26 | end 27 | 28 | % The average energy/magnetization of the last one tenth steps. 29 | et = sum(energy(end - 0.1 * steps * size^2 + 1: end))/(0.1 * steps * size^2); 30 | mt = sum(magnetization(end - 0.1 * steps * size^2 + 1: end))/(0.1 * steps * size^2); -------------------------------------------------------------------------------- /left.m: -------------------------------------------------------------------------------- 1 | % The function gives the left-side neighbor of grid(i , j) 2 | function out = left(i , j , grid) 3 | if i < 1 || i > size(grid , 1) || j < 1 || j > size(grid , 2) 4 | out = 'incorrect inputs'; 5 | else 6 | if j == 1 7 | out = grid(i , end); 8 | else 9 | out = grid(i , j - 1); 10 | end 11 | end 12 | end 13 | 14 | -------------------------------------------------------------------------------- /metropolisrule.m: -------------------------------------------------------------------------------- 1 | % The function decides wether to accept the change by Metropolis-Acceptance-Ratio. 2 | function out = metropolisrule(i , j , J , H , T , grid) 3 | de = deltaenergy(i , j , J , H , grid); 4 | if de < 0 || rand(1) < exp(-de / T) 5 | out = 1; 6 | else 7 | out = 0; 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /randompick.m: -------------------------------------------------------------------------------- 1 | % The function gives a coordinate randomly. 2 | function out = randompick(grid) 3 | out(1) = ceil(size(grid , 1) * rand(1)); 4 | out(2) = ceil(size(grid , 2) * rand(1)); 5 | end -------------------------------------------------------------------------------- /right.m: -------------------------------------------------------------------------------- 1 | % The function gives the right-side neighbor of grid(i , j) 2 | function out = right(i , j , grid) 3 | if i < 1 || i > size(grid , 1) || j < 1 || j > size(grid , 2) 4 | out = 'incorrect inputs'; 5 | else 6 | if j == size(grid , 2) 7 | out = grid(i , 1); 8 | else 9 | out = grid(i , j + 1); 10 | end 11 | end 12 | end 13 | 14 | -------------------------------------------------------------------------------- /totalenergy.m: -------------------------------------------------------------------------------- 1 | % The function is used to calculate the total energy. 2 | function out = totalenergy(J , H , grid) 3 | out = 0 4 | for i = 1 : size(grid , 1) 5 | for j = 1 : size(grid , 2) 6 | out = out + unitenergy(i , j , J , H , grid); 7 | end 8 | end 9 | end 10 | 11 | -------------------------------------------------------------------------------- /totalmagnetization.m: -------------------------------------------------------------------------------- 1 | % The function is used to calculate the total magnetization. 2 | function out = totalmagnetization(grid) 3 | out = sum(sum(grid)); 4 | end 5 | -------------------------------------------------------------------------------- /unitenergy.m: -------------------------------------------------------------------------------- 1 | function out = unitenergy(i , j , J , H , grid) 2 | out1 = - J * grid(i,j) * (left(i,j,grid) + right(i,j,grid) + up(i,j,grid) + down(i,j,grid)); 3 | out2 = - H * grid(i,j); 4 | out = out1 + out2; 5 | end 6 | 7 | -------------------------------------------------------------------------------- /up.m: -------------------------------------------------------------------------------- 1 | % The function gives the up-side neighbor of grid(i , j) 2 | function out = up(i , j , grid) 3 | if i < 1 || i > size(grid , 1) || j < 1 || j > size(grid , 2) 4 | out = 'incorrect inputs'; 5 | else 6 | if i == 1 7 | out = grid(end , j); 8 | else 9 | out = grid(i - 1 , j); 10 | end 11 | end 12 | end 13 | 14 | --------------------------------------------------------------------------------