我正在努力加速一些用python编写的数值建模代码。它依赖于numpy
数组和scipy.linalg
的矩阵求解方法。这是一个有限差分偏微分方程解算器。在分析和处理一些较慢的位之后,最大的时间块被built-in method __new__
占用。__new__
方法是否在每次声明数字时都执行?有什么办法可以避免吗?以下是解算器的主循环:
#iterate over time steps
for j in range(1,N_t):
#store some numbers
jm1 = j - 1
mm2 = m - 2
mm1 = m - 1
mp1 = m + 1
pm1 = p - 1
pm2 = p - 2
#load the "b vector"
vec[0] = v1*C[0,jm1] + v2*C[1,jm1]
for i in r_vec_a:
vec[i] = hlam_a*C[i-1,jm1] + v3*C[i,jm1] + hlam_a*C[i+1,jm1]
vec[mm1] = -f1*C[mm2,jm1] + f5*C[mm1,jm1] - f3*C[m,jm1] - f4*C[mp1,jm1]
vec[m] = -g1*C[mm2,jm1] - g2*C[mm1,jm1] + g5*C[m,jm1] - g4*C[mp1,jm1]
for i in r_vec_b:
vec[i] = hlam_b*C[i-1,jm1] + v4*C[i,jm1] + hlam_b*C[i+1,jm1]
vec[pm1] = v5*C[pm2,jm1] + v6*C[pm1,jm1]
#solve the matrix equation for new concentrations
C[:,j] = scipy.linalg.solve_banded(u1, banded, vec, check_finite = u2,
overwrite_b = u3)
#compute boundary values (with 2 extra orders of accuracy because it's easy)
C_x0[0,j] = w1*C[0,j] - w2*C[1,j] + w3*C[2,j] - w4*C[3,j]
C_xL[0,j] = e1*C[mm2,j] + e2*C[mm1,j] + e3*C[m,j] + e4*C[mp1,j]
C_yL[0,j] = K_r*C_xL[0,j]
C_y0[0,j] = -w4*C[p-4,j] + w3*C[p-3,j] - w2*C[pm2,j] + w1*C[pm1,j]
我的第一个想法是存储所有索引变量和常量(如果它们被重用),但这并没有减少对__new__
的调用。你知道吗
探查器应该告诉您正在调用哪个对象的
__new__
方法。你知道吗代码中最突出的一点是,在
solve_banded
调用的幕后有相当多的复制。你知道吗答案在
solve_banded
的来源中: https://github.com/scipy/scipy/blob/v0.17.1/scipy/linalg/basic.py#L180-L255如果您的scipy版本是0.15.1或更低,它不会对三对角矩阵进行特殊处理,而是将您的输入复制到一个更大的LAPACK矩阵中(请参阅源代码中的
not l==u==1
分支)。你知道吗因为您是在循环中进行操作,所以可能需要直接调用相关的LAPACK函数:只需内联
solve_banded
的相关部分。然后再做一次侧写。你知道吗相关问题 更多 >
编程相关推荐