Sparse Arrays

Juliaは、SparseArrays標準ライブラリモジュールでスパースベクトルとsparse matricesをサポートしています。スパース配列は、ゼロが十分に含まれている配列であり、特別なデータ構造に格納することで、密な配列と比較して、スペースと実行時間の節約が可能になります。

異なるスパースストレージタイプ、マルチディメンショナルスパース配列などを実装する外部パッケージは、Noteworthy External Sparse Packages で見つけることができます。

Compressed Sparse Column (CSC) Sparse Matrix Storage

Juliaでは、スパース行列はCompressed Sparse Column (CSC) formatに格納されます。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構造内で以前に保存されていなかったエントリを1つずつ挿入するような操作は遅くなる傾向があります。これは、挿入ポイントを超えるスパース行列のすべての要素を1つずつ移動させる必要があるためです。

すべてのスパース行列に対する操作は、パフォーマンスを最大限に引き出すために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  ⋅
 ⋅  ⋅  ⋅

Sparse Vector Storage

スパースベクトルは、スパース行列の圧縮スパースカラム形式に近い形で保存されます。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型は明示的に保存されたゼロも含むことができます。(Sparse Matrix Storageを参照してください。)

Sparse Vector and Matrix Constructors

スパース配列を作成する最も簡単な方法は、Juliaが密な配列を扱うために提供するzeros関数に相当する関数を使用することです。代わりにスパース配列を生成するには、同じ名前にspプレフィックスを付けて使用できます:

julia> spzeros(3)
3-element SparseVector{Float64, Int64} with 0 stored entries

sparse 関数は、スパース配列を構築する便利な方法です。例えば、スパース行列を構築するために、行インデックスのベクトル I、列インデックスのベクトル J、および保存された値のベクトル V を入力できます(これは COO (coordinate) format とも呼ばれます)。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

Sparse matrix operations

Arithmetic operations on sparse matrices also work as they do on dense matrices. Indexing of, assignment into, and concatenation of sparse matrices work in the same way as dense matrices. Indexing operations, especially assignment, are expensive, when carried out one element at a time. In many cases it may be better to convert the sparse matrix into (I,J,V) format using findnz, manipulate the values or the structure in the dense vectors (I,J,V), and then reconstruct the sparse matrix.

Correspondence of dense and sparse methods

次の表は、スパース行列の組み込みメソッドと、それに対応する密行列タイプのメソッドとの対応関係を示しています。一般に、スパース行列を生成するメソッドは、密行列の対応するメソッドとは異なり、結果として得られる行列が与えられたスパース行列 S と同じスパースパターンに従うか、または結果として得られるスパース行列が密度 d を持つこと、すなわち各行列要素が非ゼロである確率 d を持つことが特徴です。

詳細は標準ライブラリリファレンスの Sparse Vectors and Matrices セクションにあります。

SparseDenseDescription
spzeros(m,n)zeros(m,n)Creates a m-by-n matrix of zeros. (spzeros(m,n) is empty.)
sparse(I,n,n)Matrix(I,n,n)Creates a n-by-n identity matrix.
sparse(A)Array(S)Interconverts between dense and sparse formats.
sprand(m,n,d)rand(m,n)Creates a m-by-n random matrix (of density d) with iid non-zero elements distributed uniformly on the half-open interval $[0, 1)$.
sprandn(m,n,d)randn(m,n)Creates a m-by-n random matrix (of density d) with iid non-zero elements distributed according to the standard normal (Gaussian) distribution.
sprandn(rng,m,n,d)randn(rng,m,n)Creates a m-by-n random matrix (of density d) with iid non-zero elements generated with the rng random number generator

SparseArrays API

SparseArrays.AbstractSparseVectorType
AbstractSparseVector{Tv,Ti}

要素の型が Tv でインデックス型が Ti の一次元スパース配列(または配列のような型)のスーパークラス。 AbstractSparseArray{Tv,Ti,1} のエイリアスです。

source
SparseArrays.AbstractSparseMatrixType
AbstractSparseMatrix{Tv,Ti}

要素の型が Tv でインデックス型が Ti の二次元スパース配列(または配列のような型)のスーパタイプ。 AbstractSparseArray{Tv,Ti,2} のエイリアス。

source
SparseArrays.SparseVectorType
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であることを示しています。

dense ベクトルから直接スパースベクトルを作成するために sparse を使用する方が便利な場合があります。

sparse([5, 6, 0, 7])

は同じスパースベクトルを生成します。

source
SparseArrays.sparseFunction
sparse(A::Union{AbstractVector, AbstractMatrix})

ベクトルまたは行列 A をスパース配列に変換します。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

julia> [1.0, 0.0, 1.0]
3-element Vector{Float64}:
 1.0
 0.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
source
sparse(I, J, V,[ m, n, combine])

次のように、S[I[k], J[k]] = V[k] となる m x n のスパース行列 S を作成します。combine 関数は重複を結合するために使用されます。mn が指定されていない場合、それぞれ 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
source
SparseArrays.sparse!Function
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の効率的な連続構築が可能になり、結果の転置の非ソート列表現を追加コストなしで抽出することも可能になります。

このメソッドは、主に3つのステップで構成されています: (1) 提供された座標表現を、重複エントリを含む非ソート行CSR形式にカウントソートします。 (2) CSR形式をスイープしながら、目的のCSC形式の列ポインタ配列を同時に計算し、重複エントリを検出し、重複エントリを組み合わせてCSR形式を再パッキングします。この段階では、重複エントリのない非ソート行CSR形式が得られます。 (3) 前のCSR形式を、重複エントリのない完全にソートされたCSC形式にカウントソートします。

入力配列csrrowptrcsrcolval、およびcsrnzvalは、中間CSR形式のストレージを構成し、length(csrrowptr) >= m + 1length(csrcolval) >= length(I)、およびlength(csrnzval >= length(I))を必要とします。入力配列klasttouchは、第二段階のワークスペースであり、length(klasttouch) >= nを必要とします。オプションの入力配列csccolptrcscrowval、およびcscnzvalは、返されるCSC形式Sのストレージを構成します。必要に応じて、これらは自動的にサイズ変更され、length(csccolptr) = n + 1length(cscrowval) = nnz(S)、およびlength(cscnzval) = nnz(S)を満たします。したがって、nnz(S)が最初から不明な場合は、適切な型の空のベクター(それぞれVector{Ti}()およびVector{Tv}())を渡すか、cscrowvalおよびcscnzvalを無視してsparse!メソッドを呼び出すだけで済みます。

戻り値として、csrrowptrcsrcolval、およびcsrnzvalは、結果の転置の非ソート列表現を含みます。

出力配列(csccolptrcscrowvalcscnzval)のために、入力配列のストレージ(IJV)を再利用することができます。たとえば、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によって記述されたHALFPERMアルゴリズム、「スパース行列のための2つの高速アルゴリズム: 乗算と順序付けられた転置」、ACM TOMS 4(3)、250-269 (1978)が、このメソッドのカウントソートのペアの使用にインスピレーションを与えました。

source
SparseArrays.sparse!(I, J, V, [m, n, combine]) -> SparseMatrixCSC

入力ベクトル(IJV)を最終的な行列ストレージに再利用するsparse!のバリアントです。構築後、入力ベクトルは行列バッファをエイリアスします。S.colptr === IS.rowval === J、およびS.nzval === Vが成り立ち、必要に応じてresize!されます。

なお、一部の作業バッファはまだ割り当てられます。具体的には、このメソッドはsparse!(I, J, V, m, n, combine, klasttouch, csrrowptr, csrcolval, csrnzval, csccolptr, cscrowval, cscnzval)の便利なラッパーであり、このメソッドは適切なサイズのklasttouchcsrrowptrcsrcolval、およびcsrnzvalを割り当てますが、csccolptrcscrowval、およびcscnzvalにはIJ、およびVを再利用します。

引数mn、およびcombineはそれぞれmaximum(I)maximum(J)、および+にデフォルト設定されています。

Julia 1.10

このメソッドはJuliaバージョン1.10以降を必要とします。

source
SparseArrays.sparsevecFunction
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
source
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
source
sparsevec(A)

ベクトル A を長さ m のスパースベクトルに変換します。A の数値ゼロは構造ゼロに変換されます。

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
source
Base.similarMethod
similar(A::AbstractSparseMatrixCSC{Tv,Ti}, [::Type{TvNew}, ::Type{TiNew}, m::Integer, n::Integer]) where {Tv,Ti}

与えられた要素型、インデックス型、およびサイズに基づいて、指定されたソース SparseMatrixCSC に基づいて初期化されていない可変配列を作成します。新しいスパース行列は、出力行列の次元が異なる場合を除いて、元のスパース行列の構造を維持します。

出力行列は、入力と同じ位置にゼロを持ちますが、非ゼロの位置には初期化されていない値を持ちます。

source
SparseArrays.issparseFunction
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
source
SparseArrays.nnzFunction
nnz(A)

スパース配列に格納されている(埋められた)要素の数を返します。

julia> A = sparse(2I, 3, 3)
3×3 SparseMatrixCSC{Int64, Int64} with 3 stored entries:
 2  ⋅  ⋅
 ⋅  2  ⋅
 ⋅  ⋅  2

julia> nnz(A)
3
source
SparseArrays.findnzFunction
findnz(A::SparseMatrixCSC)

スパース行列 A における保存された(「構造的に非ゼロ」)値の行と列のインデックスを含むタプル (I, J, V) を返します。IJ はインデックスで、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])
source
SparseArrays.spzerosFunction
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
source
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

このメソッドはJuliaバージョン1.10以降を必要とします。

source
SparseArrays.spzeros!Function
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

このメソッドは、Juliaバージョン1.10以降を必要とします。

source
SparseArrays.spzeros!(::Type{Tv}, I, J, [m, n]) -> SparseMatrixCSC{Tv}

入力ベクトル IJ を最終的な行列ストレージに再利用する spzeros! のバリアント。構築後、入力ベクトルは行列バッファをエイリアスします;S.colptr === I および S.rowval === J が成り立ち、必要に応じて resize! されます。

いくつかの作業バッファはまだ割り当てられることに注意してください。具体的には、このメソッドは spzeros!(Tv, I, J, m, n, klasttouch, csrrowptr, csrcolval, csccolptr, cscrowval) の便利なラッパーであり、このメソッドは適切なサイズの klasttouchcsrrowptr、および csrcolval を割り当てますが、csccolptrcscrowvalIJ を再利用します。

引数 mn はそれぞれ maximum(I)maximum(J) にデフォルト設定されています。

Julia 1.10

このメソッドは Julia バージョン 1.10 以降を必要とします。

source
SparseArrays.spdiagmFunction
spdiagm(kv::Pair{<:Integer,<:AbstractVector}...)
spdiagm(m::Integer, n::Integer, kv::Pair{<:Integer,<:AbstractVector}...)

Pairのベクトルと対角線からスパース対角行列を構築します。各ベクトルkv.secondkv.first対角線に配置されます。デフォルトでは、行列は正方形であり、そのサイズはkvから推測されますが、必要に応じてゼロでパディングされた非正方形のサイズ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  ⋅
source
spdiagm(v::AbstractVector)
spdiagm(m::Integer, n::Integer, v::AbstractVector)

ベクトルの要素を対角要素とする疎行列を構築します。デフォルトでは(mnが指定されていない場合)、行列は正方形で、そのサイズはlength(v)によって決まりますが、最初の引数としてmnを渡すことで非正方形のサイズm×nを指定できます。

Julia 1.6

これらの関数は少なくとも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
source
SparseArrays.sparse_hcatFunction
sparse_hcat(A...)

次元2に沿って連結します。SparseMatrixCSCオブジェクトを返します。

Julia 1.8

このメソッドはJulia 1.8で追加されました。これは、LinearAlgebra.jlからの特化された「スパース」行列型との連結が、SparseArray引数がない場合でも自動的にスパース出力を生成する以前の連結動作を模倣しています。

source
SparseArrays.sparse_vcatFunction
sparse_vcat(A...)

次元1に沿って連結します。SparseMatrixCSCオブジェクトを返します。

Julia 1.8

このメソッドはJulia 1.8で追加されました。これは、LinearAlgebra.jlからの特化された「スパース」行列型との連結が、SparseArray引数がない場合でも自動的にスパース出力を生成する以前の連結動作を模倣しています。

source
SparseArrays.sparse_hvcatFunction
sparse_hvcat(rows::Tuple{Vararg{Int}}, values...)

スパースの水平および垂直の連結を1回の呼び出しで行います。この関数はブロック行列構文のために呼び出されます。最初の引数は、各ブロック行に連結する引数の数を指定します。

Julia 1.8

このメソッドはJulia 1.8で追加されました。これは、LinearAlgebra.jlからの特化された「スパース」行列型との連結が、SparseArray引数がない場合でも自動的にスパース出力を生成する以前の連結動作を模倣しています。

source
SparseArrays.blockdiagFunction
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
source
SparseArrays.sprandFunction
sprand([rng],[T::Type],m,[n],p::AbstractFloat)
sprand([rng],m,[n],p::AbstractFloat,[rfn=rand])

ランダムな長さ m のスパースベクトルまたは m x n のスパース行列を作成します。この行列の任意の要素が非ゼロである確率は独立して p によって与えられ(したがって、非ゼロの平均密度も正確に p になります)。オプションの rng 引数は乱数生成器を指定し、Random Numbersを参照してください。オプションの T 引数は要素の型を指定し、デフォルトは Float64 です。

デフォルトでは、非ゼロ値は rand 関数を使用して一様分布からサンプリングされます。つまり、rand(T) または rng が指定されている場合は rand(rng, T) です。デフォルトの T=Float64 の場合、これは [0,1) の範囲で一様にサンプリングされた非ゼロ値に対応します。

異なる分布から非ゼロ値をサンプリングするには、rand の代わりにカスタム rfn 関数を渡します。これは、希望する分布からサンプリングされた k 個の乱数の配列を返す関数 rfn(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
source
SparseArrays.sprandnFunction
sprandn([rng][,Type],m[,n],p::AbstractFloat)

長さ m のランダムスパースベクトルまたはサイズ m x n のスパース行列を作成し、任意のエントリが非ゼロである確率 p を指定します。非ゼロの値は正規分布からサンプリングされます。オプションの rng 引数は乱数生成器を指定します。詳細は Random Numbers を参照してください。

Julia 1.1

出力要素型 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
source
SparseArrays.nonzerosFunction
nonzeros(A)

スパース配列 A の構造的な非ゼロ値のベクトルを返します。これには、スパース配列に明示的に格納されているゼロも含まれます。返されるベクトルは A の内部非ゼロストレージを直接指し、返されたベクトルへの変更は A も変更します。rowvalsnzrange を参照してください。

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
source
SparseArrays.rowvalsFunction
rowvals(A)

スパース配列 A の行インデックスのベクトルを返します。返されたベクトルに対する変更は、A も変更します。行インデックスが内部でどのように格納されているかにアクセスすることは、構造的な非ゼロ値を反復処理する際に便利です。[nonzeros](@ref) および [nzrange](@ref) も参照してください。

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
source
SparseArrays.nzrangeFunction
nzrange(A, col::Integer)

スパース配列 A の列 col の構造的非ゼロ値のインデックスの範囲を返します。これに nonzerosrowvals を組み合わせることで、スパース行列を便利に反復処理できます:

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]
      # スパースの魔法を実行...
   end
end
Warning

行列に非ゼロ要素を追加または削除すると nzrange が無効になる可能性があるため、反復処理中に行列を変更してはいけません。

source
nzrange(x::SparseVectorUnion, col)

スパースベクトルの構造的な非ゼロ値のインデックスの範囲を返します。列インデックス col は無視されます(1 と仮定されます)。

source
SparseArrays.droptol!Function
droptol!(A::AbstractSparseMatrixCSC, tol)

Aから絶対値がtol以下の保存された値を削除します。

source
droptol!(x::AbstractCompressedVector, tol)

xから絶対値がtol以下の保存された値を削除します。

source
SparseArrays.dropzeros!Function
dropzeros!(x::AbstractCompressedVector)

xから保存された数値のゼロを削除します。

アウトオブプレースバージョンについては、dropzerosを参照してください。アルゴリズムに関する情報については、fkeep!を参照してください。

source
SparseArrays.dropzerosFunction
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
source
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
source
SparseArrays.permuteFunction
permute(A::AbstractSparseMatrixCSC{Tv,Ti}, p::AbstractVector{<:Integer},
        q::AbstractVector{<:Integer}) where {Tv,Ti}

行列 A を双方向に置換し、PAQA[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  ⋅  ⋅  ⋅
source
Base.permute!Method
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 に格納します。オプション引数 C が存在する場合、中間結果 (AQ)^T (transpose(A[:,q])) を C に格納します。XA、および、存在する場合は C が互いにエイリアスしないことが必要です。結果 PAQA に戻すには、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))、また XA のすべての割り当てられたエントリを収容できるだけのストレージを持っていなければなりません(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))、また CA のすべての割り当てられたエントリを収容できるだけのストレージを持っていなければなりません(length(rowvals(C)) >= nnz(A) および length(nonzeros(C)) >= nnz(A))。

追加の(アルゴリズム的な)情報や、引数チェックを省略したこれらのメソッドのバージョンについては、(エクスポートされていない)親メソッド unchecked_noalias_permute! および unchecked_aliasing_permute! を参照してください。

また permute も参照してください。

source
SparseArrays.halfperm!Function
halfperm!(X::AbstractSparseMatrixCSC{Tv,Ti}, A::AbstractSparseMatrixCSC{TvA,Ti},
          q::AbstractVector{<:Integer}, f::Function = identity) where {Tv,TvA,Ti}

列を入れ替え、Aを転置し、同時にfAの各エントリに適用し、その結果(f(A)Q)^Tmap(f, transpose(A[:,q])))をXに格納します。

Xの要素型Tvf(::TvA)と一致しなければなりません。ここで、TvAAの要素型です。Xの次元はtranspose(A)の次元と一致しなければならず(size(X, 1) == size(A, 2}およびsize(X, 2) == size(A, 1))、XAのすべての割り当てられたエントリを収容できるだけのストレージを持っていなければなりません(length(rowvals(X)) >= nnz(A)およびlength(nonzeros(X)) >= nnz(A))。列の入れ替えqの長さはAの列数と一致しなければなりません(length(q) == size(A, 2))。

このメソッドは、SparseMatrixCSCに対する転置および入れ替え操作を実行するいくつかのメソッドの親です。このメソッドは引数のチェックを行わないため、直接使用するのではなく、安全な子メソッド([c]transpose[!]permute[!])を使用することをお勧めします。

このメソッドは、F. Gustavsonによって記述されたHALFPERMアルゴリズムを実装しています。「スパース行列のための2つの高速アルゴリズム:乗算と入れ替え転置」、ACM TOMS 4(3)、250-269 (1978)。このアルゴリズムはO(size(A, 1), size(A, 2), nnz(A))の時間で実行され、渡された以外のスペースは必要ありません。

source
SparseArrays.ftranspose!Function
ftranspose!(X::AbstractSparseMatrixCSC{Tv,Ti}, A::AbstractSparseMatrixCSC{Tv,Ti}, f::Function) where {Tv,Ti}

Aを転置し、非ゼロ要素に関数fを適用しながらXに格納します。fによって生成されたゼロは削除されません。size(X)size(transpose(A))と等しくなければなりません。必要に応じてXのrowvalとnzvalのサイズ変更以外に追加のメモリは割り当てられません。

halfperm!を参照してください。

source

Noteworthy External Sparse Packages

いくつかの他のJuliaパッケージが言及されるべきスパース行列の実装を提供しています:

  1. SuiteSparseGraphBLAS.jl は、高速でマルチスレッド対応の SuiteSparse:GraphBLAS C ライブラリのラッパーです。CPU上では、通常これが最も高速なオプションであり、しばしば MKLSparse を大幅に上回ります。
  2. CUDA.jl は、GPU スパース行列操作のための CUSPARSE ライブラリを公開しています。
  3. SparseMatricesCSR.jl は、圧縮スパース行(CSR)フォーマットのJuliaネイティブ実装を提供します。
  4. MKLSparse.jl は、IntelのMKLライブラリを使用してSparseArraysのスパース-密行列演算を加速します。
  5. SparseArrayKit.jl は多次元スパース配列に利用可能です。
  6. LuxurySparse.jl は、静的スパース配列フォーマットと座標フォーマットを提供します。
  7. ExtendableSparse.jl は、新しい保存されたインデックスへの遅延アプローチを使用して、スパース行列への高速挿入を可能にします。
  8. Finch.jl は、ネイティブのJuliaを使用して、ミニテンソル言語とコンパイラを通じて、広範な多次元スパース配列フォーマットと操作をサポートします。COO、CSF、CSR、CSCなどのサポートに加え、ブロードキャスト、リデュースなどの操作やカスタム操作も含まれています。

外部パッケージによるスパース直接ソルバー:

  1. KLU.jl
  2. Pardiso.jl

固有値系と特異値分解の反復解法を提供する外部パッケージ:

  1. ArnoldiMethods.jl
  2. KrylovKit
  3. Arpack.jl

グラフを扱うための外部パッケージ:

  1. Graphs.jl