1

Based on a Wolfram Demonstration of the Ising ferromagnet using Monte-Carlo Metropolis, I modified it a bit to the anti-ferromagnet case and to get the plot of the order parameters as a function of the Temperature. The problem is that for sizes of the system larger that 10 spins and for more than 100000 Monete-Carlo iterations it takes really long times to evaluate (days). Some people have said to me that MATLAB may run much faster, but I haven't been able to find some concise package that makes the job to translate the FULL code to MATLAB. What is available is ToMatlab but it translates just simple expressions, like sin(x)*cos(x), not functions. There are many stack discussions of examples of translations MLB<->WM but they're very particular examples, all focused on expressions, not on functions. Also matlink.org is not very informative.

I put the code for reference, but it's not about the code.

    accept[m_, z_] := Module[{ech, x1, y1},
   {x1, y1} = RandomInteger[{2, Length[m] - 1}, 2];
   ech = m[[x1 - 1, y1]] + m[[x1 + 1, y1]] + m[[x1, y1 - 1]] + 
     m[[x1, y1 + 1]];
   If[RandomReal[] < Exp[-ech*z*2.*m[[x1, y1]]], 
    ReplacePart[m, {x1, y1} -> -m[[x1, y1]]], m]];
M[T_] := Module[{ic, TL, TLT},
   SeedRandom[1234];
   ic = ReplaceAll[ArrayPad[RandomInteger[{1, 2}, {nx, nx}], 1], 
     2 -> -1];
   TL = NestList[accept[#, -1/T] &, ic, nsteps];
   TLT = Accumulate[
      Abs@(Total /@ (Total /@ TL))]/(nx nx (Range[nsteps + 1]));
   N[Last[TLT]]];
s[T_] := Module[{ic, TL, TLT, TLTa},
   SeedRandom[1234];
   ic = ReplaceAll[ArrayPad[RandomInteger[{1, 2}, {nx, nx}], 1], 
     2 -> -1];
   TL = NestList[accept[#, -1/T] &, ic, nsteps];
   TLT = Accumulate[
      Abs@(Total /@ (Total /@ TL))]/(nx nx (Range[nsteps + 1]));
   TLTa = 
    Accumulate[
      Abs[Total /@ 
        Total[Table[Diagonal[#, 2 i], {i, -nx, nx}] & /@ 
          TL, {3}]]]/(nx nx (Range[nsteps + 1]));
   N[2 Last[TLTa] - Last[TLT]]];
nx = 10
nsteps = 10000
ListLinePlot[{Table[{T, s[T]}, {T, 0.1, 5, 1/20}], 
  Table[{T, M[T]}, {T, 0.1, 5, 1/20}], {{2.269, 0}, {2.269, 1}}}, 
 PlotRange -> All]
Daniel Castro
  • 631
  • 3
  • 11
  • 6
    "Also matlink.org is not very informative." That is not a fair description. matlink.org explains very clearly what MATLink is for: calling MATLAB from Mathematica, not for converting code. – Szabolcs Jan 10 '20 at 22:12
  • 10
    There is no way to automatically convert complex Mathematica code to MATLAB code. The languages are too different. Writing an Ising simulation in MATLAB from scratch is much simpler than converting existing code from another language. Perhaps you can try that. – Szabolcs Jan 10 '20 at 22:12
  • For speed up the calculations in Mma you can use Compile – vi pa Jan 10 '20 at 23:15
  • 1
    "Some people have said to me that MATLAB may run much faster", this is a long-standing prejudice. your code is clearly under-optimized, for example, ReplacePart and ReplaceAll should be avoided if speed is concerned. – xzczd Jan 11 '20 at 03:49
  • 3
    Just eyeballing the code, there is a lot of creating and passing of matrices that is likely computationally costly. For example, your accept[ ] function recreates m on every call, when you are just changing one element of the matrix, and could just pass the coordinates. So I think it could be improved before switching to Matlab. – MikeY Jan 11 '20 at 03:51
  • 4
    few years ago i did the same thing, you can find more here https://mathematica.stackexchange.com/questions/173286/function-fails-to-use-local-variable-when-it-is-called-inside-a-module henrik's solution was amazingly fast. Near the critical point you can also implement the wolff's algorithm which is also insanely fast compared to simple metropolis. i ran simulations with up to 50*10^6 microsteps. if only i could find the original notebook... – Alucard Jan 11 '20 at 14:59

0 Answers0