numpy矩阵人口很慢

时间:2015-10-14 01:16:57

标签: python performance numpy matrix hessian-matrix

我正在编写一个用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秒才能运行。这太长了,我需要找到另一种方式。

1 个答案:

答案 0 :(得分:0)

查看计算中的模式,尤其是您可以在ij的整个范围内计算的内容。

我看到例如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矢量化操作来为您提供工具和解决方案,而不是迭代ij的所有元素。< / 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上测试详细信息。