質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
Windows 10

Windows 10は、マイクロソフト社がリリースしたOSです。Modern UIを標準画面にした8.1から、10では再びデスクトップ主体に戻され、UIも変更されています。PCやスマホ、タブレットなど様々なデバイスに幅広く対応していることが特徴です。

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

プログラミング言語

プログラミング言語はパソコン上で実行することができるソースコードを記述する為に扱う言語の総称です。

コードレビュー

コードレビューは、ソフトウェア開発の一工程で、 ソースコードの検査を行い、開発工程で見過ごされた誤りを検出する事で、 ソフトウェア品質を高めるためのものです。

Q&A

解決済

1回答

7442閲覧

[線形代数-c言語]ガウスジョルダン法を使った連立一次方程式のコードを改造してほしい

oinari03

総合スコア59

Windows 10

Windows 10は、マイクロソフト社がリリースしたOSです。Modern UIを標準画面にした8.1から、10では再びデスクトップ主体に戻され、UIも変更されています。PCやスマホ、タブレットなど様々なデバイスに幅広く対応していることが特徴です。

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

プログラミング言語

プログラミング言語はパソコン上で実行することができるソースコードを記述する為に扱う言語の総称です。

コードレビュー

コードレビューは、ソフトウェア開発の一工程で、 ソースコードの検査を行い、開発工程で見過ごされた誤りを検出する事で、 ソフトウェア品質を高めるためのものです。

0グッド

0クリップ

投稿2020/11/07 06:53

編集2020/11/07 07:03

解決したいこと

以下の式からなる連立一次方程式をガウスジョルダン法を用いてc言語で実装したい

2x + 4y + 1z - 3w = 0 -1x - 2y + 2z + 4w = 10 4x + 2y - 3z + 5w = 2 5x - 4y - 3z + 1w = 6

やったこと

以下のようにソースコードと結果を示します。

#include <stdio.h> #define N 4 void gauss_jordan(double a[N][N+1], int size); int main(void) { double coeff[][N+1] = { {2,4,1,-3,0}, {-1,-2,2,4,10}, {4,2,-3,5,2}, {5,-4,-3,1,6}, }; gauss_jordan(coeff, N); // show answer printf("Answer\n"); for (int i=0; i < N; i++) { printf("x%d = %.15f\n",i, coeff[i][N]); } return 0; } void gauss_jordan(double a[N][N+1], int size) { // show default printf("Default:\n"); for (int i=0;i<N;i++) { for (int j=0;j<=N;j++){ printf("%10.5f",a[i][j]); }printf("\n"); }printf("\n"); for (int k=0; k < size; k++){ double pivot = a[k][k]; // make 1 for pivot for (int i =k; i < size+1; i++) { a[k][i] *= 1.0/pivot; } // substract 1*s(=a[k][i]*s) and make 0 for (int j=0; j< size; j++) { if (j == k) continue; double s = a[j][k]; for (int p=k; p < size+1; p++) { a[j][p] = a[j][p] - s*a[k][p]; } } // show a[][] printf("Loop:k=%d\n",k); for (int i=0;i<N;i++) { for (int j=0; j<=N;j++){ printf(" %10.5f",a[i][j]); }printf("\n"); }printf("\n"); } return; }

結果

Default: 2.00000 4.00000 1.00000 -3.00000 0.00000 -1.00000 -2.00000 2.00000 4.00000 10.00000 4.00000 2.00000 -3.00000 5.00000 2.00000 5.00000 -4.00000 -3.00000 1.00000 6.00000 Loop:k=0 1.00000 2.00000 0.50000 -1.50000 0.00000 0.00000 0.00000 2.50000 2.50000 10.00000 0.00000 -6.00000 -5.00000 11.00000 2.00000 0.00000 -14.00000 -5.50000 8.50000 6.00000 Loop:k=1 1.00000 -nan -inf -inf -inf 0.00000 -nan inf inf inf 0.00000 -nan inf inf inf 0.00000 -nan inf inf inf Loop:k=2 1.00000 -nan -nan -nan -nan 0.00000 -nan -nan -nan -nan 0.00000 -nan -nan -nan -nan 0.00000 -nan -nan -nan -nan Loop:k=3 1.00000 -nan -nan -nan -nan 0.00000 -nan -nan -nan -nan 0.00000 -nan -nan -nan -nan 0.00000 -nan -nan -nan -nan Answer x0 = -nan x1 = -nan x2 = -nan x3 = -nan

一応0がない時なら正常に解を導き出してくれます。
これだと、0が解にあるためか、結果が-nanになってしまっておかしくなってしまいます。
どこをどのように改造したら0を考慮する必要がなくなるのかわかりません。

考え

対角化のところでpivot=0が出てきてしまった時に、行数を入れ替える処理がかけたらいいんですが....
わかりません

お願いします。

上記の内容から0があるときにでも解を導けるようにどのようにそーすこーどをいじればよいのかアドバイスをお願いします。
自分の考えとして間違いないのですが、二回目の対角化のところで1ではなく0が出てきてしまったので、その時に、行を入れ替える処理を書きたいんですが、思いつきません....

初心者ですので、至らない点がありましたら指摘してくださいませ。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

久しぶりに、大学のころを思い出しました。
部分ピポッテイングとか、完全ピボッティングがあるのですね。
勉強になりました。
以下を参考にして、部分ピポッテイングでコードを入れてみました。
http://nkl.cc.u-tokyo.ac.jp/12s/3D/pivoting.pdf
参考になれば幸いです。
行を検索して、最大値があれば、検索開始行と最大値が見つかった行を入れ替えています。

c

1// 部分ピボッティング 2void partial_pivot(double a[N][N + 1], int pos, int size) { 3 double max = a[pos][pos]; 4 int max_line = pos; 5 double tmp; 6 7 // search max value in lines 8 for (int i = pos + 1; i < size; i++) { 9 if (a[i][pos] > max) { 10 max = a[i][pos]; 11 max_line = i; 12 } 13 } 14 if (max_line != pos) { 15 // max_lineとposを入れ替える 16 for (int i = 0; i < size + 1; i++) { 17 tmp = a[pos][i]; 18 a[pos][i] = a[max_line][i]; 19 a[max_line][i] = tmp; 20 } 21 } 22}

以下に上記の関数を追加

c

1 for (int k = 0; k < size; k++) { 2 partial_pivot(a, k, size); //★ここ 3 double pivot = a[k][k]; 4 // make 1 for pivot 5 for (int i = k; i < size + 1; i++) {

このソースでのanswer

text

1Answer 2x0 = 2.000000000000000 3x1 = -1.000000000000000 4x2 = 3.000000000000000 5x3 = 1.000000000000000

投稿2020/11/07 10:16

akiruno-oneone

総合スコア815

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問