ピボット選択の方法とは?

このQ&Aのポイント
  • ピボット選択とは、行列の前進消去法で使用される手法の1つで、主要な係数を選択して、行列の並び替えを行う操作です。
  • ピボット選択は、行列の主要な係数(ピボット)を選び、それを使って行列の要素を操作することで、計算の効率性や安定性を向上させることができます。
  • ピボット選択は、連立方程式の解を求める際や、行列の逆行列を求める際などに利用されます。適切なピボット選択を行うことで、計算過程のエラーを最小化することができます。
回答を見る
  • ベストアンサー

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

ピボット選択がどのように行われてるか確かめたいので 関数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; } }

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

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

#そこまで自力で書けて何で出来ないかなあ(汗 #これ単独では動かないので、前回(Q5959140)のと繋げておいた。 http://ideone.com/z0Hcq #ERRORが-1なのは単なる好み。

yuusei99
質問者

お礼

ありがとうございます。 一回のみならず二回も... 理解することができました。

関連するQ&A

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

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

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

  • 基本選択法

    宜しくお願いします。 基本選択法のプログラムを書いていますが、コンパイルは通りますが、うまくソートされません。 改良点をご教示ください。 #課題ではありません。 #include <stdio.h> int getMin(int in[], int n, int a); void swap(int *m, int *n); int main(void) {   int a[10] = { 84, 121, 43, 93, 140, 83, 14, 93, 181, 58};   int i, j, k;   for(i=0; i<10; i++){     k = getMin(a, 10, i);     swap(&a[i], &a[k]);     for(j=0; j<10; j++){       printf("a[%d] = %d ", j, a[j]);     }     printf("\n");   }   return 0; } void swap(int *m, int *n) {   int tmp;   tmp = *m;   *m = *n;   *n = tmp; } int getMin(int in[], int n, int a) {   int i, ret, min;   min = in[a];   ret = 0;   for(i = a; i < n; i++)   {     if(in[i] < min){       min = in[i];       ret = i;     }   }   return ret; }

  • 正しい結果が表示されない

    以下のプログラムはガウスの消去法を使って 解を求めるプログラムです。 しかし、gauss関数にprintf関数を入れてコンパイルすると 正しい結果 5 3 1 0 0 がでますが、gauss関数にprintf関数をいれずmain関数に書くと 0 0 0 0 0 となります。 なぜでしょうjか?? #include<stdio.h> #include<math.h> #define N 5 void gauss(double a[N][N+1]); int main(){ double a[N][N+1] = { { 1,-1,-1,-1,-1, 1}, {-1, 1,-1,-1,-1,-3}, {-1,-1, 1,-1,-1,-7}, {-1,-1,-1, 1,-1,-9}, {-1,-1,-1,-1, 1,-9} }; double x[N]; int i; gauss(a); printf("\n[x]=\n"); /* x[i] を表示する */ for(i=0; i<N; i++){ printf(" %8.3lf\n", x[i]); } return(0); } void gauss(double a[N][N+1]) { int i,j,k,p; double m, pmax, s, x[N]; for(k = 0; k < N-1; k++){ /* ピボット操作 */ p = k; /* p, pmax の初期値 */ pmax = fabs(a[k][k]); for(i = k+1; i < N; i++){ /* 最大値を検索 */ if(fabs(a[i][k]) > pmax){ p = i; pmax = fabs(a[i][k]); } } if(fabs(pmax) < 1.0e-12){ /* 最大値がゼロに近い時はエラー */ fprintf(stderr, "too small pivot!\n"); exit(1); } if(p != k){ /* ピボット操作 */ for(j = 0; j < N+1; j++) { s = a[k][j]; /* 値の入れ替え */ a[k][j] = a[p][j]; a[p][j] = s; } } for(i = k+1; i < N; i++) { /* 第 i 行 */ m = a[i][k] / a[k][k]; /* 倍率 m を計算 */ a[i][k] = 0; /* 注1 (下記参照) */ for(j = k+1; j < N+1; j++) { /* 第 j 列 */ a[i][j] = a[i][j] - a[k][j] * m; } } } for(i = N-1; i >= 0; i--){ /* 後退代入 */ m = 0; for(j = N-1; j > i; j--){ m = m + a[i][j] * x[j]; } x[i] = (a[i][N] - m) / a[i][i]; } }

  • -1.#IND00と出てしまうのですが・・・

    vc++(2010)でガウスの消去法を使って連立方程式を解く、というプログラムを組みました。 正直中身自体をきちんと理解していないので、 組みながら理解しようと思って組んだのですが、 結果に-1.#IND00と出てしまいました。 これは何なのでしょうか? 下記がそのプログラムです。 #include<stdio.h> #include<math.h> #define N 3 int main(void){ double a[N][N+1] = {{2,3,4}, {3,-2,5}, {5,4,-7}}; double b[1][N+1] = {20,14,-8}; double x[N]; int i = 0; int j = 0; int k = 0; int l = 0; int pivot = 0; double p = 0; double q = 0; double m = 0; for(i = 0; i < N; i++){ x[i] = 0; } for(i = 0; i < N; i++){ pivot = i; for(l = i; l < N; l++){ if(fabs(a[l][i]) > m){ m = fabs(a[l][i]); pivot = l; } } if(pivot != i){ for(j = 0; j < N; j++){ b[0][j] = a[i][j]; a[i][j] = a[pivot][j]; a[pivot][j] = b[0][j]; } } } for(k = 0; k < N; k++){ a[k][j] = a[k][j] / p; a[k][k] = 1; for(j = k; j < N; j++){ a[k][j] = a[k][j] / p; } for(i = k+1; i < N; i++){ q = a[i][k]; for(j = k+1; j < N; j++){ a[i][j] = a[i][j] - q*a[k][j]; } a[i][k] = 0; } } for(i = N-1; i >= 0; i--){ x[i] = a[i][N]; for(j = N-1; j > i; j--){ x[i] = x[i] - a[i][j] * x[j]; } } // for(i = 0; i < N; i++){ // for(j = 0; j < N+1; j++){ // printf("%.1f", a[i][j]); // } // printf("\n"); // } // printf("解\n"); // for(i = 0; i < N; i++){ // printf("%f\n", x[i]); // } return 0; } 最後のコメントにしてある行は解を表す時と行列を表す時で使い分けているので、 実際はどちらかを外して使用しています。

  • C++についての質問です

    プログラミング初心者です 以下の通りに正方行列の積を求めるプログラムを作成したのですが、うまくいきません。 #include<stdio.h> #define DTM 20 void InputMatrix(double[][DTM], int, char); void PrintMatrix(double[][DTM], int, char); void MatrixMulti(double[][DTM], double[][DTM], double[][DTM], int); int main(void) { double matrixA[DTM][DTM]; double matrixB[DTM][DTM]; double matrixC[DTM][DTM]; int n; printf("正方行列の積を求めるプログラムです\n"); printf("正方行列の次元を入れてください(<=20):"); scanf_s("%d", &n); InputMatrix(matrixA, n, 'A'); InputMatrix(matrixB, n, 'B'); MatrixMulti(matrixA, matrixB, matrixC, n); printf("\n行列 C =A×B\n"); PrintMatrix(matrixC, n, 'C'); return 0; } void InputMatrix(double a[][DTM], int n, char ch) { int i, j; printf("行列 %cの入力\n", ch); for (i = 0; i < n;i++) { for (j = 0;j < n;j++) { printf("%c[%d][%d] =", ch, i + 1, j + 1); scanf_s("%lf", &a[i][j]); } } } void PrintMatrix(double a[][DTM], int n, char ch) { int i, j; printf("行列 %c の出力\n", ch); for (i = 0;i < n;i++) { for (j = 0;j < n;j++) { printf("%5.2f\t", a[i][j]); } printf("\n"); } } void MatrixMulti(double a[][DTM], double b[][DTM], double c[][DTM], int n) { int i, j, k; for (i = 0;i < n;i++) { for (j = 0;j < n;j++) { c[i][j] = 0; for (k = 0;k < n;k++) { c[i][j] =a[i][k] * b[k][j]; } printf("%5.2f\t",c[i][j]); } printf("\n"); } }

  • ガウスの消去法、後退代入について

    ガウスの消去法で、n変数n式の連立一次方程式を解くプログラムを 作っています。 ですが、前進消去およびピボット選択ははおそらくできたのですが 後退代入が悪いのか、答えが出ません。 もしかしたら前進消去部分も悪いのかもしれませんが;; いろいろ調べたのですが どうしたら直るのかわからなくなってしまいました。 どのようにして直せばいいのか教えてください。 プログラムは以下です。 #include<stdio.h> #include<math.h> #define SIZE 100/*上限MAXのマクロ定義*/ #define EPS (1.0e-5) int main() { /*変数宣言*/ int n; /*連立方程式の式数*/ int i; /*1つ目のループカウンタ*/ int j; /*2つ目のループカウンタ*/ int k;/*3つ目のループカウンタ*/ int pivot; /*pivot選択を行う際に使用する変数*/ double max; /*pivot選択用の絶対値が最大の値*/ double matrix_a[SIZE][SIZE]; /*変数xijの係数aij*/ double matrix_b[SIZE]; /*式iの定数項bi*/ double a_hozon;/*matrix_aの値を一時保存する変数*/ double b_hozon;/*matrix_bの値を一時保存する変数*/ double r_hozon;/*前進消去法をする時使用する値を一時保存する変数*/ int l; int m; /*入力処理*/ /*未知数nの入力*/ printf("n変数n式の連立一次方程式を解きます。\n"); printf("式数n(1~100)を入力してください。 n=?\n"); scanf("%d",&n); /*未知数nのチェック*/ if(n>SIZE||n<1) { printf("\n\nn=%dはプログラムの利用可能範囲外です。\n",n); return -1; } printf("%d変数%d式の一次方程式を入力して下さい。\n",n,n); printf("入力は、式毎に係数、定数項の順に行ってください。\n\n"); printf("連立一次方程式の拡大係数行列を表示します。\n"); for(i=0; i<n; i++) { for(j=0; j<n; j++) { scanf("%lf",&matrix_a[i][j]); } scanf("%lf",&matrix_b[i]); } for(i=0; i<n; i++) { for(j=0; j<n; j++) { printf("%6.2f",matrix_a[i][j]); } printf("|%6.2f\n",matrix_b[i]); } printf("計算します。\n"); /*pivot選択*/ for(k=0; k<n; k++) { max=0.0; pivot=0; for(i=k; i<n; i++) { if(fabs(matrix_a[i][k])>max) { max=fabs(matrix_a[i][k]); pivot=i; } } if(matrix_a[pivot][k]==0.0) { printf("正則性なし\n"); } if(pivot!=k) { for(j=0; j<n; j++) { a_hozon = matrix_a[k][j]; matrix_a[k][j] = matrix_a[pivot][j]; matrix_a[pivot][j] = a_hozon; } b_hozon = matrix_b[k]; matrix_b[k] = matrix_b[pivot]; matrix_b[pivot] = b_hozon; } } /*入れ換え後の行列を表示*/ for(l=0; l<n; l++) { for(m=0; m<n; m++) { printf("%6.2f",matrix_a[l][m]); } printf("|%6.2f\n",matrix_b[l]); } /*消去法*/ for(k=0; k<n; k++) { for(i=k+1; i<n-1; i++) { r_hozon = matrix_a[i][k]/matrix_a[k][k]; for(j=k; j<n; j++) { matrix_a[i][j] = matrix_a[i][j]-r_hozon*matrix_a[k][j]; } matrix_b[i] = matrix_b[i]-r_hozon*matrix_b[k]; } } /*後退代入*/ for(i=n-1; i>=0; i--) { matrix_b[i]=0.0; for(j=i+1; j<n; j++) { matrix_b[i]=matrix_b[i]-matrix_a[i][j]*matrix_b[j]; } } /* for(i=n-1; i>0; i--) { temp = 0.0; for(j=i+1; j<n; j++) { xn = b[n]/a[n][n]; xn-1 = (-a[n-1][n]*x[n]+b[n-1])/a[n-1][n-1]; xn-2 = (-a[n-2][n-1]*x[n-2]+a[n-2][n]*x[n]+b[n-2])/a[n-2][n-2]; xn-j = (-a[i][n-j]*x[i+1]+b[i])/a[i][i]; temp = matrix_a[][] temp=temp+matrix_a[i][j]*matrix_a[j][n]; matrix_a[i][n]=matrix_a[i][n]-temp; matrix_a[i][n]=matrix_a[i][n]/matrix_a[i][i]; } } */ /*不定、不能の判別*/ if(matrix_a[k][k]<EPS) { printf("解は一意に求まらない。\n"); return -1; } /*出力処理*/ printf("連立一次方程式の解を表示します。\n"); for(i=0; i<n; i++) { printf("x%d = %6.2f\n",i,matrix_b[i]); } return 0; }

  • マトリクスの行列式の値

    以下のプログラムで「マトリクスの行列式の値」を示す部分はどこにあたりますか?? よろしくお願いします。 #include<stdio.h> #include<stdlib.h> #include<math.h> int main(void){ int i,j,k,p,N; double r,*b,*a,*ai,*ak,*ap; double amax; /*第k列の第k行から第N-1行までの最大値*/ printf("N="); scanf("%d",&N); a= (double*)malloc(N*N*sizeof(double)); if(a==NULL){ printf("Can't allocate memory"); exit(1); } ai=a; ak=a; for(i=0;i<N;i++){ for(j=0;j<N;j++){ printf("a[%d][%d]=",i,j); scanf("%lf",&ai[j]); } ai+=N; } b=(double*)malloc(N*sizeof(double)); if(b==NULL){ printf("Can't allocate memory"); exit(1); } for(i=0;i<N;i++){ printf("b[%d]",i); scanf("%lf",&b[i]); } for(k=0;k<N-1;k++){ /*前進消去法*/ ai=ak+N; ap=a; p=k; amax=ak[k]; for(i=k+1;i<N;i++){ /*k行からN-1行の中で最大のものをだす*/ if(fabs(amax)<fabs(ai[k])){ p=i; /*最大となる値とその値の行を記憶*/ amax=ai[k]; } ai+=N; } ap+=p*N; for(j=0;j<N;j++){ /*第k行と第p行を入れ替える*/ amax=ak[j]; ak[j]=ap[j]; ap[j]=amax; } amax=b[k]; b[k]=b[p]; b[p]=amax; ai=ak+N; for(i=1+k;i<N;i++){ r=ai[k]/ak[k]; for(j=k+1;j<N;j++){ ai[j]-=ak[j]*r; } b[i]-=r*b[k]; ai+=N; } ak+=N; } /*このときのakは第N-1行を指すポインタとなっている*/ for(k=N-1;0<=k;k--){ for(j=N-1;k<=j;j--){ /*後退代入*/ if(j!=k){ b[k]-=ak[j]*b[j]; } } b[k]=b[k]/ak[k]; /*今回は特に変数xなどをつくらなくても答は出せる*/ ak-=N; } free(a); for(i=0;i<N;i++){ printf("x[%d]=%.2f\n",i,b[i]); } free(b); return 0; }

  • 直接選択法

    Cでアルゴリズムの勉強をしているものです。 以下のプログラムを実行して 9 8 7 6 5 4 3 2 1 10 入力すると 10 2 3 4 5 6 7 8 9 9 と帰ってきます。 習いたてでどこが悪いかわからないのでどなたか教えてください 汗。 ////*直接選択法*//// #include <stdio.h> #define MAXDATA 10 void selection(int a[],int n){ int i,j,t; for(i=0 ; i < n ; i++){ for(j=i+1 ; j<n ; j++){ if(a[j] < a[i]) t = a[i]; a[i] = a[j]; a[j] = t; } } } int main(void) { int k,j,sort[MAXDATA]; for(k=0;k < MAXDATA;k++) {printf("sort[%d]:",k); scanf("%d",&sort[k]);} for(k=0;k < MAXDATA;k++) printf("%3d",sort[k]); puts("ソートしますか? Yes:1 No:0 ///"); scanf("%d",&j); if(j==1){ selection(sort,MAXDATA); for(k=0;k < MAXDATA;k++) printf("%3d",sort[k]); } putchar('\n'); return(0); }

  • 5×5行列、固有値、固有ベクトル

    5つの値を入力し、それぞれの相対比を求めて行列にして、固有値と固有ベクトルを求めたいのですが、分からないので教えて下さい。下のプログラムは固有値を求めるものです。これは過去の質問にあったプログラムを少し変えてみたのですが、値が出てこないのでどうすればうまく出てくるのか教えて下さい。それと、固有ベクトルを求めるプログラムも教えて下さい。宜しくお願いします。 #include <math.h> #include <stdlib.h> #include <stdio.h> int main(void) { int i, j, k, l; double max,theta,x,y,a[5][5],b[5]; printf("値1: "); scanf("%d",&b[0]); printf("値2: "); scanf("%d",&b[1]); printf("値3: "); scanf("%d",&b[2]); printf("値4: "); scanf("%d",&b[3]); printf("値5: "); scanf("%d",&b[4]); printf("行列\n"); for(j=0;j<5;j++){ for(k=0;k<5;k++){ a[j][k]=b[k]/b[j]; printf("%1.3f ",a[j][k]); } printf("\n"); } while(1){ max=0; for(i=0;i<5;i++){ for(j=0;j<5;j++){ if (i!=j && max<fabs(a[i][j])){ max=fabs(a[i][j]); k=i; l=j; } } } if (max<1.0e-6) break; theta=(a[k][k]!=a[l][l])? atan2(-2*a[k][l],a[k][k]-a[l][l])/2:M_PI/4; for(i=0;i<5;i++){ x=a[i][k]; y = a[i][l]; a[i][k] = cos(theta) * x - sin(theta)*y; a[i][l] = sin(theta) * x + cos(theta)*y; } for (j=0;j<5;j++){ x=a[k][j]; y=a[l][j]; a[k][j]=cos(theta)*x-sin(theta)*y; a[l][j]=sin(theta)*x+cos(theta)*y; } } printf("固有値\n"); for (i=0;i<5;i++){ printf("%1.3f\n",a[i][i]); } return 0; }

専門家に質問してみよう