Math_Matrix
行列を利用するためにはまず、「Math_Matrix.php」をロードします。
require_once 'Math/Matrix.php';
行列は配列の配列を用いて生成します。
$data = array (
array(1,2),
array(3,4)
);
$m = new Math_Matrix($data);
echo $m->toString();
実行すると、行列を整形して表示します。
1.00 2.00 3.00 4.00
メソッドtoHTMLを使って行列をHTML形式で出力することができますが、次のようにXHTMLとして妥当なものではないので、これをそのまま使うべきではありません。
<table border>
<caption align="top"><b>Matrix</b></caption>
<tr align="center">
<th>2x2</th><th>0</th><th>1</th>
</tr>
<tr align="center">
<th>0</th><td bgcolor="#ffffdd">1</td><td bgcolor="#ffffdd">2</td>
</tr>
<tr align="center">
<th>1</th><td bgcolor="#ffffdd">3</td><td bgcolor="#ffffdd">4</td>
</tr>
</table>
Math_Matrixの主なメンバを表にまとめました。行列の場合には、ベクトルの場合のMath_VectorOpのような行列演算を提供するクラスはありません。Math_Matrixのメンバの一部が静的メソッドになっています(表中ではstaticと記述しています)。
| 種類 | メンバ名 | 概要 |
| Math_Vector() | コンストラクタ。引数はオプション(配列やMath_Matrix) | |
| add(Math_Matrix) | 引数で与えた行列を足す | |
| clone2() | 行列を複製して返す(PHP5のための簡便な修正) | |
| determinant() | 行列式を返す | |
| getCol($i) | 第$i列を返す | |
| getData() | 配列の配列を返す | |
| getElement($i, $j) | $i$j成分を返す | |
| get(Row($i) | 第$i行を返す | |
| getSize() | 行列のサイズを配列で返す(0番目が行数、1番目が列数) | |
| getSubMatrix($i, $j, $rows, $cols) | $i$j成分を基点に、rows行、cols列の部分行列を返す | |
| invert() | 逆行列で置き換える | |
| static | makeIdentity($n) | $n x $nの単位行列を返す |
| static | makeUnit | makeIdentityと同じ |
| static | makeZero($rows, $cols) | 成分がすべて0のrows行cols列行列を返す |
| static | readFromFile($filename, $format) | $format形式のファイルを読み、行列を生成する。$formatは'serialized'か'csv' |
| scale($f) | 行列を$f倍する | |
| scaleRow($i, $f) | 第$i行を$f倍する | |
| scaleCow($i, $f) | 第$i列を$f倍する | |
| setElement($i, $j, $val) | 第$i$j成分の値を$valにする | |
| static | solve($a, $b) | $aを行列、$bをベクタとして、$a x = $bとなるようなMath_Vector xを返す |
| sub(Math_Matrix) | 引数で与えた行列を引く | |
| swapCol($i, $j) | 第$i列と第$j列を入れ替える | |
| swapRow($i, $j) | 第$i行と第$j行を入れ替える | |
| toHTML() | HTMLの表形式の文字列を返す | |
| toString($format) | 行列を表す文字列を返す。各成分は$format(省略すると'%6.2f')どおりの文字列で整形する | |
| trace() | トレースを返す | |
| transpose() | 転置する | |
| vectorMultiply(Math_Vector) | 引数で与えたベクトルに、行列を左から掛けた結果のベクトルを返す | |
| static | writeToFile($filename, $format) | $format形式でファイルに書く。$formatは'serialized'か'csv' |
連立一次方程式
初めにも述べたように、Math_Matrixの機能はあまり豊富とは言えませんが、連立一次方程式を解くメソッドsolveは便利です。
{x + 2y = 5, 3x + 4y = 6}のような連立方程式は次のように解くことができます。
$data = array (
array(1,2),
array(3,4)
);
$m = new Math_Matrix($data);
$b = new Math_Vector(array(5,6));
$x = Math_Matrix::solve($m, $b);
echo "Solution: ".$x->toString()."\n";
echo "$m:\n";
echo $m->toString();
solveを実行すると、行列が逆行列で置き換えられることに注意してください(行列を再利用したい場合には、コピーを作っておきます)。
Solution: Vector: < -4, 4.5 > m: -2.00 1.00 1.50 -0.50
メソッドsolveは、行列の逆行列を求めることによって連立方程式を解いているため、{x + 2y = 5, 2x + 4y = 10}のように解が1意に定まらないものや、{x + 2y = 5, 2x + 4y = 11}のように解がないものを解こうとするとエラーになります。エラーが発生すると、今では非推奨になってしまっているPEAR_Errorオブジェクトが返ることになっています。連立方程式は次のようなコードで解くとよいでしょう(解が存在するにもかかわらずエラーになることに注意してください)。
$data = array (
array(1,2),
array(2,4)
);
$m = new Math_Matrix($data);
$b = new Math_Vector(array(5,10));
$x = Math_Matrix::solve($m, $b);
if(PEAR::isError($x)) {
echo 'error: '.$x->getMessage()."\n";
//error: Cannot continue inversion, pivoting element is zero
}
else {
echo 'Solution: '.$x->toString()."\n";
}
おわりに
PEARのMath_VectorやMath_Matrixを使って、PHPでベクトルや行列を扱う方法を紹介しました。これらはまだβ版で、十分な機能が備わっているとは言えない段階ですが、行列やベクトルを使った簡単な処理を行いたいという場合には、きっと役に立つでしょう。もっと高度な計算を行いたいけれどそれを自分で実装したくはないという場合には、LAPACKのようなライブラリ(C言語やFortran)や、MathematicaやMaxima(フリーソフトウェア)のような処理系を利用するとよいでしょう。
