共轭梯度实现Python

时间:2018-12-07 07:59:58

标签: python numpy optimization sparse-matrix matrix-multiplication

我通过查看Wikipedia参考-https://en.wikipedia.org/wiki/Conjugate_gradient_method

在python中实现了共轭梯度。

该实现应解决

ax = b

我的应用程序输入如下,

a = <400x400 sparse matrix of type '<class 'numpy.float64'>'
    with 1920 stored elements in Compressed Sparse Row format>
b = vector of shape (400, ) and dtype = float64
x = vector of random numbers of shape (400, )

这是我的实现-

def ConjGrad(a, b, x):
       r = (b - np.dot(np.array(a), x));
       p = r;
       rsold = np.dot(r.T, r);

       for i in range(len(b)):
           a_p = np.dot(a, p);
           alpha = rsold / np.dot(p.T, a_p);
           x = x + (alpha * p);
           r = r - (alpha * a_p);
           rsnew = np.dot(r.T, r);
           if (np.sqrt(rsnew) < (10 ** -5)):
               break;
           p = r + ((rsnew / rsold) * p);
           rsold = rsnew;        
       return p

当我调用上述CG函数时,该行的函数中出现错误-

r = (b - np.dot(np.array(a), x));

这样的错误-

NotImplementedError: subtracting a sparse matrix from a nonzero scalar is 
not supported 

在运行时,以下是CG函数中变量的属性-

np.dot(np.array(a), x).shape
(400,)
b.shape
(400,)

我想知道为什么减法没有发生?

我使用下面的示例输入参数测试了相同的功能,并且效果很好。

a = np.array([[3, 2, -1], [2, -1, 1], [-1, 1, -1]]) # 3X3 symmetric matrix
b = (np.array([1, -2, 0])[np.newaxis]).T  # 3X1 matrix
x = (np.array([0, 1, 2])[np.newaxis]).T

有人可以告诉我为什么它不适用于稀疏矩阵吗?

1 个答案:

答案 0 :(得分:1)

将稀疏矩阵乘以数组时,不应使用: np.dot(np.array(a),x)),而应使用 a.dot(x) >。请参阅下面的文档:

https://docs.scipy.org/doc/scipy/reference/sparse.html

遵循正确的例程:

    def conjGrad(A,x,b,tol,N):

    r = b - A.dot(x)
    p = r.copy()
    for i in range(N):
        Ap = A.dot(p)
        alpha = np.dot(p,r)/np.dot(p,Ap)
        x = x + alpha*p
        r = b - A.dot(x)
        if np.sqrt(np.sum((r**2))) < tol:
            print('Itr:', i)
            break
        else:
            beta = -np.dot(r,Ap)/np.dot(p,Ap)
            p = r + beta*p
    return x