C言語による数値計算の指導に関する質問

このQ&Aのポイント
  • C言語で2次関数の係数を求めるプログラムを作成したいが、ガウス消去法で解けない
  • ガウス消去法を用いたC言語のプログラムを作成したがエラーが出ている
  • 他の人が教えてくれることでプログラムが完成できるかどうか知りたい
回答を見る
  • ベストアンサー

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; }

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

  • ベストアンサー
noname#88356
noname#88356
回答No.2

double *simple_gauss( double a[3][3], double b[3] ); などはこれでも正解なのですが、具体的な数値名が関数の定義に含んでいるので 本当はポインタであることを明確にするために double *simple_gauss( double **a, double *b ); などとするべきかなと思います。(その方が一々数字を書き換えなくていいですし) 後、細かいことではありますが、 double a[3][3]; /* マトリックスの宣言*/ double x[3]; /* 解ベクトルの宣言*/ double y[3]; /* 右辺ベクトルの宣言*/ double xx, yy; /* キーボード入力のための一時変数*/ の部分は個々の変数名が分かりにくいのも問題かなと思います。 私も昔はこういう書き方をしていましたが、エラーが出る可能性の増大が馬鹿に出来ないことに ある時気がつき、forループなどの一時的なカウンター変数を除いては一時的なものであっても 分かりやすい命名を心がけています。 さらに、これらの変数は見たところ共通している要素であるため、構造体、または C++であればクラスなどでパックにした方が後々の修正や読む人が楽であると思います。 最後に、コメントに /* コメント */ の方法を取っているようですが、これは単一の行で用いるにはあまり推奨されない方法です。 というのも/* */はその間に/* */をはさんでコメントアウトなどが出来ないので、 もしある関数の中身でコメントに/* */が多用されているとテストするときに ここからここまでコメントアウトしたい・・などというときに/* */を使って一気に コメントアウトしようとしても間に/* */が混じっているとコンパイルエラーになってしまい、 大規模なソフトを作る際にはかなり面倒が起こりやすいです。 初期のC言語では/* */が唯一のコメント方法であり、//コメント の形式はサポートされていませんでしたが、 現在は標準Cで//コメントの形式がサポートされているので、例えば double a[3][3]; /* マトリックスの宣言*/ double x[3]; /* 解ベクトルの宣言*/ double y[3]; /* 右辺ベクトルの宣言*/ double xx, yy; /* キーボード入力のための一時変数*/ は double a[3][3]; //マトリックスの宣言 double x[3];  //解ベクトルの宣言 double y[3];  //右辺ベクトルの宣言 double xx, yy; //キーボード入力のための一時変数 のようにした方が良いかと思います。 後、要素の数が3の配列が多いですが、これらは必ず3と固定されているのでしょうか? もし数学的な理由で3と固定されているなら #define ARY_NUM 3 などとして配列の宣言時は double a[ ARY_NUM ][ ARY_NUM ];  //マトリックスの宣言 double x[ ARY_NUM ];          //解ベクトルの宣言 double y[ ARY_NUM ];          //右辺ベクトルの宣言 double xx, yy;               //キーボード入力のための一時変数 などとした方が色々な面で後の変更や修正が楽です (C++ならconst intでやる方法もあります) ところで自宅のPCにはVisual Studioを入れていないということでしたが、 http://www.microsoft.com/japan/msdn/vstudio/express/ 無料版があることは既にご存知でしょうか? おせっかいかもしれませんが、もしご存知でなければ本当に便利ですので導入をオススメします。 (私もCやC++で3Dのプログラム組む時などはこれが手放せないです)

abc_060
質問者

お礼

Visual Studioの情報ありがとうございます aが3×3の行列なので、縦横の順にa[3][3]とおきました 対応してx、yは3×1行列なのでx[3]、y[3]とおきました a×x=yの関係です 求めるa,b,cと行列aが同じに見えてややこしいのでp,q,rに変えますね、すいません 要は以下の連立方程式を行列化しただけなのですが p×Σxi^4+q×Σxi^3+r×Σxi^2=Σxi^2*yi p×Σxi^3+q×Σxi^2+r×Σxi=Σxi*yi p×Σxi^2+q×Σxi+r×5=Σyi 見ての通りこれを行列化しa×x=yにするとaがややこしくなるのでa[1][1]=~,a[1][2]=~....と成分を書き出しました main(void)内で5点の座標(x,y)をキーボード入力して、その後の計算して表示double *simple_gaussで計算した結果を表示してくれればいいのですが それで http://www.ma.is.saga-u.ac.jp/minamoto/book/book8/book8.html の本を授業で使ってまして、これの第3章3.1のプログラムをもとに作成したのですが、これはinput.dat等のファイルから展開して計算をしているのですがこれをscanfで直接5点の座標(x,y)をキーボード入力して取り込みそれをもとに計算するように変えようとして失敗したのが始めに投稿したプログラムです ガウス消去法の部分はそのまま使えるのでmain(void)部分内を何とか変えることができたらと思うんですが ちなみに/* コメント */もこの本を参考にしているので詳しいことは知りませんでした、全くの素人なんでfatalitaさんのような専門の人に質問を回答いただいて本当に感謝しています

その他の回答 (1)

noname#88356
noname#88356
回答No.1

私には数学の知識が中卒程度しかないのでプログラム部分だけアドバイスを ・main(void)はint main( void )と書くべき ・simple_gauss関数でfor( i = k+1; i <= ; i++)となっている(タイプミスでは? ・ y=*simple_gauss(a,y);は定義済みのyに配列確保しようとしています。  mallocするかあるいはdouble * y2 = simple_gauss( a, y );のように新しい配列を確保しなおす必要があります。 これを修正したらコンパイルは通りましたが、これはあまり良いコードとは思えません。

abc_060
質問者

お礼

スペースを空けたのに何故か全部左詰めになって見にくくてすみません。 あまりよいコードではないとは? 点(x,y)を5点キーボード入力してa,b,cがでればいいのですが.... すんません、今返信してるパソコンにはWindowsVisualStudio等のコンパイラがないので大学のパソコンでしか動作確認ができない状態なんですがOTLすいません。

abc_060
質問者

補足

すみませ~ん!ガウス消去法の部分がちょっと間違ってました {    int i, j, k;    double alpha, tmp;    /* 前進消去 */    for( k = 1; k <= 2; k++)    {      for( i = k+1; i <= 3 ; i++)      {       alpha = - a[i][k]/a[k][k];       for( j = k+1; j <= 3; j++)       {        a[i][j] = a[i][j] + alpha * a[k][j];       }       y[i] = y[i] + alpha * y[k];      }     }    /* 後退代入 */    y[3] = y[3]/a[3][3];    for( k = 2; k >= 1; k--)    {      tmp = y[k];      for( j = k+1; j <= 3; j++)      {       tmp = tmp - a[k][j] * y[j];      }     y[k] = tmp/a[k][k];    }    return y; } です 仰るとおりタイプミスも修正しましたが....

関連するQ&A

  • 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]); } }

  • ラグランジュの補間法の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言語です。

    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言語でのFFTについて

    http://tsuyu.cocolog-nifty.com/blog/2007/03/publi.html に掲載されているVBAのFFTプログラムをC言語に書き換えて 実行しているのですがうまくいきません。 どこが、間違っているか教えてください。 ======以下FFTのサブルーチンソースコード===== void FFT(float Xr[], float Xi[]) { i=0,j=0,k=0,l=0,m=0,n=0,p=0,q=0; n=DN; m = log10(n)/log10(2); Table(c,s); l=n,h=1; for(g=1;g<=m;g++){ l/=2,k=0; for(q=1;q<=h;q++){ p=0; for(i=k;i<=l+k-1;i++){ j=i+l; a=Xr[i]-Xr[j], b=Xi[i]-Xi[j]; Xr[i] = Xr[i] + Xr[j], Xi[i] = Xi[i] + Xi[j]; if(p==0){ Xr[j]=a,Xi[j]=b; }else{ Xr[j] = a * c[p] + b * s[p], Xi[j] = b * c[p] - a * s[p]; } p+=h; } k+=l+l; } h+=h; } j=n/2; for(i=1;i<=n-1;i++){ k=n; if(j<i){ //ビットリバース swap(&Xr[i],&Xr[j]); swap(&Xi[i],&Xi[j]); } k=k/2; while(j>=k){ j=j-k; k /=2; } j = j + k; } }

  • C言語の課題で悩んでいます

    線形最小2乗法と直接探索法の併用により、あるデータを最小2乗近似によって係数を求めるプログラムを作りました。 プログラムを実行したところ以下の警告が出て悩んでいます。 114行目 互換性のないポインタ型からの引数 1 個の `sweep' を渡しますです 114行目 互換性のないポインタ型からの引数 5 個の `sweep' を渡しますです 分りやすいように114行目のところに@がつけてあります。 どなたかご指摘お願いします。 #include<stdio.h> #include<math.h> #define eps 1.e-5 void sweep(double *,double *,int,int,int *,int); void DSO(double *,double *,int *,double *,double *,int,int); void FUN(double *,double *,double *,int,double *,int *); int main(void) { double a[1],da[1],x[7],y[7]; int i,n,delta[1]; scanf("%d",&n); for(i=0;i<n;++i) scanf("%lf %lf",&x[i],&y[i]); scanf("%lf %lf",&a[0],&da[0]); printf("Iteration b(1) b(2) b(3) a f\n"); DSO(a,da,delta,x,y,1,n); } /*DSO*/ void DSO(double *pa,double *pda,int *pdelta,double *px,double *py,int m,int n) { double ak,akp,akm,f0,fp,fm; int k,j,iteration=0; for(k=0;k<m;++k){ *(pdelta+k)=1; } FUN(pa,px,py,n,&f0,&iteration); do{ j=0; for(k=0;k<m;++k){ ak=*(pa+k); akp=*(pa+k)+*(pda+k); akm=*(pa+k)-*(pda+k); if(*(pdelta+k)==1){ *(pa+k)=akp; FUN(pa,px,py,n,&fp,&iteration); if(f0>fp){ *(pdelta+k)=1; f0=fp; break; } else{ *(pa+k)=akm; FUN(pa,px,py,n,&fm,&iteration); if(f0>fm){ *(pdelta+k)=-1; f0=fm; break; } else{ j++; *(pa+k)=ak; } } } else{ *(pa+k)=akm; FUN(pa,px,py,n,&fm,&iteration); if(f0>fm){ *(pdelta+k)=-1; f0=fm; break; } else{ *(pa+k)=akp; FUN(pa,px,py,n,&fp,&iteration); if(f0>fp){ *(pdelta+k)=1; f0=fp; break; } else{ j++; *(pa+k)=ak; } } } } }while(j!=m); printf("*** SOLVED ***\n"); FUN(pa,px,py,n,&f0,&iteration); return; } /*Function for sum of square errors*/ void FUN(double *pa,double *px,double *py,int n,double *pf,int *pi) { double b[3],c[3][4],iwork[3],t[3],yi; int i,ILL; c[0][0]=n; c[0][1]=0.; c[0][2]=0.; c[0][3]=0.; c[1][1]=0.; c[1][2]=0.; c[1][3]=0.; c[2][2]=0.; c[2][3]=0.; for(i=0;i<n;i++){ c[0][1]+=log10(*(px+i)); c[1][1]+=log10(*(px+i))*log10(*(px+i)); c[0][2]+=pow(log10(*(px+i)),*(pa+0)); c[1][2]+=pow(log10(*(px+i)),*(pa+0)+1.); c[2][2]+=pow(log10(*(px+i)),2.**(pa+0)); c[0][3]+=*(py+i); c[1][3]+=*(py+i)*log10(*(px+i)); c[2][3]+=*(py+i)*pow(log10(*(px+i)),*(pa+0)); } c[1][0]=c[0][1]; c[2][0]=c[0][2]; c[2][1]=c[1][2]; sweep(c,t,3,4,iwork,ILL); @114行目 for(i=0;i<3;++i){ b[i]=c[i][3]; } *pf=0.; for(i=0;i<n;++i){ yi=b[0]+b[1]*log10(*(px+i))+b[2]*pow(log10(*(px+i)),*(pa+0)); *pf+=(*(py+i)-yi)*(*(py+i)-yi); } printf("%6d %12.3e%12.3e%12.3e%7.2f%11.2e\n", *pi,b[0],b[1],b[2],*(pa+0),*pf); ++*pi; return; } /*Gauss-Jordan method*/ void sweep(double *pa,double *pt,int n,int m,int *piwork,int ILL) { double max,w; int i,j,k,iw,p,q; for(i=0;i<n;++i){ max=fabs(*(pa+m*i)); for(j=0;j<n;++j){ if(max<fabs(*(pa+m*i+j)))max=fabs(*(pa+m*i+j)); } for(j=0;j<m;++j) *(pa+m*i+j)=*(pa+m*i+j)/max; } for(j=0;j<n;++j){ max=fabs(*(pa+j)); for(i=0;i<n;++i){ if(max<fabs(*(pa+m*i+j)))max=fabs(*(pa+m*i+j)); } *(pt+j)=max; for(i=0;i<n;++i) *(pa+m*i+j)=*(pa+m*i+j)/max; } for(i=0;i<n;++i){ *(piwork+i)=i; } for(k=0;k<n;++k){ max=fabs(*(pa+m*k+k)); p=k; q=k; for(j=k;j<n;++j){ for(i=k;i<n;++i){ if(max<fabs(*(pa+m*i+j))){ max=fabs(*(pa+m*i+j)); p=i; q=j; } } } if(max<=eps){ ILL=1; printf("MATRIX IS ILL\n"); return; } for(i=0;i<n;++i){ w=*(pa+m*i+k); *(pa+m*i+k)=*(pa+m*i+q); *(pa+m*i+q)=w; } for(j=k;j<m;++j){ w=*(pa+m*k+j); *(pa+m*k+j)=*(pa+m*p+j); *(pa+m*p+j)=w; } i=*(piwork+k); *(piwork+k)=*(piwork+q); *(piwork+q)=i; for(j=k+1;j<m;++j){ *(pa+m*k+j)=*(pa+m*k+j)/(*(pa+m*k+k)); } for(i=0;i<n;++i){ if(i!=k){ for(j=k+1;j<m;++j){ *(pa+m*i+j)=*(pa+m*i+j)-*(pa+m*i+k)*(*(pa+m*k+j)); } } } } for(j=n;j<m;++j){ for(i=0;i<n;++i){ iw=*(piwork+i); *(pa+m*iw+n-1)=*(pa+m*i+j); } for(i=0;i<n;++i){ *(pa+m*i+j)=*(pa+m*i+n-1)/(*(pt+i)); } } return; }

  • C言語★

    012   012 123 × 123 234   234 を計算させるために以下の関数と表示するプログラムを作りました。 しかし、セグメントエラーで実行できません。 関数 void matprod(int nrow,int ncol,double **a,double **b,double ** prod){ int i,j,k; for(i=0;i<nrow;i++){ for(j=0;j<ncol;j++){ for(k=0;k<ncol;k++){ prod[i][j]=a[k][j]*b[i][k];} } } return ; } 表示部分 matprod(3,3,a,b,prod); for(i=0;i<nrow;i++){ for(j=0;j<ncol;j++){ printf("%d",prod[i][j]); //3*3の計算をして、答えを表示する。 }} この中に間違えがあると思うのですが、いくらチェックしても分かりません。>< お願いです。 どなたか、間違いを分かる方がいらっしゃったら教えてください!!

  • プログラムに内容と計算の質問です。

    こんにちは。 補間多項式についての、コンピュータのプログラムの解読に困っています。内容は、 「For the numerical experiments suggested in the computer problems, the following two procedures should be satisfactory. The first is called Coef. It requires as input the number n and tabular values in the array {Xi} and {Yi}. Remember that the number of points in the table is n+1. The procedure then computes the coefficients required in the Newton interpolating polynomial, storing them in the array{Ai}. -------------------------------------------------------- procedure; Coef(n,{Xi},{Yi},{Ai}) real array; {Xi}0:n, {Yi}0:n, {Ai}0:n integer; i,j,n for i=0 to n do {Ai}←{Yi} end for for j=1 to n do for i=n to j step -1 do Ai←({Ai}-{Ai-1})/({Xi}-{Xi-j}) end for end for end procedure Coef --------------------------------------------------------- このプログラムのn=3の時を考えるとき、  (1)j=1のとき、i=3,2,1 <j=1,i=1> {A1}=({A1}-{A0})/({X1}-{X0}) =({Y1}-{Y0})/({X1}-{X0}) <i=1,i=2> {A2}=({A2}-{A1})/({X2}-{X1}) =({Y2}-{Y1})/({X2}-{X1}) <i=1,i=3> {A3}=({A3}-{A2})/({X3}-{X2}) =({Y3}-{Y2})/({X3}-{X2}) (2)j=2のとき、i=3,2 <j=2,i=1> A1=({A2}-{A1})/({X2}-{X0})          ={[({Y2}-{Y1})/({X2}-{X1})]-[({Y1}-{Y0})/({X1}-{X0})]}/({X2}-{X0}) =この式変形をしたいのですが、どのように         すれば良いのかわかりません。ラグランジェ         型になりそうでなりません(泣)         (1)で求めた{A1},{A2},{A3}を使って求めな         いといけないみたいです。 見にくい表し方で申し訳ありません。 アドバイスお願いします!!

  • 配列を利用したコードにしてください

    下記コードですが 計算速度が遅いので配列を利用した コードに修正してください。お願いいたします。 Dim mx As long Dim Rp As Double Dim yy1 As Double Dim pai As Double Dim Ba AS long Dim i As long, j as long Dim K As Doubke Dim xx1 As Double, yy1 As Double Dim x0 As Double,y0 As Double Dim x1 As Double, y1 As Double mx = Sheets("nn").Range("B65536").End(xlUp).Row Rp1= Sheets("pp").Range("B65536").End(xlUp).Row yy1= Sheets("pp").Range("A25") With Sheets("zzz") pai=Atn(1) * 4 Ba=Sheets("sheet1").Range("A1")  For I = 1 To Ba K = -Sheets("sheet1").Range("B" & I + 3).Value * pai/180 xx1 = Sheets("sheet1").Range("C" & I + 3).Value   yy1 = Sheets("sheet1").Range("D" & I + 3).Value  For j = 1 To mx - 1 x0 = .Cells(2 + j, 2) y0 = .Cells(2 + j, 3) X1 = x0 * Cos(K) + y0 * Sin(K) Y1 = -x0 * Sin(K) + y0 * Cos(K) .Cells(2 + j, 2 * I + 2) = X1 + xx1 - Rp1 .Cells(2 + j, 2 * I + 3) = Y1 + yy1  Next j  Next I End with

  • 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言語についてなのですが・・・

    さきほども上げたのですがカテゴリが間違っていたのでもう一回書き込みました まだプログラムの勉強をはじめた初心者なのですが、 テキストファイルから文字を読みこみ、大文字ならば小文字に変換し辞書順に並びかえるプログラムを作っているのですがどうしてもうまくいきません。 例えばtest.txtに XXX YYY YY XX BBB aaa aa BB とあれば aa aaa bb bbb xx xxx yy yyy と表示されるよにしたいんです。 自分が作ったプログラむはこれです。 まだテキストファイルからでなくキーボードからの入力になっていますが・・・ #include<stdio.h> #include<stdlib.h> #include<string.h> #include <ctype.h> int soto( const void *x, const void *y); int main(int argc, char *argv[]){ FILE *input; char str1[1000]; int i, j; for (i = 1; i < argc; i++){ qsort(argv[i], 1000, sizeof( char *), soto); strcpy(str1, argv[i]); for(j = 0; j < 100; j++){ str1[j] = tolower( str1[j] ); } printf("%s\n", str1); } return 0; } int soto( const void *a, const void *b){ char *x, *y; x = (char*)a; y = (char*)b; return x-y; } これだと小文字にはなるんですがソートされずに表示されてしまいます・・・ どのようにすればいけるのかご指摘のほどおねがいします