从仅包含零的稀疏矩阵中有效删除列的最佳方法是什么.我有一个矩阵,我已经创建并填充了数据:
matrix = sp.sparse.lil_matrix((100, 100))
Run Code Online (Sandbox Code Playgroud)
我现在希望删除最后20列只包含零数据的列.我怎样才能做到这一点?
我有兴趣在有限域上n解析大(最多10 ^ 5甚至10 ^ 6)矩形(可能比行多10%的列)稀疏(每行<10非零)系统(可能是1000附近的素数或者所以).从文献来看,看起来块Lanczos方法可能是最合适的.Ax = bGF(q)q
我有Linbox应该有这样的方法,但是无法让BlockLanczos求解器在那里工作,并且有一份报告称自2003年以来已经破坏了.该SparseElimination方法确实有效,但似乎这不会很好n因为矩阵的填充而变大.
那么,有什么可用于解决这些问题呢?
我们有一个存储稀疏矩阵的应用程序.该矩阵具有主要存在于矩阵的主对角线周围的条目.我想知道是否有任何有效的算法(或现有的库)可以有效地处理这种稀疏矩阵?优选地,这将是通用实现,其中每个矩阵条目可以是用户定义的类型.
编辑以回答问题/回复:
当我主要围绕主对角线说我的意思是大多数矩阵的特征是大多数条目聚集在主对角线之外但是可能存在靠近对角线的零并且可能存在远离的非零值对角线.我想要一些有效的"大多数"案例.
我将用它做什么?我需要能够有效地访问一行中的所有值或列中的所有值.存储的值将是布尔值.一个例子是:
这些都是先前使用链接列表完成的,但实现起来非常混乱.我希望用稀疏矩阵可以改进算法但是找到"正确"类型的稀疏矩阵算法已经证明是困难的.
ps感谢迄今为止的回复
我正在使用ublas :: Compressed Matrix来处理稀疏线性求解器UMFPACK.由于我正在进行模拟,所以每次线性系统的构造都略有不同,可能涉及扩大/缩小系数矩阵和一些稀疏矩阵乘法.线性系统的规模约为25k.
即使有一个绑定补丁用于增强与UMFPACK一起工作,我仍然需要不时更改矩阵,有时甚至计算非零值的数量将是耗时的(理想情况下,我必须给出数字当我初始化矩阵时的非零值).另外,我使用ublas :: range动态追加列/行.
所以我的问题是:有没有有效的方法来做到这一点?现在对我来说太慢了.转换尺寸为15k的矩阵成本接近6s并且附加大约12k行是很快的(因为我猜它是行主矩阵),但是向矩阵添加相同数量的列可能花费多达20s(我想同样的如上所述,所以即使我使用了列主矩阵,所需的总时间也是相同的).
有点在这里绝望.任何建议都是受欢迎的.
干杯.
我试图用C++计算一个非常大的矩阵(11300x21500)的逆.到目前为止,我已经尝试了Eigen和Armadillo库,但都在初始化阶段失败,说没有足够的内存.有没有办法克服这种情况?
提前致谢
PS
我应该将矩阵的大小更正为21500x21500.正如UmNyobe所说,这不是方阵.它实际上是观察矩阵X,我试图计算(X T X)-1
我有一个8GB内存(在64位系统中),但我不认为我正在利用所有这些内存空间.任务管理器显示错误时的内存使用量为1GB.也许Windows7中有一个操作系统命令可以在内存使用量超过1GB时关闭应用程序.
顺便说一句,我最初的目的是对这个观察矩阵进行回归.
还有一件事:观察矩阵X的每一行中的大多数列都是零.有没有办法利用这个,限制反相操作中的内存使用?
我有兴趣将我的Matlab实现移植到C++中以提高速度.我试过犰狳.它非常适合从Matlab移植代码,因为Armadillo的库函数名称/语法非常接近于Matlab编程.然而我意识到在某些地方,Matlab会执行犰狳,因为我的数据主要是稀疏的,而犰狳并没有给它任何特殊的处理,只是把它当作密集的矩阵.Armadillo团队正在研究稀疏矩阵支持,但目前还没有.所以我正在寻找一个像Armadillo一样的库,它的语法非常接近Matlab(或者易于使用),并且支持稀疏矩阵用于速度和空间优化.
我有一个稀疏矩阵类,它的非零和相应的列索引按行顺序存储在基本上类似STL-vector的容器中.他们可能有未使用的容量,如矢量; 要插入/删除元素,必须移动现有元素.
说我有手术insert_erase_replace,或ier简称.ier给定位置p,列索引j和值,可以执行以下操作v:
v==0,ier删除条目p并左移所有后续条目.v!=0和j已经存在的p,ier在替换单元格内容p有v.v!=0,并且j不存在p,ier则在右移所有后续条目后插入条目v和列索引.jp所以这一切都是微不足道的.
现在让我说我有ier2,它做了同样的事情,除了它采用包含多个列索引j和相应值的列表v.它还有一个大小n,表示列表中存在多少个索引/值对.但由于向量仅存储非零,有时实际插入大小小于n.
仍然微不足道.
但现在让我说我有ier3,不仅仅是一个列表ier2,而是多个列表.这表示编辑稀疏矩阵的切片.
在某些时候,迭代遍历向量,逐个复制它们并ier2在我们到达每个插入点时插入/替换/删除列表索引/值- 样式变得更有效.如果总插入大小会导致我的向量无论如何都需要调整大小,那么我们就这样做了.
鉴于我的向量比列表的总长度大得多,是否有一种算法可以有效地将列表合并到向量中?
到目前为止,这就是我所拥有的:
传递给每个列表ier3表示条目的净删除(左移),净替换(没有移动,因此便宜)或条目的净插入(右移).那里可能还有一些元素的重新安排,但昂贵的部分是净删除和净插入.
要弄清楚有效地进行网络插入或净删除的算法并不难.
当两者中的任何一个发生时,它会更难.
我唯一能想到的就是两次通过:
我正在尝试使用glmnet创建一个模型,(目前使用cv来查找lambda值),我收到一个错误NA/NaN/Inf in foreign function call (arg 5).我相信这与我的数据集中的NA值有关,因为当我用NA删除所有数据点时,命令成功运行.
我的印象是glmnet 可以处理NA值.我不确定错误来自哪里:
> res <- cv.glmnet(features.mat, as.factor(tmp[,"outcome"]), family="binomial")
Error in lognet(x, is.sparse, ix, jx, y, weights, offset, alpha, nobs, :
NA/NaN/Inf in foreign function call (arg 5)
Run Code Online (Sandbox Code Playgroud)
数据集看起来像这样:
> head(features.mat)
6 x 8 sparse Matrix of class "dgCMatrix"
a b c e f g h i
1 1 1 138 NA NA 15 NA .
4 1 3 171 NA NA 17 NA .
7 1 1 156 NA NA …Run Code Online (Sandbox Code Playgroud) 我正在a**16使用scipy-0.17 进行简单的稀疏矩阵求幂.(注意,不是逐元素乘法).但是,在我的机器上(运行Debian stable和Ubuntu LTS),这比使用for循环或做一些愚蠢的事情慢十倍a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a.这没有意义,所以我假设我做错了什么,但是什么?
import scipy.sparse
from time import time
a=scipy.sparse.rand(2049,2049,.002)
print ("Trying exponentiation (a**16)")
t=time()
x=a**16
print (repr(x))
print ("Exponentiation took %f seconds\n" % (time()-t))
print ("Trying expansion (a*a*a*...*a*a)")
t=time()
y=a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a
print (repr(y))
print ("Expansion took %f seconds\n" % (time()-t))
print ("Trying a for loop (z=z*a)")
t=time()
z=scipy.sparse.eye(2049)
for i in range(16):
z=z*a
print (repr(z))
print ("Looping took %f seconds\n" % (time()-t))
# Sanity check, all approximately the same answer, right?
assert (abs(x-z)>=1e-9).nnz==0 …Run Code Online (Sandbox Code Playgroud) 我有一个pytorch稀疏张量,我需要切片行/列使用此切片[idx][:,idx],其中idx是索引列表,使用提到的切片在普通浮点张量上产生我想要的结果.是否可以在稀疏张量上应用相同的切片?这里的例子:
#constructing sparse matrix
i = np.array([[0,1,2,2],[0,1,2,1]])
v = np.ones(4)
i = torch.from_numpy(i.astype("int64"))
v = torch.from_numpy(v.astype("float32"))
test1 = torch.sparse.FloatTensor(i, v)
#constructing float tensor
test2 = np.array([[1,0,0],[0,1,0],[0,1,1]])
test2 = autograd.Variable(torch.cuda.FloatTensor(test2), requires_grad=False)
#slicing
idx = [1,2]
print(test2[idx][:,idx])
Run Code Online (Sandbox Code Playgroud)
输出:
Variable containing:
1 0
1 1
[torch.cuda.FloatTensor of size 2x2 (GPU 0)]
Run Code Online (Sandbox Code Playgroud)
我持有250.000 x 250.000邻接矩阵,我需要使用随机idx 对n行和n列进行切片,只需对n随机idx进行采样.由于数据集太大,转换为更方便的数据类型是不现实的.
我可以在test1上实现相同的切片结果吗?它甚至可能吗?如果没有,是否有任何解决方法?
现在我正在使用以下"hack"解决方案来运行我的模型:
idx = sorted(random.sample(range(0, np.shape(test1)[0]), 9000))
test1 = test1AsCsr[idx][:,idx].todense().astype("int32")
test1 = autograd.Variable(torch.cuda.FloatTensor(test1), requires_grad=False)
Run Code Online (Sandbox Code Playgroud)
test1AsCsr是我的test1转换为numpy CSR矩阵的地方.这个解决方案有效,但速度非常慢,并且使我的GPU利用率非常低,因为它需要不断地从CPU内存中读/写.
编辑:结果很好,非稀疏张量