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 セクションに記載されています。
Sparse | Dense | Description |
---|---|---|
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 から関数を呼び出します。以下の因子分解が利用可能です:
Type | Description |
---|---|
CHOLMOD.Factor | Cholesky and LDLt factorizations |
UMFPACK.UmfpackLU | LU factorization |
SPQR.QRSparse | QR factorization |
これらの因数分解は、Sparse Linear Algebra API sectionでより詳細に説明されています:
SparseArrays API
SparseArrays.AbstractSparseArray
— TypeAbstractSparseArray{Tv,Ti,N}
Tv
型の要素とTi
型のインデックスを持つN
次元のスパース配列(または配列のような型)のスーパタイプです。 SparseMatrixCSC
、SparseVector
およびSuiteSparse.CHOLMOD.Sparse
はこのサブタイプです。
SparseArrays.AbstractSparseVector
— TypeAbstractSparseVector{Tv,Ti}
要素の型が Tv
でインデックスの型が Ti
の一次元スパース配列(または配列のような型)のスーパークラス。 AbstractSparseArray{Tv,Ti,1}
のエイリアスです。
SparseArrays.AbstractSparseMatrix
— TypeAbstractSparseMatrix{Tv,Ti}
要素の型が Tv
でインデックス型が Ti
の二次元スパース配列(または配列のような型)のスーパークラス。 AbstractSparseArray{Tv,Ti,2}
のエイリアスです。
SparseArrays.SparseVector
— TypeSparseVector{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])
は同じスパースベクトルを生成します。
SparseArrays.SparseMatrixCSC
— TypeSparseMatrixCSC{Tv,Ti<:Integer} <: AbstractSparseMatrixCSC{Tv,Ti}
疎行列を圧縮スパース列形式で格納するための行列タイプ。SparseMatrixCSCを構築する標準的な方法は、sparse
関数を通じてです。spzeros
、spdiagm
、およびsprand
も参照してください。
SparseArrays.sparse
— Functionsparse(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
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!
— Functionsparse!(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形式にカウントソートします。
入力配列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}()
)を渡すか、cscrowval
およびcscnzval
を無視してsparse!
メソッドを呼び出すだけで済みます。
戻り値として、csrrowptr
、csrcolval
、およびcsrnzval
は、結果の転置の非ソート列表現を含みます。
出力配列(csccolptr
、cscrowval
、cscnzval
)のために、入力配列のストレージ(I
、J
、V
)を再利用することができます。たとえば、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)が、このメソッドのカウントソートのペアの使用にインスピレーションを与えました。
SparseArrays.sparse!(I, J, V, [m, n, combine]) -> SparseMatrixCSC
入力ベクトル(I
、J
、V
)を最終的な行列ストレージに再利用するsparse!
のバリアントです。構築後、入力ベクトルは行列バッファをエイリアスします;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
を割り当てますが、csccolptr
、cscrowval
、およびcscnzval
にはI
、J
、およびV
を再利用します。
引数m
、n
、およびcombine
はそれぞれmaximum(I)
、maximum(J)
、および+
にデフォルト設定されています。
このメソッドはJuliaバージョン1.10以降を必要とします。
SparseArrays.sparsevec
— Functionsparsevec(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
— Methodsimilar(A::AbstractSparseMatrixCSC{Tv,Ti}, [::Type{TvNew}, ::Type{TiNew}, m::Integer, n::Integer]) where {Tv,Ti}
与えられた要素型、インデックス型、およびサイズに基づいて、指定されたソース SparseMatrixCSC
に基づいて初期化されていない可変配列を作成します。新しいスパース行列は、出力行列の次元が異なる場合を除いて、元のスパース行列の構造を維持します。
出力行列は、入力と同じ位置にゼロを持ちますが、非ゼロの位置には初期化されていない値を持ちます。
SparseArrays.issparse
— Functionissparse(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
— Functionnnz(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
— Functionfindnz(A::SparseMatrixCSC)
スパース行列 A
に格納された(「構造的に非ゼロ」)値の行と列のインデックスを持つタプル (I, J, V)
を返します。ここで I
と J
はインデックス、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
— Functionspzeros([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])
構造的ゼロが S[I[k], J[k]]
にある m x n
のスパース行列 S
を作成します。
このメソッドは行列のスパースパターンを構築するために使用でき、例えば sparse(I, J, zeros(length(I)))
を使用するよりも効率的です。
追加のドキュメントと専門的なドライバーについては SparseArrays.spzeros!
を参照してください。
このメソッドはJuliaバージョン1.10以降を必要とします。
SparseArrays.spzeros!
— Functionspzeros!(::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}
入力ベクトル I
と J
を最終的な行列ストレージに再利用する spzeros!
のバリアントです。構築後、入力ベクトルは行列バッファをエイリアスします; S.colptr === I
および S.rowval === J
が成り立ち、必要に応じて resize!
されます。
いくつかの作業バッファはまだ割り当てられることに注意してください。具体的には、このメソッドは spzeros!(Tv, I, J, m, n, klasttouch, csrrowptr, csrcolval, csccolptr, cscrowval)
の便利なラッパーであり、このメソッドは適切なサイズの klasttouch
、csrrowptr
、および csrcolval
を割り当てますが、csccolptr
と cscrowval
に I
と J
を再利用します。
引数 m
と n
はそれぞれ maximum(I)
と maximum(J)
にデフォルト設定されています。
このメソッドは Julia バージョン 1.10 以降を必要とします。
SparseArrays.spdiagm
— Functionspdiagm(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 ⋅
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
— Functionsparse_hcat(A...)
次元2に沿って連結します。SparseMatrixCSCオブジェクトを返します。
このメソッドはJulia 1.8で追加されました。これは、LinearAlgebra.jlからの特化された「スパース」行列型との連結が、SparseArray引数がない場合でも自動的にスパース出力を生成する以前の連結動作を模倣しています。
SparseArrays.sparse_vcat
— Functionsparse_vcat(A...)
次元1に沿って連結します。SparseMatrixCSCオブジェクトを返します。
このメソッドはJulia 1.8で追加されました。これは、LinearAlgebra.jlからの特化された「スパース」行列タイプとの連結が、SparseArray引数がない場合でも自動的にスパース出力を生成する以前の連結動作を模倣しています。
SparseArrays.sparse_hvcat
— Functionsparse_hvcat(rows::Tuple{Vararg{Int}}, values...)
スパースの水平および垂直の連結を1回の呼び出しで行います。この関数はブロック行列構文のために呼び出されます。最初の引数は、各ブロック行に連結する引数の数を指定します。
このメソッドはJulia 1.8で追加されました。これは、LinearAlgebra.jlからの特化された「スパース」行列型との連結が、SparseArray引数がない場合でも自動的にスパース出力を生成する以前の連結動作を模倣しています。
SparseArrays.blockdiag
— Functionblockdiag(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
— Functionsprand([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
SparseArrays.sprandn
— Functionsprandn([rng][,Type],m[,n],p::AbstractFloat)
長さ m
のランダムスパースベクトルまたはサイズ m
x n
のスパース行列を作成し、任意のエントリが非ゼロである確率 p
を指定します。非ゼロの値は正規分布からサンプリングされます。オプションの rng
引数は乱数生成器を指定し、Random Numbersを参照してください。
出力要素型 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
— Functionnonzeros(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
— Functionrowvals(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
— Functionnzrange(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
行列に非ゼロ要素を追加または削除すると、nzrange
が無効になる可能性があるため、反復処理中に行列を変更しないでください。
nzrange(x::SparseVectorUnion, col)
スパースベクトルの構造的な非ゼロ値のインデックスの範囲を返します。列インデックス col
は無視されます(1
と仮定されます)。
SparseArrays.droptol!
— Functiondroptol!(A::AbstractSparseMatrixCSC, tol)
A
の絶対値がtol
以下の保存された値を削除します。
droptol!(x::AbstractCompressedVector, tol)
x
から絶対値がtol
以下の格納された値を削除します。
SparseArrays.dropzeros!
— Functiondropzeros!(x::AbstractCompressedVector)
x
から保存された数値のゼロを削除します。
アウトオブプレースバージョンについては、dropzeros
を参照してください。アルゴリズムに関する情報については、fkeep!
を参照してください。
SparseArrays.dropzeros
— Functiondropzeros(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
— Functionpermute(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!
— Methodpermute!(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
に格納します。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!
— Functionhalfperm!(X::AbstractSparseMatrixCSC{Tv,Ti}, A::AbstractSparseMatrixCSC{TvA,Ti},
q::AbstractVector{<:Integer}, f::Function = identity) where {Tv,TvA,Ti}
列を入れ替え、A
を転置し、同時にA
の各エントリにf
を適用し、その結果(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
アルゴリズムを実装しています。「スパース行列のための2つの高速アルゴリズム:乗算と入れ替え転置」、ACM TOMS 4(3)、250-269(1978)。このアルゴリズムはO(size(A, 1), size(A, 2), nnz(A))
の時間で実行され、渡された以外のスペースは必要ありません。
SparseArrays.ftranspose!
— Functionftranspose!(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!
を参照してください。
Sparse Linear Algebra API
LinearAlgebra.cholesky
— Functioncholesky(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
、\
、inv
、det
、logdet
、および 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
cholesky(A, RowMaximum(); tol = 0.0, check = true) -> CholeskyPivoted
密な対称半正定値行列 A
のピボット付きコレスキー分解を計算し、CholeskyPivoted
分解を返します。行列 A
は、Symmetric
または Hermitian
AbstractMatrix
であるか、完全に 対称またはエルミートな AbstractMatrix
である必要があります。
三角形のコレスキー因子は、分解 F
から F.L
と F.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
、\
、inv
、det
、および 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
cholesky(A::SparseMatrixCSC; shift = 0.0, check = true, perm = nothing) -> CHOLMOD.Factor
スパースの正定値行列 A
のコレスキー分解を計算します。A
は SparseMatrixCSC
または SparseMatrixCSC
の Symmetric
/Hermitian
ビューでなければなりません。A
が型タグを持っていなくても、対称またはエルミートである必要があります。perm
が指定されていない場合、フィル削減置換が使用されます。F = cholesky(A)
は、F\b
を使用して方程式系を解くために最も頻繁に使用されますが、diag
、det
、および logdet
のメソッドも F
に対して定義されています。また、F
から個々の因子を F.L
を使用して抽出することもできます。ただし、ピボッティングがデフォルトでオンになっているため、分解は内部的に A == P'*L*L'*P
として表現され、置換行列 P
が含まれます。P
を考慮せずに L
のみを使用すると、誤った結果が得られます。置換の効果を含めるためには、通常、PtL = F.PtL
(P'*L
の同等物)や LtP = F.UP
(L'*P
の同等物)などの「結合」因子を抽出する方が好ましいです。
check = true
の場合、分解が失敗した場合はエラーがスローされます。check = false
の場合、分解の有効性を確認する責任(issuccess
を介して)はユーザーにあります。
オプションの shift
キーワード引数を設定すると、A
の代わりに A+shift*I
の分解が計算されます。perm
引数が提供される場合、それは 1:size(A,1)
の置換であり、使用する順序を指定します(CHOLMOD のデフォルトの AMD 順序の代わりに)。
例
次の例では、使用されるフィル削減置換は [3, 2, 1]
です。perm
が 1: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
このメソッドは、SuiteSparse の CHOLMOD[ACM887][DavisHager2009] ライブラリを使用しています。CHOLMOD は、単精度または倍精度の実数または複素数型のみをサポートしています。これらの要素型でない入力行列は、適切にこれらの型に変換されます。
CHOLMOD からの他の多くの関数はラップされていますが、Base.SparseArrays.CHOLMOD
モジュールからはエクスポートされていません。
LinearAlgebra.cholesky!
— Functioncholesky!(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:
[...]
cholesky!(A::AbstractMatrix, RowMaximum(); tol = 0.0, check = true) -> CholeskyPivoted
cholesky
と同様ですが、入力 A
を上書きすることでスペースを節約し、コピーを作成しません。因数分解が A
の要素型で表現できない数を生成した場合、例えば整数型の場合、InexactError
例外がスローされます。
cholesky!(F::CHOLMOD.Factor, A::SparseMatrixCSC; shift = 0.0, check = true) -> CHOLMOD.Factor
行列 A
のコレスキー ($LL'$) 分解を計算し、符号的分解 F
を再利用します。A
は SparseMatrixCSC
または SparseMatrixCSC
の Symmetric
/ Hermitian
ビューでなければなりません。A
が型タグを持っていなくても、対称またはエルミートである必要があります。
詳細は cholesky
を参照してください。
このメソッドは SuiteSparse の CHOLMOD ライブラリを使用しており、実数または複素数の単精度または倍精度の型のみをサポートしています。これらの要素型でない入力行列は、適切にこれらの型に変換されます。
LinearAlgebra.lowrankupdate
— Functionlowrankupdate(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)
の演算のみを使用します。
lowrankupdate(F::CHOLMOD.Factor, C::AbstractArray) -> FF::CHOLMOD.Factor
A + C*C'
の LDLt
因子分解を、A
の LDLt
または LLt
因子分解 F
に基づいて取得します。
返される因子は常に LDLt
因子分解です。
他にも lowrankupdate!
, lowrankdowndate
, lowrankdowndate!
を参照してください。
LinearAlgebra.lowrankupdate!
— Functionlowrankupdate!(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
は計算中に破棄されます。
lowrankupdate!(F::CHOLMOD.Factor, C::AbstractArray)
A
のLDLt
またはLLt
因子分解F
をA + C*C'
の因子分解に更新します。
LLt
因子分解はLDLt
に変換されます。
lowrankupdate
、lowrankdowndate
、lowrankdowndate!
も参照してください。
LinearAlgebra.lowrankdowndate
— Functionlowrankdowndate(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)
の演算のみを使用します。
lowrankdowndate(F::CHOLMOD.Factor, C::AbstractArray) -> FF::CHOLMOD.Factor
与えられた A
の LDLt
または LLt
因子分解 F
に対して、A + C*C'
の LDLt
因子分解を取得します。
返される因子は常に LDLt
因子分解です。
他にも lowrankdowndate!
、lowrankupdate
、lowrankupdate!
を参照してください。
LinearAlgebra.lowrankdowndate!
— Functionlowrankdowndate!(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
は計算中に破棄されます。
lowrankdowndate!(F::CHOLMOD.Factor, C::AbstractArray)
A
のLDLt
またはLLt
因子分解F
をA - C*C'
の因子分解に更新します。
LLt
因子分解はLDLt
に変換されます。
lowrankdowndate
、lowrankupdate
、lowrankupdate!
も参照してください。
SparseArrays.CHOLMOD.lowrankupdowndate!
— Functionlowrankupdowndate!(F::CHOLMOD.Factor, C::Sparse, update::Cint)
A
のLDLt
またはLLt
因子分解F
をA ± C*C'
の因子分解に更新します。
スパース性を保持する因子分解が使用されている場合、すなわちL*L' == P*A*P'
であれば、新しい因子はL*L' == P*A*P' + C'*C
となります。
update
: Cint(1)
はA + CC'
、Cint(0)
はA - CC'
を示します。
LinearAlgebra.ldlt
— Functionldlt(S::SymTridiagonal) -> LDLt
実数対称三重対角行列 S
の LDLt
(すなわち、$LDL^T$)因子分解を計算します。ここで、S = L*Diagonal(d)*L'
となり、L
は単位下三角行列、d
はベクトルです。LDLt
因子分解 F = ldlt(S)
の主な用途は、線形方程式系 Sx = b
を F\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
ldlt(A::SparseMatrixCSC; shift = 0.0, check = true, perm=nothing) -> CHOLMOD.Factor
スパース行列 A
の $LDL'$ 分解を計算します。A
は SparseMatrixCSC
または SparseMatrixCSC
の Symmetric
/Hermitian
ビューでなければなりません。A
が型タグを持っていなくても、対称またはエルミートである必要があります。フィル削減置換が使用されます。F = ldlt(A)
は、最も頻繁に方程式系 A*x = b
を F\b
で解くために使用されます。返される分解オブジェクト F
は、diag
、det
、logdet
、および inv
メソッドもサポートしています。F
から個々の因子を F.L
を使用して抽出できます。ただし、ピボッティングがデフォルトでオンになっているため、分解は内部的に A == P'*L*D*L'*P
として表現され、置換行列 P
が含まれます。P
を考慮せずに単に L
を使用すると、誤った結果が得られます。置換の影響を含めるためには、通常、PtL = F.PtL
(P'*L
の同等物)や LtP = F.UP
(L'*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 順序の代わりに)。
このメソッドは、SuiteSparse の CHOLMOD[ACM887][DavisHager2009] ライブラリを使用します。CHOLMOD は、単精度または倍精度の実数または複素数型のみをサポートしています。これらの要素型でない入力行列は、適切にこれらの型に変換されます。
CHOLMOD の他の多くの関数はラップされていますが、Base.SparseArrays.CHOLMOD
モジュールからはエクスポートされていません。
LinearAlgebra.lu
— Functionlu(A::AbstractSparseMatrixCSC; check = true, q = nothing, control = get_umfpack_control()) -> F::UmfpackLU
スパース行列 A
のLU因子分解を計算します。
実数または複素数要素型のスパース A
に対して、F
の戻り値の型は UmfpackLU{Tv, Ti}
であり、Tv
は Float64
または ComplexF64
でそれぞれ、Ti
は整数型(Int32
または Int64
)です。
check = true
の場合、分解が失敗した場合はエラーがスローされます。check = false
の場合、分解の有効性を確認する責任はユーザーにあります(issuccess
を介して)。
置換 q
は置換ベクトルまたは nothing
である可能性があります。置換ベクトルが提供されない場合や q
が nothing
の場合、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
の個々のコンポーネントにはインデックスを使用してアクセスできます:
コンポーネント | 説明 |
---|---|
L | LU の L (下三角)部分 |
U | LU の U (上三角)部分 |
p | 右置換 Vector |
q | 左置換 Vector |
Rs | スケーリングファクターの Vector |
: | (L,U,p,q,Rs) コンポーネント |
F
と A
の関係は次の通りです。
F.L*F.U == (F.Rs .* A)[F.p, F.q]
F
はさらに以下の関数をサポートしています:
また lu!
も参照してください。
lu(A::AbstractSparseMatrixCSC)
は、SuiteSparse の一部であるUMFPACK[ACM832]ライブラリを使用します。このライブラリは、Float64
または ComplexF64
要素を持つスパース行列のみをサポートしているため、lu
は A
を SparseMatrixCSC{Float64}
または SparseMatrixCSC{ComplexF64}
型のコピーに変換します。
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.L | LU の L (下三角)部分 |
F.U | LU の U (上三角)部分 |
F.p | (右)置換 Vector |
F.P | (右)置換 Matrix |
分解を反復することで、コンポーネント F.L
、F.U
、および F.p
を得ることができます。
F
と A
の関係は次の通りです。
F.L*F.U == A[F.p, :]
F
はさらに次の関数をサポートします:
サポートされる関数 | LU | LU{T,Tridiagonal{T}} |
---|---|---|
/ | ✓ | |
\ | ✓ | ✓ |
inv | ✓ | ✓ |
det | ✓ | ✓ |
logdet | ✓ | ✓ |
logabsdet | ✓ | ✓ |
size | ✓ | ✓ |
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
LinearAlgebra.qr
— Functionqr(A::SparseMatrixCSC; tol=_default_tol(A), ordering=ORDERING_DEFAULT) -> QRSparse
スパース行列 A
の QR
分解を計算します。フィル削減行と列の置換が使用され、F.R = F.Q'*A[F.prow,F.pcol]
となります。このタイプの主な用途は、\
を使用して最小二乗法または過剰決定問題を解決することです。この関数は C ライブラリ SPQR[ACM933] を呼び出します。
qr(A::SparseMatrixCSC)
は SuiteSparse の一部である SPQR ライブラリを使用します。このライブラリは Float64
または ComplexF64
要素を持つスパース行列のみをサポートしているため、Julia v1.4 以降、qr
は A
を SparseMatrixCSC{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
qr(A, pivot = NoPivot(); blocksize) -> F
行列 A
の QR 分解を計算します:直交行列(または A
が複素数の場合はユニタリ行列)Q
と上三角行列 R
で、次のようになります。
\[A = Q R\]
返されるオブジェクト F
は、パック形式で分解を格納します:
pivot == ColumnNorm()
の場合、F
はQRPivoted
オブジェクトです。- それ以外の場合、
A
の要素型が BLAS 型(Float32
、Float64
、ComplexF32
またはComplexF64
)である場合、F
はQRCompactWY
オブジェクトです。 - それ以外の場合、
F
はQR
オブジェクトです。
分解の個々のコンポーネント F
はプロパティアクセサを介して取得できます:
F.R
を介して上三角因子に各参照を行うと、新しい配列が割り当てられます。したがって、その配列をキャッシュすることをお勧めします。たとえば、R = F.R
として、R
で作業を続けます。
分解を繰り返すことで、コンポーネント Q
、R
、および存在する場合は p
を生成します。
QR
オブジェクトに対しては、次の関数が利用可能です:inv
、size
、および \
。A
が長方形の場合、\
は最小二乗解を返し、解が一意でない場合は、最小ノルムのものが返されます。A
がフルランクでない場合、最小ノルム解を得るためには(列)ピボッティングを伴う分解が必要です。
フル/正方行列または非フル/正方行列 Q
に関しての乗算が許可されています。すなわち、F.Q*F.R
と F.Q*A
の両方がサポートされています。Q
行列は Matrix
を使用して通常の行列に変換できます。この操作は「薄い」Q因子を返します。すなわち、A
が m
×n
で m>=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
を参照してください。
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
qr
は複数の型を返します。これは、LAPACK がハウスホルダー基本反射の積のメモリストレージ要件を最小限に抑えるためにいくつかの表現を使用するためであり、Q
および R
行列を2つの別々の密行列としてではなく、コンパクトに格納できるようにします。
Noteworthy External Sparse Packages
いくつかの他のJuliaパッケージが言及されるべきスパース行列の実装を提供しています:
- SuiteSparseGraphBLAS.jl は、高速でマルチスレッド対応の SuiteSparse:GraphBLAS C ライブラリのラッパーです。CPU上では、通常これが最も高速なオプションであり、しばしば MKLSparse を大幅に上回ります。
- CUDA.jl は、GPU スパース行列操作のための CUSPARSE ライブラリを公開しています。
- SparseMatricesCSR.jl は、圧縮スパース行(CSR)フォーマットのJuliaネイティブ実装を提供します。
- MKLSparse.jl は、IntelのMKLライブラリを使用してSparseArraysのスパース-密行列操作を加速します。
- SparseArrayKit.jl は多次元スパース配列に利用可能です。
- LuxurySparse.jl は、静的スパース配列フォーマットと座標フォーマットを提供します。
- ExtendableSparse.jl は、新しい保存されたインデックスへの遅延アプローチを使用して、スパース行列への高速挿入を可能にします。
- Finch.jl は、ネイティブのJuliaを使用して、ミニテンソル言語とコンパイラを通じて、広範な多次元スパース配列フォーマットと操作をサポートします。COO、CSF、CSR、CSCなどのサポートに加え、ブロードキャスト、リデュースなどの操作やカスタム操作も可能です。
外部パッケージによるスパース直接ソルバー:
外部パッケージは、固有システムおよび特異値分解の反復解法のためのソルバーを提供しています:
グラフを扱うための外部パッケージ:
- 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