
連立方程式を解いたりする時は行列形式のデータをよく扱います。その時に使う逆行列計算は手計算だと非常に面倒ですが、Pythonの線形代数モジュールであれば簡単に求めることが出来ます。
こんにちは。wat(@watlablog)です。
今回は小技として行列の逆行列をPythonで求める方法を紹介します!
目次(項目クリックでジャンプできます)
逆行列を2×2行列の場合で説明
行列式については高校数学で習う人が多いと思いますが、線形代数という分野で学ぶ学問です。
逆行列とは、簡単に言うと行列の場合の逆数を意味します。
方程式で式変換をがちゃがちゃやっている時、例えば\(a\)という実数であれば\(1/a\)が逆数となり、\(a\)に\(1/a\)をかけると1になります。この特性を利用して式を簡単にしたりします。
行列には大きさがあり、式(1)のような2行、2列の行列は2×2行列と呼ばれます。
\[
A= \begin{pmatrix}
a & b\\
c & d
\end{pmatrix} (1)
\]
この行列の逆行列は以下の式(2)で計算可能です。2×2の場合は覚えている方も多いのではないでしょうか。
\[
A^{-1}= \frac{1}{ad-bc}\begin{pmatrix}
d & -b\\
-c & a
\end{pmatrix} (2)
\]
ここで、式(2)内の\(ad-bc\)は行列式とよばれるもので、数学的には\(\left | A \right |\)または\(detA\)と書くこともあります。
逆行列を求める場合は、この\(detA\)が0でないことが条件となります。
3×3行列以上の場合は掃き出し法を利用して逆行列を求める方法が一般的ですが、こちらについてはわかりやすいページがありましたので、以下の参考サイト様を参照して下さい。
高校数学の美しい物語:逆行列を求める2通りの方法と例題
横長の行列(AI)に行基本変形を繰り返し行って(IB)になったら,B は A の逆行列である。
それではPythonでコーディングしていきましょう!
Pythonのlinalgで逆行列を求める
PythonではNumPyを使って計算を行います。まずは2×2行列Aを定義します。
inv_Aが逆行列で、np.linalg.inv関数で計算します。ちなみに、linalgは線形代数(Linear Algebra)から来ています。
1 2 3 4 5 6 7 8 |
import numpy as np A = np.array([[1, 2], [3, 4]]) # 行列を定義 inv_A = np.linalg.inv(A) # 逆行列を計算 print(A) print(inv_A) print(np.dot(A, inv_A)) |
ちゃんと逆行列が計算されているかは、行列の積を求めて単位行列になっているかどうかで判別しましょう。
しかし、ここで注意ですが、単純にA*inv_Aとしてしまうと、NumPy配列としての計算がされてしまいます。線形代数のルールで行列の積を計算するためには、ベクトルの内積でも使われるnp.dot関数を使用します。
2×2行列同士の積は以下の式(3)で求めることができます。
\[\begin{bmatrix}
a_{1} &a_{2} \\
a_{3} &a_{4}
\end{bmatrix} \times
\begin{bmatrix}
b_{1} &b_{2} \\
b_{3} &b_{4}
\end{bmatrix} =
\begin{bmatrix}
a_{1}b_{1}+a_{2}b_{3} &a_{1}b_{2}+a_{2}b_{4} \\
a_{3}b_{1}+a_{4}b_{3} &a_{3}b_{2}+a_{4}b_{4}
\end{bmatrix} (3)\]
上記コードを実行すると以下の結果を得ます。最後の結果が行列Aに逆行列inv_Aをかけた結果ですが、対角が1でそれ以外が0(実際は数値誤差の影響で左下が0でない非常に小さい値になっていますが)という単位行列になっています。
1 2 3 4 5 6 7 8 9 10 11 |
# 行列A [[1 2] [3 4]] # 逆行列inv_A [[-2. 1. ] [ 1.5 -0.5]] # 行列の積の結果 [[1.0000000e+00 0.0000000e+00] [8.8817842e-16 1.0000000e+00]] |
複素数の逆行列も作れる
逆行列は複素数の場合も同様の求め方をします。
以下のコードは複素数に対して逆行列演算を行い、上と同じように内積により単位行列を作る事で検証を行っています。
1 |
import numpy as np<br><br># 複素数の変数と行列を定義<br>a = 1 + 1j<br>b = 11 + 11j<br>A = np.array([[a, b], [a, a]]) # 行列を定義<br><br># 逆行列を計算<br>inv_A = np.linalg.inv(A)<br><br># 元行列と逆行列を表示<br>print('A=\n', A)<br>print('A^-1=\n',inv_A)<br><br># 内積を計算して検証<br>print('AA^-1=\n',np.dot(A, inv_A)) |
以下が結果です。複素数でも問題なく逆行列ができています。
1 2 3 4 5 6 7 8 9 |
A= [[ 1. +1.j 11.+11.j] [ 1. +1.j 1. +1.j]] A^-1= [[-0.05+0.05j 0.55-0.55j] [ 0.05-0.05j -0.05+0.05j]] AA^-1= [[ 1.00000000e+00+0.j 2.77555756e-17+0.j] [-8.32667268e-17+0.j 1.00000000e+00+0.j]] |
まとめ
今回は行列や行列式、逆行列の概要とPythonによるコーディング方法を紹介しました。
この行列計算は各種Pythonによる科学技術計算で多用することになると思いますので、基本のキとしておさえておきましょう!
今回は簡単な計算だけど、行列は技術計算で基本中の基本!取り扱い方法をマスターしておこう!
Twitterでも関連情報をつぶやいているので、wat(@watlablog)のフォローお待ちしています!
コメント