从mathematica到matlab的模型

时间:2011-02-19 13:13:36

标签: matlab model wolfram-mathematica

我有mathematica的问题,这是指ising model.Here是一段代码:

J1k = Table[2 RandomInteger[] - 1, {L}, {L}];
J2k = Table[2 RandomInteger[] - 1, {L}, {L}];

energy1 := 
 Module[{ii1, ii2, jj1, jj2, kk1, kk2, dG1, ener1, ener2, ener}, 
  ener = 0.;
  Do[
   Do[
    jj1 = ii1 + 1; jj2 = ii2 + 1; kk1 = ii1 - 1; kk2 = ii2 - 1;
    If[jj1 > L, jj1 = 1]; If[jj2 > L, jj2 = 1];
    If[kk1 < 1, kk1 = L]; If[kk2 < 1, kk2 = L];
    ener1 = -J1k[[ii1, ii2]]*mlat[[ii1, ii2]]*mlat[[jj1, ii2]] - 
      J1k[[kk1, ii2]]*mlat[[ii1, ii2]]*mlat[[kk1, ii2]];
    ener2 = -J2k[[ii1, ii2]]*mlat[[ii1, ii2]]*mlat[[ii1, jj2]] - 
      J2k[[ii1, kk2]]*mlat[[ii1, ii2]]*mlat[[ii1, kk2]];
    ener = ener1 + ener2 - 2*mlat[[ii1, ii2]] *\[Mu]Bk,
    {ii1, 1, L}],
   {ii2, 1, L}];
  ener = ener/2.]

energy = energy1

这就是我所做的:

J1k=2*randint(L,L)-1;
J2k=2*randint(L,L)-1;
I have created a function:
function Energy1 =energy1()
%spin interaction with the neighbors
ener=0;
L=16;
J1k=2*randint(L,L)-1;
J2k=2*randint(L,L)-1;
for ii2=1:L
for ii1=1:L
    jj1=ii1+1;jj2=ii2+1;kk1=ii1-1;kk2=ii2-1;
    if (jj1>L & jj1==1)
    end
        if (jj2>L & jj2==1)
        end
            if (kk1<1 & kk1==L)
            end
                if (kk2<1 & kk2==L)
                end
                    ener1=-J1k(ii1,ii2).*mlat(ii1,ii2).*mlat(jj1,ii2)-J1k(kk1,ii2).*mlat(ii1,ii2).*mlat(kk1,ii2);
                    ener2=-J2k(ii1,ii2).*mlat(ii1,ii2).*mlat(ii1,jj2)-J2k(ii1,kk2).*mlat(ii1,ii2).*mlat(ii1,kk2);
                    ener=ener1+ener2-2.*mlat(ii1,ii2).*mBk;


end                
end
ener=ener ./2;

end

能量= @ energy1

问题在于,当我称之为能量“energy = @ energy1”时,没有值返回。它假设返回值“1”或“-1”。

此外,它继续(在mathematica中):

T = 5.2; dT = 0.1; Umean = {};
energy = energy1;
Do[energyseries = {}; T = T - dT;
  Do[i1 = RandomInteger[{1, L}]; i2 = RandomInteger[{1, L}];
   j1 = i1 + 1; j2 = i2 + 1; k1 = i1 - 1; k2 = i2 - 1;
   If[j1 > L, j1 = 1]; If[j2 > L, j2 = 1];
   If[k1 < 1, k1 = L]; If[k2 < 1, k2 = L];
   dG1 = -J1k[[i1, i2]]*mlat[[j1, i2]] - 
     J1k[[k1, i2]]*mlat[[k1, i2]];
   dG2 = -J2k[[i1, i2]]*mlat[[i1, j2]] - 
     J2k[[i1, k2]]*mlat[[i1, k2]];
   dE = 2.*mlat[[i1, i2]] (dG1 + dG2 + \[Mu]Bk);
   W = N[Exp[-dE/T]];
   If[W < 1 && W > Random[] || dE <= 0, 
    mlat[[i1, i2]] = -mlat[[i1, i2]]; index = 1, index = 0];
   energy = energy + dE*index // N;
   AppendTo[energyseries, energy],
   {i, 1, Maxstep}];
  PrependTo[Umean, {T, Mean[energyseries]/L2}],
  {jT, 1, 51}];

我做了:

T=5.2;
dT=0.1;
Umean=zeros();
energy=@energy1
for jT=1:51
    energyseries=zeros();
    T=T-dT;
    for i=1:Maxstep
    i1=randint(1,L);
    i2=randint(1,L);
    j1=i1+1;
    j2=i2+1;
    k1=i1-1;
    k2=i2-1;
    if (j1>L & j1==1)
    end
        if (j2>L & j2==1)
        end
            if (k1<1 & k1==L)
            end
                if (k2<1 & k2==L)
                end
                    dG1=-J1k(i1,i2).*mlat(j1,i2)-J1k(k1,i2).*mlat(k1,i2);
                    dG2=-J2k(i1,i2).*mlat(i1,j2)-J2k(i1,k2).*mlat(i1,k2);
                    dE=2.*mlat(i1,i2).*(dG1+dG2+mBk);
                    W=exp(-dE./T);
                    if (W<1 & W>rand() | dE<=0)
                        mlat(i1,i2)=-mlat(i1,i2);
                        index=1;
                        index=0;
                    end
                    energy=energy+dE.*index;
                    energyseries(:)=[energy]
    end
    Umean(:)=[T mean(energyseries(:))./L2]
end

它给我的消息“下标索引必须是真正的正整数或逻辑。

==&gt;中的错误现年58岁                     DG1 = -J1k(I1,I2)* MLAT(J1,I2)-J1k(K1,I 2)* MLAT(K1,I 2);” 有什么想法吗?

2 个答案:

答案 0 :(得分:1)

对于第一个问题,您没有为输出设置值“Energy1”。只是做

Energy1 = ener;

在功能结束时。

我认为你的第二个问题是你使用“if”语句。 Matlab中的“if”在mathematica中不像“if”那样工作。在Matlab中,它的工作原理如下:

if (expression==true)   
     execute statement
end

所以你想做的是

if (j1>L)
     j1 = 1;
end

等...

编辑总结评论中的讨论: 使用“rand(L)”来定义i1和i2而不是“randint”

答案 1 :(得分:1)

几年前我在Matlab中实现了一个Ising模型。也许我的代码对你有用;它在本说明中提供:Monte Carlo investigation of the Ising model (PDF)。代码很短,Matlabesque,从第6页开始。

作为惯用的Matlab编程示例,假设您有一个矩阵grid,它将您的旋转网格编码为+1(向上)或-1(向下)。然后你可以通过这样做来计算每个站点的邻居的平均磁化强度而不使用任何for循环:

% Calculate the number of neighbors of each cell
neighbors = circshift(grid, [ 0 1]) + ...
            circshift(grid, [ 0 -1]) + ...
            circshift(grid, [ 1 0]) + ...
            circshift(grid, [-1 0]);

然后你可以计算由于翻转任何旋转引起的能量变化:

% Calculate the change in energy of flipping a spin
DeltaE = 2 * J * (grid .* neighbors);

此声明同时适用于每个网格站点;这种“矢量化”(一次计算整个数组)是高效的Matlab代码的关键。