MATLAB 環境の行列
このトピックでは、MATLAB® で行列を作成し、基本的な行列演算を行う方法を紹介します。
MATLAB 環境では、"行列" という用語を使って、2 次元グリッドに配置された実数または複素数を含む変数を示します。"配列" とは一般的に数値のベクトル、行列または高次元グリッドです。MATLAB のすべての配列は四角形になり、すべての次元の成分は同じ長さになります。行列で定義される数学演算は、線形代数で取り扱う内容です。
行列の作成
MATLAB には、さまざまな行列を作成する関数が多数用意されています。たとえば、パスカルの三角形に基づくエントリを含んだ対称行列を作成することができます。
A = pascal(3)
A =
1 1 1
1 2 3
1 3 6
または、行方向と列方向の和が等しい非対称の "魔方陣行列" を作成することもできます。
B = magic(3)
B =
8 1 6
3 5 7
4 9 2
もう 1 つの例は、ランダムな整数からなる 3 行 2 列の方形行列です。ここでは、randi への最初の入力が整数値の取り得る範囲を示し、次の 2 つの入力が行と列の数を示します。
C = randi(10,3,2)
C =
9 10
10 7
2 1列ベクトルは m 行 1 列の行列、行ベクトル は 1 行 n 列の行列、スカラー は 1 行 1 列の行列です。行列を手動で定義するには、大かっこ [ ] を使用して配列の先頭と末尾を示します。大かっこ内で行末を示すには、セミコロン ; を使用します。スカラー (1 行 1 列の行列) の場合、大かっこは不要です。たとえば、以下のステートメントは列ベクトル、行ベクトル、およびスカラーを生成します。
u = [3; 1; 4] v = [2 0 -1] s = 7
u =
3
1
4
v =
2 0 -1
s =
7
行列の作成と取り扱い方法の詳細は、行列の作成、連結、および拡張を参照してください。
行列の加算と減算
行列と配列の加算および減算は要素ごとに、すなわち "要素単位" で実行されます。たとえば、A を B に加算し、その結果から A を減算すると B に戻ります。
X = A + B
X =
9 2 7
4 7 10
5 12 8Y = X - A
Y =
8 1 6
3 5 7
4 9 2加算と減算では、両方の行列の次元に互換性がなければなりません。次元に整合性がない場合はエラーになります。
X = A + C
Arrays have incompatible sizes for this operation.
詳細については、配列と行列の演算を参照してください。
ベクトル積と転置
同じ長さの行ベクトルと列ベクトルの乗算は、順番を変えても計算結果は同じになります。結果は、"内積" と呼ばれるスカラーか、"外積" と呼ばれる行列のいずれかになります。
u = [3; 1; 4]; v = [2 0 -1]; x = v*u
x =
2X = u*v
X =
6 0 -3
2 0 -1
8 0 -4実数行列の "転置" 演算では、aij と aji を交換します。複素数行列の場合、もう 1 つの考慮事項は、配列内の複素数エントリの複素共役から "複素共役転置" を形成するかどうかです。MATLAB はアポストロフィ演算子 (') を使用して複素共役転置を行い、ドットアポストロフィ演算子 (.') を使用して共役なしの転置を行います。すべての要素が実数の行列では、これら 2 つの演算子の処理は同じになります。
例の行列 A = pascal(3) は "対称" であるため、A' は A と等しくなります。しかし、B = magic(3) は対称でないため、B' の各要素は主対角に対し鏡像の位置になります。
B = magic(3)
B =
8 1 6
3 5 7
4 9 2X = B'
X =
8 3 4
1 5 9
6 7 2ベクトルの場合、転置によって行ベクトルは列ベクトル (またはその逆) になります。
x = v'
x =
2
0
-1x と y が共に実数の列ベクトルの場合、積 x*y は定義されません。ただし、次の 2 つの積、
x'*y
および
y'*x
は同じスカラーの結果を生成します。これらは使用頻度が高く、"内" 積、"スカラー" 積、"ドット" 積と呼ばれています。dot という名前の、ドット積専用の関数も用意されています。
複素数ベクトルや行列 z に対して、z' は複素共役転置を表します。すなわち、各要素の虚数部の符号が逆になります。たとえば、次の複素行列を考えます。
z = [1+2i 7-3i 3+4i; 6-2i 9i 4+7i]
z = 1.0000 + 2.0000i 7.0000 - 3.0000i 3.0000 + 4.0000i 6.0000 - 2.0000i 0.0000 + 9.0000i 4.0000 + 7.0000i
z の複素共役転置は次のようになります。
z'
ans = 1.0000 - 2.0000i 6.0000 + 2.0000i 7.0000 + 3.0000i 0.0000 - 9.0000i 3.0000 - 4.0000i 4.0000 - 7.0000i
各要素の虚数部がその符号を保持し、共役を取らない複素転置は z.' で定義します。
z.'
ans = 1.0000 + 2.0000i 6.0000 - 2.0000i 7.0000 - 3.0000i 0.0000 + 9.0000i 3.0000 + 4.0000i 4.0000 + 7.0000i
複素ベクトルに対して 2 つのスカラー積 x'*y と y'*x は互いに複素共役で、スカラー積 x'*x は実数です。
行列の乗算
行列の乗算は、線形変換の構成を反映するように定義されており、連立線形方程式を簡潔に表現できます。行列積 C = AB は、A の列の次元が B の行の次元と等しいとき、またはどちらかがスカラーの場合に定義されます。A が m 行 p 列で、B が p 行n 列の行列の場合、積 C は m 行 n 列の行列になります。積は、実際には MATLAB の for ループ、colon 表記、ベクトルのドット積を使って定義できます。
A = pascal(3); B = magic(3); m = 3; n = 3; for i = 1:m for j = 1:n C(i,j) = A(i,:)*B(:,j); end end
MATLAB では、C = A*B のように、アスタリスクを使って行列の乗算を示します。行列の乗算は可換的ではありません。つまり、通常において A*B は B*A と等価ではありません。
X = A*B
X =
15 15 15
26 38 26
41 70 39Y = B*A
Y =
15 28 47
15 34 60
15 28 43行列は、列ベクトルを右から、行ベクトルを左から乗算します。
u = [3; 1; 4]; x = A*u
x =
8
17
30v = [2 0 -1]; y = v*B
y =
12 -7 10方形行列の乗算では、次元を一致させる必要があります。A は 3 行 3 列で、u は 3 行 1 列のため、両者を乗算して 3 行 1 列の結果が得られます (共通の内部次元が相殺されます)。
x = A*u
x =
8
17
30ただし、乗算は逆の順序では実行できません。
y = u*A
Error using * Incorrect dimensions for matrix multiplication. Check that the number of columns in the first matrix matches the number of rows in the second matrix. To operate on each element of the matrix individually, use TIMES (.*) for elementwise multiplication.
あらゆるものをスカラーで乗算できます。
s = 10; w = s*y
w = 120 -70 100
配列をスカラーで乗算する場合、スカラーは暗黙的にもう一方の入力と同じサイズに拡張されます。これはしばしば "スカラー拡張" と呼ばれます。
単位行列
一般的な数学表記では、大文字の I で単位行列を表します。単位行列は対角要素が 1 で、他の要素が 0 である任意のサイズの行列です。この行列の次元が一致する場合、AI = A かつ IA = A になります。
MATLAB の以前のバージョンでは大文字と小文字を区別して認識していなかったため、単位行列に I を使用できませんでした。これは i を既に添字や複素数単位として使用していたためです。そこで、英語の語呂合わせで関数名を作成しました。関数
eye(m,n)
は m 行 n 列の方形の単位行列を返し、eye(n) は n 行 n 列の正方の単位行列を返します。
逆行列
行列 A が正方行列で特異ではない (非ゼロの行列式の) 場合、方程式 AX = I と XA = I は同じ解 X をもちます。この解は、A の "逆数" と呼ばれ、A-1 として表されます。関数 inv と式 A^-1 は両方とも逆行列を計算します。
A = pascal(3)
A =
1 1 1
1 2 3
1 3 6X = inv(A)
X =
3.0000 -3.0000 1.0000
-3.0000 5.0000 -2.0000
1.0000 -2.0000 1.0000A*X
ans =
1.0000 0 0
0.0000 1.0000 0
0 0 1.0000det で計算される "行列式" は、行列で記述される線形変換のスケーリング ファクターの尺度となります。行列式が正確にゼロの場合、行列は "特異行列" で逆行列は存在しません。
d = det(A)
d =
1一部の行列は "近特異行列" で、逆行列が存在するにもかかわらず、計算は数値誤差の影響を受けます。関数 cond は、逆行列から得られる結果の精度がわかる "逆行列計算の条件数" を計算します。条件数の範囲は、数値的に安定した行列の 1 から特異行列の Inf までです。
c = cond(A)
c = 61.9839
行列の明示的な逆行列を求める必要はあまりありません。関数 inv は、連立線形方程式 Ax = b を解くときにしばしば誤用されます。実行時間と数値精度の両面でこの方程式を解く一番優れた方法は、行列バックスラッシュ演算子を x = A\b のように使用することです。詳細については、mldivide を参照してください。
クロネッカー テンソル積
2 つの行列のクロネッカー積 kron(X,Y) は、X と Y の要素のすべての組み合わせの積で作成される大規模な行列です。X が m 行 n 列で、Y が p 行q 列の場合、kron(X,Y) は mp 行 nq 列の行列になります。要素は、X の各要素が行列 Y 全体で乗算されるように配置されます。
[X(1,1)*Y X(1,2)*Y . . . X(1,n)*Y
. . .
X(m,1)*Y X(m,2)*Y . . . X(m,n)*Y]クロネッカー積は 0 と 1 からなる行列を使って、繰り返し小さな行列のコピーを作成します。たとえば X が 2 行 2 列の行列であるとき、
X = [1 2
3 4]および
I = eye(2,2)
kron(X,I)
ans =
1 0 2 0
0 1 0 2
3 0 4 0
0 3 0 4および
kron(I,X)
ans =
1 2 0 0
3 4 0 0
0 0 1 2
0 0 3 4kron の他に、配列の複製に役立つ関数としては repmat、repelem、および blkdiag などがあります。
ベクトルと行列のノルム
ベクトル x の p ノルムは次のように定義され、
norm(x,p) で計算されます。この演算は、p > 1 を満たす任意の値に対して定義されますが、最も広く使われる p の値は 1、2、および ∞ です。既定値は p = 2 で、"ユークリッド長" や "ベクトル振幅" に対応します。
v = [2 0 -1]; [norm(v,1) norm(v) norm(v,inf)]
ans =
3.0000 2.2361 2.0000行列 A の p ノルム
は p = 1, 2, ∞ に対して norm(A,p) で計算されます。ここでも既定値は p = 2 です。
A = pascal(3); [norm(A,1) norm(A) norm(A,inf)]
ans = 10.0000 7.8730 10.0000
行列の各行または各列のノルムを計算する場合は、vecnorm を使用できます。
vecnorm(A)
ans =
1.7321 3.7417 6.7823線形代数関数のマルチスレッド計算
MATLAB は多数の線形代数関数と要素ごとに計算する数値関数のマルチスレッド計算をサポートしています。これらの関数は自動的にマルチスレッドで実行されます。関数や式に対し、複数の CPU を使用して計算を高速化するにはさまざまな条件があります。
関数は同時実行可能な部分へ簡単に分割できる処理を実行します。この分割部分は各処理間で通信をほとんど行わずに実行されるものでなければなりません。すなわちシーケンシャルな処理がほとんどないものを扱います。
データを分割し、複数の実行スレッドを管理する時間を含めても同時実行する価値があるように、データ サイズは十分に大きいものを扱います。たとえば配列が数千個以上の要素を含む場合は、ほとんどの関数に対して高速化の効果があります。
処理がメモリに拘束されないものを扱います。すなわち処理時間の大部分がメモリのアクセス時間にならないものを扱います。一般的には、シンプルな処理より複雑な処理をする関数の方が、高速化の効果があります。
行列の乗算 (X*Y) と行列のべき乗 (X^p) の処理は、大規模な倍精度配列 (10,000 個以上の要素) に対して計算負荷を増大させます。行列解析関数 det、rcond、hess、expm も同様です。