C言語のプログラムで質問です

このQ&Aのポイント
  • 下のプログラムを実行したところ、#IND00エラーが出てしまいます。どこを修正すれば良いでしょうか。
  • C言語のプログラムで最小二乗法の計算を実行した結果、#IND00エラーが発生しました。エラーを修正する方法を教えてください。
  • C言語のプログラムで最小二乗法の計算を実行すると、#IND00エラーが表示されます。どの部分を修正すれば良いのか教えてください。
回答を見る
  • ベストアンサー

C言語のプログラムで質問です。

C言語のプログラムで質問です。 下のプログラム(最小二乗法の計算)を実行したところ -1.#IND00 というエラーが出てしまいます。 どこを直せばいいのでしょうか、教えてください。 #include <stdio.h> #include <math.h> /* gauss33.c */ #define N 3 main(){ double A[N][N],Aa[N][N]; double b[N],x[N], bb[N], e[N]; int n=N; int i, j, k; double akk, aik, s; double y[N]; double xx,yy; for(i=0;i<n;i++){ /*変数の初期化*/ x[i]=y[i]=0; for(j=0;j<n;j++) A[i][j]=0; } for(i=0;i<5;i++){ /*データ点は5点*/ printf("\n(x,y)="); scanf("%lf,%lf",&xx,&yy); A[0][0]+=xx*xx*xx*xx; /*Σx^4*/ A[0][1]+=xx*xx*xx; /*Σx^3*/ A[0][2]+=xx*xx; /*Σx^2*/ A[0][1]=A[1][0]; A[0][2]=A[1][1]=A[2][0]; A[1][2]+=xx; /*Σx*/ A[1][2]=A[2][1]; A[2][2]=n; y[0]+=xx*xx*yy; /*Σx^2y*/ y[1]+=xx*yy; /*Σxy*/ y[2]+=yy; /*Σy*/ } /* save original coefficients */ for(i=0; i<n; i++){ for(j=0; j<n; j++){ Aa[i][j]=A[i][j]; } bb[i]=b[i]; } /* forward operation */ for(k=0; k<n-1; k++){ akk=1/A[k][k]; for (i=k+1; i<n; i++){ aik=-A[i][k]*akk; for (j=k+1; j<n; j++){ A[i][j]+=aik*A[k][j]; } b[i]+=aik*b[k]; } for(j=k+1; j<n; j++){ A[k][j]*=akk; } b[k]*=akk; } /* backward operation */ x[n-1]=b[n-1]/A[n-1][n-1]; for(k=n-2; k>=0; k--){ s=0.0; for (j=k+1; j<n; j++){ s+=A[k][j]*x[j]; } x[k]=b[k]-s; } /* chek */ for(i=0; i<n; i++){ s=0.0; for(j=0; j<n; j++){ s+=Aa[i][j]*x[j];} e[i]=s-bb[i]; printf("\nx(%d)=%f error=%f\n",i, x[i], e[i]); } }

質問者が選んだベストアンサー

  • ベストアンサー
  • asuncion
  • ベストアンサー率33% (2126/6288)
回答No.2

代入文は、右辺を左辺に代入するために使うことを 理解できていますか? 今のコードには、せっかく計算した結果を 直後の代入文で不用意に上書きしている箇所が 散見されます。

naozerojp
質問者

お礼

代入文があまり理解できてなかったようです。 直したら上手くいきました。ありがとうございます。

その他の回答 (1)

回答No.1

ロジックを追い切れていないので、全体的にどこがどうとは言えませんが、 パッと見たところでも代入の右辺と左辺の配置がおかしそうなところが見受けられます。 > A[0][1]=A[1][0]; > A[0][2]=A[1][1]=A[2][0]; > A[1][2]=A[2][1]; このあたり、一番右辺の項にはループ内で1回も代入が無いし、他の項もこの式しかないから、 ループをいくら回しても値が初期化した0のまま変わりません。 これが最終的に割り算の分母に入ってきて除算エラーになっているのでしょう。 基本に戻ってソースを見直してみてはいかがですか? 数式等のコメントでもあれば、もう少しアドバイスできるかもしれませんが。

naozerojp
質問者

お礼

上手くいきました。代入の方法がいまいち分かっていなかったようです。 有難うございます。

関連するQ&A

  • C言語のプログラムで質問です。

    C言語のプログラムで質問です。 これは、2元1次連立方程式の解を求めるプログラムです。 このプログラムを (1)3元1次連立方程式の解を求めるプログラムにする (2)係数行列、定数行列(6、7行目)をキーボードからの入力にする。 ようにしたいのですが、どうすればよいでしょうか。 前半の部分を変えれば良いようなのですが分かりません。教えてください。 #include <stdio.h> #include <math.h> /* gauss22.c */ #define N 2 main(){ double A[N][N]={1.,4.,3.,2.}, Aa[N][N]; /*簡単のため係数行列を予め指定*/ double b[N]={4.,5.}, x[N], bb[N], e[N]; /*簡単のため定数ベクトルを予め指定*/ int n=2; int i, j, k; double akk, aik, s; /* save original coefficients */ for (i=0; i<n; i++){ for (j=0; j<n; j++){ Aa[i][j]=A[i][j]; } bb[i]=b[i]; } /* forward operation */ for (k=0; k<n-1; k++){ akk=1/A[k][k]; for (i=k+1; i<n; i++){ aik=-A[i][k]*akk; for (j=k+1; j<n; j++){ A[i][j]+=aik*A[k][j]; } b[i]+=aik*b[k]; } for (j=k+1; j<n; j++){ A[k][j]*=akk; } b[k]*=akk; } /* backward operation */ x[n-1]=b[n-1]/A[n-1][n-1]; for (k=n-2; k>=0; k--){ s=0.0; for (j=k+1; j<n; j++){ s+=A[k][j]*x[j]; } x[k]=b[k]-s; } /* chek */ for (i=0; i<n; i++){ s=0.0; for (j=0; j<n; j++){ s+=Aa[i][j]*x[j];} e[i]=s-bb[i]; printf("x(%d)=%f error=%f?n",i, x[i], e[i]); } }

  • C言語についての質問です。

    C言語についての質問です。 このプログラムの前半にある A[N][N]={{1,0,0},{0,1,0},{0,0,1}} b[N]={4,5,3} という行列の成分をキーボードから入力するようにする にはどうすればいいでしょうか。 for や scanf や printf を使って、変えてくれないでしょうか。 #include <stdio.h> #include <math.h> /* gauss33.c */ #define N 3 main(){ double A[N][N]={{1,0,0},{0,1,0},{0,0,1}}; double b[N]={4,5,3}; double Aa[N][N]; double x[N], bb[N], e[N]; int n=N; int i, j, k; double akk, aik, s; /* input original coefficients */ /* save original coefficients */ for(i=0; i<n; i++){ for(j=0; j<n; j++){ Aa[i][j]=A[i][j]; } bb[i]=b[i]; } /* forward operation */ for(k=0; k<n-1; k++){ akk=1/A[k][k]; for (i=k+1; i<n; i++){ aik=-A[i][k]*akk; for (j=k+1; j<n; j++){ A[i][j]+=aik*A[k][j]; } b[i]+=aik*b[k]; } for(j=k+1; j<n; j++){ A[k][j]*=akk; } b[k]*=akk; } /* backward operation */ x[n-1]=b[n-1]/A[n-1][n-1]; for(k=n-2; k>=0; k--){ s=0.0; for (j=k+1; j<n; j++){ s+=A[k][j]*x[j]; } x[k]=b[k]-s; } /* chek */ for(i=0; i<n; i++){ s=0.0; for(j=0; j<n; j++){ s+=Aa[i][j]*x[j];} e[i]=s-bb[i]; printf("\nx(%d)=%f error=%f\n",i, x[i], e[i]); } }

  • C言語による数値計算を教えて下さい

    「2次関数y = ax2 + bx + c の係数を最小2乗法で求めるための正規方程式を導出せよ.その上でキーボードからデータの組(xi, yi)を 5点入力してa,b,cを求めるプログラムを作成せよ(x1~x5,y1~y5)」 という問題なのですが、a,b,cを求める方程式を行列式の形で以下のように出せました。 |Σxi^4 , Σxi^3 , Σxi^2| |a| |Σxi^2*yi| |Σxi^3 , Σxi^2 , Σxi |*|b| = |Σxi*yi | |Σxi^2 , Σxi , 5 | |c| |Σyi | ですがこれをガウス消去法で解こうと思っているのですがどうにもプログラムができません。 どなたかC言語で数値計算できる方、助けてください。 以下のはサイエンス社の「C言語による数値計算入門」をもとに ガウス消去法で解くプログラムを自分なりに作ったのですが 当然エラーだらけです。 プログラムを作れる方、どうか教えてください。 #include <stdio.h> #include <math.h> /* ガウス消去法 */ double *simple_gauss( double a[3][3], double b[3] ); main(void) { double a[3][3]; /* マトリックスの宣言*/ double x[3]; /* 解ベクトルの宣言*/ double y[3]; /* 右辺ベクトルの宣言*/ double xx, yy; /* キーボード入力のための一時変数*/ int i, j; /* 繰り返しのための一時変数*/ for(i = 0; i < 2; i++) { /* 変数の初期化*/ x[i] = y[i] = 0; for(j = 0; j < 3; j++) a[i][j] = 0; } for(i=0; i<5; i++) { printf("\n(x, y) = "); scanf("%lf,%lf", &xx, &yy); a[1][1] += xx * xx * xx * xx; a[1][3] += xx * xx; a[2][2] = a[3][1]=a[1][3]; a[1][2] += xx * xx * xx; a[2][1]=a[1][2]; a[2][3] += xx; a[3][2]=a[2][3]; a[3][3] ++; y[2] += xx * yy; y[1] += xx * xx * yy; y[3] += yy; } y=*simple_gauss(a,y); return 0; } double *simple_gauss( double a[3][3], double y[3] ) { int i, j, k; double alpha, tmp; /* 前進消去 */ for( k = 0; k <= 1; k++) { for( i = k+1; i <= ; i++) { alpha = - a[i][k]/a[k][k]; for( j = k+1; j <= 2; j++) { a[i][j] = a[i][j] + alpha * a[k][j]; } y[i] = y[i] + alpha * y[k]; } } /* 後退代入 */ y[2] = y[2]/a[2][2]; for( k = 1; k >= 0; k--) { tmp = y[k]; for( j = k+1; j <= 2; j++) { tmp = tmp - a[k][j] * y[j]; } y[k] = tmp/a[k][k]; } return y; }

  • c言語です。

    c言語です。 実行結果 式 3 X1 + 2 X2 + 1 X3 = &g 2 X1 + 5 X2 + 2 X3 = &g 1 X1 + 4 X2 + 1 X3 = &g 解 X1 = 1 X2 = 2 X3 = 3 を 式 3 X1 + 2 X2 + 1 X3 = 10 2 X1 + 5 X2 + 2 X3 = 18 1 X1 + 4 X2 + 1 X3 = 12 解 X1 = 1 X2 = 2 X3 = 3 に直したいのですが&gの所をどのようにしたら10.18.12になりますか? #include <stdio.h> #include <float.h> #define N 3 double A[N][N] = {{3,2,1}, {2,5,2}, {1,4,1}}; double b[N] = { 10, 18, 12 }; void Gauss_J( int, double*, double* ); void main(void) { int i; printf( "%d式\n", N ); for( i = 0; i < N ; i++ ) { printf( "%g X1 + %g X2 + %g X3 = &g \n", A[i][0], A[i][1], A[i][2], b[i] ); } printf("解\n"); Gauss_J(N, (double *)A, (double *)b ); printf("X1 = %g \n", b[0]); printf("X2 = %g \n", b[1]); printf("X3 = %g \n", b[2]); } void Gauss_J(int n, double *a, double *b) { int p, i, j,I ; double pivot, c ; for ( p = 0 ; p < n ; p++ ) { pivot = a[ p*n + p ]; for ( i = p ; i < n ; i++ ) { a[ p*n + i ] /= pivot; } b[ p ] /= pivot; for ( I = 0 ; I < n ; I++) { if (I != p) { c = a[ I*n + p]; for ( j = p ; j < n; j++ ) { a[ I*n + j] -= c * a[ p*n + j ]; } b[ I ] -= c * b[ p ]; } } } return ; }

  • C言語のプログラム

    C言語で2つの微分方程式をEuler法、Heun法、Runge-Kutta法により求めるプログラムを作りたい。ただし、初期条件はx=0,y=1とする。また、間隔Δxを変えたときの解の変化を調べたい。 Euler法のプログラムはどうにか分かったのですが、Heun法、Runge-Kutta法のプログラムがわかりません。 Euler法のプログラム #include_<stdio.h> #include_<math.h> int_main(){ __double__a=0; __double__b; __int_____m=10; __int_____n; __double__h; __double__x,y; __double__dydx; __int_____k; __double__e; __double__f; __printf("オイラー法計算例:y=e^x,_y=1/e^4x\n\n"); __//_y_=_e^x __b_=_1; __for(n=100;n<=10000;n*=100){ ____h_=_(b-a)/n; ____printf("y'_=_y:_h(=dx)_=_%.1e_(y=e^x)\n",h); ____x_=_a;_y_=_1; ____for(k=0;k<=n;k++)_{ ______x_=_k*h; ______if(k%(n/m)==0)_{ ________f_=_exp(x); ________e_=_fabs(y-f); ________printf("x=%.2f,_y=%f,_e^x=%f_er=%.0e\n", ________x,y,f,e); ______} ______dydx_=_y; ______y_=_y_+_dydx*h; ____} __} __printf("\n"); __//_y_=_1/e^4x __b_=_4; __for(n=100;n<=10000;n*=100){ ____h_=_(b-a)/n; ____printf("y'_=_-4y:_h(=dx)_=_%.1e_(y=1/e^4x)\n",h); ____x_=_a;_y_=_1; ____for(k=0;k<=n;k++)_{ ______x_=_k*h; ______if(k%(n/m)==0)_{ ________f_=_exp(-4*x); ________e_=_fabs(y-f); ________printf("x=%.2f,_y=%f,_1/e^4x=%f_er=%.0e\n", ________x,y,f,e); ______} ______dydx_=_-4*y; ______y_=_y_+_dydx*h; ____} __} __return_0; } 分かる方がいましたら、回答よろしくお願いします。

  • c言語のプログラムで行列の積を計算する

    指定された行・列数(それぞれ10以下とする)の行列 X, Y の積 Z = X × Y を求めるプログラムを作成せよ.行列の要素はすべて整数とする. このプログラムで行と列の成分を入力するときに、1列になってしまうのですがどうしたらちゃんと入力できますか? int main(void) { double A[10][10]; double B[10][10]; int i,j,m,n,p,k; printf("行列xの行数は?:"); scanf("%d",&m); printf("行列xの列数(行列yの行数)は?:"); scanf("%d",&n); printf("行列yの列数は?:"); scanf("%d",&p); printf("行列xを入力してください。\n"); for (i = 0; i < m; i++) { for (j = 0; j < n; j++) { scanf("%d", &A[i][j]); } } printf("行列yを入力してください。\n"); for (i = 0; i < n; i++) { for (j = 0; j < p; j++) { scanf("%d", &B[i][j]); } }

  • ラグランジュの補間法のCプログラム

    昨日学校でラグランジュの補間法の問題をC言語のプログラムで解けという課題が出されました しかし、友達と相談してもよくわかりませんでした 課題は以下の問題です sin関数6点、(0.92+0.01x)、x=0,1,2,3,4,5を求めて、ラグランジュの方法でsin(0.923)を計算せよ ちなみに答えは、0.79742です 先生からサンプルのプログラムをもらいました 以下のサンプルプログラムを参考にして解いてくださいと言われたのですが、どうしても解けません すいませんが分かる方、よろしくお願いします #include <stdio.h> #include <math.h> #define N 6 //データ数 double x[N]={ 0.0,1.0,2.0,3.0,3.1,5.0}; //X座標 double y[N]={0.0,1.1,2.5,4.0,4.1,5.0}; //Y座標 double lagrange( double); int main() { double xx,yy; //補間計算 printf("XX\t\tYY\n"); for( xx=0.0; xx<=5.0; xx+=.2 ) { yy = lagrange( xx); printf("%8.2lf\t%8.2lf\n", xx, yy ); } return 0; } //補間サブルーチン double lagrange( double xx ) { double z[N]; double yy=0.0; int i,j; for( i=0; i<N; i++ ) { z[i] = 1.0; //係数計算 for( j=0; j<N; j++ ) if( i!=j ) z[i]*=(xx-x[j])/(x[i]-x[j]); //補間値計算 yy+=z[i]*y[i]; } return yy; } 上記はあくまでサンプルプログラムなので、中に入っている数値は適当です よろしくお願いします

  • c言語 行列のn階乗のプログラム

      1 2 -1 D= 3 0 -2   -1 1 2 の3次正方行列のn乗を計算するプログラムを作成しています。 いろいろと試してみましたがうまくいきません。 どなたか教えていただけるとうれしいです。 よろしくおねがいします。 #include <stdio.h> int main(void) { int a[3][3]={ {-1,2,-1},{3,0,-2},{-1,1,2} }; int b[3][3]={ {-1,2,-1},{3,0,-2},{-1,1,2} }; int s[3][3]; int m,n; int i,j,k; printf("[A]^n;n = ");scanf("%d",&n); for (m=2;m <= n;m++){ for (i=0;i<3;i++){ for (j=0;j<3;j++){ s[i][j] = 0; for(k=0;k<3;k++){ s[i][j] =s[i][j] + a[i][k] * b[k][j]; } } } for(i=0;i<3;i++){ for(j=0;j<3;j++){ b[i][j]=s[i][j]; } } printf("%3d",s[i][j]); putchar('\n'); } return (0); }

  • ガウスの消去法のプログラム

    ガウスの消去法(部分ピボット選択)のプログラムを組んでみたつもりなのですが上手くいきません。 間違いだらけだと思いますがどうかアドバイスをして頂けませんでしょうか? #include <stdio.h> double main(void){ int i,j,k,N,M,m; double A[N+1][N+1][N+1],B[j],S,X[N+1]; printf("次数の入力。\n"); scanf("%d",&N); for(k=1;k<=N;k++){ for(i=1;i<=N;i++){ for(j=1;j<=N+1;j++){ A[k][i][j]=0; } } } for(i=1;i<=N;i++){ for(j=1;j<=N+1;j++){ printf("係数の入力.\n A[1][%d][%d]?\n",i,j); scanf("%f",&A[1][i][j]); } } for(k=2;k<=N;k++){ if(A[k-1][k-1][k-1]=0){ for(M=k;M<=N;M++){ if(A[k-1][M][k-1]!=0){ for(j=k-1;j<=N+1;j++){ B[j]=A[k-1][k-1][j]; A[k-1][k-1][j]=A[k-1][M][j]; A[k-1][M][j]=B[j]; } goto abc; } else {printf("解は無い\n");} } } abc: for(i=k;i<=N;i++){ for(j=k;j<=N+1;j++){ A[k][i][j]=A[k-1][i][j]-(A[k-1][i][k-1]/A[k-1][k-1][k-1])*A[k-1][k-1][j]; } } X[N]=A[N][N][N+1]/A[N][N][N]; printf("解X(N)は %f 。\n",X[N]); for(k=N-1;k>=1;k--){ S=0; for(m=N;m>=k+1;m--){ S+=A[k][k][m]*X[m]; } X[k]=(A[k][k][N+1]-S)/A[k][k][k]; printf("解X(%d)は %f 。\n",k,X[k]);} } }

  • ガウスのの単純消去法のプログラムです。

    ガウスのの単純消去法のプログラムです。 前進消去の第k段階が終わった段階でaij,biが表示されるようにしたいんですがどうすればいいでしょうか↓ よろしくお願いします。 #include<stdio.h> #include<stdlib.h> #include<math.h> #define ERROR -1 #define EPS 1.0e-15 int gausssimp(double *, double *, double *, int); int main(void) { double *a,*b,*x,val; char s[32]; int i,j,n,result; printf("Input size n="); gets(s); sscanf(s,"%d",&n); if((a=(double *)calloc(n*n,sizeof(double)) ) == NULL){ fprintf(stderr,"Memory allocation error\n"); exit(-1); } if((b=(double *)calloc(n,sizeof(double))) == NULL){ fprintf(stderr,"Memory allocation error\n"); exit(-1); } if((x=(double *)calloc(n,sizeof(double))) == NULL){ fprintf(stderr,"Memory allocation error\n"); exit(-1); } /* A,b の成分を入力 */ printf("----- A -----\n"); for(i=0; i<n; i++){ for(j=0; j<n; j++){ printf("a(%2d,%2d)=",i+1,j+1); gets(s); sscanf(s,"%lf",&val); a[n*i+j]=val; } } printf("\n----- b -----\n"); for(i=0; i<n; i++){ printf("b(%2d)=",i+1); gets(s); sscanf(s,"%lf",&val); b[i]=val; } /* Gaussの単純消去法による求解 */ result = gausssimp(x,a,b,n); /* 解の表示 */ if(result == ERROR){ printf("ERROR occurs. pivot 0\n"); } else { printf("\n----- solution -----\n"); for(i=0; i<n; i++){ printf("x(%2d)=%.8e\n",i+1, x[i]); } } free(a); free(b); free(x); return 0; } int gausssimp(double *x, double *a, double *b, int n) { int i,j,k; double tmp,p,sum; /* step 1: 前進消去 */ /**** 追加 ****/ /* 前進消去の各段階を終えるごとに,式がどのように変化しているかわかるように表示する */ /**************/ for(k=0; k<n-1;k++){ if(a[n*k+k] == 0.0) { /* ピボットの値が0.割り算でエラーが起きる.*/ return ERROR; } else { /* k+1番目以降の式から x[k] の項を消去 */ for(i=k+1; i<n; i++){ p=a[n*i+k]/a[n*k+k]; for(j=0; j<n; j++){ a[n*i+j]=a[n*i+j]-p*a[n*k+j]; } b[i]=b[i]-p*b[k]; printf("a[%d %d]=%d b[%d]=%d",i,j,a[n*i+j]-p*a[n*k+j],i,b[i]-p*a[n*k+j]); ↑これではできませんでした。。。 } /**********************************/ } printf("k=%d\n",k); } /* step 2: 後退代入 */ for(k=n-1; k>=0; k--){ if(fabs(a[n*k+k]) < EPS) return(ERROR); sum=0.0; for(j=k+1; j<n; j++) sum+=a[n*k+j]*x[j]; x[k]=(b[k] - sum)/a[k*n+k]; } return 0; }

専門家に質問してみよう