行列 \(A\) の行と列を入れ替えたものを「転置行列 (transposed matrix)」といい \(A^{\mathrm{T}}\) と表記します。転置行列の基本的な性質を以下に示します。\(A\) は正方行列を表します。
SymPy での操作と実行例を示します。
>>> a = sy.Matrix([[1,2],[3,4]]) >>> a Matrix([ [1, 2], [3, 4]]) >>> a.T Matrix([ [1, 3], [2, 4]]) >>> a.trace() 5 >>> a.T.trace() 5 >>> a.det() -2 >>> a.T.det() -2 >>> b = sy.Matrix([[5,6],[7,8]]) >>> b Matrix([ [5, 6], [7, 8]]) >>> (a * b).T Matrix([ [19, 43], [22, 50]]) >>> b.T * a.T Matrix([ [19, 43], [22, 50]]) >>> a.T.inv() Matrix([ [-2, 3/2], [ 1, -1/2]]) >>> a.inv().T Matrix([ [-2, 3/2], [ 1, -1/2]])
正方行列 \(A\) とその転置行列 \(A^{\mathrm{T}}\) が等しい行列のことを「対称行列 (symmetric matrix)」といい、その中で対角成分 \(a_{ii}\) 以外の要素が 0 の行列のことを「対角行列 (diagonal matrix)」といいます。単位行列は対角行列の一種です。簡単な例を示しましょう。
>>> a = sy.Matrix([[1,3],[3,2]]) >>> a Matrix([ [1, 3], [3, 2]]) >>> a.T Matrix([ [1, 3], [3, 2]]) >>> b = sy.Matrix([[1, 4, 5], [4, 2, 6], [5, 6, 3]]) >>> b Matrix([ [1, 4, 5], [4, 2, 6], [5, 6, 3]]) >>> b.T Matrix([ [1, 4, 5], [4, 2, 6], [5, 6, 3]]) >>> c = sy.Matrix([[1, 0, 0], [0, 2, 0], [0, 0, 3]]) >>> c Matrix([ [1, 0, 0], [0, 2, 0], [0, 0, 3]]) >>> c.T Matrix([ [1, 0, 0], [0, 2, 0], [0, 0, 3]])
対角行列 A の基本的な性質を以下に示します。
4 はあとで説明します。簡単な例を示しましょう。
>>> c Matrix([ [1, 0, 0], [0, 2, 0], [0, 0, 3]]) >>> c.det() 6 >>> c * c Matrix([ [1, 0, 0], [0, 4, 0], [0, 0, 9]]) >>> c * c * c Matrix([ [1, 0, 0], [0, 8, 0], [0, 0, 27]]) >>> c ** 2 Matrix([ [1, 0, 0], [0, 4, 0], [0, 0, 9]]) >>> c ** 3 Matrix([ [1, 0, 0], [0, 8, 0], [0, 0, 27]]) >>> c ** 10 Matrix([ [1, 0, 0], [0, 1024, 0], [0, 0, 59049]]) >>> c Matrix([ [1, 0, 0], [0, 2, 0], [0, 0, 3]]) >>> c.inv() Matrix([ [1, 0, 0], [0, 1/2, 0], [0, 0, 1/3]])
\(A^{\mathrm{T}}\) と \(A^{-1}\) が等しい行列のことを「直交行列 (orthogonal matrix)」といいます。簡単な例を示しましょう。
>>> d = sy.Matrix([[0,1],[1,0]]) >>> d Matrix([ [0, 1], [1, 0]]) >>> d.T Matrix([ [0, 1], [1, 0]]) >>> d.inv() Matrix([ [0, 1], [1, 0]]) >>> e = sy.Matrix([[0, 1, 0], [1, 0, 0], [0, 0, 1]]) >>> e Matrix([ [0, 1, 0], [1, 0, 0], [0, 0, 1]]) >>> e.T Matrix([ [0, 1, 0], [1, 0, 0], [0, 0, 1]]) >>> e.inv() Matrix([ [0, 1, 0], [1, 0, 0], [0, 0, 1]])
d と e のように、各行各列にちょうど一つだけ 1 の要素を持ち、それ以外は全て 0 となるような正方行列を「置換行列」といいます。置換行列を掛け算すると、列または行を入れ替える働きをします。
直交行列の基本的な性質を以下に示します。
3 はあとで説明します。簡単な例を示しましょう。
n 次の正方行列 \(A\) に対して、\(Ax = \lambda x\) を満たす数 \(\lambda\) を \(A\) の「固有値」、ゼロではないベクトル \(x\) を \(A\) の「固有ベクトル」といいます。このとき、固有値は \(|A - \lambda I| = 0\) の根になります。この式を「固有方程式」とか「特性方程式」といいます。
\(Ax = \lambda x\) を変形すると \((A - \lambda I)x = 0\) になります。行列 \((A - \lambda I)\) に逆行列が存在する場合、両辺にその逆行列を掛け算すると \(x = 0\) になってしまいます。つまり、ゼロではないベクトル \(x\) が存在するためには、逆行列が存在しないこと (\(|A - \lambda I| = 0\)) が条件になるわけです。
それでは、具体的に固有値と固有ベクトルを求めてみましょう。たとえば、行列 \(A = \begin{pmatrix} 1 & 2 \\ 2 & 1 \end{pmatrix}\) の固有値は以下のようになります。
固有値が求まったら、連立方程式 \((A - \lambda I)x = 0\) を解いて固有ベクトル x を求めます。
一般に、n 次の正方行列 \(A\) は n 個の固有値とそれに対応する固有ベクトルを持ちます。なお、固有方程式が重根を持つ場合、固有値の個数は n よりも少なくなります。
それでは実際に SymPy で固有値と固有ベクトルを求めてみましょう。メソッド eigenvals() で行列の固有値を、メソッド eigenvects() は固有ベクトルを求めます。
>>> import sympy as sy >>> sy.Matrix([[1,2],[2,1]]).eigenvals() {3: 1, -1: 1} >>> sy.Matrix([[1,2],[2,1]]).eigenvects() [(-1, 1, [Matrix([ [-1], [ 1]])]), (3, 1, [Matrix([ [1], [1]])])] >>> sy.Matrix([[4,-2],[1,1]]).eigenvals() {3: 1, 2: 1} >>> sy.Matrix([[4,-2],[1,1]]).eigenvects() [(2, 1, [Matrix([ [1], [1]])]), (3, 1, [Matrix([ [2], [1]])])] >>> sy.Matrix([[1,0,0],[0,2,0],[0,0,3]]).eigenvals() {1: 1, 2: 1, 3: 1} >>> sy.Matrix([[1,0,0],[0,2,0],[0,0,3]]).eigenvects() [(1, 1, [Matrix([ [1], [0], [0]])]), (2, 1, [Matrix([ [0], [1], [0]])]), (3, 1, [Matrix([ [0], [0], [1]])])]
3 番目の例のように、対角行列の固有値は対角成分の値となります。
n 次の正方行列 \(A\) の固有ベクトル \(x_{1}, x_{2}, ..., x_{n}\) を列に持つ行列 \(X = [x_{1}, x_{2}, ...., x_{n}]\) を考えます。すると、\(X\) によって行列 \(A\) を以下のように対角行列 \(\varLambda\) に変換することができます。
固有値と固有ベクトルの定義 \(Ax_i = \lambda_i x_i\) から \(AX\) は次のように変形することができます。
左側から両辺に \(X\) の逆行列を掛け算すれば \(X^{-1}AX = \varLambda\) となります。
それでは実際に SymPy で試してみましょう。
>>> a Matrix([ [1, 2], [2, 1]]) >>> x Matrix([ [1, -1], [1, 1]]) >>> x.inv() * a * x Matrix([ [3, 0], [0, -1]]) >>> b Matrix([ [4, -2], [1, 1]]) >>> y Matrix([ [1, 2], [1, 1]]) >>> y.inv() * b * y Matrix([ [2, 0], [0, 3]])
なお、SymPy には対角化を行うメソッド diagonalize() が用意されているので、それを使う便利です。
>>> a Matrix([ [1, 2], [2, 1]]) >>> a.diagonalize() (Matrix([ [-1, 1], [ 1, 1]]), Matrix([ [-1, 0], [ 0, 3]])) >>> b Matrix([ [4, -2], [1, 1]]) >>> b.diagonalize() (Matrix([ [1, 2], [1, 1]]), Matrix([ [2, 0], [0, 3]]))
数学の線形代数では、正則行列 \(P\) を用いて正方行列 \(A\) を \(P^{-1}AP\) に変換することを「相似変換」といい、\(B = P^{-1}AP\) が成り立つ正方行列 \(A, B\) の関係を「相似」といいます。相似な行列 \(A\) と \(B\) の間は様々な性質が保存されます。保存される主な性質を以下に示します。
つまり、相似変換を行ってもこれらの値が変化することはありません。たとえば、正方行列 \(A\) を相似変換により対角行列に変換します。対角行列は対角成分が固有値になるので、トレースは固有値の総和になります。相似変換でトレースは保存されるので、行列 \(A\) のトレースも固有値の総和であることがわかります。
要素がすべて実数の対称行列を「実対称行列」といいます。実対称行列には次に示す性質があります。
3 は直交行列の定義 \(L^{\mathrm{T}} = L^{-1}\) から明らかです。2 は固有ベクトルが「一次独立」であることを言っています。
ベクトル \(x_{1}, ..., x_{i}, ..., x_{n}\) において、式 \(a_{1}x_{1} + \cdots + a_{i}x_{i} + \cdots + a_{n}x_{n} = 0\) が成り立つとき、係数 \(a_{i} = 0 \ (i = 1, \ldots, n)\) 以外の解がないことを一次独立といいます。逆に、係数 \(a_{i} \ne 0 \ (i = 1, \ldots, n)\) であっても式が 0 になることを「一次従属」といいます。
簡単な例を示しましょう。
このように、実対称行列の固有ベクトルは一次独立になります。
それでは実際に SymPy で試してみましょう。
>>> a Matrix([ [1, 2], [2, 1]]) >>> p, d = a.diagonalize() >>> p Matrix([ [-1, 1], [ 1, 1]]) >>> d Matrix([ [-1, 0], [ 0, 3]]) >>> p[:, 0].T * p[:, 1] Matrix([[0]]) >>> b Matrix([ [1.0, 4.0, 5.0], [4.0, 2.0, 6.0], [5.0, 6.0, 3.0]]) >>> p, d = b.diagonalize() >>> p Matrix([ [0.496599784546191, -0.809585461739751, 0.31298567719356], [0.577350269189626, 0.577350269189626, 0.577350269189626], [0.648116749247652, 0.106009654307055, -0.754126403554706]]) >>> d Matrix([ [12.1759710650469, 0, 0], [ 0, -2.50728796709364, 0], [ 0, 0, -3.66868309795326]]) >>> p[:, 0].T * p[:, 1] Matrix([[0]]) >>> p[:, 0].T * p[:, 2] Matrix([[0]]) >>> p[:, 1].T * p[:, 2] Matrix([[1.38777878078145e-17]])