Pickling scipy的SuperLU类用于不完整的LU分解

时间:2015-04-14 06:44:53

标签: python numpy scipy linear-algebra pickle

使用scipy.sparse.linalg.spilu,我计算了一个非常大的稀疏矩阵的不完整LU分解。由于这个过程非常耗时,我想保存计算出的LU分解。该函数返回一个scipy.sparse.linalg.SuperLU对象。

我的第一次尝试是使用pickle模块来保存整个对象。但是,我得到了一个:

cPickle.PicklingError: Can't pickle <type 'SuperLU'>:
   attribute lookup __builtin__.SuperLU failed

错误消息。

我的第二个想法是保存SuperLU对象('L', 'U', 'nnz', 'perm_c', 'perm_r', 'shape')的相关类成员,然后重新组装它。但是,SuperLU对象似乎是不可实例化的:

>>> SuperLU()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: cannot create 'SuperLU' instances

有人知道我如何将不完整的LU分解结果缓存到文件中吗?

2 个答案:

答案 0 :(得分:1)

最后,我按照ali_m的建议编写了自己的solve()函数。重构置换矩阵PrPc后,我可以将它们与LR一起转储,并拥有我需要的一切。我还填写了scipy的功能请求,希望在将来的版本中有更直接的选项。

答案 1 :(得分:0)

如果你能找到实际定义SuperLU类的地方,那么可以腌制......除非在 C 中定义SuperLU类 - 这是完全可能的。如果在 python 中定义了类,则可以使用dill模块对其进行pickle。如果它在 C 中,那么你就不会直接腌制该对象。

问题在于:

>>> import dill
>>> import scipy
>>> import scipy.sparse
>>> import scipy.sparse.linalg                       
>>> import numpy
>>> a = numpy.array([[1,2,2],[4,2,0],[2,0,0]])
>>> lu = scipy.sparse.linalg.splu(a)
>>> dill.detect.errors(lu)
PicklingError("Can't pickle <type 'SuperLU'>: it's not found as __builtin__.SuperLU",)
>>> lu
<SuperLU object at 0x106eb0360>
>>> lu.__class__ 
<type 'SuperLU'>
>>> lu.__class__.__module__
'__builtin__'

那你做什么?

我不确定这是完整的答案,但您可以转储构成SparseLU实例的稀疏矩阵。我可能会错过一些州,但这应该传达这个想法......

>>> dill.dumps(lu.L)
'\x80\x02cscipy.sparse.csc\ncsc_matrix\nq\x00)\x81q\x01}q\x02(U\x06formatq\x03U\x03cscq\x04U\x06_shapeq\x05K\x03K\x03\x86q\x06U\x06indptrq\x07cnumpy.core.multiarray\n_reconstruct\nq\x08cnumpy\nndarray\nq\tK\x00\x85q\nU\x01bq\x0b\x87q\x0cRq\r(K\x01K\x04\x85q\x0ecnumpy\ndtype\nq\x0fU\x02i4q\x10K\x00K\x01\x87q\x11Rq\x12(K\x03U\x01<q\x13NNNJ\xff\xff\xff\xffJ\xff\xff\xff\xffK\x00tq\x14b\x89U\x10\x00\x00\x00\x00\x01\x00\x00\x00\x03\x00\x00\x00\x04\x00\x00\x00q\x15tq\x16bU\x07indicesq\x17h\x08h\tK\x00\x85q\x18h\x0b\x87q\x19Rq\x1a(K\x01K\x04\x85q\x1bh\x12\x89U\x10\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\x02\x00\x00\x00q\x1ctq\x1dbU\x08maxprintq\x1eK2U\x04dataq\x1fh\x08h\tK\x00\x85q h\x0b\x87q!Rq"(K\x01K\x04\x85q#h\x0fU\x02f8q$K\x00K\x01\x87q%Rq&(K\x03U\x01<q\'NNNJ\xff\xff\xff\xffJ\xff\xff\xff\xffK\x00tq(b\x89U \x00\x00\x00\x00\x00\x00\xf0?\x00\x00\x00\x00\x00\x00\xf0?\x00\x00\x00\x00\x00\x00\xe0?\x00\x00\x00\x00\x00\x00\xf0?q)tq*bub.'
>>> dill.dumps(lu.U)
'\x80\x02cscipy.sparse.csc\ncsc_matrix\nq\x00)\x81q\x01}q\x02(U\x06formatq\x03U\x03cscq\x04U\x06_shapeq\x05K\x03K\x03\x86q\x06U\x06indptrq\x07cnumpy.core.multiarray\n_reconstruct\nq\x08cnumpy\nndarray\nq\tK\x00\x85q\nU\x01bq\x0b\x87q\x0cRq\r(K\x01K\x04\x85q\x0ecnumpy\ndtype\nq\x0fU\x02i4q\x10K\x00K\x01\x87q\x11Rq\x12(K\x03U\x01<q\x13NNNJ\xff\xff\xff\xffJ\xff\xff\xff\xffK\x00tq\x14b\x89U\x10\x00\x00\x00\x00\x01\x00\x00\x00\x03\x00\x00\x00\x06\x00\x00\x00q\x15tq\x16bU\x07indicesq\x17h\x08h\tK\x00\x85q\x18h\x0b\x87q\x19Rq\x1a(K\x01K\x06\x85q\x1bh\x12\x89U\x18\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00q\x1ctq\x1dbU\x08maxprintq\x1eK2U\x04dataq\x1fh\x08h\tK\x00\x85q h\x0b\x87q!Rq"(K\x01K\x06\x85q#h\x0fU\x02f8q$K\x00K\x01\x87q%Rq&(K\x03U\x01<q\'NNNJ\xff\xff\xff\xffJ\xff\xff\xff\xffK\x00tq(b\x89U0\x00\x00\x00\x00\x00\x00\x00@\x00\x00\x00\x00\x00\x00\xf0?\x00\x00\x00\x00\x00\x00\x10@\x00\x00\x00\x00\x00\x00\x00@\x00\x00\x00\x00\x00\x00\x00@\x00\x00\x00\x00\x00\x00\xf0\xbfq)tq*bub.'

显然,您希望使用dump代替dumps来挑选文件。您甚至可以使用numpy的内置序列化(泡菜较小),但我不知道。