0

我正在使用 sympy 构建稀疏 (N^2 x N^2) 矩阵并尝试将其转换为稀疏 scipy 矩阵。它用于有限差分法中求解二维网格上的薛定谔方程,具体取决于 k 向量 k = (kx, ky)。

密集矩阵到 SciPy

我目前的方法是使用lambdify从一个sympy矩阵A创建函数B,它为某个k向量提供一个有限差分矩阵,我将其转换为稀疏矩阵M。

N = 80
kx, ky = sp.symbols('kx ky')

A = dill.load(open("./A_{0}".format(N), "rb"))

B = sp.lambdify([kx, ky], A)

M = sparse.csc_matrix(B(1,0))

dill.dump(B, open("./B_{0}".format(N), "wb"))

我的问题是,一旦 N >= 80,lambdify 就会出现内存溢出错误(超过 32 GB),并且 lambdify 进程被终止。

Lambdify 稀疏 Sympy 矩阵

或者,我想直接为 lambdify 提供一个稀疏矩阵,但我不知道 sympy 正在创建哪种类型的稀疏矩阵......

B = sp.lambdify([kx, ky], sp.SparseMatrix(A))
M = B(1,0)

...并尝试在行中评估 BM = B(1,0)会导致错误

File "<lambdifygenerated-1>", line 2, in _lambdifygenerated
TypeError: __init__() got multiple values for argument 'shape'

我正在使用 Python 3.7.6、sympy 1.6 和 scipy 1.4.1

4

1 回答 1

0

虽然我已经做了很多工作,但scipy.sparse我以前没有使用sy.SparseMatrix过。查看文档,我可以制作一个简单的文档(在isympy会话中):

In [4]: A = SparseMatrix(4,4, {(1,1): x, (3,3):y})                              

In [5]: A                                                                       
Out[5]: 
⎡0  0  0  0⎤
⎢          ⎥
⎢0  x  0  0⎥
⎢          ⎥
⎢0  0  0  0⎥
⎢          ⎥
⎣0  0  0  y⎦

In [6]: B=lambdify([x,y], A)                                                    

In [7]: B                                                                       
Out[7]: <function _lambdifygenerated(x, y)>

In [10]: M=B(10,20)                                                             
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-10-442f4a9e4340> in <module>
----> 1 M=B(10,20)

<lambdifygenerated-1> in _lambdifygenerated(x, y)
      1 def _lambdifygenerated(x, y):
----> 2     return (coo_matrix([x, y], ([1, 3], [1, 3]), shape=(4, 4)))

TypeError: __init__() got multiple values for argument 'shape'

所以我收到了你的错误信息。并且清楚地表明它试图创建什么样的稀疏矩阵。你没看到吗?我很想在这一点上停下来,因为你显然持有有价值的信息!

===

B.__doc__

Created with lambdify. Signature:

func(x, y)

Expression:

Matrix([[0, 0, 0, 0], [0, x, 0, 0], [0, 0, 0, 0], [0, 0, 0, y]])

Source code:

def _lambdifygenerated(x, y):
    return (coo_matrix([x, y], ([1, 3], [1, 3]), shape=(4, 4)))

这就是回溯显示的内容。显然它正在尝试制作一个sparse.coo_matrix. 但是有一个错误,缺少(). 设置矩阵的正确方法是:

In [11]: from scipy import sparse                                               
In [14]: sparse.coo_matrix(([x,y],([1,3], [1,3])), shape=(4,4))                 
Out[14]: 
<4x4 sparse matrix of type '<class 'numpy.object_'>'
    with 2 stored elements in COOrdinate format>

In [15]: print(_)                                                               
  (1, 1)    x
  (3, 3)    y

B我对with symbolic xand无能为力y(甚至没有将其显示为密集)。

x但是如果我把它放在一个函数中,我可以为and提供数值数值y

In [16]: def foo(x,y): 
    ...:     return sparse.coo_matrix(([x,y],([1,3], [1,3])), shape=(4,4)) 
    ...:                                                                        

In [17]: foo(10,20).A                                                           
Out[17]: 
array([[ 0,  0,  0,  0],
       [ 0, 10,  0,  0],
       [ 0,  0,  0,  0],
       [ 0,  0,  0, 20]])

所以SparseMatrixlambdify是错误的。我不会尝试建议修复。

于 2020-06-23T22:09:54.920 回答