참고 : 원래 게시 한 코드에서 바보 같은 실수를했습니다. 워렌 웨 커서 (Warren Weckesser)는 말합니다. 정정되면 일부 해석자는 정답을 주지만 다른 표제는 NaN 또는 오답을 제공합니다. 또한 런타임 경고를 출력에 포함하는 것을 잊었습니다. 그들은 지금 거기에있다. 그에 따라 질문을 수정했습니다. 나는 작동하는 솔버를 사용할 수 있을지 모르지만 다른 사람들이 실패하는 이유를 이해하면 훨씬 행복해집니다.scipy의 스파 스 솔버가 잘못된 답을주는 이유는 무엇입니까?
scipy.sparse.linalg에있는 하나 이상의 솔버를 사용하여 선형 방정식의 스파 스 시스템을 해결하려고합니다. 나는이 프로그램을 실행할 때
import numpy as np
import scipy.sparse as ss
A = np.matrix([[ 0., 0., 0., 0., 0., 1., -1., -0., -0., -0., -0.],
[ 0., 0., 0., 0., 0., 2., -0., -1., -0., -0., -0.],
[ 0., 0., 0., 0., 0., 2., -0., -0., -1., -0., -0.],
[ 0., 0., 0., 0., 0., 2., -0., -0., -0., -1., -0.],
[ 0., 0., 0., 0., 0., 1., -0., -0., -0., -0., -1.],
[ 1., 2., 2., 2., 1., 0., -0., -0., -0., -0., -0.],
[-1., 0., 0., 0., 0., 0., -1., -0., -0., -0., -0.],
[ 0., -1., 0., 0., 0., 0., -0., -1., -0., -0., -0.],
[ 0., 0., -1., 0., 0., 0., -0., -0., -1., -0., -0.],
[ 0., 0., 0., -1., 0., 0., -0., -0., -0., -1., -0.],
[ 0., 0., 0., 0., -1., 0., -0., -0., -0., -0., -1.]])
b = np.matrix([0.,0.,0.,0.,0.,1.,0.,0.,0.,0.,0.]).T
As = ss.coo_matrix(A)
# The linear system Ax = b has a solution:
x1 = np.linalg.solve(A,b)
print("Solution to Ax = b:",x1)
print("Ax - b = ",A*x1-b)
print("Info and maximum error in solutions found by various other methods: ")
x2,info = ss.linalg.bicg(As,b)
print("bicg:",info,np.max(np.abs(x2-x1.ravel())))
x2,info = ss.linalg.bicgstab(As,b)
print("bicgstab:",info,np.max(np.abs(x2-x1.ravel())))
x2,info = ss.linalg.cgs(As,b)
print("cgs:",info,np.max(np.abs(x2-x1.ravel())))
x2,info = ss.linalg.gmres(As,b)
print("gmres:",info,np.max(np.abs(x2-x1.ravel())))
x2,info = ss.linalg.lgmres(As,b)
print("lgmres:",info,np.max(np.abs(x2-x1.ravel())))
x2,info = ss.linalg.minres(As,b)
print("minres:",info,np.max(np.abs(x2-x1.ravel())))
x2,info = ss.linalg.qmr(As,b)
print("qmr:",info,np.max(np.abs(x2-x1.ravel())))
, 나는 다음과 같은 출력을 얻을 :
다음 예에서 볼 수 있듯이 시스템, 스파 스 해법의 일부는 잘못된 답을주고있다, 직접 해결할 수있을만큼 작은 테스트 케이스에서는,Solution to Ax = b: [[ 0.07142857]
[ 0.14285714]
[ 0.14285714]
[ 0.14285714]
[ 0.07142857]
[-0.07142857]
[-0.07142857]
[-0.14285714]
[-0.14285714]
[-0.14285714]
[-0.07142857]]
Ax - b = [[ 0.00000000e+00]
[ 0.00000000e+00]
[ 2.77555756e-17]
[ 0.00000000e+00]
[ 1.38777878e-17]
[ 0.00000000e+00]
[ 2.77555756e-17]
[ -2.77555756e-17]
[ -5.55111512e-17]
[ 2.77555756e-17]
[ 0.00000000e+00]]
Info and maximum error in solutions found by various other methods:
bicg: 1 nan
bicgstab: 1 nan
cgs: 1 nan
gmres: 0 5.55111512313e-17
lgmres: 0 1.38777878078e-16
minres: 0 0.142857142857
qmr: -11 0.142857142857
/Users/ebunn/anaconda/lib/python3.5/site-packages/scipy/sparse/linalg/isolve/iterative.py:197: RuntimeWarning: invalid value encountered in multiply
work[slice2] *= sclr2
/Users/ebunn/anaconda/lib/python3.5/site-packages/scipy/sparse/linalg/isolve/iterative.py:318: RuntimeWarning: invalid value encountered in multiply
work[slice2] *= sclr2
/Users/ebunn/anaconda/lib/python3.5/site-packages/scipy/sparse/linalg/isolve/minres.py:244: RuntimeWarning: divide by zero encountered in double_scalars
Acond = gmax/gmin
X2 각각 계산 제로 (또는 적어도 소)이어야 X1 같은 선형 시스템에 대한 해결책으로 지난 7 개 라인에서 그 오류 때문에 모든 가정된다.
gmres 및 lgmres가 작동하지만 다른 것은 작동하지 않습니다. 대부분의 경우 정보는 오류를 올바르게 표시하지만 minres는 모두 0 (올바르지 않은) 인 솔루션을 반환하는 동안 성공 (정보 = 0)을 나타냅니다.
- 행렬 A는 명확한 긍정적 인 대칭하지만되지 않습니다 : 여기에 몇 가지 잠재적으로 관련 추가 정보입니다.
- 행렬 A는 상당히 잘 조절되어 있습니다.
- 스파 스 표현을 바꾸면 결과가 바뀌지 않습니다. 모든 희소 해석에서 원래 행렬 A와 마찬가지로 대신 ss.linalg.bicg (A, b) ss라고 말하면 결과는 변하지 않습니다. linalg.bicg (As, b) 등
- bicgstab을 포함하는 것이 실제로 불공정합니다. 설명서에는 긍정적 인 명확한 행렬만을위한 것이기 때문에. 이 방법이 원리 상 무한한 행렬에 적용 가능하기 때문에 그것이 효과가있을 것이라는 희망으로 포함 시켰습니다.
- 저는 파이썬 3.5.1, scipy 버전 0.17.0을 사용하고 있습니다.
물론이 시스템의 경우 직접적으로 문제를 해결하는 것이 중요하기 때문에 문제가되지 않습니다. 희박성이 필수적인 큰 문제의 경우 워밍업 문제입니다.
gmres 및/또는 lgmres가 내 요구 사항을 충족시킬 수 있지만 나 자신의 이해를 돕기 위해 부분적으로 다른 점이 무엇인지 이해하고 싶습니다.하지만 더 광범위한 일련의 방법을 사용할 수도 있습니다. 에서 고르다. 특히, 작동하는 두 가지 방법 중 어느 것도 A의 대칭을 이용하지 않으며, 그렇게하는 방법을 사용하는 것이 좋을 수도 있습니다. 난 당신의 코드 (py3)
Maximum error in solutions found by various other methods:
bicg: nan
/usr/lib/python3/dist-packages/scipy/sparse/linalg/isolve/iterative.py:197: RuntimeWarning: invalid value encountered in multiply
work[slice2] *= sclr2
bicgstab: nan
/usr/lib/python3/dist-packages/scipy/sparse/linalg/isolve/iterative.py:318: RuntimeWarning: invalid value encountered in multiply
work[slice2] *= sclr2
cgs: nan
gmres: 0.285714285714
lgmres: 0.285714285714
/usr/lib/python3/dist-packages/scipy/sparse/linalg/isolve/minres.py:244: RuntimeWarning: divide by zero encountered in double_scalars
Acond = gmax/gmin
minres: 0.142857142857
qmr: 0.142857142857
을 실행할 때
주의하십시오! 'A'는'np.matrix'이기 때문에,'x1' 또한 shape (11, 1)을 가진'np.matrix'입니다. 반면에'x2'는 shape (11,)을 가진'np.ndarray'입니다. 그래서'x2 - x1'을 계산할 때 방송이 적용되고 결과는 (11, 11)이됩니다. 이 방법을 피할 수 있습니다. 예를 들어'A = np.array (...) '를 사용합니다. ('A * x1'을'A.dot (x1)'로 바꾸거나)'x2'를 빼기 전에'x1'을 평평하게 만듭니다. . –
테스트를 위해 코드를 복사하여 붙여 넣는 것이 좋습니다. 그러나 여러분의 실수는 여러분이 실제로'x2' 결과를 보지 않았다고 제안합니다. 당신은'x1'과의 비교에 즉시 뛰어 오른 것 같습니다. – hpaulj
감사! 그건 내 바보 같았 어. 여러분이 짐작 했겠지만, 저는 Python 프로그래밍을 처음 접했습니다. 나는 그것을 알아 내야했다. –