LU分解について

このQ&Aのポイント
  • LU分解のcによるプログラムについてお尋ねしたいことがございます。
  • LU分解の方法として以下のようなコードが記載されています。
  • LU分解を実行するためのメイン関数の書き方を教えてください。
回答を見る
  • ベストアンサー

LU分解について

こんにちは。 行列のLU分解のcによるプログラムを勉強している者です。 LU分解のcによるプログラムについてお尋ねしたいことがございます。 ニューメリカルレシピに、LU分解の方法として 以下のようなコードが記載せれておりました。 void ludcmp(double **a, int n, int *indx, double *d) { int i,imax,j,k; double big,dum,sum,temp; double *vv; // 各行の暗黙のスケーリングを記録する. vv=vector(n); *d=1.0; // まだ行交換していない. for (i=0;i<n;i++) { // 行についてループし,暗黙のスケーリングの情報を得る. big=0.0; for (j=0;j<n;j++) if ((temp=fabs(a[i][j])) > big) big=temp; if (big == 0.0) printf("Singular matrix in routine ludcmp\n"); // 最大要素が0なら特異行列である. vv[i]=1.0/big; // スケーリングを記録する. } for (j=0;j<n;j++) { // Crout法,列についてのループ for (i=0;i<j;i++) { // 方程式(2.3.12)のi=j以外 sum=a[i][j]; for (k=0;k<i;k++) sum -= a[i][k]*a[k][j]; a[i][j]=sum; } big=0.0; for (i=j;i<n;i++) { sum=a[i][j]; for (k=0;k<j;k++) sum -= a[i][k]*a[k][j]; a[i][j]=sum; if ( (dum=vv[i]*fabs(sum)) >= big) { big=dum; imax=i; } } if (j != imax) { for (k=0;k<n;k++) { dum=a[imax][k]; a[imax][k]=a[j][k]; a[j][k]=dum; } *d = -(*d); vv[imax]=vv[j]; } indx[j]=imax; if (a[j][j] == 0.0) a[j][j]=TINY; if (j != n) { dum=1.0/(a[j][j]); for (i=j+1;i<n;i++) a[i][j] *= dum; } } free_vector(vv); } 例えば、LU分解させたい行列3×3の({4,7,6}{2,5,9}{3,1,8})だとしたら、 メイン関数にどのように書いたらLU分解を実行できるでしょうか? ニューメリカルレシピを買って読んでみたものの、よく理解できず、質問させていただきます。 稚拙な質問かもしれませんが、どうぞよろしくお願いいたします。

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

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

あ、もしかして、 double a[3][3]; じゃなくて、 double a1[] = {4, 7, 6}; double a2[] = {2, 5, 9}; doulle a3[] = {3, 1, 8}; double *a[] = {a1, a2, a3}; なら、とりあえずはうまくいきますね。 でも、まだ、ludcmp(); をじっくり眺めるとおかしなところが残っています。 特異行列の時の処理とか。 あと、vector() はたぶん、どこかで独自に定義しているでしょうね。

ramusi
質問者

お礼

お礼欄に書くのはおかしいですが、 でたエラーメッセージは 1>------ ビルド開始: プロジェクト: LU, 構成: Debug Win32 ------ 1> LU.cpp 1>LU.obj : error LNK2019: 未解決の外部シンボル "void __cdecl free_vector(double *)" (?free_vector@@YAXPAN@Z) が関数 "void __cdecl ludcmp(double * *,int,int *,double *)" (?ludcmp@@YAXPAPANHPAHPAN@Z) で参照されました。 1>LU.obj : error LNK2019: 未解決の外部シンボル "double * __cdecl vector(long)" (?vector@@YAPANJ@Z) が関数 "void __cdecl ludcmp(double * *,int,int *,double *)" (?ludcmp@@YAXPAPANHPAHPAN@Z) で参照されました。 1>C:\Users\njdata\Documents\Visual Studio 2010\Projects\LU\Debug\LU.exe : fatal error LNK1120: 外部参照 2 が未解決です。 ========== ビルド: 0 正常終了、1 失敗、0 更新不要、0 スキップ ========== でした。お伝えし忘れていました、すみません。

ramusi
質問者

補足

丁寧にお答えくださいましてありがとうございます。 さっそくお答えいただいた通りに、以下のようにして動かしてみたのですが、動きませんでした・・・。 どうしてでしょうか??(質問ばかりで申し訳ありません) #include <stdio.h> #include <math.h> #include "nr.h" #define TINY 1.0e-20; int main() { double d; int indx; double a1[] = {4, 7, 6}; double a2[] = {2, 5, 9}; double a3[] = {3, 1, 8}; double *a[] = {a1, a2, a3}; ludcmp(a, 3, &indx, &d); return(0); } void ludcmp(double **a, int n, int *indx, double *d) { int i,imax,j,k; double big,dum,sum,temp; double *vv; // 各行の暗黙のスケーリングを記録する. vv=vector(n); *d=1.0; // まだ行交換していない. for (i=0;i<n;i++) { // 行についてループし,暗黙のスケーリングの情報を得る. big=0.0; for (j=0;j<n;j++) if ((temp=fabs(a[i][j])) > big) big=temp; if (big == 0.0) printf("Singular matrix in routine ludcmp\n"); // 最大要素が0なら特異行列である. vv[i]=1.0/big; // スケーリングを記録する. } for (j=0;j<n;j++) { // Crout法,列についてのループ for (i=0;i<j;i++) { // 方程式(2.3.12)のi=j以外 sum=a[i][j]; for (k=0;k<i;k++) sum -= a[i][k]*a[k][j]; a[i][j]=sum; } big=0.0; for (i=j;i<n;i++) { sum=a[i][j]; for (k=0;k<j;k++) sum -= a[i][k]*a[k][j]; a[i][j]=sum; if ( (dum=vv[i]*fabs(sum)) >= big) { big=dum; imax=i; } } if (j != imax) { for (k=0;k<n;k++) { dum=a[imax][k]; a[imax][k]=a[j][k]; a[j][k]=dum; } *d = -(*d); vv[imax]=vv[j]; } indx[j]=imax; if (a[j][j] == 0.0) a[j][j]=TINY; if (j != n) { dum=1.0/(a[j][j]); for (i=j+1;i<n;i++) a[i][j] *= dum; } } free_vector(vv); } ちなみに >あと、vector() はたぶん、どこかで独自に定義しているでしょうね。 その通りです。ヘッダファイルで定義されております。 記載せず、申し訳ありませんでした。 /*nr.h*/ #define DIM 3 void ludcmp(double **a, int n, int *indx, double *d); double *vector(long size); void free_vector(double *v); double **matrix(long rows, long cols); void free_matrix(double **m); int *ivector(long nh); void free_ivector(int *v);

その他の回答 (2)

回答No.3

単に、vector の実体がリンクの指定にないだけです。 void ludcmp(double **a, int n, int *indx, double *d) と同じように、vector の中身が書いてあるファイルをリンクしてください。

ramusi
質問者

お礼

ご丁寧にありがとうございます。 どうしてもうまくいかないのですが、 方向性は示して頂けたので、もう少しじっくり自分で勉強してみたいと思います。 何度もご丁寧にありがとうございました。大変参考になりました!

回答No.1

気持ちとしては、こんな感じなんだろうなと思います。 でも、これでは、うまくいきません。 肝心の ludcmp(); 自体にいくつかの間違いがあるからです。 勉強中なのだし、まずは、ludcmp(); の間違いを修正するというのはいいかもしれません。 int main() { double d; int indx; double a[3][3] = { {4, 7, 6}, {2, 5, 9}, {3, 1, 8} }; ludcmp(a, 3, &indx, &d); // その他の処理 }

関連するQ&A

  • LU分解を利用した逆行列のプログラム(Java)

    LU分解を利用した逆行列のプログラムが作れません… というか、作ったのですが実行するとエラーが出てしまいます(´Д`;) どこをどう直せばいいか、もしくはこのようにプログラムした方が効率がよい などのアドバイスどなたか下さい double a[][]={{2,5,4}, {2,3,-1}, {6,9,28}}; int N=a.length; double[][] s=new double[N][N]; for(int k=0; k<a[0].length-1; k++){ for(int i=k+1; i<N; i++){ s[i][k]=a[i][k]/a[k][k]; a[i][k]=s[i][k]; for(int j=k+1; j<N; j++){ a[i][j] -= s[i][k] * a[k][j]; } } } double[][] y=new double[N][N]; double[][] X=new double[N][N]; double[][] e=new double[N][N]; for(int i=0;i<N;i++){ for(int j=0;j<N;j++){ if(i==j){ e[i][j]=1; }else{ e[i][j]=0; } } } for(int i=0;i<N;i++){ y[1][i]=e[1][i]; for(int k=2;k<=N;k++){ for(int j=1;j<=N;j++){ y[k][i]=e[k][i]-s[k][j]*y[j][i]; } } X[N][i]=y[N][i]/a[N][N]; for(int k=N-1;k>=1;k--){ for(int j=k+1;j<=N;j++){ X[k][j]=(y[k][j]-s[k][j]*X[j][i])/a[k][k]; } } } for(int i=0;i<N;i++){ for(int j=0;j<N;j++){ System.out.printf(" %6.5f ", X[i][j] ); } System.out.println(""); }

  • 配列やif文について

    課題がでました。 最大で30個の整数を入力し、それを大きい順に並び替えるプログラムを 1次元配列と繰り返し・if文を使い作成しなさい。 例は input 12 8 90 the large order 90 12 8 という課題がでました。 ここの方なら簡単とは思いますが、よろしくお願いいたします。 自分で作ったプログラムは #include <stdio.h> main() { int a[30]; int n; int imax; int work; int max ; int i,k; printf("seisuunokosuu(<=30)="); scanf("%d",&n); for(i=0;i<n;i++){ printf("input.%2d=",i+1); scanf("%d",&a[i]);} for(i=0;i<n;i++){ imax = i; max = a[imax]; for(k=i+1;k<=n;k++){ if(a[k] > max){ imax =k; max = a[imax]; } } work = a[i]; a[i] = a[imax]; a[imax] = work; } for(i=0;i<n;i++){ printf("%d\n",a[i]); } return(0); } ですが、繰り返し・if文(一度)をつかっていません。 アドバイスの方よろしくおねがいいたします。

  • 行列の行の入換え

    | -1 -1 -2 -1 10 | | -1 -2 -1 10 -1 | | -2 -1 10 -1 -1 | | -1 10 -1 -1 -2 | | 10 -1 -1 -2 -1 | この行列を次の順序で並び替えたいのですが 1.第1列にある要素の中で絶対値の最大値がある行を探し,その行と第1行を入れ換える. 2.第2列にある要素の中で絶対値の最大値がある行を第2行以下から探し,その行と第2行を入れ換える. 3.これを左上から右下へ順次移動して,行の入れ換えを行う. #include<stdio.h> #include<math.h> #define N 5 #define M 5 int main(){ float a[N][M]={{-1.0,-1.0,-2.0,-1.0,10.0},{-1.0,-2.0,-1.0,10.0,-1.0},{-2.0,-1.0,10.0,-1.0,-1.0}, {-1.0,10.0,-1.0,-1.0,-2.0},{10.0,-1.0,-1.0,-2.0,-1.0}}; float nmax; int i,j,k=0,s,imax; for(j=0; j<M; j++){ nmax = a[0][j]; imax = 0; for(i=1; i<N; i++){ if(fabs(nmax) < fabs(a[i][j])){ nmax = a[i][j]; imax = i; } } for(j=0; j<M; j++){ s=a[k][j]; a[k][j]=a[imax][j]; a[imax][j]=s; } k++; } for(i=0; i<N; i++){ for(j=0; j<M; j++){ printf("%5.1f ",a[i][j]); } printf("\n"); } return(0); } このように作成したのですが、1行目と5行目しかいれかわりません。 なぜでしょうか??

  • Gaussの消去法のプログラムなんですがこれを利用して、消去法による行

    Gaussの消去法のプログラムなんですがこれを利用して、消去法による行列式の計算プログラムをつくりたいのですが難しくてよくわかりません。。。 教えていただきたいです。 困ってるのでよろしくお願いします。 int gauss(double *x, double *a, double *b, int n) { int i,j,k,m; double tmp,p,sum; for(k=0; k<n-1;k++){ printf("---- Step %d ----\n",k+1); printf("-- before --\n"); for( m = k;m < n;m++){ printf("%lf\n",a[n * m + k]); } printf("-- --\n"); j = pivot(a,n,k); if(j == ERROR) { return ERROR; } else { if(j != k) { for(i=0; i<n; i++){ tmp = a[n*k+i]; a[n*k+i] = a[n*j+i]; a[n*j+i] = tmp; } tmp=b[j]; b[j]=b[k]; b[k]=tmp; } } printf("-- after --\n"); for( m = k;m < n;m++){ printf("%lf \n",a[n * m + 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]; printf("a[%d %d]=%lf",i,j,a[n*i+j]); } b[i]=b[i]-p*b[k]; printf("b[%d]=%lf\n",i,b[i]); } 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; } int pivot(double *a, int n, int k) { int i,m; double d; /* ピボットの探索 */ m = k; d = fabs(a[k*n+k]); for(i=k+1; i<n; i++){ if(fabs(a[n*i+k]) > d){ m = i; d = fabs(a[n*i+k]); } } if(fabs(d) < EPS) { return ERROR; } else { return m; } }

  • 下記プログラミングについて

    下のプログラミングの解説ができる方がいましたら教えてください! どう頑張っても理解できなくて困っています;; もしかしたら間違っているところがあるかもしれませんが、よろしくお願いします。 ---------------------------------------------------------------- #include<stdio.h> #include<math.h> main() { int A,B,C,t,h,i,j,k; int sum_column,sum_row,diagonal1,diagonal2; int conf,diag,seed,max; int U[101][101],V[101][101]; int rand(); A=1,B=1,C=1; printf("Please define the pueen problem size(5-100).\n"); scanf("%d", &max); printf("Please input a seed(0-999).\n"); scanf("%d", &seed); for(i=1; i<=seed; i++){ U[1][1]=rand(); }; for(i=1; i<=max; i++){ for(j=1; j<=max; j++){ U[i][j] = -(abs(rand() % 8)); V[i][j]=0; }; };   /* Main program */ t=0; diag=1; while((diag>0)&&(t<500)){ diag=0; for(i=1; i<=max; i++){ for(j=1; j<=max; j++){ sum_column=0; sum_row=0; for(k=1; k<=max; k++){ sum_row=sum_row+V[i][k]; sum_column=sum_column+V[k][j]; } diagonal1=0; k=1; while(((j+k)<=max)&&((i-k)>=1)){ diagonal1=diagonal1+V[i-k][j+k]; k++; } k=1; while(((j-k)>=1)&&((i+k)<=max)){ diagonal1=diagonal1+V[i+k][j-k]; k++; } k=1; while(((j+k)<=max)&&((i+k)<=max)){ diagonal2=diagonal2+V[i+k][j+k]; k++; } k=1; while(((j-k)>=1)&&((i-k)>=1)){ diagonal2=diagonal2+V[i-k][j-k]; k++; } k=1; h=0; conf=1; if(sum_column == 0) h=1; if(sum_row == 0) h++; if((sum_column+sum_row==2) && (diagonal1<2) && (diagonal2<2)) conf=0; U[i][j]=U[i][j]-A*(sum_row+sum_column-2)-B*(diagonal1+diagonal2)+C*h; if(U[i][j]>8) U[i][j]=8; if(U[i][j]<-8) U[i][j]=-8; if(U[i][j]>0) V[i][j]=1; else V[i][j]=0; diag=diag+conf; }; }; t++; printf("t=%d\n", t); if((t % 15) < 5) C=4; else C=1; }; printf("the number of iteretion steps=%d\n", t); printf("\n"); for(i=1; i<=max; i++){ for(j=1; j<=max; j++){ if(j==max){ if(V[i][j]==1) printf("*\n"); else printf("-\n"); } else{ if(V[i][j]==1) printf("* "); else printf("- "); } } } }

  • ピボット選択がどのように行われてるか確かめたいので

    ピボット選択がどのように行われてるか確かめたいので 関数pivotを呼び出す前と呼び出して式を入れ替えた後のakk,ak+1k,...,ankを調べたいのですが どうすればいいのでしょうか? int gauss(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++){ printf("---- Step %d ----\n",k+1); /* ピボットの選択 */ /*** 追加(2):ピボット選択前,選択して式を入れ替えた後それぞれの * a(k,k), a(k+1,k), ... , a(n-1,k) * を表示して,ピボット選択がどのように行なわれたか調べる. ***/ /*--- ピボット選択前の位置 ---*/ printf("-- before --\n"); /* a(k,k), a(k+1,k), ... , a(n-1,k) を表示させる.*/ /*----------------------------*/ j = pivot(a,n,k); /* j: ピボットとして選ばれたa(j,k)の行番号 */ if(j == ERROR) { return ERROR; } else { if(j != k) { /* ピボットにはa(k,k)ではなくa(j,k)が選ばれた.式の入れ替えが必要 */ /* Aのk行とj行の入れ替え.*/ for(i=0; i<n; i++){ tmp = a[n*k+i]; a[n*k+i] = a[n*j+i]; a[n*j+i] = tmp; } /* b[k] と b[j] の入れ替え */ tmp=b[j]; b[j]=b[k]; b[k]=tmp; } } /*--- ピボット選択をし,式の入れ替えをした直後の位置 ---*/ printf("-- after --\n"); /* a(k,k), a(k+1,k), ... , a(n-1,k) を表示させる. /*------------------------------------------------------*/ /* 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]; printf("a[%d %d]=%lf",i,j,a[n*i+j]); } b[i]=b[i]-p*b[k]; printf("b[%d]=%lf\n",i,b[i]); } /*--- 追加(1):第k段によって x[k] を消去した後の,各式の状態を表示する. ---*/ /* a(1,1),a(1,2),...,a(1,n),b(1); a(2,1),a(2,2),... a(2,n),b(2), ... */ 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; } int pivot(double *a, int n, int k) { int i,m; double d; /* ピボットの探索 */ m = k; d = fabs(a[k*n+k]); for(i=k+1; i<n; i++){ if(fabs(a[n*i+k]) > d){ m = i; d = fabs(a[n*i+k]); } } if(fabs(d) < EPS) { return ERROR; } else { return m; } }

  • 行列に関して。

    以下の行列を対角成分が最も大きくなるような プログラムをつくりたいのですが 0   1   4  3 7   0   1  -5 1    3   0   7 -2   4   4  -8 #include<stdio.h> #include<math.h> #include<stdlib.h> #define NUM 4 int main(){ /* 初期化 */ int i; /* ループ変数 (行)*/ int j; /* ループ変数 (列)*/ int k; /* ループ変数 */ int imax; /* 最大値のi成分 */ int jmax; /* 最大値のj成分 */ double nmax; /* 最大値を入れるための変数 */ double tmp; /* ソートのための一時的な変数 */ double eps = 1.0e-6; /* 判定値 */ double a[NUM][NUM] = { { 0.0, 1.0, 4.0, 3.0}, { 7.0, 0.0, 1.0, -5.0}, { 1.0, 3.0, 0.0, 7.0}, {-2.0, 4.0, 4.0, -8.0}}; /* 対象とする要素位置 = k */ for( k = 0 ; k < NUM ; k++ ){ /*対象とする要素位置 = k*/ nmax = 0.0;/* 初期化 */ imax = k;/* 初期化 0とは限らない */ jmax = k;/* 初期化 0とは限らない */ /* 1.絶対値の最大値を求める */ for( i = k ; i < NUM ; i++ ){ for( j = k ; j < NUM ; j++ ){ if(fabs(nmax) < fabs(a[i][j])){ nmax = a[i][j]; imax = i; jmax = j; /* 対象としている行列要素の中で,最大となる行列要素のi,j成分を探す */ /*ここに絶対値の最大値を求め、nmax、imax、jmaxに代入するプログラムを書く*/ /*絶対値の求め方、数学関数fabs(x)を用いる*/ } } } /* 2.行入れ換え */ if( k != imax ){/* 対象としている行と最大値を持つ行が同じなら,入れ替える必要が無い */ for( j = 0 ; j < NUM ; j++ ){ tmp=a[k][j]; a[k][j]=a[imax][j]; a[imax][j]=tmp;/* 対象としている行と最大値を持つ行との入れ替え */ /*ここに行の入れ替え行うプログラムを書く*/ } } /* 3.列入れ換え */ if( k != jmax ){/* 対象としている列と最大値を持つ列が同じなら,入れ替える必要が無い */ for( i = 0 ; i < NUM ; i++ ){ tmp=a[i][k]; a[i][k]=a[i][imax]; a[i][imax]=tmp;/*対象としている列と最大値を持つ列との入れ替え*/ /*ここに列の入れ替え行うプログラムを書く*/ } } } /* 結果の出力 */ for(i=0; i<NUM; i++){ for(j=0; j<NUM; j++){ printf("%5.1f ",a[i][j]); } printf("\n"); } /*ここに行列の表示プログラムを書く*/ return(0); } 上のぷろぐらむを実行しても、1個目のfor文の1ループ目で終了してしまい 1行目と、4行目を交換、4列目と1列目を交換した行列だけが表示されます。 結果が以下のような行列にするにはどう改善すればよいでしょうか? -8.0   -2.0  4.0  4.0 -5.0   7.0  1.0  0.0   3.0   0.0  4.0  1.0  7.0   1.0  0.0  3.0 です。

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

    ガウスのの単純消去法のプログラムです。 前進消去の第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; }

  • 行列の和、積、乗算について(C言語)

    まだC言語の勉強を始めて1か月の初心者なのですが、みなさんにお聞きしたいことがあります。 任意の行列に対して和、積、乗算の関数を作り出力するプログラムを 作りたいのですが、試しに和の関数を作ってビルトしてみたら、 31個もエラーが出て、困っています。 ↓参考書を見ながら、自分なりに考えたプログラムです。 #include <stdio.h> typedef struct matrix{ int m; int n; double data[100][100]; } MATRIX; int main(void) { MATRIX a; MATRIX b; a.m=2; a.n=3; a.data[100][100]={{1,2,1},{2,3,3}}; b.m=2; b.n=3; b.data[100][100]={{2,3,1},{1,2,1}}; kekka=add_mat(MATRIX a,MATRIX b); printf("和:%f,kekka.data); //行列和関数 MATRIX add_mat(MATRIX a,MATRIX b){ MATRIX sum; int i,j; sum.m=a.m; sum.n=a.n; sum.data[100][100]={{0,0,0}{0,0,0}}; for(i=0;i<sum.m;i++){ for(j=0;j<sum.n;j++){ sum.data=(a.data)+(b.data); return sum; } } } return 0; } おそらく相当ダメな感じなのでしょうが、エラー文を読んでも なかなか解決できません。 ちなみに、積の関数は mul_mat(MATRIX c,MATRIX a,MATRIX b){ int i,j,k; for(i = 0; i < a.m; i++){ for(j = 0; j < b.n; j++){ for(k = 0; k < a.n; k++){ C[i][j] = C[i][j] + A[i][k] * B[k][j]; } } } という風に考えました。みなさまのお力を借りたいです。 よろしくお願いします

  • 行列の和、積、乗算(C言語)

    まだC言語の勉強を始めて1か月の初心者なのですが、みなさんにお聞きしたいことがあります。 任意の行列に対して和、積、乗算の関数を作り出力するプログラムを 作りたいのですが、試しに和の関数を作ってビルトしてみたら、 31個もエラーが出て、困っています。 ↓参考書を見ながら、自分なりに考えたプログラムです。 #include <stdio.h> typedef struct matrix{ int m; int n; double data[100][100]; } MATRIX; int main(void) { MATRIX a; MATRIX b; a.m=2; a.n=3; a.data[100][100]={{1,2,1},{2,3,3}}; b.m=2; b.n=3; b.data[100][100]={{2,3,1},{1,2,1}}; kekka=add_mat(MATRIX a,MATRIX b); printf("和:%f,kekka.data); //行列和関数 MATRIX add_mat(MATRIX a,MATRIX b){ MATRIX sum; int i,j; sum.m=a.m; sum.n=a.n; sum.data[100][100]={{0,0,0}{0,0,0}}; for(i=0;i<sum.m;i++){ for(j=0;j<sum.n;j++){ sum.data=(a.data)+(b.data); return sum; } } } return 0; } おそらく相当ダメな感じなのでしょうが、エラー文を読んでも なかなか解決できません。 ちなみに、積の関数は mul_mat(MATRIX c,MATRIX a,MATRIX b){ int i,j,k; for(i = 0; i < a.m; i++){ for(j = 0; j < b.n; j++){ for(k = 0; k < a.n; k++){ C[i][j] = C[i][j] + A[i][k] * B[k][j]; } } } という風に考えました。みなさまのお力を借りたいです。 よろしくお願いします。