首页 > 解决方案 > 如何遍历稀疏矩阵和普通矩阵的所有非零值

问题描述

我正在使用 Julia,我想迭代矩阵的值。该矩阵可以是普通矩阵或稀疏矩阵,但我没有这方面的先验知识。我想创建一个适用于两种情况并针对两种情况进行优化的代码。

为简单起见,我做了一个计算向量总和乘以随机值的示例。我想要做的实际上与此类似,但不是乘以随机数实际上是一个需要很长时间来计算的函数。

myiterator(m::SparseVector) = m.nzval
myiterator(m::AbstractVector) = m

function sumtimesrand(m)
   a = 0.
   for i in myiterator(m)
      a += i * rand()
   end
   return a
end


I = [1, 4, 3, 5]; V = [1, 2, -5, 3];
Msparse = sparsevec(I,V)
M = rand(5)
sumtimesrand(Msparse)
sumtimesrand(M)

我希望我的代码以这种方式工作。即大部分代码是相同的,并且通过使用正确的迭代器,代码针对两种情况(稀疏和法线向量)进行了优化。

我的问题是:是否有任何迭代器可以实现我想要实现的目标?在这种情况下,迭代器返回值,但索引上的迭代器可以工作。

干杯,迪伦

标签: iteratorjuliasparse-matrix

解决方案


我想你几乎得到了你要的东西?即,将您的AbstractVectorand更改SparseVectorAbstractArrayand AbstractSparseArray。但也许我错过了什么?请参阅下面的 MWE:

using SparseArrays
using BenchmarkTools # to compare performance

# note the changes here to "Array":
myiterator(m::AbstractSparseArray) = m.nzval
myiterator(m::AbstractArray) = m

function sumtimesrand(m)
   a = 0.
   for i in myiterator(m)
      a += i * rand()
   end
   return a
end

N = 1000
spV = sprand(N, 0.01); V = Vector(spV)
spM = sprand(N, N, 0.01); M = Matrix(spM)

@btime sumtimesrand($spV); #  0.044936 μs
@btime sumtimesrand($V);   #  3.919    μs

@btime sumtimesrand($spM); # 0.041678 ms
@btime sumtimesrand($M);   # 4.095    ms

推荐阅读