使用`scipy.sparse`构造一个简单的线性系统

时间:2014-05-03 00:21:44

标签: python numpy scipy sparse-matrix

想象一个简单的3x3矩阵,我在其上施加以下“边界条件”。下面是一个数组,显示相应的索引(如果被展平)和边界值。

I =     B = 
0 3 6   3 0 1
1 4 7   3 0 1
2 5 8   3 0 1

很容易看出展平的边界值数组是

b = 
3 3 3 0 0 0 1 1 1

我还有一个连接结构C,以一组对的形式给出,

C = 
0 0 1 1 2 3 3 4 4 5 6 7
1 3 2 4 5 4 6 5 7 8 6 8

我想构建一个代表这个线性系统的矩阵A,使用spsolve(A, b)得到

A =
 1  0  0  0  0  0  0  0  0
 0  1  0  0  0  0  0  0  0
 0  0  1  0  0  0  0  0  0
 1  0  0 -3  1  0  1  0  0
 0  1  0  1 -4  1  0  1  0
 0  0  1  0  1 -3  0  0  1
 0  0  0  0  0  0  1  0  0
 0  0  0  0  0  0  0  1  0
 0  0  0  0  0  0  0  0  1

x = 
3 3 3 2 2 2 1 1 1

使用numpy和操作密集矩阵,清零列等等非常简单。然而,随着矩阵变大,我开始耗尽内存并且解算器非常慢。

我以为我会用这个逻辑构建我的稀疏矩阵:

  1. 使用连接数组和np.ones_like其中一个向量
  2. 初始化矩阵
  3. 添加矩阵及其转置以填充LD区域
  4. 其中b非零:擦除行并在对角线上放置1(这表示初始条件)
  5. 其中b为零:对axis=1的矩阵求和,并将总和的负值放入每个对角线(这会平衡汇和源)
  6. 这在numpy中完美无缺,但我发现在初始化它们之后,对sparse矩阵做任何有用的事情是绝对不可能的。他们不处理项目删除,转置等。我可以了解这些操作吗?

1 个答案:

答案 0 :(得分:1)

我想我到目前为止还没有这个

似乎有些模糊不清,就像我做错了一样

b = np.array([3, 3, 3, 0, 0, 0, 1, 1, 1])
i = (0, 0, 1, 1, 2, 3, 3, 4, 4, 5, 6, 7)
j = (1, 3, 2, 4, 5, 4, 6, 5, 7, 8, 7, 8)

f = b!=0
A = sparse.lil_matrix((b.size, b.size))
A[f,f] = 1
C = sparse.coo_matrix((np.ones_like(i+j), (i+j,j+i)), shape=(b.size, b.size)).tolil()
D = sparse.diags(np.asarray(C.sum(axis=1).T)[0], 0).tocsr()
A[~f,:] = C[~f, :] - D[~f]

print A.toarray()