У меня есть два кода для вычисления функции.Один основан на python для циклов, как показано ниже:
@nb.autojit()
def ODEfunction(r):
tic = time.process_time()
NP=10
s=1
l=100
f = np.zeros(len(r))
lbound=-4* (12*s**12/(-0.5*l-r[0])**13-6*s**6/(-0.5*l-r[0])**7)
rbound=-4* (12*s**12/(0.5*l-r[NP-1])**13-6*s**6/(0.5*l-r[NP-1])**7)
f[0:NP]=r[NP:2*NP]
for i in range(NP):
fi = 0.0
for j in range(NP):
if (j!=i):
fij = -4*(12*s**12/(r[j]-r[i])**13-6*s**6/(r[j]-r[i]) ** 7)
fi = fi + fij
f[i+NP]=fi
f[NP]=f[NP]+lbound
f[2*NP-1]=f[2*NP-1]+rbound
toc = time.process_time()
print(toc-tic)
return f
Другой - это эквивалентная векторизованная версия этого кода:
@nb.autojit()
def ODEfunction(r):
tic=time.process_time()
NP=10
s=1
l=100
f = np.zeros(len(r))
lbound=-4* (12*s**12/(-0.5*l-r[0])**13-6*s**6/(-0.5*l-r[0])**7)
rbound=-4* (12*s**12/(0.5*l-r[NP-1])**13-6*s**6/(0.5*l-r[NP-1])**7)
f[0:NP]=r[NP:2*NP]
ri=r[0:NP]
rj = r[0:NP]
rij=np.subtract.outer(rj,ri)
fij = -4 * (12 * s ** 12 / (rij) ** 13 - 6 * s ** 6 / (rij) ** 7)
fij[np.diag_indices(NP)]=0
f[NP:2*NP] = fij.sum(axis=0)
f[NP]=f[NP]+lbound
f[2*NP-1]=f[2*NP-1]+rbound
toc=time.process_time()
print(toc-tic)
return f
В обоих входных данных r является цифрой 1 на 20массив и, как вы видите, я использую Numba для ускорения кодов.Удивительно, что в этом случае векторизованный код работает в 5 раз медленнее, чем циклы for.Я уже сталкивался с подобной проблемой в некоторых постах, таких как здесь: Numpy: медленный векторизованный код с одним циклом по сравнению с итерацией с двумя циклами
Однако проблема заключается в огромном размере массивов.Как вы видите, в моем случае нет большого массива.Кто-нибудь знает причину и как это можно решить?