22.1.2 疎行列の作成
スパース行列を作成するにはいくつかの方法があります。
関数から返される
疎行列を直接返す関数は多数あります。これらには 、 speye、sprand、diagなどがあります。
行列またはベクトルから構築される
関数sparse を使用すると、行、列、データを表す 3 つのベクトルから疎行列を構築できます。また、関数spconvert は3 列の行列形式を使用して、他の場所からデータを簡単にインポートできるようにします。
作成され、その後埋められる
関数sparseまたはspallocを使用すると、ユーザーが入力する空の行列を作成できます。
ユーザーバイナリプログラムから
ユーザーは、oct ファイル内にスパース マトリックスを直接作成できます。
特定の疎行列を返す基本関数がいくつかあります。たとえば、疎単位行列は、頻繁に必要となる行列です。そのため、この行列を または として作成するための独自の関数があり 、これによりn行n列またはr行c 列の疎単位行列が作成されます。 speye (n)speye (r, c)
よく必要とされるもう 1 つの典型的な疎行列は、ランダム要素のランダム分布です。関数sprandとsprandn は、要素の一様ランダム分布と正規ランダム分布に対してこれを実行します。これらの関数の呼び出し規則はまったく同じで、 は、充填された要素の密度がdであるr行c列の疎行列を作成します。 sprand (r, c, d)
疎行列を直接作成する他の興味深い関数としては、 行列の対角線の定義を受け取り、これに対応する疎行列を作成できる diagまたはその一般化spdiagsがあります。たとえば、
s = diag (sparse (randn (1,n)), -1);
単一の対角線が定義された 疎な( n +1)行( n +1)列の疎行列を作成します。
: B = spdiags (A)
: [B, d] = spdiags (A)
: B = spdiags (A, d)
: A = spdiags (v, d, A)
v: A = spdiags (v, d, m, n)
関数の一般化diag。
単一の入力引数で呼び出され、Aの ゼロ以外の対角要素dが抽出されます。
引数が 2 つある場合、抽出する対角線はベクトルdによって指定されます。
他の 2 つの形式では、spdiags対角要素を置き換えることで入力行列を変更します。vの列を使用して、ベクトルdで表される対角要素を置き換えます。疎行列Aが定義されている場合は、この行列の対角要素が置き換えられます。それ以外の場合は、 vの列によって指定された対角要素を持つm行n列の行列が作成されます。
dの負の値は主対角線の下の対角線を表し、dの正の値は主対角線の上方の対角線を表します。
例えば:
spdiags (reshape (1:12, 4, 3), [-1 0 1], 5, 4)
⇒ 5 10 0 0
1 6 11 0
0 2 7 12
0 0 3 8
0 0 0 4
See also: diag.
: s = speye (m, n)
: s = speye (m)
: s = speye ([m, n])
m x nサイズの疎な単位行列を返します。
完全な行列が構築されないため、 実装は大幅に効率的になります 。sparse (eye (m))
単一の引数で呼び出されると、サイズ m行m列の正方行列が作成されます。単一のベクトル引数で呼び出されると、この引数は作成する行列のサイズとして扱われます。
See also: sparse, spdiags, eye.
: r = spones (S)
Sのゼロ以外のエントリを1 に置き換えます。
これにより、 Sと同じ構造を持つスパース行列が作成されます。
See also: sparse, sprand, sprandn, sprandsym, spfun, spy.
: s = sprand (m, n, d)
: s = sprand (m, n, d, rc)
: s = sprand (s)
均一に分布したランダム値を持つスパース行列を生成します。
行列のサイズはm x nで、値の密度はdです。d は0 から 1 の間でなければなりません。値は区間 (0, 1) に均一に分布します。
単一の行列引数で呼び出された場合、行列sがゼロ 以外の場合はランダムな値を持つ疎行列が生成されます。
スカラーの 4 番目の引数rcで呼び出されると、逆条件数rcを持つランダムなスパース行列が生成されます。rcがベクトルの場合、生成された行列の最初の特異値を指定します ( )。 length (rc) <= min (m, n)
See also: sprandn, sprandsym, rand.
: s = sprandn (m, n, d)
: s = sprandn (m, n, d, rc)
: s = sprandn (s)
正規分布したランダム値を持つスパース行列を生成します。
行列のサイズはm x nで、値の密度はdです。d は0 から 1 の間でなければなりません。値は平均 0、分散 1 で正規分布します。
単一の行列引数で呼び出された場合、行列sがゼロ 以外の場合はランダムな値を持つ疎行列が生成されます。
スカラーの 4 番目の引数rcで呼び出されると、逆条件数rcを持つランダムなスパース行列が生成されます。rcがベクトルの場合、生成された行列の最初の特異値を指定します ( )。 length (rc) <= min (m, n)
See also: sprand, sprandsym, randn.
: S = sprandsym (n, d)
: S = sprandsym (s)
対称ランダムスパース行列を生成します。
行列のサイズはn x nで、値の密度はdで指定されます。 d は0 から 1 までの範囲でなければなりません。値は平均 0、分散 1 で正規分布します。
単一の行列引数で呼び出された場合、行列sの下三角部分がゼロ以外の 場所にランダムなスパース行列が生成されます。
See also: sprand, sprandn, spones, sparse.
疎行列を作成するための推奨方法は、データの行と列のインデックスを含む 2 つのベクトルと、格納するデータを含む同じサイズの 3 番目のベクトルを作成することです。たとえば、
ri = ci = d = []; for j = 1:c ri = [ri; randperm(r,n)']; ci = [ci; j*ones(n,1)]; d = [d; rand(n,1)]; endfor s = sparse (ri, ci, d, r, c);
列ごとにn (< r ) 個の要素がランダムに分布するr行c列の疎行列を作成します。ベクトルの要素は、データを格納する前に Octave が並べ替えるので、特定の順序で並べ替える必要はありません。ただし、データを事前に並べ替えておくと、疎行列の作成が速くなります。
spconvert関数は、3 列または 4 列の実数行列を受け取ります。最初の 2 列はそれぞれ行と列のインデックスを表し、3 列目と 4 列目は疎行列の実数部と虚数部を表します。行列には 0 個の要素を含めることができ、要素は任意の順序で並べ替えることができます。疎行列のサイズを定義するには、0 個の要素を追加するのが便利です。例:
s = spconvert ([1 2 3 4; 1 3 4 4; 1 2 3 0]')
⇒ Compressed Column Sparse (rows=4, cols=4, nnz=3)
(1 , 1) -> 1
(2 , 3) -> 2
(3 , 4) -> 3
マトリックスを作成して埋める例は次のようになります。
k = 5;
nz = r * k;
s = spalloc (r, c, nz)
for j = 1:c
idx = randperm (r);
s (:, j) = [zeros(r - k, 1); ...
rand(k, 1)] (idx);
endfor
Octave の割り当て関数の記述方法により、割り当てによって、上記ループの各反復でスパース マトリックスによって使用されるメモリが再割り当てされることに注意してください。したがって、spalloc関数はnz引数を無視し、マトリックスのメモリを事前に割り当てません。したがって、上記の構造を使用するコードは、割り当ての数を最小限に抑え、メモリ割り当ての数を減らすために、可能な限りベクトル化することが非常に重要です。
: FM = full (SM)
スパース行列、対角行列、順列行列、または範囲から完全なストレージ行列を返します。
See also: sparse, issparse.
: s = spalloc (m, n, nz)
最大nz 個の非ゼロ要素 用に事前に割り当てられたスペースを持つm行n列の疎行列を作成します。
これは、インデックス割り当てのシーケンスによってマトリックスを段階的に構築するのに役立ちます。後続のインデックス割り当ては、spalloc次の単純な形式のいずれかである場合、事前に割り当てられたメモリを再利用します。
s(I:J) = x s(:,I:J) = x s(K:L,I:J) = x
以下の条件が満たされていること 。
割り当ては減りません。 nnz (S)
割り当て後、nzを超えません。 nnz (S)
範囲外のインデックスはありません。
部分的なデータの移動は依然として発生する可能性がありますが、一般的に、このような状況では割り当てのメモリと時間がより効率的になります。特に、連続した列のブロックから事前に割り当てられたスパース マトリックスを効率的に構築することが可能です。
特定の行列に事前に割り当てられたメモリの量は、関数を使用して照会できますnzmax。
プログラミング上の注意: nzが 0 の場合でも、Octave は常に少なくとも 1 つの値に対してメモリを予約します。
See also: nzmax, sparse.
: S = sparse (A)
: S = sparse (m, n)
: S = sparse (i, j, sv)
: S = sparse (i, j, sv, m, n)
: S = sparse (i, j, sv, m, n, "unique")
: S = sparse (i, j, sv, m, n, nzmax)
完全な行列Aまたは行、列、値の 3 つ組 からスパース行列を作成します。
Aが完全な行列である場合、それをスパース行列表現に変換し、その過程ですべてのゼロ値を削除します。行列Aは、論理型または倍精度型である必要があります。
2 つの入力m (行) とn (列) が指定されている場合は、指定された次元の空のスパース行列を作成します。
整数インデックス ベクトルiとjnnz 、および 実数値または複素数値の1 行 1 列のベクトルsv が与えられて、全体の次元がmとnである疎行列を構築します 。 i、j、またはsvのいずれかがスカラーの場合、それらは共通のサイズになるように拡張されます。 S(i(k),j(k)) = sv(k)
mまたはnが指定されていない場合、それらの値は、、 で指定された ベクトルiおよびjの最大インデックスから導出されます。m = max (i)n = max (j)
注: 同じi、 jインデックスで複数の値が指定されている場合、 Sの対応する値は、繰り返される位置の値の合計になります。accumarray代わりに最小値を取るなど、異なる動作を生成する方法の例については、を参照してください。
オプションが指定され、同じi、j"unique"インデックスに複数の値が指定されている場合は、最後に指定された値のみが使用されます。完全性を保つために、このオプションを指定しても、デフォルトの動作では繰り返し位置の値を合計するため無視されます。 "sum"
sparse (m, n) will create an empty mxn sparse matrix and is equivalent to sparse ([], [], [], m, n)
オプションの最終引数は、スパース配列内のnzmax値用のスペースを予約します。これは、最終的な非ゼロ値の数が、配列の初期構築時に使用されたsv内の値の数よりも大きい場合に便利です。spalloc詳細と使用方法については、を参照してください。
例 1 (メモリを節約するために完全な行列をスパースに変換する):
x = full (diag (1:1000)); sizeof (x) ⇒ 8000000 s = sparse (x); sizeof (xs) ⇒ 24008
例 2 (繰り返しインデックスでの合計):
i = [1 1 2]; j = [1 1 2]; sv = [3 4 5];
sparse (i, j, sv, 3, 4)
⇒
Compressed Column Sparse (rows = 3, cols = 4, nnz = 2 [17%])
(1, 1) -> 7
(2, 2) -> 5
例 3 (「ユニーク」オプション):
i = [1 1 2]; j = [1 1 2]; sv = [3 4 5];
sparse (i, j, sv, 3, 4, "unique")
⇒
Compressed Column Sparse (rows = 3, cols = 4, nnz = 2 [17%])
(1, 1) -> 4
(2, 2) -> 5
See also: full, accumarray, spalloc, spdiags, speye, spones, sprand, sprandn, sprandsym, spconvert, spfun.
: x = spconvert (m)
他のプログラムで簡単に生成される単純なスパース マトリックス形式を Octave の内部スパース形式に変換します。
入力m は、疎行列の要素の行、列、実部、虚部を含む 3 列または 4 列の実数行列です。実部と虚部がゼロの要素を使用して、特定の行列サイズを強制することができます。
See also: sparse.
上記のメモリ再割り当ての問題は、oct ファイルでは回避できます。ただし、oct ファイルからのスパース マトリックスの構築は、ここで説明できるよりも複雑です。関連するテクニックの詳細については、 外部コード インターフェイスを参照してください。