2017-12-17 28 views
1

나는 일반화 된 고유치 문제를 풀기 위해 scipy.sparse.linalg.eigsh()을 사용하고 있습니다. 내가 큰 거친 매트릭스를 조작하고 있기 때문에 eigsh()을 사용하고 싶습니다. 문제는 올바른 답을 얻을 수없고 eigsh()의 고유 값과 고유 벡터 출력이 Matlab의 eigs()에서 얻은 것과 완전히 다릅니다.scipy.sparse.linalg.eigsh()는 Matlab의 eigs()와 같은 결과를 제공하지 않습니다. 이유가 무엇입니까?

그것은 다음과 같습니다 데이터 : 파이썬에서

a: 
    304.7179 103.1667 36.9583 61.3478 11.5724 
    35.5242 111.4789 -9.8928 8.2586 -4.7405 
    10.8358 4.3433 145.6586 26.5153 13.1871 
    -1.1924 -2.5430 0.4322 43.1886 -0.6098 
    -18.7751 -8.8031 -4.3962 -5.8791 17.6588 
b: 
    736.9822 615.7946 587.6828 595.7169 545.1878 
    615.7946 678.2142 575.7579 587.3469 524.7201 
    587.6828 575.7579 698.6223 593.5402 534.3675 
    595.7169 587.3469 593.5402 646.0410 530.1114 
    545.1878 524.7201 534.3675 530.1114 590.1373 

: A, B

In [11]: import scipy.sparse.linalg as lg 

In [14]: x,y=lg.eigsh(a,M=b,k=2,which='SM') 

In [15]: x 
Out[15]: array([ 0.01456738, 0.22578463]) 

In [16]: y 
Out[16]: 
array([[ 0.00052614, 0.00807034], 
     [ 0.00514091, -0.01593113], 
     [ 0.00233622, -0.00429671], 
     [ 0.01877451, -0.06259276], 
     [ 0.01491696, 0.08002341]]) 

In [18]: a.dot(y[:,0])-x[0]*b.dot(y[:,0]) 
Out[18]: array([ 1.74827445, 0.30325634, 0.71299604, 0.42842245, -0.24724681]) 

In [19]: a.dot(y[:,1])-x[1]*b.dot(y[:,1]) 
Out[19]: array([-2.2463206 , -1.64704567, -0.80086734, -1.56796329, 0.03027861]) 

고유 값과 고유 벡터가 충분하지 않은 것을 numpy.ndarray 볼 수 있습니다 원래의 행렬을 재구성하는 것.

그러나, MATLAB에서 잘 작동합니다

[y,x] = eigs(a,b,2,'sm'); 

y = 

    0.0037 -0.0141 
    -0.0056 0.0151 
    0.0015 0.0079 
    -0.0117 0.0666 
    -0.0298 -0.0753 
x = 

    0.0202   0 
     0 0.3499 
a*x(:,1)-y(1,1)*b*x(:,1) 

ans = 

    1.0e-14 * 

    -0.3775 
    0.0777 
    0.0777 
    0.0555 
    0.0666 

플러스, 데이터 b는 명확한 긍정적이다 : 나는 파이썬에서 바로 답변을 얻을 수없는 이유

In [24]: np.linalg.eigvals(b) 
Out[24]: 
array([ 2951.07297125, 137.81545217, 90.40223937, 107.04818229, 
      63.65818086]) 

아무도 설명 할 수 있을까?


우리가 MATLAB과 같은 출력을 얻는다 lg.eigs() 사용. 매트릭스는이 같은 커지면 하지만 ... 문제가 발생합니다 : MATLAB에서 우리는이 같은 일이있어

test_eigs.mat

:

>> [x,y] = eigs(A,B,4,'sm'); 
y = 

0.0001   0   0   0 
    0 0.0543   0   0 
    0   0 0.1177   0 
    0   0   0 0.1350 

동안 파이썬 (python3.5.2, scipy1을. 0.0)가 고유 값으로 결과를 사용 lg.eigs(A,M=B,k=4,which='SM') 폴 전차가 "eigsh"에서 "H"는약자 말했듯

array([ 4.43277284e+51 +0.00000000e+00j, 
    1.04797857e+48 +8.30096152e+47j, 
    1.04797857e+48 -8.30096152e+47j, -1.45582240e+31 +0.00000000e+00j]) 
+3

과잉의'h' 때문에 어쩌면? 나는 그것에 깊게 들여다 보지 않았지만'eigsh'는'A'가 대칭 적이거나 Hermitian 인 것을 요구합니다. 이것은'A'가 아닙니다. 그러나'scipy'도'eigs'를 가지고 있습니다. –

+0

또한,'eigsh()'와'eigs()'의 출력은 매번 무작위로 바뀝니다. 그건 내 프로그램에서 용납 할 수없는 일이다. –

+0

B는 수치 적으로 양의 값을 가지므로'sigma'가 필요합니다. – percusse

답변

2

, 매트릭스 A는 그렇지 않습니다. (또한 긍정적 인 고유치를 갖는 것은 양의 확증을 의미하지 않으며, 행렬이 처음에는 허물이있는 경우에만 해당됩니다.) eigsh 메서드는 허미 시안의 입력을 검사하지 않습니다. 그것은 단지 그것이 있다고 가정하는 과정을 따른다. 가정이 실패 할 때 산출은 부정확하다.

사용 eigs 방법은 matlab에 같은 결과를 얻게

물론
x, y = lg.eigs(a,M=b,k=2,which='SM') 
np.real(x), np.real(y) # x and y have tiny imaginary parts due to float math errors 

(array([ 0.02022333, 0.34993346]), 
array([[-0.00368007, -0.0140898 ], 
    [ 0.0056435 , 0.01509067], 
    [-0.00154725, 0.00790518], 
    [ 0.01170563, 0.06664118], 
    [ 0.02981777, -0.07528778]])) 

, eigseigsh 프로그램보다 훨씬 더 오래 걸립니다.


번째 예는 전혀 제로가없는, 34 밀도 의해 34 행렬이다. 희소 선형 대수학을 사용하는 것은 합리적이지 않습니다. 그 방법이 수렴하지 않았다는 경고가 나온다. 정규 선형 대수 모듈은 정상적으로 작동합니다.

import scipy.linalg as la 
sorted_eigenvals = np.sort(np.real(la.eigvals(Am, Bm))) 

이 반환

5.90947734e-05, 5.42521180e-02, 1.17669899e-01, 1.34952286e-01, ... MATLAB의 출력

계약

그 당신은 인용 (matlab에이 숫자를 반올림 제외)

0.0001, 0.0543, 0.1177, 0.1350

+0

고마워요 :)하지만 ... 큰 매트릭스 (34 * 34에서 1000 * 1000) 내 시나리오에서 다시 문제가 있습니다. 질문을 수정하고 원시 데이터 파일을 github에 업로드했습니다. 수표를받을 기회가 있으면 매우 감사 할 것입니다. 많은 감사합니다 :) –

+0

마침내 매트릭스를 테스트 할 시간이있었습니다. (팁 : 파이썬에서 데이터를 테스트 해보고 싶다면 Matlab 만 읽을 수있는 형식으로 표현하지 마십시오. CSV로 저장할 수 있습니다. 'csvwrite'와 함께). 대답에 대한 추가 내용을보십시오. – FTP