julia、sparsearrays、CSC 格式

问题描述 投票:0回答:1

我正在尝试直接以 csc 格式创建稀疏矩阵。这是因为我可以重复使用我编写的数组,预先分配它们并在其中创建@view。

但是,如果我使用@view,它会给出错误,而如果我离开简单的切片,它会起作用。

N::Int32 = 4
m::Int32 = 2
nzval_Sz = Array{Int8}(undef, N)
nzval_Sz[1] = 1
nzval_Sz[2] = -1
rowval_Sz = Array{Int32}(undef, N)
rowval_Sz[1] = 1
rowval_Sz[2] = 2
colptr_Sz = Array{Int32}(undef, N+1)
colptr_Sz[1] = 1
colptr_Sz[2] = 2
colptr_Sz[3] = 3 #last one is tot_nnz+1

sparsematrix = SparseMatrixCSC(m, m, colptr_Sz[1:m+1], rowval_Sz[1:m], nzval_Sz[1:m])

我确定它没有复制数据吗? (这非常重要,因为进行预分配是因为我需要迭代很多克罗内克乘积,它将成为一个非常大的切片,直到它覆盖一个非常大的矩阵)

julia slice sparse-matrix
1个回答
0
投票

如果您查看 Julia 中稀疏数组的实现方式,您会注意到仅接受

Vector
(这是来自 https://github.com/JuliaSparse/SparseArrays.jl/blob/main/src/sparsematrix 的代码。 jl):

struct SparseMatrixCSC{Tv,Ti<:Integer} <: AbstractSparseMatrixCSC{Tv,Ti}
    m::Int                  # Number of rows
    n::Int                  # Number of columns
    colptr::Vector{Ti}      # Column i is in colptr[i]:(colptr[i+1]-1)
    rowval::Vector{Ti}      # Row indices of stored values
    nzval::Vector{Tv}       # Stored values, typically nonzeros
    ...

这意味着在某些时候需要转换为

Vector
。 唯一的非分配选项是
resize!
你的向量,这可能意味着可重用性问题:

resize!(colptr_Sz, m) # non allocating

但是,您可以轻松地实现自己的 SparseMatrixCSC 实现。或多或少类似于:

struct FlexiSparseMatrixCSC{Tv, Ti<:Integer, Vi<:AbstractVector{Ti}, Vv<:AbstractVector{Tv}} <: SparseArrays.AbstractSparseMatrixCSC{Tv,Ti}
    m::Int                 
    n::Int                 
    colptr::Vi 
    rowval::Vi
    nzval::Vv
    ...

现在基本上您需要做的是从 SparseArrays 复制大部分代码,这应该可以很好地与视图配合使用。

甚至更快的是拥有一个

FlexiSparseMatrixCSC
,它宁愿有一个额外的参数,只是裁剪大小(不使用视图 - 只是传递太大的向量),但这很可能需要对代码进行更大的重写。

© www.soinside.com 2019 - 2024. All rights reserved.