【发布时间】:2019-10-29 13:46:57
【问题描述】:
这段代码包含 3 个嵌套循环,在 Matlab 中运行需要 30 秒,而在 Python 中运行则超过 5 分钟。非常感谢任何有关如何使 Python 更快的建议!该代码通过使用 Newmark 数值解来创建响应谱。 我知道矢量化将解决挑战,但我找不到实施它的空间。
from numba import jit
import numpy as np
import matplotlib.pyplot as plt
import scipy as sp
import timeit
start = timeit.default_timer()
sig=np.loadtxt('LXR1N.txt')
t=sig[:,0]
ag=0.01*sig[:,1]
h=t[1]-t[0]
f=-ag
alfa=1/6; delta=0.5
alfa0=1/(alfa*h**2)
alfa1=delta/(alfa*h)
alfa2=1/(alfa*h)
alfa3=1/(2*alfa)-1
alfa4=delta/alfa-1
alfa5= h/2*(delta/alfa-2)
alfa6= h*(1-delta)
alfa7= delta*h;
D=np.array([0.01,0.04,0.06,0.1])
T=np.zeros(1198,float)
d=np.zeros([len(t)])
len(d)
v=np.zeros([len(t)])
a=np.zeros([len(t)])
fb=np.zeros([len(t)-1])
sd=np.empty((len(D),len(T)))
sa=np.empty((len(D),len(T)))
sv=np.empty((len(D),len(T)))
aex=np.empty((len(D),len(T)))
vex=np.empty((len(D),len(T)))
for i in range(0,len(T)):
T[i]=0.015+0.005*i
i=None
s=-1
for q in D:
s+=1
for i in range(0,len(T)):
omega=2*np.pi/T[i]
c=2*q*omega
k=omega**2
kb=k+alfa0+alfa1*c
d[0]=0
v[0]=0
a[0]=0
for j in range(0,len(t)-1):
fb[j]=f[j]+alfa0*d[j]+alfa2*v[j]+alfa3*a[j]+c*alfa1*d[j]+c*alfa4*v[j]+c*alfa5*a[j]
d[j+1]=fb[j]/kb
a[j+1]=alfa0*d[j+1]-alfa0*d[j]-alfa2*v[j]-alfa3*a[j]
v[j+1]=v[j]+alfa6*a[j]+alfa7*a[j+1]
atot=a+ag
atot1=-omega**2*d-2*q*omega*v
sd[s,i]=max(abs(d))
sa[s,i]=omega**2*sd[s,i]
sv[s,i]=omega*sd[s,i]
aex[s,i]=max(abs(atot))
vex[s,i]=max(abs(v))
del i
del j
plt.figure(1,figsize=(10, 4))
for i in range(sd.shape[0]):
plt.plot(T,sd[i,:],label=str(D[i]*100)+"%")
plt.xlabel("Period [s]")
plt.ylabel("Sd [m]")
plt.xlim([0,6])
plt.ylim([0,0.6])
plt.legend()
plt.savefig('Sd.jpg')
plt.show()
plt.figure(2,figsize=(6, 3))
for j in range(sa.shape[0]):
plt.plot(T,1/9.81*sa[j,:],label=str(D[j]*100)+"%")
plt.xlabel("Period [s]")
plt.ylabel("Sa [g]")
plt.xlim([0,6])
plt.ylim([0,2.5])
plt.legend()
plt.savefig('Sa.png')
plt.show()
stop = timeit.default_timer()
execution_time = stop - start
print("Program Executed in: ",execution_time, 'seconds')
【问题讨论】:
-
请为 sig 提供一些数字数据,这样用户可能会尝试帮助您提供一个很好的可重现示例。另外,你是不是直接导入了 numba @jit 装饰器,甚至没有使用它?
-
请添加一个完整的工作示例。这包括一个具有明确定义的输入和输出的函数(一个用于计算,一个用于绘图)@Yacola 代码中有一些东西是 Numba 无法处理的。例如。 v=np.zeros([len(t)])
-
我发现它是一个建议,实际上只需导入它,运行时间就减少了 20 秒。
-
这里是txt文件:(dropbox.com/s/j1xz7exn4bsgvum/LXR1N.txt?dl=0)
-
MATLAB 实现了 jit 编译,让您可以在没有太多时间损失的情况下使用迭代。
numpy就像旧的 MATLAB 版本一样,需要我们考虑整个数组操作,通常称为vectorized。但是,只是随便阅读一下,很难判断您的代码中有多少本质上是串行的(必须一个接一个地循环),以及可以在“并行”中完成什么(即在编译的整个数组中执行)方法)。