我已经编写了基于蒙特卡罗模拟和Metropolis算法的Ising模型模拟,但我遇到了一些麻烦,即ValueError: setting an array element with a sequence
。任何帮助解决这个问题将不胜感激。
以下显示错误在代码中的位置:
如果有人发现任何可能阻止代码生成图表的其他错误,请告诉我。
# Code Mark 1.4: Ising Model in 2D
# Importing all the necessary packages I will use:
import numpy as np
import scipy as sp
import matplotlib.pyplot as plt
import numpy.random as rnd
# Before I do anything I need to make sure the specifics of the size of the lattice as a 12x12 sized, number of steps, number of temperature points used, number of points in order to reach an equilibrium state are all accounted for
num=16
steps_monte=100
temp_points=50
steps_equil=100
num_a=1/(steps_monte*(num**2))
num_b=1/((steps_monte**2)*(num**2))
# Next I must create an intitial spin state for my molecule:
def startspin(num):
spin=rnd.randint(2,size=(num,num))-1
return spin
# Now I need to define the energy function. This will give the energy of any given spin state:
def Energy(Q):
starting_energy=0
for i in range(len(Q)):
for j in range(len(Q)):
g=Q[i,j]
n_y=Q[(i+1)%num,j]+Q[i,(j+1)%num]+Q[(i-1)%num,j]+Q[i,(j-1)%num]
starting_energy+=g*-n_y
return starting_energy/4
# Now I need to code the Monte Carlo Steps with Metro ALgorithm for the ising model:
def montestep(Q,P):
for i in range(num):
for j in range(num):
x=rnd.randint(0,num)
y=rnd.randint(0,num)
z=Q[x,y]
n_y=Q[(x+1)%num,y]+Q[x,(y+1)%num]+Q[(x-1)%num,y]+Q[x,(y-1)%num]
l=2*z*n_y
if l<0:
z*=-1
elif rnd.rand()<np.exp(P*-l):
z*=-1
Q[x,y]=z
return Q
#Now I need to define the magnetization function. This gives the Magnetization of any given spin state:
def Magnetization(Q):
magnetization=np.sum(Q)
return magnetization
# Here I am saying that the temperature points need to have a midpoint where we expect the disorder to begin and to give us random points between this value as 1<T<5
temp_mid = 2.25;
Temp=rnd.normal(temp_mid,0.5,temp_points)
Temp=Temp[(Temp>1)&(Temp<5)]
temp_points=np.size(Temp)
# I need to define 0 points for each of the 4 physical quantities I wish to find:
Magnetization=np.zeros(temp_points)
SpecificHeat=np.zeros(temp_points)
Energy=np.zeros(temp_points)
Susceptibility=np.zeros(temp_points)
# Now I need to implement each function above by creating an Ising Function with them:
for j in range(len(Temp)):
E_a=M_a=0
E_b=M_b=0
Q=startspin(num)
init_Temp_a=1/Temp[j]
init_Temp_b=init_Temp_a**2
for i in range(steps_monte):
montestep(Q,init_Temp_a)
Energy_calc=Energy[Q]
Mag_calc=Magnetization[Q]
E_a=E_a+(Energy_calc)
M_a=M_a+(Mag_calc)
M_b=M_b+(Mag_calc**2)
E_b=E_b+(Energy_calc**2)
Energy[j]=num_a*E_a[i][j]
Magnetization[j]=num_a*M_a[i][j]
SpecificHeat[j]=(num_a*E_b[i][j]-num_b*(E_a[i][j]**2))*init_Temp_b
Susceptibility[j]=(num_a*M_b[i][j]-num_b*(M_a[i][j]**2))*init_Temp_a
for k in range(steps_equil):
montestep(Q,init_Temp_a)
#Finally I can plot the 4 graphs I need to show the monte carlo steps of the ising model and can then conduct my research thereafter.
plt.plot(T, Energy,'d', color="#8A2BE2")
plt.xlabel("Temperature (Kelvin)")
plt.ylabel("Energy (Arbitrary Units)")
plt.show()
plt.plot(T, abs(Magnetization),'x', color="#7FFF00")
plt.xlabel("Temperature (Kelvin)")
plt.ylabel("Magnetization (Arbitrary Units)")
plt.show()
plt.plot(T, SpecificHeat, 'd', color="#00FFFF")
plt.xlabel("Temperature (Kelvin)")
plt.ylabel("Specific Heat (Arbitrary Units)")
plt.show()
plt.plot(T, Susceptibility, 'x', color="#0000FF")
plt.xlabel("Temperature (Kelvin)")
plt.ylabel("Susceptibility (Arbitrary Units)")
plt.show()
答案 0 :(得分:1)
您可以通过以下方式找到此错误:
print(type(Energy[j]), type(num_a), type(E_a))
在您设置Energy[j]
之前。你发现它不会起作用:
<class 'numpy.float64'> <class 'float'> <class 'numpy.ndarray'>
E_a
是一个numpy数组。您无法将数组分配给必须解析为浮点数的值。我不熟悉算法,但您可能想要使用以下内容吗?
Energy[j]= num_a * E_a[i][j]
稍后设置Magnetization[j]
您会发现同样的问题。同样的问题,同样的修复。
这解决了我的机器上运行Python 3.5.2的问题。但代码仍有问题。例如,num_b
被引用两次但从未创建过。
编辑:将num_2
重命名为num_b
,将M1
重命名为M_a
,还有一些错误。基本上你的功能可能是这样的:
for i in range(len(Temp)):
E_a=M_a=0
E_b=M_b=0
Q=startspin(num)
init_Temp_a=1/Temp[i]
init_Temp_b=init_Temp_a**2
for j in range(steps_monte):
montestep(Q,init_Temp_a)
Energy_calc=Energy[Q]
Mag_calc=Magnetization[Q]
E_a=E_a+(Energy_calc)
M_a=M_a+(Mag_calc)
M_b=M_b+(Mag_calc**2)
E_b=E_b+(Energy_calc**2)
print(E_a[i][j])
Energy[j]= num_a * E_a[i][j]
Magnetization[j]=num_a*M_a[i][j]
SpecificHeat[j]=(num_a*E_b[i][j]*(E_a[i][j]**2))*init_Temp_b
Susceptibility[j]=(num_a*M_b[i][j]*(M_a[i][j]**2))*init_Temp_a
for _ in range(steps_equil):
montestep(Q,init_Temp_a)
但这显示出更多问题。看看以下内容:
for i in range(len(Temp)):
for j in range(steps_monte):
steps_monte
设置为1024,Temps
的长度似乎是非常数(但超过250)。所以这将迭代很多值,对吧?好吧,不是真的。因为它迭代的数组并不大。因此迭代将超出界限。该数组比迭代更早停止。
这让我想知道算法实现是否以更大的方式存在缺陷。
注意:您的代码在j
之前使用i
。我改变了这一点,这是一种更常见的符号,更容易理解。