////////////////////////////////////////////////////////// // // LU.c 数値解析(C) 2008.12.24 の課題 // LU 分解法 // 3次元限定のサンプルプログラム // ////////////////////////////////////////////////////////// // // 課題: // ・大域変数 SIZE をサイズとする行列が扱えるように、 //  LU_decomp, LU_step2, LU_step3 を書き換えよ // ・main() 内で SIZE の値を 4, 8, 16 と取り替えて実行せよ。 // // 発展課題: // ・行列やベクトルを取り替えて実行してみよ。 // ////////////////////////////////////////////////////////// #include"sqmatrix.h" // sqmatrix.h を同じディレクトリに download して用いよ。 // ( sqmatrix.h は書き換えなくて良い。) // 正方行列 A の LU 分解を計算する手続き // ふたつの行列 L, U はポインタで返す。 // pivot 選択は使っていない。 void LU_decomp(MATRIX A, MATRIX *L, MATRIX *U) { *L=zeromat(); // 初期値はゼロ行列 *U=unitmat(); // 初期値は単位行列 L->ent[0][0] = A.ent[0][0]; U->ent[0][1] = A.ent[0][1] / L->ent[0][0]; U->ent[0][2] = A.ent[0][2] / L->ent[0][0]; L->ent[1][0] = A.ent[1][0]; L->ent[1][1] = A.ent[1][1] - L->ent[1][0] * U->ent[0][1]; U->ent[1][2] = (A.ent[1][2] - L->ent[1][0] * U->ent[0][2]) / L->ent[1][1]; L->ent[2][0] = A.ent[2][0]; L->ent[2][1] = A.ent[2][1] - L->ent[2][0] * U->ent[0][1]; L->ent[2][2] = A.ent[2][2] - L->ent[2][0] * U->ent[0][2] - L->ent[2][1] * U->ent[1][2]; } // LU 分解法の前進代入 : L y = b の解 y を求める。 VECTOR LU_step2(MATRIX L, VECTOR b) { VECTOR y; y.ent[0] = b.ent[0] / L.ent[0][0]; y.ent[1] = (b.ent[1] - L.ent[1][0] * y.ent[0]) / L.ent[1][1]; y.ent[2] = (b.ent[2] - L.ent[2][0] * y.ent[0] - L.ent[2][1] * y.ent[1]) / L.ent[2][2]; return y; } // LU 分解法の後退代入 : U x = y の解 x を求める。 VECTOR LU_step3(MATRIX U, VECTOR y) { VECTOR x; x.ent[2] = y.ent[2]; x.ent[1] = y.ent[1] - U.ent[1][2] * x.ent[2]; x.ent[0] = y.ent[0] - U.ent[0][1] * x.ent[1] - U.ent[0][2] * x.ent[2]; return x; } main() { MATRIX A,L,U,C; VECTOR b,x,y,z; int i,j,n,k; RANDOMIZE(); // 行列のサイズはここで設定する。 SIZE = 3; // 課題の行列・ベクトル for(i=0; i