i have this problem from mathematica,which refers to ising model.Here is a piece of code:
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
Here is what i have done:
J1k=2*randint(L,L)-1;
J2k=2*randint(L,L)-1;
I have created a function:
function Energy1 =energy1()
%spin interaction with the 开发者_StackOverflowneighbors
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
energy=@energy1
The problem is that when i call energy "energy=@energy1" no value returns.It supposes to return a value "1" or "-1".
Also, it continues (in 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}];
And i did :
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
which gives me message " Subscript indices must either be real positive integers or logicals.
Error in ==> ising at 58 dG1=-J1k(i1,i2).*mlat(j1,i2)-J1k(k1,i2).*mlat(k1,i2);" Any ideas?
For your first problem, you haven't set a value for the output, "Energy1". Just do
Energy1 = ener;
at the end of the function.
I think that your second problem is your use of the "if" statements. "If" in Matlab does not work like "if" in mathematica. In Matlab it works like this:
if (expression==true)
execute statement
end
So what you want to do is
if (j1>L)
j1 = 1;
end
etc...
EDIT to summarize discussion in comments: Use "rand(L)" to define i1 and i2 instead of "randint"
I implemented an Ising model in Matlab a few years ago. Perhaps my code would be useful to you; it is available in this note: Monte Carlo investigation of the Ising model (PDF). The code is very short and Matlabesque and begins on page 6.
As an example of idiomatic Matlab programming, suppose you have a matrix grid
which encodes your grid of spins as either +1 (up) or -1 (down). Then you can compute the average magnetization of every site's neighbors without using any for-loops by doing:
% 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]);
Then you can compute the change in energy due to flipping any spins:
% Calculate the change in energy of flipping a spin
DeltaE = 2 * J * (grid .* neighbors);
This statement works on every grid site simultaneously; such "vectorization" (computing over entire arrays at once) is the key to efficient Matlab code.
精彩评论