简体   繁体   English

如何在 Python 的 SciPy 中更改稀疏矩阵中的元素?

[英]How to change elements in sparse matrix in Python's SciPy?

I have built a small code that I want to use for solving eigenvalue problems involving large sparse matrices.我已经构建了一个小代码,我想用它来解决涉及大型稀疏矩阵的特征值问题。 It's working fine, all I want to do now is to set some elements in the sparse matrix to zero, ie the ones in the very top row (which corresponds to implementing boundary conditions).它工作正常,我现在要做的就是将稀疏矩阵中的一些元素设置为零,即最顶行中的元素(对应于实现边界条件)。 I can just adjust the column vectors (C0, C1, and C2) below to achieve that.我可以调整下面的列向量(C0、C1 和 C2)来实现这一点。 However, I wondered if there is a more direct way.但是,我想知道是否有更直接的方法。 Evidently, NumPy indexing does not work with SciPy's sparse package.显然,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()

This is a visualisation of the matrix that is build by the code above.这是由上述代码构建的矩阵的可视化。 I want so set the elements in the first row zero.我想将第一行中的元素设置为零。在此处输入图片说明

As suggested in the comments, I'll post the answer that I found to my own question. 正如评论中所建议的那样,我会在我自己的问题中找到答案。 There are several matrix classes in in SciPy's sparse package, they are listed here . SciPy的稀疏包中有几个矩阵类,它们在这里列出。 One can convert sparse matrices from one class to another. 可以将稀疏矩阵从一个类转换为另一个类。 So for what I need to do, I choose to convert my sparse matrix to the class csr_matrix, simply by 因此,对于我需要做的事情,我选择将我的稀疏矩阵转换为类csr_matrix,只需将其转换为

H = sp.csr_matrix(H)

Then I can set the elements in the first row to 0 by using the regular NumPy notation: 然后我可以使用常规的NumPy表示法将第一行中的元素设置为0:

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

For completeness, I post the full modified code snippet below. 为了完整起见,我发布了下面的完整修改后的代码段。

#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)

Using lil_matrix is much more efficient in scipy to change elements than simple numpy method.在 scipy 中使用lil_matrix比简单的numpy方法更有效地更改元素。

H = sp.csr_matrix(H)
HL = H.tolil()
HL[1,1] = 5  # same as the numpy indexing notation
print HL
print HL.todense() # if numpy style matrix is required
H = HL.tocsr()    # if csr is required

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM