wvogel日記

自分用の技術備忘録が多めです.

Gauss Jordan

だめだめだ.....
関数型やりすぎて全く手続き型が書けなくなってる...
というのも多次元配列の扱いが特に。


参照透明性が保たれているのを当然のこととして考えていて、
それで1時間ほど悩んだり。
なんとか完成。


多項式の行列表現から解を導く
Gauss-Jordan法の、
前進消去(func1())
後退代入(func2())
を実装。

Gauss-Jordanクラスは、多次元配列を引数として受け取り、
それを自身で保持します。
メンバ関数は、

void show() (配列を表示) ,
コンストラクタ(多次元配列を受け取る) ,
デストラクタ(deleteで動的領域から配列を解法) ,
gaussJordan()関数 ,(解を計算)
をpublicなものとして後悔しています。

gaussJordan()関数は、privateなメンバ関数、func1とfunc2を逐次実行。
func1(前進消去)とfunc2(後退代入)の内容は次のようにしました。

void Gauss_Jordan::func1()
{
	double temp,a;

	for(int i = 0 ; i < X-1 ; i++){
		a = data[i][i];
		for(int j = 0 ; j < Y ; j++)
			data[i][j] /= a;	//除算で規格化

		for(int k = i+1 ; k < X ; k++){
			temp = data[k][i];
			for(int j = 0 ; j < Y ; j++)
				data[k][j] -= data[i][j]*temp;
		}
	}
}

void Gauss_Jordan::func2(){			//後退代入
	double answer[Y] ,a;

	for(int i = x-1 ; i >= 0 ; i--){
		a = data[i][i];
		answer[i] = data[i][Y-1] / a;
		for(int k = X-1 ; k > i ; k--)
			answer[i] -= answer[k] * data[i][k];
		cout <<"ans:" << i << ":" << answer[i] << endl;
	}
}
int main(){
	double data[3][4] = {
				{2,4,2,8},
				{4,10,3,17},
				{3,7,1,11}
				};

	Gauss_Jordan test(data);

	test.gaussJordan();

	getchar();
	return 0;
}

として実行すると、ちゃんと解ベクトル{1,1,1}が!
やったね!