我正在编写一个用Hessian矩阵进行数值计算的程序。 Hessian矩阵是500 x 500,我需要填充数百次。我每次用两个for循环填充它。我的问题是预防性缓慢。这是我的代码:
#create these outside function
hess = np.empty([500,500])
b = np.empty([500])
def hess_h(x):
#create these first so they aren't calculated every iteration
for k in range(500):
b[k] = (1-np.dot(a[k],x))**2
for i in range(500):
for j in range(500):
if i == j:
#these are values along diagonal
hess[i,j] = float(2*(1-x[i])**2 + 4*x[i]**2)/(1-x[i]**2)**2 \
- float(a[i,j]*sum(a[i]))/b[i]
#the matrix is symmetric so only calculate upper triangle
elif j > i :
hess[i,j] = -float(a[i,j]*sum(a[i]))/b[i]
elif i > j:
hess[i,j] = hess[j,i]
return hess
我计算hess_h(np.zeros(500))
需要10.2289998531秒才能运行。这太长了,我需要找到另一种方式。
答案 0 :(得分:0)
查看计算中的模式,尤其是您可以在i
和j
的整个范围内计算的内容。
我看到例如i==j
hess[i,j] = float(2*(1-x[i])**2 + 4*x[i]**2)/(1-x[i]**2)**2 \
- float(a[i,j]*sum(a[i]))/b[i]
您可以将其更改为一次性表达式,例如:
2*(1-x)**2 + 4*x**2)/(1-x**2)**2 - np.diagonal(a)*sum(a)/b
其他部分适用于上下三角形元素。有np.triu
等函数可以为您提供索引。
我试图通过几个numpy
矢量化操作来为您提供工具和解决方案,而不是迭代i
和j
的所有元素。< / p>
看起来像
-a[i,j]*sum(a[i])/b[i]
用于每个元素。我假设a
是一个(500,500)数组。你能用吗
-a*a.sum(axis=?)/b
b
可以&#39;矢量化&#39;
b[k] = (1-np.dot(a[k],x))**2
有类似的东西:
(1 - np.dot(a, x))**2
或
(1 - np.einsum('kj,ji',a,x))**2
在较小的a
上测试详细信息。