我可以直接创建矩阵 C 为(其中元素 0、A、B 是 2X2 矩阵)
[ 0 A 0 0 0 0 ... 0 0
B 0 A 0 0 0 ... 0 0
0 B 0 A 0 0 ... 0 0
0 0 B 0 A 0 .... 0 0
..........
0 0 0 0 0 .... B 0]
其中 0 是由零组成的 2X2 矩阵,A、B 被赋予 2X2 矩阵(分别沿着上对角线和下对角线放置),矩阵 C 的大小为 2JX2J
但是,我突然想到,直接使用稀疏矩阵表示法,然后使用类似 (with J = 5) 的方法设置非零元素可能会更有效
def TheMatrix(J,alpha):
A = [[0.5, alpha],[ alpha,0.5]]
B =[[0.5,-alpha],[-alpha,0.5]]
upperDiag = A*np.ones(J-1)
lowerDiag = B*np.ones(J-1)
diagonals = [upperDiag, lowerDiag] # non-zero diagonals
ASparse = sps.diags(diagonals,offsets=[1, -1])
ASparse = sps.csc_matrix(ASparse)
然而,这似乎不起作用。有人对如何进行有任何建议吗?详细来说,报告的错误(对于 J =5 的情况)是
File "myprg.py", line 16, in TheMatrix(J,alpha)
upperDiag = A*np.ones(J-1)
~^~~~~~~~~~~~~
ValueError: operands could not be broadcast together with shapes (2,2) (5,)
所以,我知道需要以某种方式将 np.ones(J-1) 替换为使其与 A、B 兼容的东西,B 是 2X2 矩阵而不是标量。
我包含以下内容,以防对其他人有帮助:为了创建稀疏矩阵,我采纳了 delfstack
的评论因为稀疏矩阵是非零元素的位置和值的列表,所以可以直接接受稀疏矩阵可以从这些信息形成,并且 delfstack 展示了它如何与输入矩阵“Ain”一起工作
Ain = np.array([[16, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 5], [0, 0, 0, 0]])
delfstack 建议
Asparse = [] # initialise Asparse to the empty element
rows, cols = Ain.shape # the input matrix
for i in range(rows):
for j in range(cols):
if Ain[i][j] != 0: # identify the non-zero elements
triplet = [i, j, Ain[i][j]]
Asparse.append(triplet) # append to update Asparse
(在我的示例中,我实际上并未创建矩阵 A)。
这似乎大部分有效,但是当我开始通过重建原始矩阵来检查结果时,我确实遇到了一个意想不到的问题。这让我很困惑,直到我开始打印数据。当我打印出一个特定的三元组时,它给出了结果
triplet = [0, 0, np.int64(16)]
将 np.int64(16) 添加到 0 时出现问题。为了克服这个问题,我必须进行一些小的更改
triplet = [i, j, Ain[i][j]]
triplet = list(map(int,triplet))
Asparse.append(triplet)
导致
triplet = [0, 0, 16]
这似乎有效。
添加注释:不知道为什么,但今天尝试一下,代码现在似乎无需更改即可工作。
为了完整起见,我使用以下命令运行程序
sys version 3.11.9 (tags/v3.11.9:de54cf5, Apr 2 2024, 10:12:12) [MSC v.1938 64 bit (AMD64)]
python version 3.11.9
numpy version 2.0.0
scipy version 1.14.0