Numpyで逆行列の存在判定ってどうするの?

f:id:ts0818:20210110151714p:plain京都フリー写真素材

葵祭(あおいまつり、正式には賀茂祭)は、京都市賀茂御祖神社下鴨神社)と賀茂別雷神社上賀茂神社)で、5月15日(陰暦四月の中の酉の日)に行なわれる例祭石清水八幡宮の南祭に対し北祭ともいう。平安時代、「祭」といえば賀茂祭のことを指した。

葵祭 - Wikipedia

石清水祭春日祭と共に三勅祭の一つであり、庶民の祭りである祇園祭に対して、賀茂氏朝廷の行事として行っていたのを貴族たちが見物に訪れる、貴族の祭となった。京都市の観光資源としては、京都三大祭りの一つ。

葵祭 - Wikipedia

葵の花を飾った平安後期の装束での行列が有名。斎王代が主役と思われがちだが祭りの主役は勅使代である。源氏物語中、光源氏が勅使を勤める場面が印象的である。

葵祭 - Wikipedia

なお斎王代は一般公募あるいはオーディション等で選ばれていない。数千万円と言われる費用を負担できることが条件となっているため、京都ゆかりの寺社・文化人・実業家などの令嬢(主に20代)が推薦等で選ばれている。莫大な負担ができ、かつ祭の維持に理解がある一部の家の令嬢に事実上限られるため、一部の資産家に役割が集中し、母も斎王代であったという例は数多く、姉妹揃って斎王代や、祖母・母・本人と三代続けて斎王代であるという例もある。

葵祭 - Wikipedia

⇧ 衝撃...金が全てを解決する、まさに、『もう、金しかないなあ!金もってこい!(「ダウンタウンガキの使いやあらへんで」で岸部四郎さんが発した台詞)』 っていうような圧を感じますな。

貴族の祭とかって言ってるけど、やんごとなき身分である必要とか無いんね...

というわけで、「逆行列」について調べてみました。

レッツトライ~。

 

逆行列って?

そもそも、「逆行列」って?

正則行列(せいそくぎょうれつ、regular matrix)、非特異行列(ひとくいぎょうれつ、non-singular matrix)あるいは逆行列(かぎゃくぎょうれつ、invertible matrix)とは、行列の通常の積に関する逆元を持つ正方行列のことである。

正則行列 - Wikipedia

この逆元を、元の正方行列の逆行列という。例えば、複素数体上の二次正方行列

正則行列であるのは ad − bc ≠ 0 が成立するとき、かつ、そのときに限る。このとき逆行列

で与えられる。

正則行列 - Wikipedia

⇧ う、う~ん、分かり辛い... 

過程が省略され過ぎてて、上記の形に至る経過が説明されてないんだね...

一応、定義を見てみると、

n 次単位行列を En や E で表す。 の元を成分にもつ n 次正方行列 A に対して、

を満たす n 次正方行列 B が存在するとき、A は n 次正則行列、あるいは単に正則であるというA が正則ならば上の性質を満たす B は一意に定まる。 これを A の逆行列(ぎゃくぎょうれつ、inverse matrix)と呼び、A−1 と表す

正則行列 - Wikipedia

⇧ う、う~ん...、

正方行列に対してのみ、「逆行列」が存在し得るかもしれないってことは分かったけども...

正方行列って?

正方行列(せいほうぎょうれつ、square matrix)とは、行要素の数と列要素の数が一致する行列である。サイズが n × n つまり、n 行 n 列であるとき、n 次正方行列という。

正方行列 - Wikipedia

⇧ 正方行列は、上記のような特徴を持つみたいですね。

 

atarimae.biz

行列式|A| を求めることで、その行列に逆行列が存在するかどうかがパッと分かります。

逆行列・正則行列・特異行列について。逆行列が存在するための条件とは?|アタリマエ!

⇧ 上記サイト様によりますと、行列式  | A | を求めれば良いらしいのですが、「行列式」って何なんでしょうね?

Wikipediaさんの説明によりますと、 

数学における行列式(ぎょうれつしき、determinant)とは、正方行列に対して定義される量で、歴史的には行列が表す一次方程式の可解性を判定する指標として導入された。幾何的には線型空間またはより一般の有限生成自由加群上の自己準同型に対して定義され、線型変換に対して線形空間の拡大率ということができる。行列の可逆性を判定する指標として線型代数学における最も重要な指標の一つと見なされている。

行列式 - Wikipedia

⇧ もう何が何やら...

定義を見てみると、 

明示的な定義

n 次正方行列 A の i 行 j 列成分を ai,j で表すと、A の行列式は、次の式で定義される:

ここで、

Aut(n) は n 次対称群{1, …, n} の自己同型群)
sgn は置換符号

を表す。

n 次正方行列の行列式は n 次の斉次多項式で、項を n! 個持つ(ライプニッツの公式)。

行列式 - Wikipedia

⇧ Oh, my gosh...

確実に「大学数学」とかの範疇になってるんじゃなかろうか、意味不明過ぎて何も言うことができません...

 

www.snap-tck.com

⇧ 上記サイト様を参考にさせていただきますと、

\begin{eqnarray} | A | = \mathrm{ det }A  &=& \begin{vmatrix} a_{11} & {\ldots} & a_{1i} & {\ldots} & a_{1n} \\ {\vdots} & {\ddots} & {\vdots} & {\ddots} & {\vdots} \\ a_{i1} & {\cdots} & a_{ii} & {\cdots} & a_{in} \\ {\vdots} & {\ddots} & {\vdots} & {\ddots} & {\vdots} \\ a_{n1} & {\cdots} & a_{ni} & {\cdots} & a_{nn} \end{vmatrix} \\ &=& \displaystyle \sum_{\sigma}\epsilon{(\sigma)}a_{1 \sigma (1)}a_{2 \sigma (2)} \ldots a_{n \sigma (n)} \\ &=& \displaystyle \sum_{\sigma}\epsilon{(\sigma)}a_{{1}{\cdot}{i1}}a_{{2}{\cdot}{i2}}{\ldots}a_{{n}{\cdot}{n1}} \\ &=& \displaystyle \sum_{{\sigma}{\in}{Aut(n)}} \left\{ ({sgn} {\hspace{ 5pt }} {\sigma}){\displaystyle \prod_{i=1}^n a_i,{\sigma}(i) } \right\} \end{eqnarray}

 

⇧ ってな感じになるってことらしいとは思うのですが、「行列式」を求めるのって相当に難易度が高い気がして震えてますが...

Pythonの拡張ライブラリの「Numpy」に「行列式」を算出してくれるメソッドが用意されてるらしいです。

通常「逆行列」の求め方としては、

mathtrain.jp

⇧ 上記サイト様によりますと、

  • 掃き出し法
  • 余因子を使う方法

の2パターンが存在するらしいですね。 

 

Numpyで逆行列の存在判定ってどうするの?

Numpyで、ある「正方行列」に「逆行列」が存在するかどうかってのを調べるにはどうすれば良いのか?

いろいろ、ネットの情報を検索した限りでは、

sleepy-yoshi.hatenablog.com

qiita.com

qiita.com

qiita.com

⇧ 上記サイト様を参考にさせていただきますと、 

  • numpy.linalg.det()で、行列式を算出し0じゃないことを確認する
  • numpy.linalg.pinv()で、逆行列の有無を確認せず処理する
  • numpy.linalg.solve()を実施してエラーの発生有無で判断する
  • numpy.linalg.inv()を実施してエラーの発生有無で判断する
  • scipy.linalg.inv()を実施してエラーの発生有無で判断する
  • 自力で逆行列の存在判定を実装する

っていう選択肢がある感じになるんですかね。 

 

ここで、今一度、「逆行列の存在条件」って何でしたっけ?

⇧ ってことみたいなので、『「行列式」が 0 でなければ、「逆行列」を持つ』ってことになるんですかね。

ってことは、「numpy.linalg.det()」を使って「行列式」の値を算出した結果が 0 かどうか確認すればいけそうですね。

というわけで、試してみた。

■numpy.linalg.inv()を実施してエラーの発生有無で判断する

import numpy as np

ndarray_a = np.array([[1, 0], [0, 1]])
ndarray_b = np.array([[1, 2], [2, 4]])
ndarrays = [ndarray_a, ndarray_b]

# ■numpy.linalg.inv()を実施してエラーの発生有無で判断する
print("■numpy.linalg.inv()を実施してエラーの発生有無で判断する")
for index in range(len(ndarrays)):
    try:
        inverse = np.linalg.inv(ndarrays[index])
        print(True)
        print(":" + str(ndarrays[index]))
    except np.linalg.LinAlgError:
        print(False)
        print(":" + str(ndarrays[index]))
    else:
        pass

■numpy.linalg.dev()で、行列式を算出し0じゃないことを確認する

import numpy as np

ndarray_a = np.array([[1, 0], [0, 1]])
ndarray_b = np.array([[1, 2], [2, 4]])
ndarrays = [ndarray_a, ndarray_b]

# ■numpy.linalg.det()で、行列式を算出し0じゃないことを確認する
print("■numpy.linalg.dev()で、行列式を算出し0じゃないことを確認する")
for index in range(len(ndarrays)):
    determinant = int(np.linalg.det(ndarrays[index]))
    if determinant == 0:
        print(False)
        print(":" + str(ndarrays[index]))
    else:
        print(True)
        print(":" + str(ndarrays[index]))

f:id:ts0818:20210112124323p:plain
⇧ 結果、両方とも判定できてますね。

「numpy.linalg.det()で、行列式を算出し0じゃないことを確認する」方法を使えば、「逆行列」の存在判定をエラーを出すことなく実施できるってことですかね。

まぁ、『「行列式」が 0 でなければ、「逆行列」を持つ』ってことがすべての「正方行列」において真であるのかが分からんので何とも言えないですが...

1つだけ言えることは、やっぱり数学の知識があると有利なんだな~、ってことですかね、理系の人が羨ましいな~。

今回はこのへんで。