連立一次方程式をOpenCVというライブラリを使って解きます。自分で実装すると面倒くさいですから、こうライブラリが簡単に使えると便利ですよね。
今回使用したのはOpenCV 2.3(with Visual C++ Express 2010)です。OpenCVを使用する前準備として、インクルードディレクトリに「~\OpenCV2.3\build\include」、ライブラリディレクトリに「~\OpenCV2.3\build\x86\vc10\lib」を設定します(~はインストールしたディレクトリを適宜)。またビルドしてできた実行ファイルと同じディレクトリに「opencv_core230d.dll」(デバッグの場合)または「opencv_core230.dll」(リリースの場合)をコピー。
今回解く連立方程式は、
です。答えは「x = 1, y = 2, z = 3」になります。
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace std;
using namespace cv;
#ifdef _DEBUG
#pragma comment(lib, "opencv_core230d.lib")
#else
#pragma comment(lib, "opencv_core230.lib")
#endif
int main(int argc, char **argv)
{
float dataA[3][3] = {{1, 1, 1}, {1, -1, -1}, {1, 1, 2}};
float dataY[3] = {6, -4, 9};
Mat matA(3, 3, CV_32FC1, dataA);
Mat matY(3, 1, CV_32FC1, dataY);
Mat matX(3, 1, CV_32FC1);
if(solve(matA, matY, matX, CV_LU))
{
for(int i = 0; i < 3; i++)
cout << "matX[" << i << "] = " << matX.at<float>(i, 0) << "\n";
}
else
cout << "解なし\n";
return 0;
}
左辺の係数を行列matA、右辺の係数を行列matYに代入します。あとはsolve関数に入れるだけ。簡単です。第1引数に左辺の係数の行列、第2引数に右辺の係数の行列、第3引数に解を格納する行列を指定します。第4引数は逆行列を求める方法で、今回はガウスの消去法を使用するので「CV_LU」を指定しました。
また連立方程式が以下のように解を持たない場合、solve関数はfalseを返しますので、場合分けしておきましょう。
Matは行列を扱うクラスです。初期化する際に、行列のサイズや型を指定します。ここでは、3*3 or 3*1の行列を32bit浮動小数1chで確保しています。また各要素にアクセスするにはat関数を使用します。「<>」内に行列の型(今回はfloat)、「()」内にアクセスしたい要素の場所を指定します。
このMatクラスは非常に便利なクラスで、直感的に演算できます(下表)。
数学的記述 | C++のコード |
C = A + B | C = A + B |
C = A – B | C = A – B |
C = A・B (内積) | C = A.dot(B) |
C = A×B (外積) | C = A.cross(B) |
C = A-1 (逆行列) | C = A.inv() |
C = AT (転置行列) | C = A.t() |
C = |A| (行列式) | C = determinant(A) |
Matクラスなどなどは名前空間cvに含まれているので、「cv::」やら「using namespace cv」が要ります。ご活用ください。
OpenCV.jp
http://opencv.jp/
OpenCV2.3の入手、ダウンロード、インストール、環境設定
https://imagingsolution.net/program/opencv/opencv2-3/opencv2-3-downlaod-install/