web-dev-qa-db-ja.com

PythonのSciPyでスパース行列の要素を変更するにはどうすればよいですか?

大きなスパース行列を含む固有値問題を解くために使用したい小さなコードを作成しました。これは正常に機能しています。ここで実行したいのは、スパース行列の一部の要素をゼロに設定することです。つまり、一番上の行の要素(境界条件の実装に対応)です。これを実現するには、以下の列ベクトル(C0、C1、およびC2)を調整するだけです。しかし、もっと直接的な方法があるのではないかと思いました。明らかに、NumPyインデックスはSciPyのスパースパッケージでは機能しません。

import scipy.sparse as sp
import scipy.sparse.linalg  as la
import numpy as np
import matplotlib.pyplot as plt

#discretize x-axis
N = 11
x = np.linspace(-5,5,N)
print(x)
V = x * x / 2
h = len(x)/(N)
hi2 = 1./(h**2)
#discretize Schroedinger Equation, i.e. build 
#banded matrix from difference equation
C0 = np.ones(N)*30. + V
C1 = np.ones(N) * -16.
C2 = np.ones(N) * 1.
diagonals = np.array([-2,-1,0,1,2])
H = sp.spdiags([C2, C1, C0,C1,C2],[-2,-1,0,1,2], N, N)
H *= hi2 * (- 1./12.) * (- 1. / 2.)
#solve for eigenvalues
EV = la.eigsh(H,return_eigenvectors = False)

#check structure of H
plt.figure()
plt.spy(H)
plt.show()

これは、上記のコードによって構築されたマトリックスの視覚化です。最初の行の要素をゼロに設定したいのです。enter image description here

18
seb

コメントで示唆されているように、私は自分の質問に見つけた答えを投稿します。 SciPyのスパースパッケージにはいくつかの行列クラスがあり、それらはリストされています ここ 。スパース行列をあるクラスから別のクラスに変換できます。したがって、私がする必要があることのために、私はスパース行列をクラスcsr_matrixに変換することを選択します。

H = sp.csr_matrix(H)

次に、通常のNumPy表記を使用して、最初の行の要素を0に設定できます。

H[0,0] = 0
H[0,1] = 0
H[0,2] = 0

完全を期すために、変更された完全なコードスニペットを以下に投稿します。

#SciPy Sparse linear algebra takes care of sparse matrix computations
#http://docs.scipy.org/doc/scipy/reference/sparse.linalg.html
import scipy.sparse as sp
import scipy.sparse.linalg  as la

import numpy as np
import matplotlib.pyplot as plt

#discretize x-axis
N = 1100
x = np.linspace(-100,100,N)
V = x * x / 2.
h = len(x)/(N)
hi2 = 1./(h**2)

#discretize Schroedinger Equation, i.e. build 
#banded matrix from difference equation
C0 = np.ones(N)*30. + V
C1 = np.ones(N) * -16.
C2 = np.ones(N) * 1.

H = sp.spdiags([C2, C1, C0, C1, C2],[-2,-1,0,1,2], N, N)
H *= hi2 * (- 1./12.) * (- 1. / 2.)
H = sp.csr_matrix(H)
H[0,0] = 0
H[0,1] = 0
H[0,2] = 0

#check structure of H
plt.figure()
plt.spy(H)
plt.show()

EV = la.eigsh(H,return_eigenvectors = False)
22
seb