稀疏矩阵的条件数

时间:2017-04-07 15:07:27

标签: python numpy scipy

我试图获取scipy稀疏矩阵的条件数。到目前为止我设法做到的方法是将矩阵转换为密集,然后获得它的特征值:

$ python
Python 3.5.2 (v3.5.2:4def2a2901a5, Jun 26 2016, 10:47:25) 
[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from numpy import array
>>> import numpy as np
>>> import scipy.sparse as sparse
>>> I = array([0,3,1,0])
>>> J = array([0,3,1,2])
>>> V = array([4,5,7,9])
>>> A = sparse.coo_matrix((V,(I,J)),shape=(4,4))
>>> A = A.todense()
>>> eig = np.linalg.eig(A)
>>> eig = eig[0].real, np.array(eig[1].real)
>>> def split(array, cond):
...     return (array[cond], array[~cond])
... 
>>> eigv, zero = split(eig[0], eig[0]>1e-10)
>>> cond = max(eigv) / min(eigv)
>>> cond
1.75

正如您所料,这对于大型矩阵来说变得不可行。我想知道如何在Python中正确完成这项工作?

2 个答案:

答案 0 :(得分:1)

正如您所提到的,将稀疏矩阵转换为密集矩阵对于大问题通常不是一个好主意。因此,您不应该使用对numpy.linalg.cond()函数这样的函数来解决密集问题。

cond = || A || * || A ^ -1 ||

虽然它可能不是更有效的方法,但您可以在norm的稀疏模块中使用函数inversescipy.sparse来评估条件数(反转矩阵计算成本很高)过程):

norm_A = scipy.sparse.linalg.norm(A)
norm_invA = scipy.sparse.linalg.norm(scipy.sparse.linalg.inv(A))
cond = norm_A*norm_invA

示例:

import numpy as np
import scipy.sparse as sparse

n = 7
diagonals = np.array([[1, -4, 6, -4, 1]]).repeat(n, axis=0).transpose()
offsets = np.array([-2, -1, 0, 1, 2])
S = sparse.dia_matrix((diagonals, offsets), shape=(n, n))
norm_S = sparse.linalg.norm(S, np.inf)
norm_invS = sparse.linalg.norm(sparse.linalg.inv(S), np.inf)
cond = norm_S*norm_invS

答案 1 :(得分:0)

正如奥古斯托·萨(Augusto Sisa)提到的,条件编号定义为

cond(A):= || A || || A ^ {-1} ||

但这是必不可少的,最大特征值与最小特征值(大小)之比。因此,更有意义的是使用scipy.sparse.linalg.eigs() Scipy reference manual来获取值并找出自己。

import scipy.sparse
import scipy.sparse.linalg

ew1, ev = lg.eigsh(A, which='LM')
ew2, ev = lg.eigsh(K, sigma=1e-8)   #<--- takes a long time

ew1 = abs(ew1)
ew2 = abs(ew2)

condA = ew1.max()/ew2.min()

指定sigma选项是因为默认选项在查找最小特征值方面做得不好。此选项在逆位移模式下计算接近sigma的特征值。此步骤需要很长时间。您可以通过将k=ncv=选项指定为小于默认值的值来加快准确性。例如k=3ncv=8。但是,您实际上并不知道是否能很好地近似得到这样的特征值。 通过使用k参数计算更多的特征值,您几乎总是会提高准确性,但是默认值对于大多数用途应该足够准确。自己进行测试以查看矩阵的差异。

通常使用稀疏矩阵,因为矩阵的维数使所有条目的存储都被禁止。如果数据存储对于给定的维度来说是禁止的,那么对于一般矩阵而言,逆的计算会更糟。逆的计算本身是禁止的,但是稀疏矩阵通常不具有稀疏的逆,因此您再次陷入第一个问题。