vbaで数値計算 10 逆行列と疑似逆行列

17
2017-01 更新 熊本高専 森下功啓 VBA数値計算10

Upload: katsuhiro-morishita

Post on 13-Apr-2017

140 views

Category:

Education


4 download

TRANSCRIPT

Page 1: VBAで数値計算 10 逆行列と疑似逆行列

2017-01更新 熊本高専森下功啓

VBAで数値計算10

Page 2: VBAで数値計算 10 逆行列と疑似逆行列

本資料の目次

逆行列最小二乗法による連立方程式の解法その他

2

Page 3: VBAで数値計算 10 逆行列と疑似逆行列

逆行列3

Page 4: VBAで数値計算 10 逆行列と疑似逆行列

逆行列とは

𝐀𝐀がn次の正方行列(n×n行列)で、式(1)と式(2)を満たすとき、𝐀𝐀−𝟏𝟏を𝐀𝐀の逆行列という。逆行列を用いると、式(3)の様に行列の方程式を簡単に解くことができる。

4

𝐀𝐀−𝟏𝟏𝐀𝐀 = 𝐀𝐀𝐀𝐀−𝟏𝟏 = 𝐈𝐈

(1)𝐀𝐀 ≠ 𝟎𝟎

(2)

* 𝐀𝐀 は𝐀𝐀の行列式で、式(1)を満たした行列を正則行列という。

𝐀𝐀𝐁𝐁 = 𝐂𝐂

(3)𝐀𝐀−𝟏𝟏𝐀𝐀𝐁𝐁 = 𝐀𝐀−𝟏𝟏𝐂𝐂

𝐁𝐁 = 𝐀𝐀−𝟏𝟏𝐂𝐂

Page 5: VBAで数値計算 10 逆行列と疑似逆行列

逆行列のアルゴリズム掃き出し法を用いて、逆行列を求めることができる。

5

𝐀𝐀𝐀𝐀−1 = 𝐈𝐈

𝑎𝑎11 ⋯ 𝑎𝑎1𝑛𝑛⋮ ⋱ ⋮

𝑎𝑎𝑚𝑚1 ⋯ 𝑎𝑎𝑚𝑚𝑛𝑛𝒃𝒃1,⋯ ,𝒃𝒃𝑛𝑛 =

1 ⋯ 0⋮ ⋱ ⋮0 ⋯ 1

𝒃𝒃𝑗𝑗 :𝐀𝐀−1の列ベクトル

𝑎𝑎11 ⋯ 𝑎𝑎1𝑛𝑛⋮ ⋱ ⋮

𝑎𝑎𝑚𝑚1 ⋯ 𝑎𝑎𝑚𝑚𝑛𝑛𝒃𝒃1 =

1⋮0

𝑎𝑎11 ⋯ 𝑎𝑎1𝑛𝑛⋮ ⋱ ⋮

𝑎𝑎𝑚𝑚1 ⋯ 𝑎𝑎𝑚𝑚𝑛𝑛𝒃𝒃𝑛𝑛 =

0⋮1

𝑎𝑎11 ⋯ 𝑎𝑎1𝑛𝑛⋮ ⋱ ⋮

𝑎𝑎𝑚𝑚1 ⋯ 𝑎𝑎𝑚𝑚𝑛𝑛

𝒃𝒃𝑗𝑗 =𝛿𝛿1⋮𝛿𝛿𝑚𝑚

𝛿𝛿𝑖𝑖 = �1, 𝑖𝑖 = 𝑗𝑗0, 𝑖𝑖 ≠ 𝑗𝑗

係数行列の列ベクトルと単位行列の列ベクトルの関係に注目してみる。

一般化して書き直すと↓の様になる。

Page 6: VBAで数値計算 10 逆行列と疑似逆行列

6

既知 未知

これは、掃き出し法で使った構造と同じですね!?

結論 𝑎𝑎11 ⋯ 𝑎𝑎1𝑛𝑛⋮ ⋱ ⋮

𝑎𝑎𝑚𝑚1 ⋯ 𝑎𝑎𝑚𝑚𝑛𝑛

1 ⋯ 0⋮ ⋱ ⋮0 ⋯ 1

1 ⋯ 0⋮ ⋱ ⋮0 ⋯ 1

𝑏𝑏11 ⋯ 𝑏𝑏1𝑛𝑛⋮ ⋱ ⋮𝑏𝑏𝑚𝑚1 ⋯ 𝑏𝑏𝑚𝑚𝑛𝑛

これを

こうしてしまう

𝑎𝑎11 ⋯ 𝑎𝑎1𝑛𝑛⋮ ⋱ ⋮

𝑎𝑎𝑚𝑚1 ⋯ 𝑎𝑎𝑚𝑚𝑛𝑛

𝒃𝒃𝑗𝑗 =𝛿𝛿1⋮𝛿𝛿𝑚𝑚

𝛿𝛿𝑖𝑖 = �1, 𝑖𝑖 = 𝑗𝑗0, 𝑖𝑖 ≠ 𝑗𝑗

𝒃𝒃1 𝒃𝒃𝑛𝑛𝐀𝐀−1

実線で示された四角の枠内が逆行列である。

Page 7: VBAで数値計算 10 逆行列と疑似逆行列

逆行列を求めるアルゴリズム

逆行列を求めるアルゴリズムは複数あるが、ここでは以下の様に考えたい。一度に計算した方が速いが、資産(作ったプログラム)を活用したいそこで、逆行列を列ベクトル単位で求める求めた列ベクトルをArrayに順番に格納してもそのままでは転置状態matrix = Array(vect1, vect2, vect3)で行列を作ると、転置状態となる。

転置状態の行列を転置して逆行列を得る。テストとして元の行列と逆行列の積を計算し、単位行列を得るか確認

7

𝑎𝑎11 ⋯ 𝑎𝑎1𝑛𝑛⋮ ⋱ ⋮

𝑎𝑎𝑚𝑚1 ⋯ 𝑎𝑎𝑚𝑚𝑛𝑛

𝒃𝒃𝑗𝑗 =𝛿𝛿1⋮𝛿𝛿𝑚𝑚

𝛿𝛿𝑖𝑖 = �1, 𝑖𝑖 = 𝑗𝑗0, 𝑖𝑖 ≠ 𝑗𝑗

つまり、→の計算を𝑗𝑗 = 1から𝑚𝑚まで繰り返す。

Page 8: VBAで数値計算 10 逆行列と疑似逆行列

逆行列を求める関数の実装例

8

Function matrix_inverse(matrix)Dim delta As Variant

delta = Array()ReDim delta(UBound(matrix))inverse = matrix ' コピーはしているが、ただ同じサイズの行列が欲しいだけFor i = 0 To UBound(matrix)

For k = 0 To UBound(delta)If k = i Then

delta(k) = 1Else

delta(k) = 0End If

Next kb = get_x_2(delta, matrix)inverse(i) = b

Next iinverse = matrix_t(inverse)

matrix_inverse = inverseEnd Function @VBA

転置

Array()の入れ子を想定

実用上は正方行列であることや、行列式が0にならない事を確認した方がいい。

逆行列の列ベクトルの計算

単位行列の列ベクトルを格納する変数

単位行列のi列における列ベクトルを作っている

Page 9: VBAで数値計算 10 逆行列と疑似逆行列

動作のテスト

デバッグモードで止めながら変数の変化の様子を観察した様子を以下に示す。

9

元々の行列との積で単位行列ができていることが分かる。

Page 10: VBAで数値計算 10 逆行列と疑似逆行列

最小二乗法による連立方程式の解法

10

Page 11: VBAで数値計算 10 逆行列と疑似逆行列

最小二乗法とは

計算結果と観測値との差の2乗値の和(合計値)を最小にする係数を求める手法を最小二乗法という。回帰式を求める際によく利用される。

11

例えば、左の例では𝑦𝑦 = 𝑥𝑥2 + 1にノイズを加えて作った点に近似曲線𝑦𝑦 =𝑎𝑎𝑥𝑥2 + 𝑏𝑏𝑥𝑥 + 𝑐𝑐 を当てはめたものである。

この例では、予測値と実測値との差の二乗和が最小になるように 𝑎𝑎と𝑏𝑏と𝑐𝑐が決定される。

最小を目指すので、和の関数を各係数で偏微分した値が0になるように調整するのだが詳細は省略する。

Page 12: VBAで数値計算 10 逆行列と疑似逆行列

観測値Yにノイズがある場合の連立方程式の解法は?

ところで、観測値にノイズ(ランダムな観測誤差)がある場合、解の精度が劣化する。そこで最小二乗法の出番である。結論を述べると、未知数の数pに対し方程式の数(観測の数)qをp<qとし、行列Aから作成した擬似逆行列を逆行列の替わりに利用する。観測値に誤差がある場合は多数の観測により計算精度を上げることができることは直感的に理解できると思う。なお、p<qの場合はAが正方行列にならないので逆行列は求まらない。 12

𝐀𝐀𝐱𝐱 = 𝐲𝐲

(4)𝐀𝐀−𝟏𝟏𝐀𝐀𝐱𝐱 = 𝐀𝐀−𝟏𝟏𝐲𝐲

𝐱𝐱 = 𝐀𝐀−𝟏𝟏𝒚𝒚

観測値にノイズのない連立方程式は、式(4)に示すように式に逆行列をかけることで簡単に解ける。

近似曲線𝑦𝑦 = 𝑎𝑎𝑥𝑥2 + 𝑏𝑏𝑥𝑥 + 𝑐𝑐の𝑎𝑎と𝑏𝑏と𝑐𝑐が𝐱𝐱に格納されていると思ってほしい。

Page 13: VBAで数値計算 10 逆行列と疑似逆行列

擬似逆行列

擬似逆行列は式(5)で求める。擬似逆行列であることを示すために、行列の右上に+マークがついている。

13

𝐀𝐀+ = (𝐀𝐀𝐓𝐓𝐀𝐀)−𝟏𝟏𝐀𝐀𝐓𝐓 (5)

Page 14: VBAで数値計算 10 逆行列と疑似逆行列

擬似逆行列の実装例

擬似逆行列の実装例を以下に示す。

14

Function matrix_pseudo_inverse(m)' 疑似逆行列を返すmatrix_pseudo_inverse = matrix_cross(matrix_inverse(matrix_cross(matrix_t(m), m)), matrix_t(m))

End Function

@VBA

Page 15: VBAで数値計算 10 逆行列と疑似逆行列

動作のテストデバッグモードで止めながら変数の変化の様子を観察した様子を以下に示す。

15

係数行列は正方行列ではないが、擬似逆行列と元々の行列との積で単位行列ができていることが分かる。なお、掛ける順序に注意のこと。

Page 16: VBAで数値計算 10 逆行列と疑似逆行列

その他16

Page 17: VBAで数値計算 10 逆行列と疑似逆行列

参考文献

SAK Streets - VB 開発言語資料 http://sak.cool.coocan.jp/w_sak3/doc/sysbrd/sak3vb.htm 基本的にVB6.0の解説だが、VBAにほぼそのまま適用できる。かなり詳しい。

擬似逆行列(一般化逆行列) http://imagingsolution.net/math/pseudoinversematrix/

最小二乗法と特異値 http://www.comp.tmu.ac.jp/kzmurota/lect-keieisuri/1401singval160101.pdf

17