/****************************/ /* 逆行列の計算 */ /* 例: 2 1 */ /* 1 1 */ /* coded by Y.Suganuma */ /****************************/ #include <stdio.h> int gauss(double **, int, int, double); int main () { double **w, eps; int i1, ind, n = 2, m = 2; /* データの設定 */ w = new double * [n]; for (i1 = 0; i1 < n; i1++) w[i1] = new double [n+m]; eps = 1.0e-10; w[0][0] = 2.0; w[0][1] = 1.0; w[0][2] = 1.0; w[0][3] = 0.0; w[1][0] = 1.0; w[1][1] = 1.0; w[1][2] = 0.0; w[1][3] = 1.0; /* 実行と出力 */ ind = gauss(w, n, m, eps); printf("ind = %d\n", ind); printf(" %f %f\n", w[0][2], w[0][3]); printf(" %f %f\n", w[1][2], w[1][3]); return 0; } /*******************************************************/ /* 線形連立方程式を解く(逆行列を求める) */ /* w : 方程式の左辺及び右辺 */ /* n : 方程式の数 */ /* m : 方程式の右辺の列の数 */ /* eps : 逆行列の存在を判定する規準 */ /* return : =0 : 正常 */ /* =1 : 逆行列が存在しない */ /*******************************************************/ #include <math.h> int gauss(double **w, int n, int m, double eps) { double y1, y2; int ind = 0, nm, m1, m2, i1, i2, i3; nm = n + m; for (i1 = 0; i1 < n && ind == 0; i1++) { y1 = .0; m1 = i1 + 1; m2 = 0; // ピボット要素の選択 for (i2 = i1; i2 < n; i2++) { y2 = fabs(w[i2][i1]); if (y1 < y2) { y1 = y2; m2 = i2; } } // 逆行列が存在しない if (y1 < eps) ind = 1; // 逆行列が存在する else { // 行の入れ替え for (i2 = i1; i2 < nm; i2++) { y1 = w[i1][i2]; w[i1][i2] = w[m2][i2]; w[m2][i2] = y1; } // 掃き出し操作 y1 = 1.0 / w[i1][i1]; for (i2 = m1; i2 < nm; i2++) w[i1][i2] *= y1; for (i2 = 0; i2 < n; i2++) { if (i2 != i1) { for (i3 = m1; i3 < nm; i3++) w[i2][i3] -= w[i2][i1] * w[i1][i3]; } } } } return(ind); }