SparseArrays

Julia は疎ベクトルと疎行列のサポートを標準ライブラリの SparseArrays モジュールに持ちます。疎配列とはゼロ要素を多く持つために密配列ではない特別なデータ構造を使うことで空間効率と実行速度を改善できるような配列です。

疎行列の格納形式

Julia は疎行列を圧縮列格納形式 (compressed sparse column format, CSC) で格納します。Julia の疎行列は SparseMatrixCSC{Tv,Ti} という型を持ち、ここで Tv は格納される値の型、Ti は列ポインタと行インデックスに使われる整数型を表します。SparseMatrixCSC の内部表現は次の通りです:

struct SparseMatrixCSC{Tv,Ti<:Integer} <: AbstractSparseMatrix{Tv,Ti}
    m::Int                  # 行数
    n::Int                  # 列数
    colptr::Vector{Ti}      # 第 j 列は colptr[j]:(colptr[j+1]-1) にある
    rowval::Vector{Ti}      # 格納された値の行インデックス
    nzval::Vector{Tv}       # 格納される値 (通常は非ゼロ)
end

CSC 形式により疎行列の要素への列ごとのアクセスは高速になりますが、行ごとのアクセスは非常に低速になります。また CSC 形式を使う疎行列の格納されていない部分に要素を一つずつ挿入するといった操作は遅くなる傾向があります。これは挿入される要素より後ろの要素を全て一つずつ後ろに動かす必要があるためです。

疎行列に対する全ての操作は CSC を活用して性能を向上させ、コストの大きい操作を避けるよう注意深く実装されています。

異なるアプリケーションやライブラリからの CSC 形式のデータを Julia にインポートするときは、1 始まりの添え字が使われていることを確認してください。また各列の行インデックスはソートされている必要があります。SparseMatrixCSC オブジェクトがソートされていない行インデックスを持つときは、二回転置を取ると簡単にソートできます。

一部のアプリケーションでは SparseMatrixCSC に一部のゼロ要素を明示的に保存した方がよい場合もあります。Base の関数はそういったオブジェクトに対しても正しく動作します (が、改変を行う操作で格納されたゼロ要素が保存されるとは限りません)。多くのルーチンは明示的に格納されたゼロ要素を “構造的” 非ゼロ要素とみなします。例えば nnz は疎データ構造に格納された要素数を返しますが、この値には構造的非ゼロ要素の個数が含まれます。“数値的” 非ゼロ要素を数えるには、count(!iszero, x) を使って疎行列に格納された各要素を調べてください。dropzeros およびインプレースの dropzeros! を使えば疎行列に格納されたゼロ要素を削除できます。

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

julia> dropzeros(A)
3×3 SparseMatrixCSC{Int64,Int64} with 2 stored entries:
  [2, 2]  =  2
  [1, 3]  =  1

疎ベクトルの格納形式

疎ベクトルは疎行列に対する CSC 形式によく似た形式で格納されます。Julia の疎ベクトルは SparseVector(Tv,Ti) という型を持ち、ここで Tv は格納される値の型、Ti は添え字で使われる整数型です。内部表現は次の通りです:

struct SparseVector{Tv,Ti<:Integer} <: AbstractSparseVector{Tv,Ti}
    n::Int              # 疎ベクトルの長さ
    nzind::Vector{Ti}   # 格納された値の添え字
    nzval::Vector{Tv}   # 格納された値 (通常は非ゼロ)
end

SparseMatrixCSC と同様に、SparseVector 型には明示的なゼロ要素を格納できます (参照: 疎行列の格納形式)。

疎ベクトルと疎行列のコンストラクタ

疎配列を作る最も単純な方法は、密行列の zeros に対応する関数を使うものです。疎配列を作るときは sp が最初に付いた spzeros 関数を使います:

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

sparse 関数を使っても疎配列を簡単に構築できます。例えば疎行列を構築するには、行の添え字からなるベクトル I, 列の添え字からなるベクトル J, 格納される値からなるベクトル Vsparse に渡します (この形式は COO 形式と呼ばれます)。このとき sparse(I,J,V) が構築する疎行列 S では S[I[k], J[k]] = V[k] が全ての添え字 k に対して成り立ちます。同様の疎ベクトルコンストラクタは sparsevec であり、(行の) 添え字からなるベクトル I と格納する値からなるベクトル V を渡すと、全ての添え字 k に対して 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:
  [1,  4]  =  1
  [4,  7]  =  2
  [5,  9]  =  3
  [3, 18]  =  -5

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 であり、この関数は入力と同じ疎配列を作成する sparse/sparsevec への入力を返します。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 Array{CartesianIndex{2},1}:
 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 Array{Int64,1}:
 1
 3
 4
 5

sparse 関数を使って密配列から変換することでも疎配列は作成できます:

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

julia> sparse([1.0, 0.0, 1.0])
3-element SparseVector{Float64,Int64} with 2 stored entries:
  [1]  =  1.0
  [3]  =  1.0

密行列を作成する逆方向の変換は Array コンストラクタで行えます。行列が疎かどうかの判定には issparse を使います。

julia> issparse(spzeros(5))
true

疎行列に対する操作

疎行列に対する算術演算は密行列と同様に行えます。添え字アクセス・代入・連結の動作も密行列と同じです。ただし添え字を使う操作、特に代入操作は、一つずつ行うとコストが高くなります。そのため多くの場合、最初に findnz を使って疎行列を (I,J,V) の形式に変換し、それを使って所望の値もしくは構造を密ベクトル (I',J',V') として作成し、そこから疎行列を再構築する方法を取るのがよいでしょう。

密行列と疎行列のメソッドの対応

疎行列用の組み込みメソッドとそれに対応する密行列用メソッドの関係を次の表に示します。一般に疎行列を生成するメソッドと対応する密行列に対するメソッドの違いは、結果の行列が与えられた疎行列と同じ場所にだけ要素を持つこと、あるいは結果の疎行列が d の密度を持つ (行列の各要素が確率 d で非ゼロとなる) ことです。

詳細は標準ライブラリのリファレンスにあります。

疎行列用 密行列用 説明
spzeros(m,n) zeros(m,n) 要素が全てゼロの m×n 行列を作成する。
spzeros(m,n) は空となる。
sparse(I, n, n) Matrix(I,n,n) n×m の恒等行列を作成する。
Array(S) sparse(A) 形式を疎と密の間で変換する。
sprand(m,n,d) rand(m,n) 密度 dm×n ランダム行列を作成する。
各非ゼロ要素は独立に [0,1) の一様分布に従う。
sprandn(m,n,d) randn(m,n) 密度 dm×n ランダム行列を作成する。
各非ゼロ要素は独立に標準正規 (ガウス) 分布に従う。
sprandn(rng,m,n,d) randn(rng,m,n) 密度 dm×n ランダム行列を作成する。
各非ゼロ要素は独立に乱数生成器 rng から生成される。

API リファレンス

SparseArrays.AbstractSparseArray ── 型

AbstractSparseArray{Tv,Ti,N}

要素型 Tv と添え字型 Ti を持つ N 次元疎配列型 (および疎配列風の型) を表す上位型です。部分型に SparseMatrixCSC, SparseVector, SuiteSparse.CHOLMOD.Sparse を持ちます。

SparseArrays.AbstractSparseVector ── 型

AbstractSparseVector{Tv,Ti}

要素型 Tv と添え字型 Ti を持つ一次元疎配列型 (および疎配列風の型) を表す上位型です。この型は AbstractSparseArray{Tv,Ti,1} の別名です。

SparseArrays.AbstractSparseMatrix ── 型

AbstractSparseMatrix{Tv,Ti}

要素型 Tv と添え字型 Ti を持つ二次元疎配列型 (および疎配列風の型) を表す上位型です。この型は AbstractSparseArray{Tv,Ti,2} の別名です。

SparseArrays.SparseVector ── 型

SparseVector{Tv,Ti<:Integer} <: AbstractSparseVector{Tv,Ti}

疎ベクトルを格納するベクトル型です。

SparseArrays.SparseMatrixCSC ── 型

SparseMatrixCSC{Tv,Ti<:Integer} <: AbstractSparseMatrixCSC{Tv,Ti}

疎行列を CSC 形式で格納する行列型です。SparseMatrixCSC を構築するときは sparse 関数を使うのが一般的です。spzeros, spdiagm, sprand も参照してください。

SparseArrays.sparse ── 関数

sparse(A::AbstractMatrix)

AbstractMatrix 型の A を疎行列に変換します。

julia> A = Matrix(1.0I, 3, 3)
3×3 Array{Float64,2}:
 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, 1]  =  1.0
  [2, 2]  =  1.0
  [3, 3]  =  1.0
sparse(I, J, V,[ m, n, combine])

全ての添え字 k に対して S[I[k], J[k]] = V[k] が成り立つような次元 m×n の疎行列 S を作成します。重複する要素を混ぜるときは関数 combine が使われます。mn が指定されないと、それぞれ maximum(I)maximum(J) になります。combine が与えられないときのデフォルトは V の要素が真偽値でなければ + で、真偽値なら | です。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, 1]  =  1
  [2, 2]  =  2
  [3, 3]  =  3

SparseArrays.sparsevec ── 関数

sparsevec(I, V, [m, combine])

全ての添え字 k に対して S[I[k]] = V[k] が成り立つような長さ m の疎ベクトル S を作成します。重複する要素は combine 関数を使って組み合わされます。combine が指定されないときのデフォルトは V の要素が真偽値でないなら + で、真偽値なら | です。

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

非ゼロ要素の添え字が d のキーで、値が d のバリューであるような長さ m の疎ベクトルを作成します。

julia> sparsevec(Dict(1 => 3, 2 => 2))
2-element SparseVector{Int64,Int64} with 2 stored entries:
  [1]  =  3
  [2]  =  2
sparsevec(A)

ベクトル 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

SparseArrays.issparse ── 関数

issparse(S)

S が疎なら true を、そうでなければ false を返します。

julia> sv = sparsevec([1, 4], [2.3, 2.2], 10)
10-element SparseVector{Float64,Int64} with 2 stored entries:
  [1 ]  =  2.3
  [4 ]  =  2.2

julia> issparse(sv)
true

julia> issparse(Array(sv))
false

SparseArrays.nnz ── 関数

nnz(A)

疎配列に格納されている (埋まっている) 要素の個数を返します。

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

julia> nnz(A)
3

SparseArrays.findnz ── 関数

findnz(A)

疎行列 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, 1]  =  1
  [1, 2]  =  2
  [3, 2]  =  4
  [2, 3]  =  3

julia> findnz(A)
([1, 1, 3, 2], [1, 2, 2, 3], [1, 2, 4, 3])

SparseArrays.spzeros ── 関数

spzeros([type,]m[,n])

長さ m の疎ベクトルまたはサイズ m×n の疎行列を作成します。作成される疎配列は非ゼロ要素を持たず、非ゼロ要素に対する格納領域は作成時に一切アロケートされません。要素型 type を指定しなければ 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

SparseArrays.spdiagm ── 関数

spdiagm(kv::Pair{<:Integer,<:AbstractVector}...)
spdiagm(m::Integer, n::Ingeger, kv::Pair{<:Integer,<:AbstractVector}...)

整数と対角要素の組をいくつか受け取り、そこから疎な帯行列を構築します。ベクトル kv.second が第 kv.first 優対角要素に配置されます。デフォルトでは size=nothing のとき行列は正方とみなされ、サイズは kv から計算されます。ただし引数の最初に m,n を渡せば正方でないサイズ m×n を指定することもできます (必要ならゼロ埋めされます)。

julia> spdiagm(-1 => [1,2,3,4], 1 => [4,3,2,1])
5×5 SparseMatrixCSC{Int64,Int64} with 8 stored entries:
  [2, 1]  =  1
  [1, 2]  =  4
  [3, 2]  =  2
  [2, 3]  =  3
  [4, 3]  =  3
  [3, 4]  =  2
  [5, 4]  =  4
  [4, 5]  =  1

SparseArrays.blockdiag ── 関数

blockdiag(A...)

行列をブロックごとに対角に並べて連結します。現在疎行列に対してだけ実装されます。

julia> blockdiag(sparse(2I, 3, 3), sparse(4I, 2, 2))
5×5 SparseMatrixCSC{Int64,Int64} with 5 stored entries:
  [1, 1]  =  2
  [2, 2]  =  2
  [3, 3]  =  2
  [4, 4]  =  4
  [5, 5]  =  4

SparseArrays.sprand ── 関数

sprand([rng],[type],m,[n],p::AbstractFloat,[rfn])

各要素が独立な確率 p で非ゼロとなる長さ m の疎ベクトルまたはサイズ m×n の疎行列を作成します(このため非ゼロ要素の平均密度はちょうど p です)。非ゼロ要素の値は rfn が指定する分布からサンプルされ、type 型を持ちます。rfn が指定されなければ一様分布が使われます。省略可能引数 rng には乱数生成器を指定します。詳しくは Random モジュールのリファレンスを参照してください。

julia> sprand(Bool, 2, 2, 0.5)
2×2 SparseMatrixCSC{Bool,Int64} with 1 stored entry:
  [2, 2]  =  1

julia> sprand(Float64, 3, 0.75)
3-element SparseVector{Float64,Int64} with 1 stored entry:
  [3]  =  0.298614

SparseArrays.sprandn ── 関数

sprandn([rng][,Type],m[,n],p::AbstractFloat)

各要素が独立な確率 p で非ゼロとなる長さ m の疎ベクトルまたはサイズ m×n の疎行列を作成します。非ゼロ要素の値は正規分布からサンプルされます。省略可能引数 rng には乱数生成器を指定します。詳しくは Random モジュールのリファレンスを参照してください。

Julia 1.1

出力の要素型を指定する機能は Julia 1.1 以降でサポートされます。

julia> sprandn(2, 2, 0.75)
2×2 SparseMatrixCSC{Float64,Int64} with 2 stored entries:
  [1, 2]  =  0.586617
  [2, 2]  =  0.297336

SparseArrays.nonzeros ── 関数

nonzeros(A)

疎配列 A に含まれる “構造的” 非ゼロ要素からなるベクトルを返します。A に明示的に格納されたゼロは返り値に含まれます。返り値のベクトルの要素は A の非ゼロ要素の格納領域を直接指すので、返り値のベクトルを変更すると A も変更されます。rowvalsnzrange も参照してください。

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

julia> nonzeros(A)
3-element Array{Int64,1}:
 2
 2
 2

SparseArrays.rowvals ── 関数

rowvals(A::AbstractSparseMatrixCSC)

A の行インデックスのベクトルを返します。返り値のベクトルに対する任意の変更は A にも伝わります。行インデックスの内部表現へのアクセスは構造的非ゼロ要素の反復と共に使用すると有用な場合があります。nonzerosnzrange も参照してください。

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

julia> rowvals(A)
3-element Array{Int64,1}:
 1
 2
 3

SparseArrays.nzrange ── 関数

nzrange(A::AbstractSparseMatrixCSC, col::Integer)

疎行列 A の第 col 列に含まれる構造的非ゼロ要素の添え字からなる区間を返します。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

SparseArrays.droptol! ── 関数

droptol!(A::AbstractSparseMatrixCSC, tol)

A に格納されている要素で絶対値が tol 以下のものを取り除きます。

droptol!(x::SparseVector, tol)

x に格納されている要素で絶対値が tol 以下のものを取り除きます。

SparseArrays.dropzeros! ── 関数

dropzeros!(A::AbstractSparseMatrixCSC;)

A から数値的ゼロを取り除きます。

インプレースでないバージョンは dropzeros です。アルゴリズムに関しては (エクスポートされていない) fkeep! を参照してください。

dropzeros!(x::SparseVector)

x から数値的ゼロを取り除きます。

インプレースでないバージョンは dropzeros です。アルゴリズムに関しては (エクスポートされていない) fkeep! を参照してください。

SparseArrays.dropzeros ── 関数

dropzeros(A::AbstractSparseMatrixCSC;)

A のコピーを作成し、そこから数値的ゼロを取り除いて返します。

インプレースなバージョンおよびアルゴリズムについては dropzeros! を参照してください。

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

julia> dropzeros(A)
3×3 SparseMatrixCSC{Float64,Int64} with 2 stored entries:
  [1, 1]  =  1.0
  [3, 3]  =  1.0
dropzeros(x::SparseVector)

x のコピーを作成し、そこから数値的ゼロを取り除いて返します。

インプレースなバージョンおよびアルゴリズムについては dropzeros! を参照してください。

julia> A = sparsevec([1, 2, 3], [1.0, 0.0, 1.0])
3-element SparseVector{Float64,Int64} with 3 stored entries:
  [1]  =  1.0
  [2]  =  0.0
  [3]  =  1.0

julia> dropzeros(A)
3-element SparseVector{Float64,Int64} with 2 stored entries:
  [1]  =  1.0
  [3]  =  1.0

SparseArrays.permute ── 関数

permute(A::AbstractSparseMatrixCSC{Tv,Ti},
        p::AbstractVector{<:Integer},
        q::AbstractVector{<:Integer}) where {Tv,Ti}

A を両側から置換した PAQ (A[p,q]) を返します。列の置換 q の長さは A の列数と一致する (length(q) == size(A, 2)) 必要があり、行の置換 p の長さは A の行数と一致する (length(p) == size(A, 1)) 必要があります。

さらに詳しいドキュメントと実際の処理を行うドライバについては permute! を参照してください。

julia> A = spdiagm(0 => [1, 2, 3, 4], 1 => [5, 6, 7])
4×4 SparseMatrixCSC{Int64,Int64} with 7 stored entries:
  [1, 1]  =  1
  [1, 2]  =  5
  [2, 2]  =  2
  [2, 3]  =  6
  [3, 3]  =  3
  [3, 4]  =  7
  [4, 4]  =  4

julia> permute(A, [4, 3, 2, 1], [1, 2, 3, 4])
4×4 SparseMatrixCSC{Int64,Int64} with 7 stored entries:
  [4, 1]  =  1
  [3, 2]  =  2
  [4, 2]  =  5
  [2, 3]  =  3
  [3, 3]  =  6
  [1, 4]  =  4
  [2, 4]  =  7

julia> permute(A, [1, 2, 3, 4], [4, 3, 2, 1])
4×4 SparseMatrixCSC{Int64,Int64} with 7 stored entries:
  [3, 1]  =  7
  [4, 1]  =  4
  [2, 2]  =  6
  [3, 2]  =  3
  [1, 3]  =  5
  [2, 3]  =  2
  [1, 4]  =  1

Base.permute! ── メソッド

permute!(X::AbstractSparseMatrixCSC{Tv,Ti},
         A::AbstractSparseMatrixCSC{Tv,Ti},
         p::AbstractVector{<:Integer},
         q::AbstractVector{<:Integer},
         [C::AbstractSparseMatrixCSC{Tv,Ti}]) where {Tv,Ti}

A を両側から置換した PAQ (A[p,q]) を X に格納します。省略可能な引数 C が与えられると、中間結果 (AQ)^T (transpose(A[:,q])) が C に格納されます。X, A, (与えられるなら) 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) が成り立つ) 必要があり、また 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 も参照してください。

日本語 Julia 書籍 (Amazon アソシエイト)
1 から始める Julia プログラミング
Julia プログラミングクックブック―言語仕様からデータ分析、機械学習、数値計算まで
スタンフォード ベクトル・行列からはじめる最適化数学