【发布时间】:2019-12-10 10:20:23
【问题描述】:
总结:我正在寻找一种方法来使用稀疏矩阵进行计算,其非零条目不是通常的整数/浮点数/等,而是代数的元素,即具有加法、乘法和零元素的非标准 python 类。
它适用于密集矩阵。我已经通过定义一个 python 类 algebra 并重载加法和乘法来实现这个代数:
class algebra(object):
...
__mul__(self,other):
...
__add__(self,other):
...
numpy 允许我定义向量和矩阵,其条目是类algebra 的实例。它还允许我执行所有常用操作,如矩阵乘法/加法/张量点/切片/等,因此它的工作原理与整数/浮点数/等上的矩阵一样。
它不适用于稀疏矩阵。
为了加快计算速度,我现在想用稀疏矩阵替换这些密集矩阵。我试图用 SciPy 的二维稀疏矩阵包scipy.sparse 来完成这项工作,但到目前为止我失败了。我可以通过我的代数元素填充这些稀疏矩阵类的实例,但是每当我对它们进行计算时,我都会收到一条错误消息,例如
TypeError: no supported conversion for types: (dtype('O'),dtype('O'))
对我来说,这表明scipy.sparse 支持的对象类型存在限制。我看不出为什么稀疏矩阵的运算应该关心对象类型的任何数学原因。比如说,只要该类具有浮点数的所有操作,它就应该可以工作。我错过了什么?有没有支持任意对象类型的scipy.sparse 的替代品?
下面是一个最小的工作示例。请注意,我已经用通常的整数 0 实现了代数的零元素。还请注意,我感兴趣的实际代数比实整数更复杂!
import numpy as np
from scipy.sparse import csr_matrix
class algebra(object): # the algebra of the real integers
def __init__(self,num):
self.num = num
def __add__(self,other):
if isinstance(other, self.__class__):
return algebra(self.num+other.num)
else:
return self
def __radd__(self,other):
if isinstance(other, self.__class__):
return algebra(self.num+other.num)
else:
return self
def __mul__(self,other):
if isinstance(other, self.__class__):
return algebra(self.num*other.num)
else:
return 0
def __rmul__(self,other):
if isinstance(other, self.__class__):
return algebra(self.num*other.num)
else:
return 0
def __repr__(self):
return "algebra:"+str(self.num)
a=algebra(5)
print(a*a)
print(a*0)
print(0*a)
indptr = np.array([0, 2, 3, 6])
indices = np.array([0, 2, 2, 0, 1, 2])
data = np.array([a,a,a,a,a,a])
S = csr_matrix((data, indices, indptr), shape=(3, 3))
print(S)
print("Everything works fine up to here.")
S*S
输出是:
algebra:25
0
0
(0, 0) algebra:5
(0, 2) algebra:5
(1, 2) algebra:5
(2, 0) algebra:5
(2, 1) algebra:5
(2, 2) algebra:5
Everything works fine up to here.
Traceback (most recent call last):
File "test", line 46, in <module>
S*S
File "/usr/lib/python3/dist-packages/scipy/sparse/base.py", line 319, in __mul__
return self._mul_sparse_matrix(other)
File "/usr/lib/python3/dist-packages/scipy/sparse/compressed.py", line 499, in _mul_sparse_matrix
data = np.empty(nnz, dtype=upcast(self.dtype, other.dtype))
File "/usr/lib/python3/dist-packages/scipy/sparse/sputils.py", line 57, in upcast
raise TypeError('no supported conversion for types: %r' % (args,))
TypeError: no supported conversion for types: (dtype('O'), dtype('O'))
我在 Linux 上使用 Python 3.5.2。
【问题讨论】:
标签: python numpy scipy sparse-matrix