我研究宇宙学,最近我有机会获得数值模拟的经验。
我有使用C ++的经验,但我刚开始使用python。
以下是我目前编写的python代码的一部分。
def energy(s):
def spectrum(s):
phi = sol[s,:]
N = len(phi)
return 2.0 / N * np.real(np.fft.rfft(phi))
delta_t = t_array[1] - t_array[0]
sp = spectrum(s)
spb = spectrum(s-1)
spa = spectrum(s+1)
L = len(sp)
def spectrum_dot(s):
sD = np.array([]).reshape(1,L)
for j in range(0,L):
sD[j] = (spa[j] - spb[j]) / (2 * delta_t)
return sD
sd = spectrum_dot(s)
E = np.array([]).reshape(1,L)
for i in range(0,L):
E[i] = (sd[i]*sd[i]/2) + (sp[i]*sp[i]*(i*math.pi/128)*(i*math.pi/128)/2) + V(sp[i])
return E
f_l = energy(time_steps * 128 / 619)
plt.plot(f_l[1:200])
plt.axhline(0,color='black',linewidth=0.6)
plt.axis([0,200,-1,1])
plt.savefig('128.png')
对于“sD = np.array([])。reshape(1,L)”这一行,我得到一个ValueError,上面写着“ValueError:新数组的总大小必须保持不变”。
定义“spectrum_dot(s)”的返回数组似乎是个问题。
你可以给我一个提示来纠正这个错误吗?
感谢您的阅读。
答案 0 :(得分:0)
您的代码中有两个问题,第一个问题是.reshape()
方法无法更改数组的 size (或数组所指向的数据)但只能更改形状该数据
# legal
z1 = np.zeros(20)
z1.reshape((4,5))
# illegal
z1.reshape((5,5))
另一个问题是我也有fortran / c背景,所以我可以理解你的问题...当你使用numpy
时你可以避免,你应该避免,写作通过术语和数组修改术语的循环,而是写向量表达式,其值是另一个数组,如果为其指定名称,可以在以后重用,返回到代码
sD = (sda-sdb)/2/delta_t
没有初始化sD
,没有索引,没有显式循环,最重要的是,隐式循环以与编译语言相当的速度执行,即,数量级比Python中的显式循环。
处理数组表达式时numpy
遵循的规则称为广播规则,如果您要认真使用此库,则必须熟悉广播使您能够编写(有时甚至有点神秘,即使在我们的示例中不是这种情况)表达式,以避免显式循环的重载。