我试图在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
我意识到一些奇异值将为零,但这不应该是崩溃的原因,对吗?
我应该提一下,代码运行的大部分时间没有问题,但是当有很多零时,会发生这些崩溃。
答案 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])