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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15896588/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-18 21:19:21  来源:igfitidea点击:

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

pythonmathlinear-algebrasparse-matrix

提问by seb

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, i.e. 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. However, I wondered if there is a more direct way. Evidently, NumPy indexing does not work with SciPy's sparse package.

我已经构建了一个小代码,我想用它来解决涉及大型稀疏矩阵的特征值问题。它工作正常,我现在想要做的就是将稀疏矩阵中的一些元素设置为零,即最顶行中的元素(对应于实现边界条件)。我可以调整下面的列向量(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()

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.enter image description here

这是由上述代码构建的矩阵的可视化。我想将第一行中的元素设置为零。在此处输入图片说明

采纳答案by seb

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. 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

正如评论中所建议的,我将发布我对自己的问题找到的答案。SciPy 的 sparse 包中有几个矩阵类,它们在此处列出。可以将稀疏矩阵从一类转换为另一类。所以对于我需要做的事情,我选择将我的稀疏矩阵转换为类 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)