最新のWolfram言語には,このチュートリアルに関連する新機能が追加されている.最新情報は行列と線形代数を参照のこと.

行列とテンソルの操作

このチュートリアルでは,行列,ベクトル,テンソルの構築と操作のためのWolfram言語関数を復習する.まずWolfram言語に特有の関数に焦点を当て,次に行列を使った多くの例を示す.すべての関数は一般的なものであり,どれもベクトル,テンソルにも使える.

行列の構築

行列はWolfram言語ではリストで表される.Wolfram言語にはリストの入力用に{ }表記があり,これを使って行列を直接入力することができる:

Wolfram言語では,この他にもさまざまな方法で行列が作成できる.

Table[f,{i,m},{j,n}]m×n 行列の作成(fi,j 番目の要素を表す ij についての関数)
Array[f,{m,n}]i,j 番目の項目が f[i,j]である m×n 行列を作成する
DiagonalMatrix[list]対角要素が list である対角行列を作成する
IdentityMatrix[n]n×n の単位行列を作成する
ConstantArray[val,{m,n}]]各要素が val である m×n 行列を作成する
RandomReal[{0,val},{m,n}]]要素が乱数である m×n 行列を作成する
Normal[SparseArray[{{i1,j1}->v1,{i2,j2}->v2,},{m,n}]]
位置{ik,jk}に非零の値 νk を持つ m×n 行列を作成する
関数Tableは,自分の行列を作成するための組込み関数がない場合の行列の作成に特に重要である.Tableのより詳しい情報はWolfram言語のドキュメントに記載されている.ここでは例として3×3の行列を作成する:
MatrixFormは行列を二次元で表示する:
Wolfram言語で行列を作成するもうひとつの方法として,Arrayコマンドがある.Arrayを使って3×3の行列を作成する:
Wolfram言語には,特定のものに特化した行列を作成する多くの関数がある.次は単位行列を作成する例である:
生成された単位行列は整数行列である.浮動小数点数で計算したい場合は,浮動小数点数を持つ行列を使うとよい.これについてはパフォーマンスのセクションの「行列の内容」で詳細を述べる.前出の単位行列等の整数行列であっても,関数Nを使って浮動小数点行列に変換することができる.以下にそれを示す:
対角行列を作成する:

非零の値が2つ埋め込まれた34行列を作成する.SparseArray式については後のセクションで述べる.

次の例では,要素が第1対角に置かれている.MatrixFormは結果の表示に便利である:
次は要素がすべて2である5×5行列を作成する:
ここでは範囲が0から5の間の実数の擬似乱数で2×4行列を作成する:
これは範囲が-5から5までの整数の擬似乱数で3×4行列を構築する:
非零の値を埋め込んで3×4行列を作成する.SparseArray式ついては「疎行列(スパース行列)を使う」に記載されている:
SparseArray[{},{n,n}]零行列
SparseArray[{i_,i_}->1,{n,n}]n×n の単位行列
SparseArray[{i_,j_}/;i>=j->1,{n,n}]
下三角行列

SparseArrayによる特別な行列の作成

次の式は一般的な下三角行列を設定する:

ファイルから行列を読み込む関数については「行列のインポートとエキスポート」で述べる.

特別な行列

Wolfram言語には,多くの特別な行列の定義が含まれている.

HilbertMatrix[n]要素が1/(i+j-1)で与えられる n×n のヒルベルト(Hilbert)行列の作成
HilbertMatrix[{m,n}]m×n のヒルベルト行列を作成する
HankelMatrix[n]最初の列が1, 2, , n であり,主反対角要素の下がゼロである n×n のハンケル(Hankel)行列を作成する
HankelMatrix[list]最初の列が list で,主反対角要素の下がゼロであるハンケル行列を作成する
HankelMatrix[col,row]最初の列がリスト col,最後の列がリスト row で与えられるハンケル行列を作成する

特別な行列

2×4のヒルベルト行列を生成する.
ハンケル行列の要素はリストで指定する:
ハンケル行列は最終行を指定することで,非零の値で満たすことができる.この方法により,正方行列でない行列も生成できる.最初の列の最後の要素と最後の列の最初の要素は同じでなければならないことに注意:

構造操作

以下の操作はすべて行列の構造に関連している.このセクションで示す方法の多くは,行列だけではなく,他のWolfram言語式にも適用できる.

行列の一部の抽出

行列の要素,行,列の抽出は,Wolfram言語関数Partを使えば極めて容易である.一般にPart[[ ]]という表記で入力する.

m[[i,j]]i,j 番目の要素
m[[i]]i 番目の行
m[[i;;i]]i 番目から j 番目までの行
m[[All,i]]i 番目の列
m[[All,i;;j]]i 番目から j 番目間での列
m[[{i1,,ir},{j1,,js}]]行指標が ik,列指標が jk である要素を持つ r×s の部分行列
Tr[m,List]m の対角要素のリスト

行列の一部の抽出

次の行列を定義する:
最初の行の2つ目の要素を抽出する:
3番目の行を抽出する:
Allですべての行を指定すると,列を取り出すことができる:
負の指標は行列の最後を表す.次の式は最後の行の最後の要素を抽出する:
;;を使うと,行列の任意の範囲を取り出すことができる.ここでは2番目から4番目までの行を取り出す:
次では2番目から4番目までの列を取り出す:
刻み幅を与えることもできる.これは1列おきに取り出す:
関数Trは行列の対角要素を抽出するときに使う.引数が1つの場合は,対角要素がすべて足し合される:
Trの第2引数に関数を指定して,対角要素に適用することもできる.List を指定すると対角要素のリストが返される:

これらの行列の一部を抽出する関数は,他のどのWolfram言語式にも適用できる.

複数の部分の抽出

リストで指標を指定することで,複数の要素を抽出することも可能である:
2行目の1つ目と3つ目の要素を抽出する:
2つ目と4つ目の行を抽出する:
2行目と4行目の1つ目と3つ目の要素を抽出する:

行列の要素の設定

行列の要素,行,列は,割当て式の左辺にWolfram言語関数Partを指定すると簡単に変更できる.

m={{a11,a12,},{a21,a22,},}m に行列を割り当てる
m[[i,j]]=v{i,j} の要素を v に再設定する
m[[i]]=vi 行目の要素すべてを v に再設定する
m[[i]]={v1,v2,}i 行目の要素を{v1,v2,}に再設定する
m[[All,j]]=vj 列目の要素すべてを v に再設定する
m[[All,j]]={v1,v2,}j 列目の要素を{v1,v2,}に再設定する

行列の一部の要素の再設定

以下に5×5行列がある:

行列の一部に変更を加えるには,割当て式の左辺にPartを使えばよい.

3行目の3つ目の要素を設定する:
2行目が特定の値となるように設定する:
2列目を設定する:
負の指標を使って,行列を最後から数えることもできる.最後の行の最後の要素を設定する:
行列の部分を設定するために,範囲のシンタックスを使うこともできる.以下は1行おきのすべての要素をzと設定する:

複数の部分の設定

リストで指標を指定することで,複数の要素を設定することも可能である.次の行列で例を示す:
2行目の1つ目と3つ目の要素を設定する:
割当て式の右辺が,割り当てられる要素の数と同じ長さのリストならば,割当ては要素ごとに行われる.そのため,次の式では2行目の1つ目と3つ目の要素に異なる値が割り当てられる:
2行目と4行目を設定する:
次に2行目と4行目に異なる値を設定する:
2行目と4行目の1つ目と3つ目の要素を設定する:
今度は2行目と4行目の1つ目と3つ目の要素に異なる値を設定する:

部分行列の抽出

部分行列の抽出には範囲シンタックスが便利である.

m[[i0;;i1,j0;;j1]]i0 行目から i1行目,j0 列目から j1列目までの部分行列を抽出する
m[[i0;;i1]]i0 行目から i1行目までの部分行列を抽出する
m[[All,j0;;j1]]j0 列目から j1列目までの部分行列を抽出する

部分行列の抽出

m2,1からm3,2までの部分行列を抽出する:
1行目から3行目までの部分行列を抽出する:
2列目から4列目までの部分行列を抽出する:

行列の最後から数える場合は負の指標を使う.

次の式は最初と最後の列を切り落とした行列を返す:

行と列の削除

行や列の削除にはDropを使用する.

Drop[m,{i0,i1}]i0 行目から i1行目までを削除する
Drop[m,{},{j0,j1}]j0 列目から j1列目までを削除する
Drop[m,{i0,i1},{j0,j1}]i0 行目から i1行目まで,j0 列目から j1列目までを削除する

行と列の削除

2行目から4行目までを削除する:
2列目から4列目までを削除する:
次の例では2,3行目および1,2,3列目を削除する:

行と列の挿入

行の挿入にはInsertを使う.

Insert[m,r,i]行列 m の位置 i に列 r を挿入する

行の挿入

3行目の前に1行挿入する:
列を挿入する場合は,まず行列を転置し,次に列を行として挿入し,最後にもう一度行列を転置してもとに戻す.次の例では,5列目の前に列を挿入する:

行列の拡張

PadLeftPadRightを使って行列を充填し,サイズを大きくすることができる:
PadLeftは要素を行列の最初に加える:
PadRightは要素を行列の最後に加える:
充填関数の重要な使い方のひとつに,行列を複製してタイリングするというものがある.次の例では,入力行列を拡張し,各行に2つ,各列に3つ同じものが含まれるようにする:
PadLeftPadRightにはその他にも多くの機能があり,完全に一般化されているため,任意の階数のテンソルに対して使用できる.このことについてはWolfram言語ドキュメントで解説されている:

転置

行列の転置は一般的な行列操作のひとつである:
Transposeは特定の指標の要素を入れ換える:
行列の共役転置を計算するときは,関数ConjugateTransposeを使えばよい:
行列がその共役転置と等しい場合,その行列はエルミート(Hermitian)行列と呼ばれる:
関数HermitianMatrixQを使ってテストすることもできる:

要素の回転

もうひとつの構造操作は,指標内で要素をずらすことである.これには関数RotateLeftまたはRotateRightを使う:
第1レベルを1つ左にずらす.つまりこれは行について作用することになる:
次は第2レベルを1つ左にずらす.これは列について作用することになる:
行を逆方向にずらす:

行列のテスト

Wolfram言語には行列をテストし,サイズ情報を得るための関数が数多く存在する.

MatrixQ[expr]expr が行列ならばTrueを返し,行列でなければFalseを返す
Dimensions[expr]ベクトルまたは行列の大きさのリスト
mi==mj2つの行列の要素を比較して,行列が等しいかどうかを調べる

ベクトル,行列,配列の構造をテストする関数

式が行列であるかどうかをテストしたい場合はMatrixQを使用する:
整数5は行列ではない:
行列はどの次元の長さも同じでなければならない:
MatrixQの第2引数はオプションで,これは全要素に適用するテストを指定するものである.以下の例では整数であるかどうかを調べるテストが各要素について行われる:
次の例では,どの要素も1より大きい整数でなければならない:
コマンドDimensionsを使うと,大きさの情報が得られる:
2つのテンソルの要素が等しいかどうかを比較するには,Equalを使う.これは通常簡略表記==で入力する.例えば,次のようにテンソルをそれ自体と比較するとTrueが返される:
Equalでは数の値が比較されるので,整数と実数の比較も可能である:

EqualはどのようなWolfram言語式についても使用できる.行列の属性を使って総括的に2つの行列が等しいかどうか比較する場合は,行列のノルムを比較する方がよいことがある.これについては後のセクションで述べる.

その他の構造操作

このセクションでは,行列を扱う上で役に立つその他の構造操作について述べる.

Flatten[m]ネストしたリスト m をフラットにする
Flatten[m,n]ネストしたリスト m をレベル n までフラットにする
Partition[m,n]m を長さ n のサブリストに分割する
Join[m1,m2]m1m2を連結する
Append[m,r]rm の最後に挿入する
Prepend[m,r]rm の最初に挿入する
まず行列のサンプルを生成する:
行列をフラットにするとベクトルになる:
Partitionを使って行の長さを4に分割して行列に戻す:
関数Joinを使うと,行列を繋ぎ合せることができる.以下は新規の行列を新規行として挿入する:
新規行列を新規列として組み合せることもできる:
Appendを使うと行列の最後に新しい行が挿入できる:

この操作はInsertを使っても行える.「行と列の挿入」を参照のこと.

要素の操作

行列の要素の操作は,Wolfram言語では簡単に行える.まず浮動小数点数の行列を作成する:
行列に算術操作を適用すると,それは各要素まで縫い込まれる.そのため,行列に5を加算すると,各要素に5が加えられることになる:
次は行列のすべての要素を2倍する:
すべての要素が2乗される:
行列を別の行列で割ると,要素ごとに割り算が行われる.2つの行列の次元が等しくない場合はエラーが生じる:
すべての要素に関数Sinを適用するには,行列全体にSinを適用すればよい:
計算に使用する引数が両方とも行列の場合は,その計算は対応する要素について行われる:
2つの行列の次元は等しくなければならない:
引数の1つが行列でもう1つがベクトルの場合は,行列の行とベクトルの要素の間で計算が行われる:
2つの行列の掛け算にTimes(これは通常2つの引数を並べて入力する)を使うと,対応する要素の積の行列が生成される.行列の掛け算には,関数Dotを使用する.これについては「行列の掛け算」を参照されたい.要素レベルでの掛け算の例を以下に示す:

リストへの縫込み

関数に属性Listableを持たせると,作成した1つの関数を行列の各要素に適用することができる.次の例では,関数を各要素に適用して2乗し,その結果を3で割る:
関数は記号的な行列についても使える:

マップ

リストに縫い込む代りに,Mapを使って関数を行列の各要素に適用することもできる:
次のようにすると,関数fは行列の各要素に適用される:
次は,引数を2乗して3で割る関数を,行列の各要素に適用する:

ベクトルとテンソル

Wolfram言語では行列の他に,ベクトルとテンソルもサポートされている.これらはすべてリストから作成する.「Wolfram言語における線形代数入門」でも述べたが,Wolfram言語ではテンソルとは一般化された行列を表す.行列を作成する操作はすべて,ベクトルとテンソルに対しても使えるように一般化できる.Wolfram言語のベクトルは1レベルのリストである.

以下でベクトルを作成してみる:

ベクトルを生成する関数はこの他にもたくさんある.

Table[f,{i,n}]fi=1,2, ,n について評価して長さ n のベクトルを作成する
Array[a,n]{a[1],a[2],}という形の長さ n のベクトルを作成する
Range[n]リスト{1,2,3, ,n}を作成する
Range[n1,n2]リスト{n1,n1+1,n2}を作成する
Range[n1,n2,dn]リスト{n1,n1+dn ,n2}を作成する

ベクトル生成関数

非常に効率的なベクトルの生成方法のひとつにWolfram言語関数Rangeを使うというものがある.例として,整数のベクトルを作成する:
次は1で始まり,0.1ずつ4まで増加する実数のベクトルを作成する:
Tableもプログラムでのベクトルの生成に使える.これはベクトルの要素を決定するために関数を実行する場合に便利である:
しかし,リスト可能な操作を使った方が効率がよいことが多い:
前セクションで述べた操作と関数には,ベクトル用のものもある:

Wolfram言語には行ベクトル・列ベクトルという概念はないということに注意されたい.Wolfram言語におけるベクトルとは,要素をあらわす指標が1つのものをいう.

テンソルもTableコマンドを使って作ることができる.3つの反復子を用いて2×3×4のテンソル作成する:
Partに3つの指標を渡すと,要素が抽出できる:

ベクトルとテンソルのテスト

Wolfram言語には,ベクトルやテンソルのテストと,サイズ情報の抽出のためのさまざまな関数がある.

VectorQ[expr]expr がベクトル形式である場合はTrueを,それ以外はFalseを返す
MatrixQ[expr]expr が行列形式である場合はTrueを,それ以外はFalseを返す
ArrayQ[t,n]t が階数 n のテンソルであるかどうかをテストする
Dimensions[expr]ベクトルまたは行列の次元のリストを返す
ArrayDepth[t]テンソルの階数を求める
ti==tj2つのテンソルの要素が等しいかどうかを比較する

ベクトル,行列,配列の構造を調べる関数

式が行列であるかどうかは MatrixQでテストできる:
MatrixQに加え,VectorQArrayQ もベクトルとテンソルのテストに有用である:
ArrayQを使って配列の深さをテストする際に,引数として階数を使うこともできる:
ArrayQは各要素をテストするための第3引数も取る.次の例ではすべての要素がNumberQTrueとなる訳ではないので,Falseが返される:
サイズ情報を得るにはコマンドDimensionsが便利である:
Dimensionsは行列を入力したときは長さ2のリストを返す.これは行列の要素を参照するために2つの指標が使われていることを意味している.要素の参照に必要な指標の数は,ArrayDepthを使っても調べられる.次の例では,結果は2となる:
2つのテンソルの要素が等しいかどうかを比較するには,Equalが使える.これは通常簡略表記==で入力する.例えば,次のようにテンソルをそれ自体と比較するとTrueが返される:
Equalでは数の値が比較されるので,整数と実数の比較も可能である:
2つのオブジェクトの構造が一致しなければ,それらは等しいとは言えない:

行列の可視化

このセクションでは行列のフォーマットとプロットのための関数について述べる.

MatrixForm[mat]行列の要素を二次元配列形式で表示する
MatrixPlot[mat]mat の構造的パターンを示す

行列のフォーマット

行列は関数MatrixFormを使ってフォーマットできる:
MatrixFormはベクトルや,より階数の高いテンソルにも使える.カッコの表示により,グループ分けが分かりやすくなる:

行列のプロット

行列のプロットには関数MatrixPlotが便利である:

MatrixPlotには,プロットの外観を調整するための数多くのグラフィックスオプションがあり,その多くがWolfram言語DensityGraphicsオブジェクトの一般的なオプションである.行列の最大表示サイズを指定する特殊オプションMaxPlotPointsもある.このサイズより大きい行列はダウンサンプリングされる.

オプション名
デフォルト値
MaxPlotPoints200表示する行列の最大サイズ
AspectRatio1最終的な図形のスケール
ColorRulesAutomatic各要素の色
ColorFunctionAutomatic各要素の色
MeshFalse罫線描画の有無
MeshStyleGrayLevel[1]罫線スタイル

MatrixPlotのオプション

MatrixPlotの便利な機能のひとつに,非常に大きい行列がプロットできるということがある.以下で非常に大きい疎行列を生成する:
これをMatrixPlotでプロットすることができる.ここではプロットされる点の数は100個に減少されている:
デフォルトでは,描画された図の各要素の周りに罫線はないが,Meshオプションを使って表示することもできる.一般に行列が非常に大きいときには罫線を描かない方がよい.罫線を描く場合は,スタイルをMeshStyleオプションで変更すると便利なことがある:
ColorRulesオプションを使って色付けを変更することができる.この例ではゼロを白で,他すべてを黒でプロットする:
ColorFunctionオプションを使って画像に色を付けることもできる:

行列のインポートとエキスポート

このセクションでは行列のインポートとエキスポートに使う関数について述べる.

Import[file, format] 指定の形式でファイルからデータをインポートする
Export[file, mat, format] 行列を指定の形式に変換してエキスポートする

Wolfram言語にはインポート・エキスポートのためのさまざまなツールがある.後で同僚がWolfram言語で作業を続けられるようにデータをファイルに保存したいときは,ファイルに含まれるWolfram言語式が処理できる関数を使った方がよい.これについては「式の入出力」で述べる.

Wolfram言語外部のソースの行列を特定のデータ形式で操作したいときは,関数ImportおよびExportが便利である.関数Importは多種の形式をサポートしており,そのうちのいくつかは行列に関連したものである:
表データをWolfram言語に読み込む場合はTable形式を使う.この形式は行列専用のものではない.また,数値,データ,通貨等さまざまな情報が処理できる.多くの場合,行列を読むのにはこの方法が簡単である.次の例では,サンプルデータファイルを表示する:
Importコマンドを使ってTable形式でデータファイルをWolfram言語に読み込む.結果は行列となる:
Exportを使うと,行列を特定の形式で書き出すことができる.ここではTable 形式にしてみる:
次は行列をCSV形式で書き出す.これはスプレッドシート等の他のアプリケーションで読み込むことができる:

この他の行列形式もある.例えばHarwell-Boeingは疎行列に使われ,Matrix Marketは密・疎行列ともに使われる.これについては,「疎行列のインポートとエキスポート」で述べる.また,MAT行列形式とFITS天文データ形式も有用なインポート・エキスポート形式である.

行列の掛け算

行列の掛け算(内積とも言う)はWolfram言語では関数Dotで実行できる.これは通常簡略表記のドットで入力する:
次の例では,行列にそれ自身を掛け合せる:
行列とベクトルを掛け合せる:
行列の積は,2つの行列の大きさが異なっていても,適合しているなら行える.つまり,行列に関して言えば,m1×n1の行列と m2×n2の行列を掛け合せるためには,n1m2が等しければよいということである.次の例は2×3行列と3×2行列の掛け算である:
結果は2×2行列となる:
次の例では結果は3×3行列となる:
次元が適合しない場合はエラーが生じる:
Dotは同じ長さのベクトルの掛け算にも使用できる.結果はスカラーとなる:
行列とベクトルの掛け算も同様である.次の例は2×3行列に長さ3のベクトルを掛け合せる:
長さ3のベクトルに3×2行列を掛け合せる:

行列の掛け算の定義は,2つの行列 の積 は以下のような になるというものである.

2つの任意の階数のテンソル の積 が次のようになるように,定義を一般化する.

そのため,Dotを階数 のテンソルと階数 のテンソルに適用すると,結果は階数 のテンソルとなる.以下に例を示す.

まず2×3×4テンソルを定義する:
次に4×2×1のテンソルを定義する:
次にtensor1tensor2を掛け合せる.tensor1の最も深いレベルの指標の長さとtensor2の最も外側のレベル指標の長さが一致しているので,この2つは適合する:
結果は2×3×2×1のテンソルとなる:

外積

外積は階数の低いテンソルからより高いテンソルを作り出す方法である.Wolfram言語にはこの機能を持つ関数Outerがある.2つのベクトルを結合し,外積として行列を形成するにはこの関数を使用する:
対応する要素の結合に使う関数は第1引数で指定する.この第1引数には,次の例のように未知の関数を指定することもできる:

外積の可視化

Outerでの操作を可視化する方法のひとつを紹介する.まず点のリストを作成する:
Outerは次のように各点を他の点と接合する:

一般化された内積

行列の掛け算は線形代数計算の基本的な操作である.そのため,Wolfram言語には最適化された専用の関数Dotがある.また,これを一般化したものがInnerである.Innerを使うと,積を形成するのに使用する演算が2種類の中から指定できる.

2つのベクトルがある:
スカラー積を求める:
同じ計算をInnerを使って行う:
Timesの代りにPowerを使う:

行列の置換

行列演算の多くは,行列を特定の方法で並べることで行われる.例えば,演算技術の中には対角に要素を置くように行列の並べ替えを試みるものや,特定の要素を密ブロックのグループにまとめようとするものがある.Wolfram言語関数Partは行列の行や列の置換に非常に適した関数である.

m[[perm]]行列の行に置換を適用する
m[[All,perm]]行列の列に置換を適用する
m[[perm,perm]]行列の行と列に置換を適用する
m[[perm]]=m行列の行に逆置換を適用する
m[[All,perm]]=m行列の列に逆置換を適用する

行列の置換

ランダムな行列を作成する:

行が2-ノルムの大きさの増加列となるように行列を並べ替える(ノルムについては「行列の計算:ノルム」で述べる).

まず,各行のノルムを計算する:
最小の数が最初になるように置換する方法を求める:
行列の行を入れ替える.結果の行列では行は 2-ノルムの大きさの増加列となる:
次に,部分割当てを使って逆置換を行う.この操作によりシンボルpmatの行列が変更されることに注意.部分割当てについては前述の通りである:
置換後の行列を逆置換すると,もとの行列になる:

置換行列

置換を行う別の方法として,掛け算により置換を行う行列を計算するというものがある.例として,4×4の行列を作る:
行を2-ノルムの増加列で並べ替えるのに必要な置換を計算する:
置換行列は通常疎行列となる.これについては「疎行列(スパース行列)を使う」に記述されている.次のように入力すると,疎単位行列ができる:
単位行列に置換行列を適用すると,置換行列となる:
置換を適用する.ノルムが最も小さい行が一番上になる:
逆置換する:

一般に,置換にはWolfram言語関数Partを使用した方が速い.しかし置換行列の方が便利なこともあるだろう.