「プログラムソース」 2−1、------------------------------------------------------------- #include #define N 128 #define N2 N*2 int main(){ int n; int kaihi, gyou, retu, bai, keisann; double matrix[N][N2]; /*Nの数を指定*/ printf("N×2N行列のNの数を入力して下さい。\n"); printf("N="); scanf("%d",&n); /*行列の入力*/ printf("行列を入力します。\n"); for (gyou=1; gyou<=n; gyou++){ printf("%d行目の値を順番に入力して下さい。\n",gyou); for (retu=1; retu<=n*2; retu++){ printf("%d行%d列目の数値=", gyou, retu); scanf("%lf",&(matrix[gyou][retu])); } } /*入力した行列の表示*/ printf("入力された行列は、\n"); for (gyou=1; gyou<=n; gyou++){ for (retu=1; retu<=n*2; retu++){ printf("%f ",matrix[gyou][retu]); } printf("\n"); } printf("です。\n\n"); printf("何行目を定数倍しますか?\n(行数)="); scanf("%d",&gyou); kaihi = gyou; printf("何倍しますか?\n(定数倍)="); scanf("%d",&bai); printf("\n"); for (retu=1; retu<=n*2; retu++){ matrix[gyou][retu] = matrix[gyou][retu] * bai; } for (gyou=1; gyou<=n; gyou++){ for (retu=1; retu<=n*2; retu++){ printf("%f ",matrix[gyou][retu]); } printf("\n"); } printf("\n"); printf("以上のように定数倍されました。\n"); printf("定数倍した行と、どの行を加減算しますか?\n(行数)="); scanf("%d",&gyou); printf("加算と減算どちらをしますか?\n(加算なら1、減算なら2を入力)="); scanf("%d",&keisann); if(keisann == 1){ for(retu=1; retu<=n*2; retu++){ matrix[gyou][retu] += matrix[kaihi][retu]; } } if(keisann == 2){ for(retu=1; retu<=n*2; retu++){ matrix[gyou][retu] -= matrix[kaihi][retu]; } } for (gyou=1; gyou<=n; gyou++){ for (retu=1; retu<=n*2; retu++){ printf("%f ",matrix[gyou][retu]); } printf("\n"); } printf("\n"); printf("以上のように加減算されました。\n"); return 0; } -------------------------------------------------------------------------------- 2−2、 #include #define N 128 #define N2 N*2 int main(){ int a, k, n; int gyou, retu; double kaihi; double matrix[N][N], gyakumatrix[N][N], tannimatrix[N][N], hakidasi[N][N2]; /*Nの数を指定*/ printf("N×N行列のNの数を入力して下さい。\n"); printf("N="); scanf("%d",&n); /*行列の入力*/ printf("行列を入力します。\n"); for (gyou=1; gyou<=n; gyou++){ printf("%d行目の値を順番に入力して下さい。\n",gyou); for (retu=1; retu<=n; retu++){ printf("%d行%d列目の数値=", gyou, retu); scanf("%lf",&(matrix[gyou][retu])); } } /*入力した行列の表示*/ printf("入力された行列は、\n"); for (gyou=1; gyou<=n; gyou++){ for (retu=1; retu<=n; retu++){ printf("%f ",matrix[gyou][retu]); } printf("\n"); } printf("です。\n\n"); /*逆行列を掃き出し法で演算*/ for (gyou=1; gyou<=n; gyou++){ for (retu=1; retu<=n; retu++){ hakidasi[gyou][retu] = matrix[gyou][retu]; if(gyou == retu) hakidasi[gyou][n+retu] = 1.0; else hakidasi[gyou][n+retu] = 0.0; } } for (gyou=1; gyou<=n; gyou++){ kaihi = hakidasi[gyou][gyou]; for (k=1; k<=2*n; k++){ hakidasi[gyou][k] = hakidasi[gyou][k] / kaihi; } for (retu=1; retu<=n; retu++){ if (retu != gyou){ kaihi = hakidasi[retu][gyou]; for (k=1; k<=2*n; k++){ hakidasi[retu][k] -= kaihi * hakidasi[gyou][k]; } } } } for (gyou=1; gyou<=n; gyou++){ for (retu=1; retu<=n; retu++){ gyakumatrix[gyou][retu] = hakidasi[gyou][n+retu]; } } for (gyou=1; gyou<=n; gyou++){ for (retu=1; retu<=n; retu++){ tannimatrix[gyou][retu] = 0; for (k=1; k<=n; k++){ tannimatrix[gyou][retu] += matrix[gyou][k] * gyakumatrix[k][retu]; } } } printf("入力された行列の逆行列は、\n"); for (gyou=1; gyou<=n; gyou++){ for (retu=1; retu<=n; retu++){ printf("%f ",gyakumatrix[gyou][retu]); } printf("\n"); } printf("です。\n\n"); printf("<入力された行列>×<求まった逆行列>は、\n"); for (gyou=1; gyou<=n; gyou++){ for (retu=1; retu<=n; retu++){ printf("%f ",tannimatrix[gyou][retu]); } printf("\n"); } printf("です。\n\n"); return 0; } ------------------------------------------------------------------------- 「実行結果」 2−1-------------------------------------------------------------------------- C:\Documents and Settings\i865gpen4\My Documents\プログラムソース>suutikeisann2- 1 N×2N行列のNの数を入力して下さい。 N=2 行列を入力します。 1行目の値を順番に入力して下さい。 1行1列目の数値=1 1行2列目の数値=1 1行3列目の数値=0 1行4列目の数値=0 2行目の値を順番に入力して下さい。 2行1列目の数値=0 2行2列目の数値=0 2行3列目の数値=1 2行4列目の数値=1 入力された行列は、 1.000000 1.000000 0.000000 0.000000 0.000000 0.000000 1.000000 1.000000 です。 何行目を定数倍しますか? (行数)=2 何倍しますか? (定数倍)=2 1.000000 1.000000 0.000000 0.000000 0.000000 0.000000 2.000000 2.000000 以上のように定数倍されました。 定数倍した行と、どの行を加減算しますか? (行数)=1 加算と減算どちらをしますか? (加算なら1、減算なら2を入力)=1 1.000000 1.000000 2.000000 2.000000 0.000000 0.000000 2.000000 2.000000 以上のように加減算されました。 --------------------------------------------------------------------------- 2−2 C:\Documents and Settings\i865gpen4\My Documents\プログラムソース>suutikeisann2- 2 N×N行列のNの数を入力して下さい。 N=3 行列を入力します。 1行目の値を順番に入力して下さい。 1行1列目の数値=1 1行2列目の数値=0 1行3列目の数値=1 2行目の値を順番に入力して下さい。 2行1列目の数値=2 2行2列目の数値=2 2行3列目の数値=0 3行目の値を順番に入力して下さい。 3行1列目の数値=0 3行2列目の数値=1 3行3列目の数値=1 入力された行列は、 1.000000 0.000000 1.000000 2.000000 2.000000 0.000000 0.000000 1.000000 1.000000 です。 入力された行列の逆行列は、 0.500000 0.250000 -0.500000 -0.500000 0.250000 0.500000 0.500000 -0.250000 0.500000 です。 <入力された行列>×<求まった逆行列>は、 1.000000 0.000000 0.000000 0.000000 1.000000 0.000000 0.000000 0.000000 1.000000 です。 -------------------------------------------------------------------------------- 「考察」 2−1は多次元配列のようなもの(C言語なので配列の配列のようなものだが)を利用して 行列を表した。 対話的なプログラムにし、随時操作を実行していくような形にしたらうまくいった。 変数を意味のある名前にしていたために、かなりやりやすかった。 誰がみても非常に理解しやすいものになったと思う。 2−2は、2−1を利用して掃きだし法を使って逆行列を求める方法をとった。 2−1で対話によって、定数倍や加減算をするソースの所に、掃きだし法の演算ルールを記述 することで、こちらもうまくいくことができた。 ただし、逆行列が存在しない場合のエラーについて、うまく対処することができなかったため 逆行列が存在しな行列に関して、エラーがでてしまう。 考えてみたんですが、うまく実装することができなかったのでこのまま出すにいたりました。 すいません。 行列表示や行列格納のソースは、2−1から利用できたので、2−2で考えることになった場所は 掃きだしほうによって逆行列を求めるソースだけだった。 感想としては、色々なソースの場所を再利用できたために、JAVAでクラスなどで定義して行えば かなり簡単なものになるんじゃないかなっとおもった。 あ、C言語でも関数として定義すればもっと簡潔で美しいものになったと思う。