有许多零的SVD崩溃了SLEPc4py

时间:2017-03-30 13:50:39

标签: python cython svd

我试图在python / cython中使用SLEPc:s Lanczos类型的svd求解器从多个零的矩阵中计算出奇异值。

我使用的矩阵是PETc矩阵

[[ 0.00648130+0.32060635j  0 0 0 0 0 ]
 [ 0 0 0 0 0 0 ]
 [ 0 0 0 0 0 0 ]
 [ 0 0 0 0 0 0 ]
 [ 0 0 0 0 0 0 ]
 [ 0 0 0 0 0 -0.00668978-0.31948359j ]]

当我用下面的代码调用svd求解器时

size = Matrix.getSize()
S = SLEPc.SVD()
S.create()
S.setOperator(Matrix)
S.setType(SLEPc.SVD.Type.LANCZOS)
S.setDimensions(min(size))
S.solve()

我收到错误

/usr/local/lib/python2.7/dist-packages/slepc4py/lib/linux-gnu-cxx-complex/SLEPc.so in slepc4py.SLEPc.SVD.solve (src/slepc4py.SLEPc.c:35357)()

Error: error code 76
[0] SVDSolve() line 111 in /home/fremling/slepc-3.7.2/src/svd/interface/svdsolve.c
[0] SVDSolve_Lanczos() line 229 in /home/fremling/slepc-3.7.2/src/svd/impls/lanczos/gklanczos.c
[0] DSSolve() line 543 in /home/fremling/slepc-3.7.2/src/sys/classes/ds/interface/dsops.c
[0] DSSolve_SVD_DC() line 255 in /home/fremling/slepc-3.7.2/src/sys/classes/ds/impls/svd/dssvd.c
[0] Error in external library
[0] Error in Lapack xBDSDC 5

我意识到一些奇异值将为零,但这不应该是崩溃的原因,对吗?

我应该提一下,代码运行的大部分时间没有问题,但是当有很多零时,会发生这些崩溃。

1 个答案:

答案 0 :(得分:1)

完整的代码示例适用于除SLEPc.SVD.Type.CROSS之外的所有SLEPc SVD方法的给定矩阵。使用版本3.7.0的slepc4py和petsc4py进行测试。

import numpy as np
import slepc4py.SLEPc as SLEPc
import petsc4py.PETSc as PETSc

# numpy version
A = np.array([[0.00648130+0.32060635j,0,0,0,0,0]
              ,[0,0,0,0,0,0]
              ,[0,0,0,0,0,0]
              ,[0,0,0,0,0,0]
              ,[0,0,0,0,0,0]
              ,[0,0,0,0,0,-0.00668978-0.31948359j]])

u,s,d = np.linalg.svd(A)
print('Singular values: ', s)

# SLEPc version
Ap = PETSc.Mat()
Ap.create()
Ap.setSizes(A.shape)
Ap.setUp()
for row in range(A.shape[0]):
    for col in range(A.shape[1]):
        Ap.setValue(row, col, A[row,col])
Ap.assemble()

#for stype in [SLEPc.SVD.Type.CROSS, SLEPc.SVD.Type.CYCLIC, SLEPc.SVD.Type.LANCZOS, SLEPc.SVD.Type.LAPACK, SLEPc.SVD.Type.TRLANCZOS]:
for stype in [SLEPc.SVD.Type.CYCLIC, SLEPc.SVD.Type.LANCZOS, SLEPc.SVD.Type.LAPACK, SLEPc.SVD.Type.TRLANCZOS]:
    S = SLEPc.SVD()
    S.create()
    S.setOperator(Ap)
    S.setType(stype)
    S.setDimensions(A.shape[0])
    S.solve()

    s_slepc = []
    i=0
    while i < S.getConverged():
        s_slepc.append(S.getValue(i))
        i += 1

    print('Singular values (SLEPc %s): ' % S.getType(), s_slepc)

产生输出:

('Singular values: ', array([ 0.32067186,  0.31955362,  0.        ,  0.        ,  0.        ,  0.        ]))
('Singular values (SLEPc cyclic): ', [0.3206718555003113, 0.31955362216025096, 5.558046393682893e-17, 1.5567126663969806e-34, 1.1955235065555233e-34, 8.758810386256485e-36])
('Singular values (SLEPc lanczos): ', [0.32067185550031124, 0.31955362216025107, 7.598620143277e-17, 9.80035376111015e-18, 8.135560423584465e-18, 4.5426042596528355e-18])
('Singular values (SLEPc lapack): ', [0.32067185550031124, 0.31955362216025107, 0.0, 0.0, 0.0, 0.0])
('Singular values (SLEPc trlanczos): ', [0.32067185550031124, 0.31955362216025107, 1.4803092323093608e-09, 9.80035376111015e-18, 8.135560423584465e-18, 4.5426042596528355e-18])