稀疏陣列
Julia 在 SparseArrays
stdlib 模組中支援稀疏向量和 稀疏矩陣。稀疏陣列是包含大量零的陣列,與稠密陣列相比,將它們儲存在特殊資料結構中可節省空間和執行時間。
可在 值得注意的外部套件 中找到實作不同稀疏儲存類型、多維稀疏陣列等功能的外部套件。
壓縮稀疏欄 (CSC) 稀疏矩陣儲存
在 Julia 中,稀疏矩陣儲存在 壓縮稀疏欄 (CSC) 格式 中。Julia 稀疏矩陣的類型為 SparseMatrixCSC{Tv,Ti}
,其中 Tv
是儲存值的類型,而 Ti
是用於儲存欄指標和列索引的整數類型。SparseMatrixCSC
的內部表示如下:
struct SparseMatrixCSC{Tv,Ti<:Integer} <: AbstractSparseMatrixCSC{Tv,Ti}
m::Int # Number of rows
n::Int # Number of columns
colptr::Vector{Ti} # Column j is in colptr[j]:(colptr[j+1]-1)
rowval::Vector{Ti} # Row indices of stored values
nzval::Vector{Tv} # Stored values, typically nonzeros
end
壓縮稀疏欄儲存讓存取稀疏矩陣中欄的元素變得容易且快速,但透過列存取稀疏矩陣的速度則會慢得多。在 CSC 結構中逐一插入先前未儲存的條目的操作往往很慢。這是因為稀疏矩陣中所有超出插入點的元素都必須向後移動一個位置。
稀疏矩陣上的所有操作都經過仔細實作,以利用 CSC 資料結構來提升效能,並避免昂貴的操作。
如果您有來自不同應用程式或函式庫的 CSC 格式資料,並希望將其匯入 Julia,請務必使用從 1 開始的索引。每個欄位的列索引需要排序,否則矩陣將顯示不正確。如果您的 SparseMatrixCSC
物件包含未排序的列索引,一種快速排序它們的方法是進行雙重轉置。由於轉置操作是延遲的,請製作一份副本以具體化每個轉置。
在某些應用程式中,在 SparseMatrixCSC
中儲存明確的零值很方便。這些值會被 Base
中的函式接受(但無法保證它們會在變異操作中保留)。許多常式將此類明確儲存的零視為結構性非零值。nnz
函式會傳回稀疏資料結構中明確儲存的元素數量,包括非結構性零值。若要計算確切的數值非零值數量,請使用 count(!iszero, x)
,它會檢查稀疏矩陣的每個儲存元素。dropzeros
和就地 dropzeros!
可用於從稀疏矩陣中移除儲存的零值。
julia> A = sparse([1, 1, 2, 3], [1, 3, 2, 3], [0, 1, 2, 0])
3×3 SparseMatrixCSC{Int64, Int64} with 4 stored entries:
0 ⋅ 1
⋅ 2 ⋅
⋅ ⋅ 0
julia> dropzeros(A)
3×3 SparseMatrixCSC{Int64, Int64} with 2 stored entries:
⋅ ⋅ 1
⋅ 2 ⋅
⋅ ⋅ ⋅
稀疏向量儲存
稀疏向量的儲存方式類似於稀疏矩陣的壓縮稀疏欄位格式。在 Julia 中,稀疏向量的類型為 SparseVector{Tv,Ti}
,其中 Tv
是儲存值的類型,而 Ti
是索引的整數類型。內部表示如下
struct SparseVector{Tv,Ti<:Integer} <: AbstractSparseVector{Tv,Ti}
n::Int # Length of the sparse vector
nzind::Vector{Ti} # Indices of stored values
nzval::Vector{Tv} # Stored values, typically nonzeros
end
至於 SparseMatrixCSC
,SparseVector
類型也可以包含明確儲存的零值。(請參閱 稀疏矩陣儲存。)
稀疏向量和矩陣建構函式
建立稀疏陣列最簡單的方法是使用一個函式,其等同於 Julia 提供給密集陣列使用的 zeros
函式。若要產生稀疏陣列,您可以使用相同的名稱,並加上 sp
前綴
julia> spzeros(3)
3-element SparseVector{Float64, Int64} with 0 stored entries
sparse
函式通常是建構稀疏陣列的便利方法。例如,若要建構稀疏矩陣,我們可以輸入一個列索引向量 I
、一個欄索引向量 J
,以及一個儲存值向量 V
(這也稱為 COO(座標)格式)。sparse(I,J,V)
然後建構一個稀疏矩陣,使得 S[I[k], J[k]] = V[k]
。等效的稀疏向量建構函式為 sparsevec
,它會取得(列)索引向量 I
和具有儲存值的向量 V
,並建構一個稀疏向量 R
,使得 R[I[k]] = V[k]
。
julia> I = [1, 4, 3, 5]; J = [4, 7, 18, 9]; V = [1, 2, -5, 3];
julia> S = sparse(I,J,V)
5×18 SparseMatrixCSC{Int64, Int64} with 4 stored entries:
⎡⠀⠈⠀⠀⠀⠀⠀⠀⢀⎤
⎣⠀⠀⠀⠂⡀⠀⠀⠀⠀⎦
julia> R = sparsevec(I,V)
5-element SparseVector{Int64, Int64} with 4 stored entries:
[1] = 1
[3] = -5
[4] = 2
[5] = 3
sparse
和 sparsevec
函式的反函式為 findnz
,它會擷取用於建立稀疏陣列的輸入。findall(!iszero, x)
會傳回 x
中非零條目的笛卡爾索引(包括等於零的儲存條目)。
julia> findnz(S)
([1, 4, 5, 3], [4, 7, 9, 18], [1, 2, 3, -5])
julia> findall(!iszero, S)
4-element Vector{CartesianIndex{2}}:
CartesianIndex(1, 4)
CartesianIndex(4, 7)
CartesianIndex(5, 9)
CartesianIndex(3, 18)
julia> findnz(R)
([1, 3, 4, 5], [1, -5, 2, 3])
julia> findall(!iszero, R)
4-element Vector{Int64}:
1
3
4
5
建立稀疏陣列的另一種方法是使用 sparse
函式將密集陣列轉換為稀疏陣列
julia> sparse(Matrix(1.0I, 5, 5))
5×5 SparseMatrixCSC{Float64, Int64} with 5 stored entries:
1.0 ⋅ ⋅ ⋅ ⋅
⋅ 1.0 ⋅ ⋅ ⋅
⋅ ⋅ 1.0 ⋅ ⋅
⋅ ⋅ ⋅ 1.0 ⋅
⋅ ⋅ ⋅ ⋅ 1.0
julia> sparse([1.0, 0.0, 1.0])
3-element SparseVector{Float64, Int64} with 2 stored entries:
[1] = 1.0
[3] = 1.0
您可以使用 Array
建構函式朝相反的方向進行。issparse
函式可查詢矩陣是否為稀疏矩陣。
julia> issparse(spzeros(5))
true
稀疏矩陣運算
稀疏矩陣的算術運算也與稠密矩陣相同。稀疏矩陣的索引、指派和串接與稠密矩陣相同。索引運算,特別是指派,在一次執行一個元素時,成本很高。在許多情況下,最好使用 findnz
將稀疏矩陣轉換為 (I,J,V)
格式,處理稠密向量 (I,J,V)
中的值或結構,然後重建稀疏矩陣。
稠密方法和稀疏方法的對應
下表列出稀疏矩陣內建方法與稠密矩陣類型對應方法之間的對應關係。一般而言,產生稀疏矩陣的方法與稠密矩陣方法不同,在於產生的矩陣遵循與給定稀疏矩陣 S
相同的稀疏模式,或產生的稀疏矩陣密度為 d
,亦即每個矩陣元素都有 d
的機率為非零。
詳細資訊請參閱標準函式庫參考中的 稀疏向量和矩陣 區段。
稀疏 | 稠密 | 說明 |
---|---|---|
spzeros(m,n) | zeros(m,n) | 建立一個 m 乘以 n 的零矩陣。(spzeros(m,n) 為空。) |
sparse(I,n,n) | Matrix(I,n,n) | 建立一個 n 乘以 n 的單位矩陣。 |
sparse(A) | Array(S) | 在稠密和稀疏格式之間進行轉換。 |
sprand(m,n,d) | rand(m,n) | 建立一個 m 乘以 n 的隨機矩陣(密度為 d),其中 iid 非零元素均勻分佈於半開區間 $[0, 1)$。 |
sprandn(m,n,d) | randn(m,n) | 建立一個m-by-n隨機矩陣(密度為d),其中 iid 非零元素依標準常態(高斯)分佈。 |
sprandn(rng,m,n,d) | randn(rng,m,n) | 建立一個m-by-n隨機矩陣(密度為d),其中 iid 非零元素由rng 隨機數產生器產生 |
SparseArrays API
SparseArrays.AbstractSparseArray
— 類型AbstractSparseArray{Tv,Ti,N}
N
維稀疏陣列(或類似陣列類型)的超類型,其元素類型為Tv
,索引類型為Ti
。 SparseMatrixCSC
、SparseVector
和 SuiteSparse.CHOLMOD.Sparse
是其子類型。
SparseArrays.AbstractSparseVector
— 類型AbstractSparseVector{Tv,Ti}
一維稀疏陣列(或類似陣列類型)的超類型,其元素類型為Tv
,索引類型為Ti
。AbstractSparseArray{Tv,Ti,1}
的別名。
SparseArrays.AbstractSparseMatrix
— 類型AbstractSparseMatrix{Tv,Ti}
二維稀疏陣列(或類似陣列類型)的超類型,其元素類型為Tv
,索引類型為Ti
。AbstractSparseArray{Tv,Ti,2}
的別名。
SparseArrays.SparseVector
— 類型SparseVector{Tv,Ti<:Integer} <: AbstractSparseVector{Tv,Ti}
用於儲存稀疏向量的向量類型。可透過傳遞向量的長度、已排序的非零索引向量和非零值向量來建立。
例如,向量 [5, 6, 0, 7]
可表示為
SparseVector(4, [1, 2, 4], [5, 6, 7])
這表示索引 1 的元素為 5,索引 2 的元素為 6,索引 3 的元素為 zero(Int)
,索引 4 的元素為 7。
使用 sparse
直接從稠密向量建立稀疏向量可能會更方便,如下所示
sparse([5, 6, 0, 7])
會產生相同的稀疏向量。
SparseArrays.SparseMatrixCSC
— 類型SparseMatrixCSC{Tv,Ti<:Integer} <: AbstractSparseMatrixCSC{Tv,Ti}
用於以 壓縮稀疏欄 格式儲存稀疏矩陣的矩陣類型。建立 SparseMatrixCSC 的標準方法是透過 sparse
函數。另請參閱 spzeros
、spdiagm
和 sprand
。
SparseArrays.sparse
— 函數sparse(A)
將 AbstractMatrix A
轉換為稀疏矩陣。
範例
julia> A = Matrix(1.0I, 3, 3)
3×3 Matrix{Float64}:
1.0 0.0 0.0
0.0 1.0 0.0
0.0 0.0 1.0
julia> sparse(A)
3×3 SparseMatrixCSC{Float64, Int64} with 3 stored entries:
1.0 ⋅ ⋅
⋅ 1.0 ⋅
⋅ ⋅ 1.0
sparse(I, J, V,[ m, n, combine])
建立維度為 m x n
的稀疏矩陣 S
,其中 S[I[k], J[k]] = V[k]
。combine
函數用於合併重複項。如果未指定 m
和 n
,則分別設定為 maximum(I)
和 maximum(J)
。如果未提供 combine
函數,則 combine
預設為 +
,除非 V
的元素為布林值,否則 combine
預設為 |
。I
的所有元素都必須符合 1 <= I[k] <= m
,而 J
的所有元素都必須符合 1 <= J[k] <= n
。保留 (I
、J
、V
) 中的數值零作為結構非零;若要捨棄數值零,請使用 dropzeros!
。
如需其他文件和專家驅動程式,請參閱 SparseArrays.sparse!
。
範例
julia> Is = [1; 2; 3];
julia> Js = [1; 2; 3];
julia> Vs = [1; 2; 3];
julia> sparse(Is, Js, Vs)
3×3 SparseMatrixCSC{Int64, Int64} with 3 stored entries:
1 ⋅ ⋅
⋅ 2 ⋅
⋅ ⋅ 3
SparseArrays.sparse!
— 函數sparse!(I::AbstractVector{Ti}, J::AbstractVector{Ti}, V::AbstractVector{Tv},
m::Integer, n::Integer, combine, klasttouch::Vector{Ti},
csrrowptr::Vector{Ti}, csrcolval::Vector{Ti}, csrnzval::Vector{Tv},
[csccolptr::Vector{Ti}], [cscrowval::Vector{Ti}, cscnzval::Vector{Tv}] ) where {Tv,Ti<:Integer}
sparse
的父級和專家驅動程式;請參閱 sparse
以了解基本用法。此方法允許使用者提供預先配置的儲存空間,以供 sparse
的中間物件和結果使用,如下所述。此功能可更有效率地從座標表示法中連續建構 SparseMatrixCSC
,並能以無額外成本擷取結果轉置的未排序欄表示法。
此方法包含三個主要步驟:(1) 將提供的座標表示法計數排序為未排序列 CSR 形式,包括重複的項目。(2) 掃描 CSR 形式,同時計算所需的 CSC 形式的欄指標陣列,偵測重複的項目,並重新封裝合併重複項目的 CSR 形式;此階段會產生未排序列 CSR 形式,且不含重複項目。(3) 將前一個 CSR 形式計數排序為完全排序的 CSC 形式,且不含重複項目。
輸入陣列 csrrowptr
、csrcolval
和 csrnzval
構成中間 CSR 形式的儲存空間,且需要 length(csrrowptr) >= m + 1
、length(csrcolval) >= length(I)
和 length(csrnzval >= length(I))
。輸入陣列 klasttouch
(第二階段的工作空間)需要 length(klasttouch) >= n
。選用輸入陣列 csccolptr
、cscrowval
和 cscnzval
構成傳回 CSC 形式 S
的儲存空間。必要時,這些陣列會自動調整大小,以符合 length(csccolptr) = n + 1
、length(cscrowval) = nnz(S)
和 length(cscnzval) = nnz(S)
;因此,如果一開始不知道 nnz(S)
,傳入適當類型的空向量(分別為 Vector{Ti}()
和 Vector{Tv}()
)就已足夠,或呼叫 sparse!
方法,忽略 cscrowval
和 cscnzval
。
傳回時,csrrowptr
、csrcolval
和 csrnzval
會包含結果轉置的未排序欄表示法。
您可以重複使用輸入陣列的儲存空間(I
、J
、V
)作為輸出陣列(csccolptr
、cscrowval
、cscnzval
)。例如,您可以呼叫 sparse!(I, J, V, csrrowptr, csrcolval, csrnzval, I, J, V)
。請注意,它們會調整大小以符合上述條件。
為了效率,此方法不執行 1 <= I[k] <= m
和 1 <= J[k] <= n
以外的引數檢查。請小心使用。建議使用 --check-bounds=yes
進行測試。
此方法在 O(m, n, length(I))
時間內執行。F. Gustavson 在「兩個用於稀疏矩陣的快速演算法:乘法和置換轉置」,ACM TOMS 4(3),250-269 (1978) 中描述的 HALFPERM 演算法啟發了此方法使用一對計數排序。
SparseArrays.sparse!(I, J, V, [m, n, combine]) -> SparseMatrixCSC
sparse!
的變體,它會重複使用輸入向量 (I
、J
、V
) 作為最終矩陣儲存。建構後,輸入向量將別名矩陣緩衝區;S.colptr === I
、S.rowval === J
和 S.nzval === V
成立,並且它們會在必要時進行 resize!
。
請注意,仍會配置一些工作緩衝區。具體來說,此方法是 sparse!(I, J, V, m, n, combine, klasttouch, csrrowptr, csrcolval, csrnzval, csccolptr, cscrowval, cscnzval)
的便利包裝器,其中此方法配置適當大小的 klasttouch
、csrrowptr
、csrcolval
和 csrnzval
,但重複使用 I
、J
和 V
作為 csccolptr
、cscrowval
和 cscnzval
。
引數 m
、n
和 combine
分別預設為 maximum(I)
、maximum(J)
和 +
。
此方法需要 Julia 版本 1.10 或更新版本。
SparseArrays.sparsevec
— 函數sparsevec(I, V, [m, combine])
建立一個長度為 m
的稀疏向量 S
,使得 S[I[k]] = V[k]
。重複項會使用 combine
函數合併,如果未提供 combine
引數,則預設為 +
,除非 V
的元素為布林值,則 combine
預設為 |
。
範例
julia> II = [1, 3, 3, 5]; V = [0.1, 0.2, 0.3, 0.2];
julia> sparsevec(II, V)
5-element SparseVector{Float64, Int64} with 3 stored entries:
[1] = 0.1
[3] = 0.5
[5] = 0.2
julia> sparsevec(II, V, 8, -)
8-element SparseVector{Float64, Int64} with 3 stored entries:
[1] = 0.1
[3] = -0.1
[5] = 0.2
julia> sparsevec([1, 3, 1, 2, 2], [true, true, false, false, false])
3-element SparseVector{Bool, Int64} with 3 stored entries:
[1] = 1
[2] = 0
[3] = 1
sparsevec(d::Dict, [m])
建立一個長度為 m
的稀疏向量,其中非零索引是字典中的鍵,非零值是字典中的值。
範例
julia> sparsevec(Dict(1 => 3, 2 => 2))
2-element SparseVector{Int64, Int64} with 2 stored entries:
[1] = 3
[2] = 2
sparsevec(A)
將向量 A
轉換為長度為 m
的稀疏向量。
範例
julia> sparsevec([1.0, 2.0, 0.0, 0.0, 3.0, 0.0])
6-element SparseVector{Float64, Int64} with 3 stored entries:
[1] = 1.0
[2] = 2.0
[5] = 3.0
Base.similar
— 方法similar(A::AbstractSparseMatrixCSC{Tv,Ti}, [::Type{TvNew}, ::Type{TiNew}, m::Integer, n::Integer]) where {Tv,Ti}
根據給定的來源 SparseMatrixCSC
,建立一個未初始化的可變陣列,具有給定的元素類型、索引類型和大小。新的稀疏矩陣會維持原始稀疏矩陣的結構,除非輸出矩陣的維度與輸出不同。
輸出矩陣在與輸入相同的位置有零,但非零位置的值未初始化。
SparseArrays.issparse
— 函數issparse(S)
如果 S
是稀疏的,則傳回 true
,否則傳回 false
。
範例
julia> sv = sparsevec([1, 4], [2.3, 2.2], 10)
10-element SparseVector{Float64, Int64} with 2 stored entries:
[1] = 2.3
[4] = 2.2
julia> issparse(sv)
true
julia> issparse(Array(sv))
false
SparseArrays.nnz
— 函數nnz(A)
傳回稀疏陣列中已儲存(已填入)的元素數量。
範例
julia> A = sparse(2I, 3, 3)
3×3 SparseMatrixCSC{Int64, Int64} with 3 stored entries:
2 ⋅ ⋅
⋅ 2 ⋅
⋅ ⋅ 2
julia> nnz(A)
3
SparseArrays.findnz
— 函數findnz(A::SparseMatrixCSC)
傳回一個元組 (I, J, V)
,其中 I
和 J
是稀疏矩陣 A
中已儲存(「結構上非零」)值的列索引和行索引,而 V
是值的向量。
範例
julia> A = sparse([1 2 0; 0 0 3; 0 4 0])
3×3 SparseMatrixCSC{Int64, Int64} with 4 stored entries:
1 2 ⋅
⋅ ⋅ 3
⋅ 4 ⋅
julia> findnz(A)
([1, 1, 3, 2], [1, 2, 2, 3], [1, 2, 4, 3])
SparseArrays.spzeros
— 函數spzeros([type,]m[,n])
建立長度為 m
的稀疏向量或大小為 m x n
的稀疏矩陣。此稀疏陣列不會包含任何非零值。建立過程中不會為非零值配置儲存空間。如果未指定類型,則預設為 Float64
。
範例
julia> spzeros(3, 3)
3×3 SparseMatrixCSC{Float64, Int64} with 0 stored entries:
⋅ ⋅ ⋅
⋅ ⋅ ⋅
⋅ ⋅ ⋅
julia> spzeros(Float32, 4)
4-element SparseVector{Float32, Int64} with 0 stored entries
spzeros([type], I::AbstractVector, J::AbstractVector, [m, n])
建立維度為 m x n
的稀疏矩陣 S
,其中結構零位於 S[I[k], J[k]]
。
此方法可用於建立矩陣的稀疏模式,而且比使用例如 sparse(I, J, zeros(length(I)))
更有效率。
如需其他文件和專家驅動程式,請參閱 SparseArrays.spzeros!
。
此方法需要 Julia 版本 1.10 或更新版本。
SparseArrays.spzeros!
— 函數spzeros!(::Type{Tv}, I::AbstractVector{Ti}, J::AbstractVector{Ti}, m::Integer, n::Integer,
klasttouch::Vector{Ti}, csrrowptr::Vector{Ti}, csrcolval::Vector{Ti},
[csccolptr::Vector{Ti}], [cscrowval::Vector{Ti}, cscnzval::Vector{Tv}]) where {Tv,Ti<:Integer}
spzeros(I, J)
的父級和專家驅動程式,允許使用者為中間物件提供預先配置的儲存空間。此方法對 spzeros
的作用,就像 SparseArrays.sparse!
對 sparse
的作用。有關詳細資料和所需的緩衝區長度,請參閱 SparseArrays.sparse!
的文件。
此方法需要 Julia 版本 1.10 或更新版本。
SparseArrays.spzeros!(::Type{Tv}, I, J, [m, n]) -> SparseMatrixCSC{Tv}
spzeros!
的變體,它會重複使用輸入向量 I
和 J
作為最終矩陣儲存空間。在建構後,輸入向量會別名矩陣緩衝區;會成立 S.colptr === I
和 S.rowval === J
,而且會視需要執行 resize!
。
請注意,仍會配置一些工作緩衝區。具體來說,此方法是 spzeros!(Tv, I, J, m, n, klasttouch, csrrowptr, csrcolval, csccolptr, cscrowval)
的便利包裝器,其中此方法配置適當大小的 klasttouch
、csrrowptr
和 csrcolval
,但重複使用 I
和 J
作為 csccolptr
和 cscrowval
。
引數 m
和 n
預設為 maximum(I)
和 maximum(J)
。
此方法需要 Julia 版本 1.10 或更新版本。
SparseArrays.spdiagm
— 函數spdiagm(kv::Pair{<:Integer,<:AbstractVector}...)
spdiagm(m::Integer, n::Integer, kv::Pair{<:Integer,<:AbstractVector}...)
根據向量的 Pair
和對角線建構一個稀疏對角矩陣。每個向量 kv.second
都會置於 kv.first
對角線上。預設情況下,矩陣是正方形,其大小會從 kv
推斷,但可以透過傳遞 m,n
作為第一個引數來指定非正方形大小 m
×n
(視需要以零填充)。
範例
julia> spdiagm(-1 => [1,2,3,4], 1 => [4,3,2,1])
5×5 SparseMatrixCSC{Int64, Int64} with 8 stored entries:
⋅ 4 ⋅ ⋅ ⋅
1 ⋅ 3 ⋅ ⋅
⋅ 2 ⋅ 2 ⋅
⋅ ⋅ 3 ⋅ 1
⋅ ⋅ ⋅ 4 ⋅
spdiagm(v::AbstractVector)
spdiagm(m::Integer, n::Integer, v::AbstractVector)
使用向量元素作為對角元素來建構稀疏矩陣。預設情況下(未提供 m
和 n
),矩陣為正方形,其大小由 length(v)
給出,但可以透過傳遞 m
和 n
作為第一個引數來指定非正方形大小 m
×n
。
這些函數至少需要 Julia 1.6。
範例
julia> spdiagm([1,2,3])
3×3 SparseMatrixCSC{Int64, Int64} with 3 stored entries:
1 ⋅ ⋅
⋅ 2 ⋅
⋅ ⋅ 3
julia> spdiagm(sparse([1,0,3]))
3×3 SparseMatrixCSC{Int64, Int64} with 2 stored entries:
1 ⋅ ⋅
⋅ ⋅ ⋅
⋅ ⋅ 3
SparseArrays.sparse_hcat
— 函數sparse_hcat(A...)
沿著維度 2 連結。傳回 SparseMatrixCSC 物件。
這個方法在 Julia 1.8 中新增。它模擬先前的連結行為,其中與 LinearAlgebra.jl 中的特殊「稀疏」矩陣類型連結會自動產生稀疏輸出,即使沒有任何 SparseArray 引數。
SparseArrays.sparse_vcat
— 函數sparse_vcat(A...)
沿著維度 1 連結。傳回 SparseMatrixCSC 物件。
這個方法在 Julia 1.8 中新增。它模擬先前的連結行為,其中與 LinearAlgebra.jl 中的特殊「稀疏」矩陣類型連結會自動產生稀疏輸出,即使沒有任何 SparseArray 引數。
SparseArrays.sparse_hvcat
— 函數sparse_hvcat(rows::Tuple{Vararg{Int}}, values...)
在一次呼叫中進行稀疏水平和垂直連結。這個函數是用於區塊矩陣語法。第一個引數指定每個區塊列中要連結的引數數量。
這個方法在 Julia 1.8 中新增。它模擬先前的連結行為,其中與 LinearAlgebra.jl 中的特殊「稀疏」矩陣類型連結會自動產生稀疏輸出,即使沒有任何 SparseArray 引數。
SparseArrays.blockdiag
— 函數blockdiag(A...)
沿著區塊對角線連結矩陣。目前僅實作於稀疏矩陣。
範例
julia> blockdiag(sparse(2I, 3, 3), sparse(4I, 2, 2))
5×5 SparseMatrixCSC{Int64, Int64} with 5 stored entries:
2 ⋅ ⋅ ⋅ ⋅
⋅ 2 ⋅ ⋅ ⋅
⋅ ⋅ 2 ⋅ ⋅
⋅ ⋅ ⋅ 4 ⋅
⋅ ⋅ ⋅ ⋅ 4
SparseArrays.sprand
— 函數sprand([rng],[T::Type],m,[n],p::AbstractFloat)
sprand([rng],m,[n],p::AbstractFloat,[rfn=rand])
建立一個長度為 m
的稀疏向量或 m
乘以 n
的稀疏矩陣,其中任何元素非零的機率由 p
獨立給出(因此非零元素的平均密度也正好為 p
)。可選的 rng
參數指定一個亂數產生器,請參閱 亂數。可選的 T
參數指定元素類型,預設為 Float64
。
預設情況下,非零值會使用 rand
函數從均勻分佈中取樣,也就是說,使用 rand(T)
,或是在提供 rng
時使用 rand(rng, T)
;對於預設的 T=Float64
,這對應到在 [0,1)
中均勻取樣的非零值。
您可以透過傳遞自訂的 rfn
函數來從不同的分佈中取樣非零值,而不是 rand
。這應該是一個 rfn(k)
函數,它會傳回一個陣列,其中包含從所需分佈中取樣的 k
個亂數;或者,如果提供了 rng
,它應該是一個 rfn(rng, k)
函數。
範例
julia> sprand(Bool, 2, 2, 0.5)
2×2 SparseMatrixCSC{Bool, Int64} with 2 stored entries:
1 1
⋅ ⋅
julia> sprand(Float64, 3, 0.75)
3-element SparseVector{Float64, Int64} with 2 stored entries:
[1] = 0.795547
[2] = 0.49425
SparseArrays.sprandn
— 函數sprandn([rng][,Type],m[,n],p::AbstractFloat)
建立一個長度為 m
的稀疏向量或大小為 m
乘以 n
的稀疏矩陣,其中任何條目的非零機率為指定的(獨立)機率 p
,而非零值會從常態分佈中取樣。可選的 rng
參數指定一個亂數產生器,請參閱 亂數。
指定輸出元素類型 Type
至少需要 Julia 1.1。
範例
julia> sprandn(2, 2, 0.75)
2×2 SparseMatrixCSC{Float64, Int64} with 3 stored entries:
-1.20577 ⋅
0.311817 -0.234641
SparseArrays.nonzeros
— 函數nonzeros(A)
傳回稀疏陣列 A
中結構非零值的向量。這包含稀疏陣列中明確儲存的零。傳回的向量直接指向 A
的內部非零儲存,對傳回向量的任何修改也會變異 A
。請參閱 rowvals
和 nzrange
。
範例
julia> A = sparse(2I, 3, 3)
3×3 SparseMatrixCSC{Int64, Int64} with 3 stored entries:
2 ⋅ ⋅
⋅ 2 ⋅
⋅ ⋅ 2
julia> nonzeros(A)
3-element Vector{Int64}:
2
2
2
SparseArrays.rowvals
— 函數rowvals(A::AbstractSparseMatrixCSC)
傳回 A
的列索引向量。對傳回向量的任何修改也會變異 A
。提供存取列索引內部儲存方式的方法,在搭配結構非零值反覆運算時很有用。另請參閱 nonzeros
和 nzrange
。
範例
julia> A = sparse(2I, 3, 3)
3×3 SparseMatrixCSC{Int64, Int64} with 3 stored entries:
2 ⋅ ⋅
⋅ 2 ⋅
⋅ ⋅ 2
julia> rowvals(A)
3-element Vector{Int64}:
1
2
3
SparseArrays.nzrange
— 函數nzrange(A::AbstractSparseMatrixCSC, col::Integer)
傳回稀疏矩陣列欄的結構非零值的索引範圍。搭配 nonzeros
和 rowvals
,這允許方便地反覆運算稀疏矩陣
A = sparse(I,J,V)
rows = rowvals(A)
vals = nonzeros(A)
m, n = size(A)
for j = 1:n
for i in nzrange(A, j)
row = rows[i]
val = vals[i]
# perform sparse wizardry...
end
end
新增或移除矩陣中的非零元素可能會使 nzrange
無效,反覆運算時不應變異矩陣。
nzrange(x::SparseVectorUnion, col)
提供稀疏向量的結構非零值的索引範圍。欄索引 col
會被忽略(假設為 1
)。
SparseArrays.droptol!
— 函數droptol!(A::AbstractSparseMatrixCSC, tol)
從 A
中移除絕對值小於或等於 tol
的儲存值。
droptol!(x::AbstractCompressedVector, tol)
從 x
中移除絕對值小於或等於 tol
的儲存值。
SparseArrays.dropzeros!
— 函數SparseArrays.dropzeros
— 函數dropzeros(A::AbstractSparseMatrixCSC;)
產生 A
的副本,並從該副本中移除儲存的數值零。
如需原位版本和演算法資訊,請參閱 dropzeros!
。
範例
julia> A = sparse([1, 2, 3], [1, 2, 3], [1.0, 0.0, 1.0])
3×3 SparseMatrixCSC{Float64, Int64} with 3 stored entries:
1.0 ⋅ ⋅
⋅ 0.0 ⋅
⋅ ⋅ 1.0
julia> dropzeros(A)
3×3 SparseMatrixCSC{Float64, Int64} with 2 stored entries:
1.0 ⋅ ⋅
⋅ ⋅ ⋅
⋅ ⋅ 1.0
dropzeros(x::AbstractCompressedVector)
產生 x
的副本,並從該副本中移除數值零。
如需原位版本和演算法資訊,請參閱 dropzeros!
。
範例
julia> A = sparsevec([1, 2, 3], [1.0, 0.0, 1.0])
3-element SparseVector{Float64, Int64} with 3 stored entries:
[1] = 1.0
[2] = 0.0
[3] = 1.0
julia> dropzeros(A)
3-element SparseVector{Float64, Int64} with 2 stored entries:
[1] = 1.0
[3] = 1.0
SparseArrays.permute
— 函數permute(A::AbstractSparseMatrixCSC{Tv,Ti}, p::AbstractVector{<:Integer},
q::AbstractVector{<:Integer}) where {Tv,Ti}
雙邊置換 A
,傳回 PAQ
(A[p,q]
)。欄置換 q
的長度必須與 A
的欄數相符 (length(q) == size(A, 2)
)。列置換 p
的長度必須與 A
的列數相符 (length(p) == size(A, 1)
)。
如需專家驅動程式和更多資訊,請參閱 permute!
。
範例
julia> A = spdiagm(0 => [1, 2, 3, 4], 1 => [5, 6, 7])
4×4 SparseMatrixCSC{Int64, Int64} with 7 stored entries:
1 5 ⋅ ⋅
⋅ 2 6 ⋅
⋅ ⋅ 3 7
⋅ ⋅ ⋅ 4
julia> permute(A, [4, 3, 2, 1], [1, 2, 3, 4])
4×4 SparseMatrixCSC{Int64, Int64} with 7 stored entries:
⋅ ⋅ ⋅ 4
⋅ ⋅ 3 7
⋅ 2 6 ⋅
1 5 ⋅ ⋅
julia> permute(A, [1, 2, 3, 4], [4, 3, 2, 1])
4×4 SparseMatrixCSC{Int64, Int64} with 7 stored entries:
⋅ ⋅ 5 1
⋅ 6 2 ⋅
7 3 ⋅ ⋅
4 ⋅ ⋅ ⋅
Base.permute!
— 方法permute!(X::AbstractSparseMatrixCSC{Tv,Ti}, A::AbstractSparseMatrixCSC{Tv,Ti},
p::AbstractVector{<:Integer}, q::AbstractVector{<:Integer},
[C::AbstractSparseMatrixCSC{Tv,Ti}]) where {Tv,Ti}
雙邊置換 A
,將結果 PAQ
(A[p,q]
) 儲存在 X
中。如果存在,將中間結果 (AQ)^T
(transpose(A[:,q])
) 儲存在選用參數 C
中。需要 X
、A
和(如果存在)C
彼此不別名;若要將結果 PAQ
儲存回 A
,請使用以下沒有 X
的方法
permute!(A::AbstractSparseMatrixCSC{Tv,Ti}, p::AbstractVector{<:Integer},
q::AbstractVector{<:Integer}[, C::AbstractSparseMatrixCSC{Tv,Ti},
[workcolptr::Vector{Ti}]]) where {Tv,Ti}
X
的維度必須與 A
的維度相符 (size(X, 1) == size(A, 1)
且 size(X, 2) == size(A, 2)
),且 X
必須有足夠的儲存空間來容納 A
中所有已配置的項目 (length(rowvals(X)) >= nnz(A)
且 length(nonzeros(X)) >= nnz(A)
)。欄位置換 q
的長度必須與 A
的欄位數相符 (length(q) == size(A, 2)
)。列置換 p
的長度必須與 A
的列數相符 (length(p) == size(A, 1)
)。
C
的維度必須與 transpose(A)
的維度相符 (size(C, 1) == size(A, 2)
且 size(C, 2) == size(A, 1)
),且 C
必須有足夠的儲存空間來容納 A
中所有已配置的項目 (length(rowvals(C)) >= nnz(A)
且 length(nonzeros(C)) >= nnz(A)
)。
有關其他 (演算法) 資訊,以及放棄引數檢查的這些方法版本,請參閱 (未匯出的) 父方法 unchecked_noalias_permute!
和 unchecked_aliasing_permute!
。
另請參閱 permute
。
SparseArrays.halfperm!
— 函數halfperm!(X::AbstractSparseMatrixCSC{Tv,Ti}, A::AbstractSparseMatrixCSC{TvA,Ti},
q::AbstractVector{<:Integer}, f::Function = identity) where {Tv,TvA,Ti}
同時欄位置換和轉置 A
,並將 f
套用於 A
的每個項目,將結果 (f(A)Q)^T
(map(f, transpose(A[:,q]))
) 儲存在 X
中。
X
的元素類型 Tv
必須與 f(::TvA)
相符,其中 TvA
是 A
的元素類型。X
的維度必須與 transpose(A)
的維度相符 (size(X, 1) == size(A, 2)
且 size(X, 2) == size(A, 1)
),且 X
必須有足夠的儲存空間來容納 A
中所有已配置的項目 (length(rowvals(X)) >= nnz(A)
且 length(nonzeros(X)) >= nnz(A)
)。欄位置換 q
的長度必須與 A
的欄位數相符 (length(q) == size(A, 2)
)。
此方法是執行轉置和排列運算的數個方法的父方法,這些方法會在 SparseMatrixCSC
上執行。由於此方法不會執行引數檢查,因此建議使用較安全的子方法 ([c]transpose[!]
、permute[!]
) 進行直接使用。
此方法實作 F. Gustavson 在「兩個用於稀疏矩陣的快速演算法:乘法和排列轉置」中所描述的 HALFPERM
演算法,ACM TOMS 4(3),250-269 (1978)。此演算法執行時間為 O(size(A, 1), size(A, 2), nnz(A))
,且不需要超出傳入的空間。
SparseArrays.ftranspose!
— 函數ftranspose!(X::AbstractSparseMatrixCSC{Tv,Ti}, A::AbstractSparseMatrixCSC{Tv,Ti}, f::Function) where {Tv,Ti}
轉置 A
並將其儲存在 X
中,同時將函數 f
套用至非零元素。不會移除 f
所建立的零。size(X)
必須等於 size(transpose(A))
。除了在需要時調整 X
的 rowval 和 nzval 大小之外,不會配置其他額外的記憶體。
請參閱 halfperm!
值得注意的外部套件
還有其他幾個 Julia 套件提供值得一提的稀疏矩陣實作
SuiteSparseGraphBLAS.jl 是快速的多執行緒 SuiteSparse:GraphBLAS C 函式庫的包裝器。在 CPU 上,這通常是最快的選項,通常會顯著優於 MKLSparse。
SparseMatricesCSR.jl 提供 Compressed Sparse Rows (CSR) 格式的 Julia 原生實作。
MKLSparse.jl 使用 Intel 的 MKL 函式庫加速 SparseArrays 稀疏-稠密矩陣運算。
SparseArrayKit.jl 可用於多維稀疏陣列。
LuxurySparse.jl 提供靜態稀疏陣列格式,以及一個座標格式。
ExtendableSparse.jl 使用一種新的儲存索引的惰性方式,讓稀疏矩陣可以快速插入。