[はじめに] 線形モデルのパラメータ推定を行うためには, 正定値行列を係数に持つ 連立方程式を解く(逆行列を計算する)必要がある. 正定値行列の分解に はコレスキ分解(Cholesky分解)と呼ばれる方法が用いられる. SDMSimple/Lib/Cholesky.{h, cc}には, コレスキ分解に関連する関数が いくつか用意されている. これらの関数の使い方を学ぶため, 以下のディ レクトリに移動しよう: > cd Example/Example.Cholesky/ このディレクトリには3つのソースファイル: main1.cc main2.cc main3.cc が保存されている. これらのソースファイルの中身を確認しながら実行 することにより, Cholesky分解の基本的な使い方を理解しよう. [コンパイル] これらのソースファイルをコンパイルするには, Makefileをこのディレ クトリにコピーする必要がある: > cp ../../SDMSimple/Makefile ./ main1.ccをコンパイルする場合, > gmake main1 とコマンドすることにより関連するファイルすべてが自動的にコンパイ ルされる(main2.cc, main3.ccの場合も同様). すべてのソースファイルを一度にコンパイルしたいときは, 単に, > gmake とコマンドするだけでよい(Makefileは該当ディレクトリのすべての .cc ファイルを探しだしそれらすべてをコンパイルする). [main1] main1.ccは行列Aのコレスキ分解を行う関数: bool choleskyDecomposition(Mat<double>& A); の使用例である. コマンドの第一引数(argv[1])には正定値行列Aのファイル名を指定し, 第二引数(argv[2])にはコレスキ分解後の行列が保存されるファイル名を 指定している. コレスキ分解後の行列の下三角部分に下三角行列Lが保存 されていることに注意すること. 行列Aが正定値行列でない場合コレスキ分解を行うことができず, 上記の 関数はfalseを返す. 一方, コレスキ分解を正常に行うことができた場合 はtrueが返される. このディレクトリには, 3行3列の正定値行列: A.mdat が用意されている. main1を実行するには, > ./main1 A.mdat A.cholDcmp.mdat とコマンドすればよく, A.cholDcmp.mdat の下三角部分にコレスキファ クタの下三角行列が与えられている. [main2] main2.ccは連立方程式: A x = b を解く関数: bool solveLinearSystemByCholeskyDecomposition(Mat<double>& A, Vec<double>& b); の使用例である. ここで, Aは正定値行列で, 例えば, n行n列であるとすると, xは未知変 数のn次元ベクトル, bは既知のn次元ベクトルである. 連立方程式を解く問題は, 左辺行列Aと右辺ベクトルbが与えられたとき に, ベクトルxを求める問題と言い換えることができる. main2.ccでは, 左辺行列A, 右辺ベクトルb, 未知ベクトルxのファイル名 を, それぞれ, 第一引数(argv[1]), 第二引数(argv[2]), 第三引数 (argv[3])として与えている. 左辺行列Aが正定値行列でない場合は, この連立方程式を一意に解くこと ができないため, 上記の関数はfalseを返す. 一方, コレスキ分解を正常 に行うことができた場合はtrueが返される. このディレクトリには, 3行3列の正定値行列: A.mdat と長さが3の右辺 ベクトル b.vdat が用意されている. main2を実行するには, > ./main2 A.mdat b.vdat x.vdat とコマンドすればよく, x.vdat に連立方程式の解が保存される. [main3] main3.ccは行列Aの逆行列を計算する関数: bool computeInverseByCholeskyDecomposition(Mat<double>& A); の使用例である. コマンドの第一引数(argv[1])には正定値行列Aのファイル名を指定し, 第 二引数(argv[2])にはその逆行列が保存されるファイル名を指定している. 行列Aが正定値行列でない場合コレスキ分解を行うことができず, 上記の 関数はfalseを返す. 一方, コレスキ分解を正常に行うことができた場合 はtrueが返される. このディレクトリには, 3行3列の正定値行列: A.mdat が用意されている. main3を実行するには, > ./main3 A.mdat A.inv.mdat とコマンドすればよく, A.inv.mdat に行列Aの逆行列が保存されている. [最後に] コレスキ分解は行列Aが正定値行列である場合のLU分解に相当するもので ある. コレスキ分解やLU分解について知識があれば, SDMSimple/Lib/Cholesky.{h, cc} を参照し, アルゴリズムを理解できるとよい.