Sparse Arrays

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

異なるスパースストレージタイプ、マルチディメンショナルスパース配列などを実装した外部パッケージは、Noteworthy External Sparse Packages にあります。

Compressed Sparse Column (CSC) Sparse Matrix Storage

ジュリアでは、スパース行列は Compressed Sparse Column (CSC) format に格納されます。ジュリアのスパース行列は 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[I[k]] = V[k] となるスパースベクトル R を構築します。

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

Sparse Linear Algebra

スパース行列ソルバーは、SuiteSparse から関数を呼び出します。以下の因子分解が利用可能です:

TypeDescription
CHOLMOD.FactorCholesky and LDLt factorizations
UMFPACK.UmfpackLULU factorization
SPQR.QRSparseQR factorization

これらの因数分解は、Sparse Linear Algebra API sectionでより詳細に説明されています:

  1. cholesky
  2. ldlt
  3. lu
  4. qr

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)

抽象行列 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
source
sparse(I, J, V,[ m, n, combine])

次のように、m x n の次元を持つ疎行列 S を作成します。ここで、S[I[k], J[k]] = V[k] です。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 のスパースベクトルに変換します。

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])

構造的ゼロが S[I[k], J[k]] にある m x n のスパース行列 S を作成します。

このメソッドは行列のスパースパターンを構築するために使用でき、例えば 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.second`は`kv.first`対角線に配置されます。デフォルトでは、行列は正方形であり、そのサイズは`kv`から推測されますが、必要に応じてゼロでパディングされた非正方形のサイズ`m`×`n`を最初の引数として渡すことで指定できます。

# 例

jldoctest 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 関数を渡します。この関数は 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
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::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
source
SparseArrays.nzrangeFunction
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]
      # スパースの魔法を実行...
   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を転置し、同時にAの各エントリにfを適用し、その結果(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

Sparse Linear Algebra API

LinearAlgebra.choleskyFunction
cholesky(A, NoPivot(); check = true) -> Cholesky

密な対称正定値行列 A のコレスキー分解を計算し、Cholesky 分解を返します。行列 A は、Symmetric または Hermitian AbstractMatrix であるか、完全に 対称またはエルミートな AbstractMatrix である必要があります。

三角コレスキー因子は、分解 F から F.L および F.U を介して取得でき、A ≈ F.U' * F.U ≈ F.L * F.L' となります。

Cholesky オブジェクトに対して利用可能な関数は、size\invdetlogdet、および isposdef です。

構築時の丸め誤差により行列 A がわずかに非エルミートである場合は、cholesky に渡す前に Hermitian(A) でラップして、完全にエルミートとして扱います。

check = true の場合、分解が失敗した場合はエラーが発生します。check = false の場合、分解の有効性を確認する責任(issuccess を介して)はユーザーにあります。

julia> A = [4. 12. -16.; 12. 37. -43.; -16. -43. 98.]
3×3 Matrix{Float64}:
   4.0   12.0  -16.0
  12.0   37.0  -43.0
 -16.0  -43.0   98.0

julia> C = cholesky(A)
Cholesky{Float64, Matrix{Float64}}
U factor:
3×3 UpperTriangular{Float64, Matrix{Float64}}:
 2.0  6.0  -8.0
  ⋅   1.0   5.0
  ⋅    ⋅    3.0

julia> C.U
3×3 UpperTriangular{Float64, Matrix{Float64}}:
 2.0  6.0  -8.0
  ⋅   1.0   5.0
  ⋅    ⋅    3.0

julia> C.L
3×3 LowerTriangular{Float64, Matrix{Float64}}:
  2.0   ⋅    ⋅
  6.0  1.0   ⋅
 -8.0  5.0  3.0

julia> C.L * C.U == A
true
source
cholesky(A, RowMaximum(); tol = 0.0, check = true) -> CholeskyPivoted

密な対称半正定値行列 A のピボット付きコレスキー分解を計算し、CholeskyPivoted 分解を返します。行列 A は、Symmetric または Hermitian AbstractMatrix であるか、完全に 対称またはエルミートな AbstractMatrix である必要があります。

三角形のコレスキー因子は、分解 F から F.LF.U を介して取得でき、置換は F.p を介して取得できます。ここで、A[F.p, F.p] ≈ Ur' * Ur ≈ Lr * Lr' であり、Ur = F.U[1:F.rank, :] および Lr = F.L[:, 1:F.rank] です。または、A ≈ Up' * Up ≈ Lp * Lp' であり、Up = F.U[1:F.rank, invperm(F.p)] および Lp = F.L[invperm(F.p), 1:F.rank] です。

CholeskyPivoted オブジェクトに対して利用可能な関数は、size\invdet、および rank です。

引数 tol は、ランクを決定するための許容誤差を決定します。負の値の場合、許容誤差はマシン精度になります。

構築時の丸め誤差により、行列 A がわずかに非エルミートである場合は、cholesky に渡す前に Hermitian(A) でラップして、完全にエルミートとして扱います。

check = true の場合、分解が失敗した場合はエラーがスローされます。check = false の場合、分解の有効性を確認する責任(issuccess を介して)はユーザーにあります。

julia> X = [1.0, 2.0, 3.0, 4.0];

julia> A = X * X';

julia> C = cholesky(A, RowMaximum(), check = false)
CholeskyPivoted{Float64, Matrix{Float64}, Vector{Int64}}
U因子のランクは1:
4×4 UpperTriangular{Float64, Matrix{Float64}}:
 4.0  2.0  3.0  1.0
  ⋅   0.0  6.0  2.0
  ⋅    ⋅   9.0  3.0
  ⋅    ⋅    ⋅   1.0
置換:
4要素のベクトル{Int64}:
 4
 2
 3
 1

julia> C.U[1:C.rank, :]' * C.U[1:C.rank, :] ≈ A[C.p, C.p]
true

julia> l, u = C; # 繰り返しによる分解

julia> l == C.L && u == C.U
true
source
cholesky(A::SparseMatrixCSC; shift = 0.0, check = true, perm = nothing) -> CHOLMOD.Factor

スパースの正定値行列 A のコレスキー分解を計算します。ASparseMatrixCSC または SparseMatrixCSCSymmetric/Hermitian ビューでなければなりません。A が型タグを持っていなくても、対称またはエルミートである必要があります。perm が指定されていない場合、フィル削減置換が使用されます。F = cholesky(A) は、F\b を使用して方程式系を解くために最も頻繁に使用されますが、diagdet、および logdet のメソッドも F に対して定義されています。また、F から個々の因子を F.L を使用して抽出することもできます。ただし、ピボッティングがデフォルトでオンになっているため、分解は内部的に A == P'*L*L'*P として表現され、置換行列 P が含まれます。P を考慮せずに L のみを使用すると、誤った結果が得られます。置換の効果を含めるためには、通常、PtL = F.PtLP'*L の同等物)や LtP = F.UPL'*P の同等物)などの「結合」因子を抽出する方が好ましいです。

check = true の場合、分解が失敗した場合はエラーがスローされます。check = false の場合、分解の有効性を確認する責任(issuccess を介して)はユーザーにあります。

オプションの shift キーワード引数を設定すると、A の代わりに A+shift*I の分解が計算されます。perm 引数が提供される場合、それは 1:size(A,1) の置換であり、使用する順序を指定します(CHOLMOD のデフォルトの AMD 順序の代わりに)。

次の例では、使用されるフィル削減置換は [3, 2, 1] です。perm1:3 に設定されて置換が行われない場合、因子内の非ゼロ要素の数は 6 になります。

julia> A = [2 1 1; 1 2 0; 1 0 2]
3×3 Matrix{Int64}:
 2  1  1
 1  2  0
 1  0  2

julia> C = cholesky(sparse(A))
SparseArrays.CHOLMOD.Factor{Float64, Int64}
type:    LLt
method:  simplicial
maxnnz:  5
nnz:     5
success: true

julia> C.p
3-element Vector{Int64}:
 3
 2
 1

julia> L = sparse(C.L);

julia> Matrix(L)
3×3 Matrix{Float64}:
 1.41421   0.0       0.0
 0.0       1.41421   0.0
 0.707107  0.707107  1.0

julia> L * L' ≈ A[C.p, C.p]
true

julia> P = sparse(1:3, C.p, ones(3))
3×3 SparseMatrixCSC{Float64, Int64} with 3 stored entries:
  ⋅    ⋅   1.0
  ⋅   1.0   ⋅
 1.0   ⋅    ⋅

julia> P' * L * L' * P ≈ A
true

julia> C = cholesky(sparse(A), perm=1:3)
SparseArrays.CHOLMOD.Factor{Float64, Int64}
type:    LLt
method:  simplicial
maxnnz:  6
nnz:     6
success: true

julia> L = sparse(C.L);

julia> Matrix(L)
3×3 Matrix{Float64}:
 1.41421    0.0       0.0
 0.707107   1.22474   0.0
 0.707107  -0.408248  1.1547

julia> L * L' ≈ A
true
Note

このメソッドは、SuiteSparse の CHOLMOD[ACM887][DavisHager2009] ライブラリを使用しています。CHOLMOD は、単精度または倍精度の実数または複素数型のみをサポートしています。これらの要素型でない入力行列は、適切にこれらの型に変換されます。

CHOLMOD からの他の多くの関数はラップされていますが、Base.SparseArrays.CHOLMOD モジュールからはエクスポートされていません。

source
LinearAlgebra.cholesky!Function
cholesky!(A::AbstractMatrix, NoPivot(); check = true) -> Cholesky

cholesky と同じですが、入力 A を上書きすることでスペースを節約します。ファクタリゼーションが A の要素型で表現できない数を生成した場合、例えば整数型の場合、InexactError 例外がスローされます。

julia> A = [1 2; 2 50]
2×2 Matrix{Int64}:
 1   2
 2  50

julia> cholesky!(A)
ERROR: InexactError: Int64(6.782329983125268)
Stacktrace:
[...]
source
cholesky!(A::AbstractMatrix, RowMaximum(); tol = 0.0, check = true) -> CholeskyPivoted

cholesky と同様ですが、入力 A を上書きすることでスペースを節約し、コピーを作成しません。因数分解が A の要素型で表現できない数を生成した場合、例えば整数型の場合、InexactError 例外がスローされます。

source
cholesky!(F::CHOLMOD.Factor, A::SparseMatrixCSC; shift = 0.0, check = true) -> CHOLMOD.Factor

行列 A のコレスキー ($LL'$) 分解を計算し、符号的分解 F を再利用します。ASparseMatrixCSC または SparseMatrixCSCSymmetric/ Hermitian ビューでなければなりません。A が型タグを持っていなくても、対称またはエルミートである必要があります。

詳細は cholesky を参照してください。

Note

このメソッドは SuiteSparse の CHOLMOD ライブラリを使用しており、実数または複素数の単精度または倍精度の型のみをサポートしています。これらの要素型でない入力行列は、適切にこれらの型に変換されます。

source
LinearAlgebra.lowrankupdateFunction
lowrankupdate(C::Cholesky, v::AbstractVector) -> CC::Cholesky

ベクトル v で Cholesky 分解 C を更新します。もし A = C.U'C.U ならば CC = cholesky(C.U'C.U + v*v') ですが、CC の計算は O(n^2) の演算のみを使用します。

source
lowrankupdate(F::CHOLMOD.Factor, C::AbstractArray) -> FF::CHOLMOD.Factor

A + C*C'LDLt 因子分解を、ALDLt または LLt 因子分解 F に基づいて取得します。

返される因子は常に LDLt 因子分解です。

他にも lowrankupdate!, lowrankdowndate, lowrankdowndate! を参照してください。

source
LinearAlgebra.lowrankupdate!Function
lowrankupdate!(C::Cholesky, v::AbstractVector) -> CC::Cholesky

ベクトル v で Cholesky 分解 C を更新します。もし A = C.U'C.U ならば CC = cholesky(C.U'C.U + v*v') ですが、CC の計算は O(n^2) の演算のみを使用します。入力の分解 C はインプレースで更新され、終了時には C == CC となります。ベクトル v は計算中に破棄されます。

source
lowrankupdate!(F::CHOLMOD.Factor, C::AbstractArray)

ALDLtまたはLLt因子分解FA + C*C'の因子分解に更新します。

LLt因子分解はLDLtに変換されます。

lowrankupdatelowrankdowndatelowrankdowndate!も参照してください。

source
LinearAlgebra.lowrankdowndateFunction
lowrankdowndate(C::Cholesky, v::AbstractVector) -> CC::Cholesky

ベクトル v で Cholesky 分解 C をダウンドデートします。もし A = C.U'C.U ならば CC = cholesky(C.U'C.U - v*v') ですが、CC の計算は O(n^2) の演算のみを使用します。

source
lowrankdowndate(F::CHOLMOD.Factor, C::AbstractArray) -> FF::CHOLMOD.Factor

与えられた ALDLt または LLt 因子分解 F に対して、A + C*C'LDLt 因子分解を取得します。

返される因子は常に LDLt 因子分解です。

他にも lowrankdowndate!lowrankupdatelowrankupdate! を参照してください。

source
LinearAlgebra.lowrankdowndate!Function
lowrankdowndate!(C::Cholesky, v::AbstractVector) -> CC::Cholesky

ベクトル v で Cholesky 分解 C をダウンドデートします。もし A = C.U'C.U ならば CC = cholesky(C.U'C.U - v*v') ですが、CC の計算は O(n^2) の操作のみを使用します。入力の分解 C はインプレースで更新され、終了時には C == CC となります。ベクトル v は計算中に破棄されます。

source
lowrankdowndate!(F::CHOLMOD.Factor, C::AbstractArray)

ALDLtまたはLLt因子分解FA - C*C'の因子分解に更新します。

LLt因子分解はLDLtに変換されます。

lowrankdowndatelowrankupdatelowrankupdate!も参照してください。

source
SparseArrays.CHOLMOD.lowrankupdowndate!Function
lowrankupdowndate!(F::CHOLMOD.Factor, C::Sparse, update::Cint)

ALDLtまたはLLt因子分解FA ± C*C'の因子分解に更新します。

スパース性を保持する因子分解が使用されている場合、すなわちL*L' == P*A*P'であれば、新しい因子はL*L' == P*A*P' + C'*Cとなります。

update: Cint(1)A + CC'Cint(0)A - CC'を示します。

source
LinearAlgebra.ldltFunction
ldlt(S::SymTridiagonal) -> LDLt

実数対称三重対角行列 SLDLt(すなわち、$LDL^T$)因子分解を計算します。ここで、S = L*Diagonal(d)*L' となり、L は単位下三角行列、d はベクトルです。LDLt 因子分解 F = ldlt(S) の主な用途は、線形方程式系 Sx = bF\b で解くことです。

類似の、しかしピボットされた任意の対称またはエルミート行列の因子分解については、bunchkaufman を参照してください。

julia> S = SymTridiagonal([3., 4., 5.], [1., 2.])
3×3 SymTridiagonal{Float64, Vector{Float64}}:
 3.0  1.0   ⋅
 1.0  4.0  2.0
  ⋅   2.0  5.0

julia> ldltS = ldlt(S);

julia> b = [6., 7., 8.];

julia> ldltS \ b
3-element Vector{Float64}:
 1.7906976744186047
 0.627906976744186
 1.3488372093023255

julia> S \ b
3-element Vector{Float64}:
 1.7906976744186047
 0.627906976744186
 1.3488372093023255
source
ldlt(A::SparseMatrixCSC; shift = 0.0, check = true, perm=nothing) -> CHOLMOD.Factor

スパース行列 A$LDL'$ 分解を計算します。ASparseMatrixCSC または SparseMatrixCSCSymmetric/Hermitian ビューでなければなりません。A が型タグを持っていなくても、対称またはエルミートである必要があります。フィル削減置換が使用されます。F = ldlt(A) は、最も頻繁に方程式系 A*x = bF\b で解くために使用されます。返される分解オブジェクト F は、diagdetlogdet、および inv メソッドもサポートしています。F から個々の因子を F.L を使用して抽出できます。ただし、ピボッティングがデフォルトでオンになっているため、分解は内部的に A == P'*L*D*L'*P として表現され、置換行列 P が含まれます。P を考慮せずに単に L を使用すると、誤った結果が得られます。置換の影響を含めるためには、通常、PtL = F.PtLP'*L の同等物)や LtP = F.UPL'*P の同等物)などの「結合」因子を抽出する方が好ましいです。サポートされている因子の完全なリストは :L, :PtL, :D, :UP, :U, :LD, :DU, :PtLD, :DUP です。

check = true の場合、分解が失敗した場合はエラーがスローされます。check = false の場合、分解の有効性を確認する責任(issuccess を介して)はユーザーにあります。

オプションの shift キーワード引数を設定すると、A の代わりに A+shift*I の分解が計算されます。perm 引数が提供される場合、それは使用する順序を指定する 1:size(A,1) の置換である必要があります(CHOLMOD のデフォルトの AMD 順序の代わりに)。

Note

このメソッドは、SuiteSparse の CHOLMOD[ACM887][DavisHager2009] ライブラリを使用します。CHOLMOD は、単精度または倍精度の実数または複素数型のみをサポートしています。これらの要素型でない入力行列は、適切にこれらの型に変換されます。

CHOLMOD の他の多くの関数はラップされていますが、Base.SparseArrays.CHOLMOD モジュールからはエクスポートされていません。

source
LinearAlgebra.luFunction
lu(A::AbstractSparseMatrixCSC; check = true, q = nothing, control = get_umfpack_control()) -> F::UmfpackLU

スパース行列 A のLU因子分解を計算します。

実数または複素数要素型のスパース A に対して、F の戻り値の型は UmfpackLU{Tv, Ti} であり、TvFloat64 または ComplexF64 でそれぞれ、Ti は整数型(Int32 または Int64)です。

check = true の場合、分解が失敗した場合はエラーがスローされます。check = false の場合、分解の有効性を確認する責任はユーザーにあります(issuccess を介して)。

置換 q は置換ベクトルまたは nothing である可能性があります。置換ベクトルが提供されない場合や qnothing の場合、UMFPACKのデフォルトが使用されます。置換がゼロベースでない場合、ゼロベースのコピーが作成されます。

control ベクトルは、UMFPACKのためのJulia SparseArraysパッケージのデフォルト設定にデフォルトで設定されます(注:これは反復精度を無効にするためにUMFPACKのデフォルトから変更されています)が、UMFPACK_CONTROL の長さのベクトルを渡すことで変更できます。可能な設定についてはUMFPACKマニュアルを参照してください。たとえば、反復精度を再有効にするには:

umfpack_control = SparseArrays.UMFPACK.get_umfpack_control(Float64, Int64) # Float64スパース行列のためのJuliaデフォルト設定を読み取る
SparseArrays.UMFPACK.show_umf_ctrl(umfpack_control) # オプション - 値を表示
umfpack_control[SparseArrays.UMFPACK.JL_UMFPACK_IRSTEP] = 2.0 # 反復精度を再有効にする(2はUMFPACKのデフォルトの最大反復精度ステップ)

Alu = lu(A; control = umfpack_control)
x = Alu \ b   # Ax = b を解く、UMFPACKの反復精度を含む

因子分解 F の個々のコンポーネントにはインデックスを使用してアクセスできます:

コンポーネント説明
LLUL(下三角)部分
ULUU(上三角)部分
p右置換 Vector
q左置換 Vector
Rsスケーリングファクターの Vector
:(L,U,p,q,Rs) コンポーネント

FA の関係は次の通りです。

F.L*F.U == (F.Rs .* A)[F.p, F.q]

F はさらに以下の関数をサポートしています:

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

Note

lu(A::AbstractSparseMatrixCSC) は、SuiteSparse の一部であるUMFPACK[ACM832]ライブラリを使用します。このライブラリは、Float64 または ComplexF64 要素を持つスパース行列のみをサポートしているため、luASparseMatrixCSC{Float64} または SparseMatrixCSC{ComplexF64} 型のコピーに変換します。

source
lu(A, pivot = RowMaximum(); check = true, allowsingular = false) -> F::LU

行列 A のLU分解を計算します。

check = true の場合、分解が失敗した場合にエラーがスローされます。check = false の場合、分解の有効性を確認する責任はユーザーにあります(issuccess を介して)。

デフォルトでは、check = true の場合、有効な因子が生成されても、上三角因子 U がランク欠損の場合にもエラーがスローされます。これは allowsingular = true を渡すことで変更できます。

ほとんどの場合、A が要素型 T+-*、および / をサポートする AbstractMatrix{T} のサブタイプ S である場合、戻り値の型は LU{T,S{T}} です。

一般に、LU分解は行列の行の順序を入れ替えることを含みます(以下に説明する F.p 出力に対応)、これは「ピボット」と呼ばれます(これは「ピボット」を含む行を選択することに対応し、F.U の対角成分です)。次のいずれかのピボット戦略をオプションの pivot 引数を介して選択できます:

  • RowMaximum()(デフォルト):標準のピボット戦略;ピボットは、残りの因子化される行の中で最大絶対値の要素に対応します。このピボット戦略は、要素型が abs および < をサポートすることを要求します。(これは一般に浮動小数点行列にとって唯一の数値的に安定したオプションです。)
  • RowNonZero(): ピボットは、残りの因子化される行の中で最初の非ゼロ要素に対応します。(これは手計算での典型的な選択に対応し、iszero をサポートするが abs< をサポートしないより一般的な代数数型にも便利です。)
  • NoPivot(): ピボットをオフにします(ピボジションでゼロエントリに遭遇した場合、allowsingular = true の場合でも失敗します)。

分解 F の個々のコンポーネントには getproperty を介してアクセスできます:

コンポーネント説明
F.LLUL(下三角)部分
F.ULUU(上三角)部分
F.p(右)置換 Vector
F.P(右)置換 Matrix

分解を反復することで、コンポーネント F.LF.U、および F.p を得ることができます。

FA の関係は次の通りです。

F.L*F.U == A[F.p, :]

F はさらに次の関数をサポートします:

サポートされる関数LULU{T,Tridiagonal{T}}
/
\
inv
det
logdet
logabsdet
size
Julia 1.11

allowsingular キーワード引数は Julia 1.11 で追加されました。

julia> A = [4 3; 6 3]
2×2 Matrix{Int64}:
 4  3
 6  3

julia> F = lu(A)
LU{Float64, Matrix{Float64}, Vector{Int64}}
L因子:
2×2 Matrix{Float64}:
 1.0       0.0
 0.666667  1.0
U因子:
2×2 Matrix{Float64}:
 6.0  3.0
 0.0  1.0

julia> F.L * F.U == A[F.p, :]
true

julia> l, u, p = lu(A); # 反復を介した分解

julia> l == F.L && u == F.U && p == F.p
true

julia> lu([1 2; 1 2], allowsingular = true)
LU{Float64, Matrix{Float64}, Vector{Int64}}
L因子:
2×2 Matrix{Float64}:
 1.0  0.0
 1.0  1.0
U因子(ランク欠損):
2×2 Matrix{Float64}:
 1.0  2.0
 0.0  0.0
source
LinearAlgebra.qrFunction
qr(A::SparseMatrixCSC; tol=_default_tol(A), ordering=ORDERING_DEFAULT) -> QRSparse

スパース行列 AQR 分解を計算します。フィル削減行と列の置換が使用され、F.R = F.Q'*A[F.prow,F.pcol] となります。このタイプの主な用途は、\ を使用して最小二乗法または過剰決定問題を解決することです。この関数は C ライブラリ SPQR[ACM933] を呼び出します。

Note

qr(A::SparseMatrixCSC)SuiteSparse の一部である SPQR ライブラリを使用します。このライブラリは Float64 または ComplexF64 要素を持つスパース行列のみをサポートしているため、Julia v1.4 以降、qrASparseMatrixCSC{Float64} または SparseMatrixCSC{ComplexF64} 型のコピーに変換します。

julia> A = sparse([1,2,3,4], [1,1,2,2], [1.0,1.0,1.0,1.0])
4×2 SparseMatrixCSC{Float64, Int64} with 4 stored entries:
 1.0   ⋅
 1.0   ⋅
  ⋅   1.0
  ⋅   1.0

julia> qr(A)
SparseArrays.SPQR.QRSparse{Float64, Int64}
Q 因子:
4×4 SparseArrays.SPQR.QRSparseQ{Float64, Int64}
R 因子:
2×2 SparseMatrixCSC{Float64, Int64} with 2 stored entries:
 -1.41421    ⋅
   ⋅       -1.41421
行の置換:
4-element Vector{Int64}:
 1
 3
 4
 2
列の置換:
2-element Vector{Int64}:
 1
 2
source
qr(A, pivot = NoPivot(); blocksize) -> F

行列 A の QR 分解を計算します:直交行列(または A が複素数の場合はユニタリ行列)Q と上三角行列 R で、次のようになります。

\[A = Q R\]

返されるオブジェクト F は、パック形式で分解を格納します:

  • pivot == ColumnNorm() の場合、FQRPivoted オブジェクトです。
  • それ以外の場合、A の要素型が BLAS 型(Float32Float64ComplexF32 または ComplexF64)である場合、FQRCompactWY オブジェクトです。
  • それ以外の場合、FQR オブジェクトです。

分解の個々のコンポーネント F はプロパティアクセサを介して取得できます:

  • F.Q: 直交/ユニタリ行列 Q
  • F.R: 上三角行列 R
  • F.p: ピボットの置換ベクトル(QRPivoted のみ)
  • F.P: ピボットの置換行列(QRPivoted のみ)
Note

F.R を介して上三角因子に各参照を行うと、新しい配列が割り当てられます。したがって、その配列をキャッシュすることをお勧めします。たとえば、R = F.R として、R で作業を続けます。

分解を繰り返すことで、コンポーネント QR、および存在する場合は p を生成します。

QR オブジェクトに対しては、次の関数が利用可能です:invsize、および \A が長方形の場合、\ は最小二乗解を返し、解が一意でない場合は、最小ノルムのものが返されます。A がフルランクでない場合、最小ノルム解を得るためには(列)ピボッティングを伴う分解が必要です。

フル/正方行列または非フル/正方行列 Q に関しての乗算が許可されています。すなわち、F.Q*F.RF.Q*A の両方がサポートされています。Q 行列は Matrix を使用して通常の行列に変換できます。この操作は「薄い」Q因子を返します。すなわち、Am×nm>=n の場合、Matrix(F.Q) は直交正規列を持つ m×n 行列を生成します。「フル」Q因子を取得するには、F.Q*I または collect(F.Q) を使用します。m<=n の場合、Matrix(F.Q)m×m の直交行列を生成します。

QR 分解のブロックサイズは、pivot == NoPivot() かつ A isa StridedMatrix{<:BlasFloat} の場合にキーワード引数 blocksize :: Integer で指定できます。blocksize > minimum(size(A)) の場合は無視されます。詳細は QRCompactWY を参照してください。

Julia 1.4

blocksize キーワード引数は Julia 1.4 以降が必要です。

julia> A = [3.0 -6.0; 4.0 -8.0; 0.0 1.0]
3×2 Matrix{Float64}:
 3.0  -6.0
 4.0  -8.0
 0.0   1.0

julia> F = qr(A)
LinearAlgebra.QRCompactWY{Float64, Matrix{Float64}, Matrix{Float64}}
Q 因子: 3×3 LinearAlgebra.QRCompactWYQ{Float64, Matrix{Float64}, Matrix{Float64}}
R 因子:
2×2 Matrix{Float64}:
 -5.0  10.0
  0.0  -1.0

julia> F.Q * F.R == A
true
Note

qr は複数の型を返します。これは、LAPACK がハウスホルダー基本反射の積のメモリストレージ要件を最小限に抑えるためにいくつかの表現を使用するためであり、Q および R 行列を2つの別々の密行列としてではなく、コンパクトに格納できるようにします。

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
  • ACM887Chen, Y., Davis, T. A., Hager, W. W., & Rajamanickam, S. (2008). Algorithm 887: CHOLMOD, Supernodal Sparse Cholesky Factorization and Update/Downdate. ACM Trans. Math. Softw., 35(3). doi:10.1145/1391989.1391995
  • DavisHager2009Davis, Timothy A., & Hager, W. W. (2009). Dynamic Supernodes in Sparse Cholesky Update/Downdate and Triangular Solves. ACM Trans. Math. Softw., 35(4). doi:10.1145/1462173.1462176
  • ACM832Davis, Timothy A. (2004b). Algorithm 832: UMFPACK V4.3–-an Unsymmetric-Pattern Multifrontal Method. ACM Trans. Math. Softw., 30(2), 196–199. doi:10.1145/992200.992206
  • ACM933Foster, L. V., & Davis, T. A. (2013). Algorithm 933: Reliable Calculation of Numerical Rank, Null Space Bases, Pseudoinverse Solutions, and Basic Solutions Using SuitesparseQR. ACM Trans. Math. Softw., 40(1). doi:10.1145/2513109.2513116