我读了这篇文章,我也有类似的问题。我想要就地多次更新稀疏矩阵,在我看来,SparseArrays.sparse!
是我最好的选择。但是,我不太理解文档,它说我可以调用
sparse!(I, J, V, csrrowptr, csrcolval, csrnzval, I, J, V)
我的问题是:
- 第一套
I, J, V
是什么 - 第二组
I, J, V
是什么 - 假设我已经创建了一个矩阵
A = sparse(I,J,V)
,我想就地更新A
。我怎样才能得到csrrowptr, csrcolval, csrnzval
?A
默认是CSC格式,而不是CSR。 - 我可以得到
sparse!
的工作示例吗?
谢谢。
看了文档后,它绝对感觉(并且确实是)SparseArrays的一个包内部函数。无论如何,根据你的问题(不分先后):
Q4(最简单的)在REPL中执行@edit sparse([1,2,3],[1,2,3],[5,6,7])
,并在编辑的文件中搜索sparse!
,这将显示sparse
如何在内部使用sparse!
。
Q1第一个I, J, V
是输入,给出通常的列索引、行索引和值。注意,这些不是结果矩阵的内部CSC存储向量。
Q2第二个I, J, V
是在得到的稀疏矩阵中用作内部CSC存储向量的数组。由于在sparse!
调用之后输入是不必要的,而不是释放输入和分配内部CSC向量,输入内存向量可以被重用(I, J, K
以外的其他向量可以作为输出传递,特别是当输入向量的内存太少而无法保存CSC表示时)。
Q3获得sparse!
内部创建的CSR-ish表示很容易-它们在您作为csrrowptr, csrcolval, csrnzval
传递的矢量中。向量需要有足够的内存,并由sparse!
填充。
sparse!
的全部要点是不进行分配/释放。内存管理是由"父"接口(在本例中为sparse
)完成的。这允许在已经分配内存或从另一个变量回收内存时直接进行非分配处理。
它花了一些时间,但这里是sparse!
使用的演示:
julia> I = sizehint!([1,2,3,1], 5)
4-element Vector{Int64}:
1
2
3
1
julia> J = sizehint!([3, 2, 1, 2], 5)
4-element Vector{Int64}:
3
2
1
2
julia> V = sizehint!([6,7,8,9],5)
4-element Vector{Int64}:
6
7
8
9
现在为sparse!
设置工作内存:
julia> my_klasttouch = Vector{Int}(undef, 10);
julia> my_csrrowptr = Vector{Int}(undef, 10);
julia> my_csrcolval = Vector{Int}(undef, 10);
julia> my_csrnzval = Vector{Int}(undef, 10);
最后:
julia> M = SparseArrays.sparse!(
I, J, V, 3, 3, +,
my_klasttouch, my_csrrowptr, my_csrcolval, my_csrnzval,
I, J, V
)
3×3 SparseMatrixCSC{Int64, Int64} with 4 stored entries:
⋅ 9 6
⋅ 7 ⋅
8 ⋅ ⋅
查看输入内存如何成为返回对象的一部分:
julia> M.colptr # this is from returned object
4-element Vector{Int64}:
1
2
4
5
julia> I
4-element Vector{Int64}:
1
2
4
5
注意I
和M.colpotr
使用相同的内存。
鉴于上述情况,我建议,在使用这个函数之前,先浏览一下实现代码并仔细理解算法。