MatrixCalculatorrev02を動作チェックしてみると、3x3の逆行列は動作していたのですが、4x4以上になるとNANが発生して動作しませんでした。EXCELで計算するときちんと解がでているので、元の行列データは良いのでライブラリーの使い方が間違っているのかもしれないので、別のライブラリーに乗せ換えてみました。
■外池幸太郎 (とのいけ こうたろう)様のHPを見つけました。
http://numeric.world.coocan.jp/index.htm
NumericWorldというお名前の通り、数値計算に特化されたプログラムを公開されてました。その中に「NUMERICAL RECIPES からの移植」というページがあって、原本の和訳が
NUMERICAL RECIPES in C (日本語版)
William H. Press, Saul A. Teukolsky, William T. Vetterling, Brian P. Flannery
技術評論社
ISBN4-87408-560-1
このCのライブラリーをVB.NETに移植されたZIPをアップされていました。
http://numeric.world.coocan.jp/computer/vb/mathpack.htm
ここのLU分解 .NETのZIP
ludecomp.NET.zip ダウンロードさせていただきました。
■ZIPを解凍してからの使い方
ZIPには、3個のファイル VBコード、解説PDF、Noticeが入っていて、コードをそのままコピーして、現在のMatrix_CalculatorのVBコードの末尾にコピペして移植終了です。コードに中は、
①Imports System.Math Classの上に追加します。
Public Function LuDet(ByVal A(,) As Double) As Double | Det行列式の値計算 |
Public Sub LuInv(ByVal A(,) As Double, ByRef B(,) As Double) | A(,)逆行列B(,)計算 |
Public Sub LuBksb(ByVal A(,) As Double, ByVal Indx() As Integer, ByVal B() As Double) | 連立方程式の解計算 |
Public Sub LuDcmp(ByVal A(,) As Double, ByRef Indx() As Integer, ByRef D As Double) | LU分解計算 |
Public Sub Mprove(ByVal A(,) As Double, ByVal Alud(,) As Double, ByVal Indx() As Integer, _ ByVal B() As Double, ByVal X() As Double) |
LuBksb()の解の改良で精度向上させる |
②ここで、私が使わせていただいたのは、LuInvです。
A(,)に逆行列計算したい元行列matAをいれてしまうと、LU行列が入って戻ってきますので、元のmatAが壊れてしまいますので、matA(,)=LUA(,)と同じ行列LUAを作っておいて、逆行列計算に使います。逆行列B(,)にRmatA(,)
LuInv(LUA,RmatA) で逆行列計算が完了しました。
③動作確認
A:3x3 行列式の値がNANですが逆行列は存在してます。
検算で、matAとInvAの積をとると
B:4x4 ImageSolution様のライブラリーではNANエラーだったのですが
外池様の移植ライブラリーだと解がでました。
これで元行列と逆行列の積をとると
C:6x6を実験データを適当に切り貼りして作った6x6ではダメでした。
Det値はNANでもゼロでもないので、逆行列の値はでてくるのですが、1列目が全部ゼロですので
積をとっても単位行列の(0,0)がゼロになってしまうのでNGです。
この6x6が逆行列がでないのかEXCELで確認してみました。
やはり計算できないようなので、この6X6は逆行列をもてないデータみたいです。
●REV03のコード
imageSolution 様ライブラリーの他、静岡理工大様の教科書用プログラムも使ってみましたが、外ノ池様のプログラムが一番すんなりと動作しました。
https://gist.github.com/dj1711572002/4b15039167bd53042553d9b83b5a0140
●以後
6x6以上で、テスト行列で正しいものは何なのか、探して、逆行列計算の成否を調査してみます。