• 締切済み

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

みんなの回答

回答No.2

とりあえず、scanf("%d",&b[0]);はscanf("%lf",&b[0]);にしましょう。 ヤコビ法をやりたいのであれば、 http://mukun_mmg.at.infoseek.co.jp/mmg/bncpp/al054.html が参考になるかと。

TiggerM
質問者

お礼

回答有難うございます。 初歩のとこから間違えてました。 参考になりました。

  • keikan
  • ベストアンサー率42% (75/176)
回答No.1

while(1){ max=0; //MAXの初期値がル-プ内で0に初期化している . . . if (i!=j && max<fabs(a[i][j])){ max=fabs(a[i][j]); //この条件においてmaxよりfabs(a[i][j])が大きければmaxにfabs(a[i][j])を代入し最大値を更新する。 ・ ・ ・ } if (max<1.0e-6) break; // maxが1.0e-6より小さければループを抜ける。 // maxの初期化がループ内で行われて、fabs(a[i][j])が1.0e-6を超えてしまうとループを抜けることはありません。(maxは大きくなるばかりですので)ループの度にmaxが0になっているので同じ処理を繰り返しています。 maxを初期化する位置を変更するか、ループを抜ける条件式の位置の変更が必要です。 または、入力データを制限する必要があると思います。 まずこの辺のアルゴリズムの検討をしてください。

TiggerM
質問者

お礼

回答有難うございます。よく分かりました。 もう一度考えて作ってみます。

関連するQ&A

  • 行列について誰か確認してください。

    下記問題について自分なりに解答してみたのですが、イマイチあっているのか分かりません。どなたかご査収願います。 問題 『25行25列で、対角要素は全て2、その隣は-1、それ以外は全て0である行列の固有値を全てJacobi(ヤコビ)法で小数点以下6桁まで求め、その固有値と解法のプログラムを示せ。 ※収束基準は非対角要素の絶対値の最大値が10^-6未満となることとせよ。』 以下に上記問題についてのプログラムおよび固有値の計算結果を示します。 プログラミング言語=C言語 #include <math.h> #include <stdlib.h> #include <stdio.h> #define SIZE 25 int main(void) { double a[SIZE][SIZE]; int i, j, k, l; double max; double theta; double x, y; for (i = 0; i < SIZE; i++) { for (j = 0; j < SIZE; j++) { if (i == j - 1 || i == j + 1) a[i][j] = -1; else if (i == j) a[i][j] = 2; else a[i][j] = 0; } } while (1) { max = 0; for (i = 0; i < SIZE; i++) { for (j = 0; j < SIZE; 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 < SIZE; 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 < SIZE; 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; } } for (i = 0; i < SIZE; i++) { printf("%lf\n", a[i][i]); } return 0; }

  • 行列の積を関数を使って求める・・?

    2つの行列の行と列を入力し、積を計算するプログラムを関数を使って書きたいのですが、上手く行きません。どこをどのように直したらよいか教えてください!お願いします!! 以下が私が書いたプログラムです。 #include<stdio.h> #define NUMBER 10 int first(int x1,int x2,int y1,int y2,int i,int j,int k) { int a[NUMBER][NUMBER] = {0}; int b[NUMBER][NUMBER] = {0}; int c[NUMBER][NUMBER] = {0}; do{ printf("2つの行列の行と列を入力してください\n"); scanf("%d", &x1); scanf("%d", &x2); scanf("%d", &y1); scanf("%d", &y2); if(x1 != y2){ printf("行列の積は計算できません\n"); } }while(x1 != y2); printf("行列Aの要素を入力してください\n"); for(i=0; i<x1; i++){ for(j=0; j<x2; j++) scanf("%d", &a[i][j]); } printf("行列Bの要素を入力してください\n"); for(j=0; j<y1; j++){ for(k=0; k<y2; k++) scanf("%d", &b[j][k]); } } int second(int x1,int x2,int y1,int y2,int i,int j,int k) { int a[NUMBER][NUMBER] = {0}; int b[NUMBER][NUMBER] = {0}; int c[NUMBER][NUMBER] = {0}; for(i=0; i<x1; i++){ for(k=0; k<y2; k++){ for(j=0; j<x2; j++) c[i][k] = c[i][k] + a[i][j]*b[j][k]; } } for(i=0; i<x2; i++){ for(k=0; k<y2; k++) printf("%3d", c[i][k]); printf("\n"); } } int main(void) { int a[NUMBER][NUMBER] = {0}; int b[NUMBER][NUMBER] = {0}; int c[NUMBER][NUMBER] = {0}; printf("行列の積を計算します\n %d\n", first(x1,x2,y1,y2,i,j,k)); printf("行列Aと行Bの積は\n %3d",second(x1,x2,y1,y2,i,j,k)); }

  • 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言語で行列の積の値を求める

    行列の成分を入力した後に、 入力された行列は X = 1 2 3 4 5 6 7 8 9 10 11 12 Y = 1 5 2 6 3 7 4 8 のように表示して、(上の数字は適当です。) 行列 X と行列 Y の積を求めて結果を表示するプログラムが作りたいのですが、上手く表示できなくて困っています。 #include <stdio.h> int main(void) { double A[10][10]; double B[10][10]; double C[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]); } } この後にどうすればいいのか教えてください。 よろしくお願いします。

  • 行列の固有ベクトルの問題を教えて下さい。

    この問題が分かりません。お願いいたします。 行列A= (cos2θ sin2θ) (sin2θ -cos2θ) がある。(0≦θ<π) 固有値と固有ベクトルを求め、固有ベクトルを図示しなさい。 という問題です。 解いてみると、固有値は1と-1だと分かりました。 しかし、固有ベクトルでつまっています。 例えば固有値1として求めると、 (cos2θ-1)x+sin2θy=0 x=1のとき、y=(1-cos2θ)/sin2θ としてsin2θ≠0のときと=0の時、みたいに場合分けしたのですが、図示出来ませんでした・・・。 固有ベクトルの良い取り方があるのでしょうか? 解答、お願いいたします

  • C言語 プログラミングで行詰まりました…

    標準入力(キーボード)からi,jk,nの値を入力し、次の漸化式を計算し、X_0からX_nまで求めるプログラムを作成したいのですが、うまく表示されません。どかがおかしいのかご指摘お願いします。 <漸化式> X_n=(a+b)/X_(n-1) , X_0=c(n=0) ================================================================== #include<stdio.h> float f_X(int a,int b,float c) { float y; y=(a+b)/c; return y; } int main (void) { int number,i,j; float k,l,n,X; printf("i:"); scanf("%d", &i); printf("j:"); scanf("%d", &j); printf("k:"); scanf("%f", &k); printf("n:"); scanf("%f", &n); X=k; printf("X_0= %.6f\n",X); for(number=1;number<=n;number++) { l=f_X(i,j,X); printf("X_%d= %.6f \n",number,l); X=l; } return 0; } ===================================================================

  • C言語 プログラミング 行列演算

    下記のプログラムのおかしい点と解決法を教えてください。 コンパイルは通りますがうまく動きません。。 #include<stdio.h> #define MAX 500 int main(void){ int matrA[MAX][MAX],matrB[MAX][MAX],matrC[MAX][MAX],l,m,n,i,j,k; printf("lとmを入力してください:"); scanf("%d",&l); scanf("%d",&m); printf("行列Aを入力してください"); for(i=0;i<l;i++){ printf(">"); for(j=0;l<m;j++){ scanf("%d",&matrA[i][j]); } printf("\n"); } printf("nを入力してください(m = %d):",m); scanf("%d",&n); printf("行列Bを入力してください"); for(i=0;i<m;i++){ printf(">"); for(j=0;j<n;j++){ scanf("%d",&matrB[i][j]); } printf("\n"); } printf("C=\n"); for(i=0;i<l;i++){ for(j=0;j<n;j++){ for(k=0;k<m;k++){ matrC[i][j]+=matrA[i][k]*matrB[k][j]; } printf("%d",matrC[i][j]); } printf("\n"); } }

  • 行列の証明問題 (固有値と固有ベクトルの性質)

    行列A=[a(jk)](j:行 k:列 )に関する諸命題を証明し、適当な例を用いて説明せよ。 ただし、λ(1),・・・,λ(n)はAの固有値とする。I:単位行列 (a)実固有値と複素固有値  Aが実行列のときには、その固有値は実数または共役複素数の対からなる。 (b)逆行列  逆行列A^(-1)は0がAの固有値でないとき、またそのときに限り存在する。  その固有値は1/λ(1),・・・,1/λnである。 (c)トレース  Aの対角成分の和をトレースまたは対角和という。これは固有値の和に等しい。 (d)スペクトル移動  行列A-kIは固有値λ(1)-k,・・・,λ(n)-kをもち,Aと同じ固有ベクトルをもつ。 (e)スカラー倍、ベキ  行列kAの固有値はkλ(1),・・・,kλ(n)であり、行列A^m(m=1,2・・)の固有値は  λ(1)^m,・・・,λ(n)^mである。固有関数はいずれもAの固有関数と同じである。 (f)スペクトル写像定理  ’多項式行列’  p(A)=k(m)A^m+k(m-1)A^(m-1)+・・・+k(1)A+k(0)I は固有値    p(λj)=k(m)λj^m+k(m-1)λj^(m-1)+・・・+k(1)λ(1)^(m-1)+k(0) (j=1,・・・,n) をもち、Aと同じ固有関数をもつ。 (g)ペロンの定理  正の成分l(12),l(13),l(31),l(32)をもつレスリー行列Lには1つの正の固有値が  存在することを示せ。 これらの問題(証明)が難しくて分かりません。教えて下さい、お願いします。

  • 3×3行列の固有値と固有ベクトル

    以下の行列Aの固有ベクトルを求めようとしているのですが,解を見つけられないでいます. 2 1 0 1 2 0 0 0 -2 計算を進めた結果,固有値λは3,1,-2となり,λ=3,1に対応する固有ベクトルはそれぞれ[1,1,0]t,[1,-1,0]tとなったのですが,λ=-2の場合で求めた固有ベクトル[1,1,k]t(kは任意の実数)がAx=λxに対応しない値になってしまいます.私の計算に何か問題があるのでしょうか? また,行列Aは対称行列なのでそれぞれの固有ベクトルの内積は0になると思うのですが,固有ベクトルの値が得られないことと何か関係があるのでしょうか? 回答よろしくお願いします.

  • 2進数の加算の繰り上がり

    2進数の四則演算のプログラムを作りたいと思い、2進数を表示するところまではできたのですが、加算になると繰り上がりという壁にぶつかってしまいました。繰り上がりや桁上げなどがよく分からないので、お教えください。(下のソースコードが繰り上がりのない加算をするまでのものです) #include <stdio.h> int main(void) { int a,b,i,j,x[8],y[8],z[8]; do{ puts("二つの符号なし整数を入力してください。(ただしa>bとし、bはのべき乗の値とする)"); printf("a="); scanf("%d",&a); printf("b="); scanf("%d",&b); if(a < = b) puts("入力した値がa>bになっていません。\a"); }while(a < = b); for( i = 0; i < = 7; i + +){ x[i] = a % 2; a = a / 2; y[i] = b % 2; b = b / 2; } puts("aとbをそれぞれ二進数で表すと"); printf("a="); for( i = 7; i > = 0; i - -){ printf("%d",x[i]); } puts(""); printf("b="); for( i = 7; i > = 0; i - -){ printf("%d",y[i]); } printf("となります。\n\n"); printf("<加算>\n"); printf("c=a+b="); for( j = 7; j > = 0; j - -){ z[j]=x[j]^y[j]; printf("%d",z[j]); } return(0); }

専門家に質問してみよう