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

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

新規登録して質問してみよう
ただいま回答率
85.48%
C

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

Q&A

解決済

1回答

1764閲覧

ガウス消去法のプログラムが上手く動作しない

VanS

総合スコア7

C

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

0グッド

0クリップ

投稿2020/12/11 08:08

前提・実現したいこと

ガウス消去法のプログラムを書いたのですが、上手くできません。
方程式は絶対値1以下の一様乱数によって作成されます。

発生している問題・エラーメッセージ

計算途中でnanが現れる。 問題を作り直しても上三角化途中である行が全て0になってしまう。

該当のソースコード

c

1 2//////////方程式を作るプログラム////////// 3#include <stdio.h> 4#include <stdlib.h> 5#include <time.h> 6 7int main(void) 8{ 9 int m,i,j; 10 double z; 11 FILE *fp; 12 char fname[32]; 13 14 15 16 printf("サイズ:"); scanf("%d",&m); 17 18 printf("ファイル名:"); scanf("%s",fname); 19 fp=fopen(fname,"w"); 20 fprintf(fp,"%d\n",m); 21 22 srand((unsigned)time(NULL)); 23 24 for (i=0;i<m;i++){ 25 for (j=0;j<m+1;j++){ 26 z=2*(rand() / (double)RAND_MAX) - 1; 27 fprintf(fp,"%.6lf\t",z); 28 29 } 30 fprintf(fp,"\n"); 31 } 32 33 fclose(fp); 34 fflush(fp); 35 return 0; 36 37} 38 39 40 41 42 43///////////////////ガウス消去法によって方程式を解く//////////////////////////// 44 45#include <stdio.h> 46#include <stdlib.h> 47#include <math.h> 48 49//一意解を持つか否かは上三角にしてから行列式を計算して求める 50 51 52int main(void) 53{ 54 FILE *fp,*gp; 55 int m,i,j; 56 int piv,q; 57 double **a,*b,*x; 58 double max,temp,r,det; 59 60 fp=fopen("af2-1.txt","r"); 61 fscanf(fp,"%d",&m); //m:行列の大きさ 62 63 printf("%d\n",m); 64 65 //メモリ確保 66 a=(double**)malloc(m*sizeof(double*)); 67 for (i=0;i<m;i++) { 68 a[i] =(double*)malloc(m*sizeof(double)); 69 } 70 b=(double*)malloc(m*sizeof(double)); 71 x=(double*)malloc(m*sizeof(double)); 72 73 74 //テキストファイルから行列の値を読み取り配列に格納 75 //係数行列をa、既知ベクトルをb 76 for(i=0;i<m;i++){ 77 for (j=0;j<m+1;j++){ 78 if (j<m){ 79 fscanf(fp,"%lf",&a[i][j]); 80 printf("%.2lf\t",a[i][j]); 81 }else if (j==m){ 82 fscanf(fp,"%lf",&b[i]); 83 printf("%.2lf\n",b[i]); 84 } 85 } 86 } 87 putchar('\n'); 88 89 //ピボット選択 90 //絶対値の大きいものの行をpivに代入(fabsを用いたほうがいい?) 91 for (q=0;q<m-1;q++){ 92 max=pow(a[q][q],2); 93 piv=q; 94 for (i=q+1;i<m;i++){ 95 if (max<pow(a[i][q],2)){ 96 max=pow(a[i][q],2); 97 piv=i; 98 } 99 } 100 101 102 //第q行と第piv行を交換 103 if (piv!=q){ 104 //係数行列 105 for (i=q;i<m;i++){ 106 temp=a[q][i]; 107 a[q][j]=a[piv][i]; 108 a[piv][i]=temp; 109 } 110 //既知ベクトル 111 temp=b[q]; 112 b[q]=b[piv]; 113 b[piv]=temp; 114 } 115 116 117 //上三角化 118 //a[q][q]==0の時を場合分け入る? 119 for (i=q+1;i<m;i++){ 120 r=a[i][q]/a[q][q]; 121 a[i][q]=0.0; 122 for (j=q+1;j<m;j++){ 123 a[i][j]=a[i][j]-r*a[q][j]; 124 } 125 b[i]=b[i]-r*b[q]; 126 } 127 } 128 129 //上三角行列の表示 130 for (i=0;i<m;i++){ 131 for (j=0;j<m+1;j++){ 132 if (j<m){ 133 printf("%.2lf\t",a[i][j]); 134 }else if (j==m){ 135 printf("%.2lf\n",b[i]); 136 } 137 } 138 } 139 140 //行列式が0でない時一意解を持つ 141 det=a[0][0]; 142 for (i=1;i<m;i++){ 143 det*=a[i][i]; 144 } 145 if (det==0){ 146 printf("一意解を持ちません。\n"); 147 exit(1); 148 } 149 150 151 //他の方のを参照したので理解していません 152 //後退代入法 153 for(i = m - 1; i >= 0; i--){ 154 for(j = i + 1; j < m; j++){ 155 b[i] = b[i] - a[i][j] * b[j]; 156 a[i][j] = 0.0; 157 } 158 b[i] = b[i] / a[i][i]; 159 a[i][i] = 1.0; 160 } 161 162 //解の表示 163 for(i = 0; i < m; i++){ 164 printf("x[%d] = %12.8lf\n",i+1,b[i]); 165 } 166 167 fclose(fp); 168 for (i=0;i<m;i++){ 169 free(a[i]); 170 } 171 free(a); 172 free(b); 173 return 0; 174} 175

試したこと

計算途中をprintfして過程を追ってみましたが挙動が全くわかりません

補足情報(FW/ツールのバージョンなど)

ターミナル
ProductName: Mac OS X
ProductVersion: 10.14.6

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

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

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

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

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

guest

回答1

0

ベストアンサー

行の入れ替えが間違えているみたいです。

diff

1*** 62,68 **** 2 //係数行列 3 for (i=q;i<m;i++){ 4 temp=a[q][i]; 5! a[q][j]=a[piv][i]; 6 a[piv][i]=temp; 7 } 8 //既知ベクトル 9--- 62,68 ---- 10 //係数行列 11 for (i=q;i<m;i++){ 12 temp=a[q][i]; 13! a[q][i]=a[piv][i]; 14 a[piv][i]=temp; 15 } 16 //既知ベクトル

投稿2020/12/11 13:12

Bull

総合スコア986

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

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

VanS

2020/12/13 05:07

なんと。。。ありがとうございます!!!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問