#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define SIZE 4
#define EPSILON 1e-9 // 収束判定条件
#define MAX_ITER 1000 // 最大反復回数
// 行列とベクトルの積 y = A * x
void mat_vec_mul(double A[SIZE][SIZE], double *x, double *y, int n) {
for (int i = 0; i < n; i++) {
y[i] = 0.0;
for (int j = 0; j < n; j++) {
y[i] += A[i][j] * x[j];
}
}
}
int main() {
// 自身で設定した行列A
double A[SIZE][SIZE] = {
{1.0, 2.0, 3.0, 5.0},
{3.0, -5.0, 1.0, 4.0},
{5.0, 9.0, 2.0, -6.0},
{1.0, 7.0, 4.0, 1.0}
};
double x[SIZE], y[SIZE], Ax[SIZE];
double lambda_old = 0.0, lambda_new = 0.0;
// 初期値の設定 [1, 1, 1, 1]^T
for (int i = 0; i < SIZE; i++) {
x[i] = 1.0;
}
printf("=== べき乗法の計算および収束状況 ===\n"); printf("初期ベクトル x(0): [%.1f, %.1f, %.1f, %.1f]\n\n", x
[0], x
[1], x
[2], x
[3]); printf("%-5s | %-14s | %-14s | %-30s\n", "Iter", "固有値の近似値", "変化量(差分)", "固有ベクトル x(k)"); printf("----------------------------------------------------------------------------\n");
int actual_iters = 0;
for (int iter = 1; iter <= MAX_ITER; iter++) {
actual_iters = iter;
// y = A * x の計算
mat_vec_mul(A, x, y, SIZE);
// スライドのアルゴリズムに従い、第1成分を基準(係数)として抽出
lambda_new = y[0];
// 第1成分が 1.0 になるように全体を正規化
if (fabs(lambda_new
) < 1e-12) { break;
}
for (int i = 0; i < SIZE; i++) {
y[i] /= lambda_new;
}
// 前のステップからの変化量を算出
double diff
= fabs(lambda_new
- lambda_old
);
// 収束過程の表示 (最初の5回、5回ごと、および最終ステップ)
if (iter <= 5 || iter % 5 == 0) {
printf("%-5d | %-14.10f | %-14.4e | [%.6f, %.6f, %.6f, %.6f]\n", iter, lambda_new, diff, y[0], y[1], y[2], y[3]);
}
// 収束判定条件のチェック
if (diff < EPSILON) {
if (iter % 5 != 0 && iter > 5) {
printf("%-5d | %-14.10f | %-14.4e | [%.6f, %.6f, %.6f, %.6f]\n", iter, lambda_new, diff, y[0], y[1], y[2], y[3]);
}
break;
}
// 次の反復のためにベクトルと値を更新
for (int i = 0; i < SIZE; i++) {
x[i] = y[i];
}
lambda_old = lambda_new;
}
printf("----------------------------------------------------------------------------\n"); printf("反復回数 %d 回で収束判定条件を満たしました。\n", actual_iters
);
// === 最終計算結果の出力 ===
printf("最大固有値 (λ1) : %.10f\n", lambda_new
); printf("対応する固有ベクトル (x1) : ["); for (int i = 0; i < SIZE; i++) {
printf("%.10f%s", y
[i
], (i
== SIZE
- 1) ? "]\n" : ", "); }
// === Ax = λx の検証出力 ===
printf("\n=== 固有値・固有ベクトルであることの検証 (Ax = λx) ===\n"); mat_vec_mul(A, y, Ax, SIZE);
for (int i = 0; i < SIZE; i++) {
printf("%.6f%s", Ax
[i
], (i
== SIZE
- 1) ? "]\n" : ", "); }
for (int i = 0; i < SIZE; i++) {
printf("%.6f%s", lambda_new
* y
[i
], (i
== SIZE
- 1) ? "]\n" : ", "); }
return 0;
}
I2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDxzdGRsaWIuaD4KI2luY2x1ZGUgPG1hdGguaD4KCiNkZWZpbmUgU0laRSA0CiNkZWZpbmUgRVBTSUxPTiAxZS05ICAgLy8g5Y+O5p2f5Yik5a6a5p2h5Lu2CiNkZWZpbmUgTUFYX0lURVIgMTAwMCAgLy8g5pyA5aSn5Y+N5b6p5Zue5pWwCgovLyDooYzliJfjgajjg5njgq/jg4jjg6vjga7nqY0geSA9IEEgKiB4CnZvaWQgbWF0X3ZlY19tdWwoZG91YmxlIEFbU0laRV1bU0laRV0sIGRvdWJsZSAqeCwgZG91YmxlICp5LCBpbnQgbikgewogICAgZm9yIChpbnQgaSA9IDA7IGkgPCBuOyBpKyspIHsKICAgICAgICB5W2ldID0gMC4wOwogICAgICAgIGZvciAoaW50IGogPSAwOyBqIDwgbjsgaisrKSB7CiAgICAgICAgICAgIHlbaV0gKz0gQVtpXVtqXSAqIHhbal07CiAgICAgICAgfQogICAgfQp9CgppbnQgbWFpbigpIHsKICAgIC8vIOiHqui6q+OBp+ioreWumuOBl+OBn+ihjOWIl0EKICAgIGRvdWJsZSBBW1NJWkVdW1NJWkVdID0gewogICAgICAgIHsxLjAsICAyLjAsIDMuMCwgIDUuMH0sCiAgICAgICAgezMuMCwgLTUuMCwgMS4wLCAgNC4wfSwKICAgICAgICB7NS4wLCAgOS4wLCAyLjAsIC02LjB9LAogICAgICAgIHsxLjAsICA3LjAsIDQuMCwgIDEuMH0KICAgIH07CgogICAgZG91YmxlIHhbU0laRV0sIHlbU0laRV0sIEF4W1NJWkVdOwogICAgZG91YmxlIGxhbWJkYV9vbGQgPSAwLjAsIGxhbWJkYV9uZXcgPSAwLjA7CgogICAgLy8g5Yid5pyf5YCk44Gu6Kit5a6aIFsxLCAxLCAxLCAxXV5UCiAgICBmb3IgKGludCBpID0gMDsgaSA8IFNJWkU7IGkrKykgewogICAgICAgIHhbaV0gPSAxLjA7CiAgICB9CgogICAgcHJpbnRmKCI9PT0g44G544GN5LmX5rOV44Gu6KiI566X44GK44KI44Gz5Y+O5p2f54q25rOBID09PVxuIik7CiAgICBwcmludGYoIuWIneacn+ODmeOCr+ODiOODqyB4KDApOiBbJS4xZiwgJS4xZiwgJS4xZiwgJS4xZl1cblxuIiwgeFswXSwgeFsxXSwgeFsyXSwgeFszXSk7CiAgICBwcmludGYoIiUtNXMgfCAlLTE0cyB8ICUtMTRzIHwgJS0zMHNcbiIsICJJdGVyIiwgIuWbuuacieWApOOBrui/keS8vOWApCIsICLlpInljJbph48o5beu5YiGKSIsICLlm7rmnInjg5njgq/jg4jjg6sgeChrKSIpOwogICAgcHJpbnRmKCItLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4iKTsKCiAgICBpbnQgYWN0dWFsX2l0ZXJzID0gMDsKICAgIGZvciAoaW50IGl0ZXIgPSAxOyBpdGVyIDw9IE1BWF9JVEVSOyBpdGVyKyspIHsKICAgICAgICBhY3R1YWxfaXRlcnMgPSBpdGVyOwogICAgICAgIAogICAgICAgIC8vIHkgPSBBICogeCDjga7oqIjnrpcKICAgICAgICBtYXRfdmVjX211bChBLCB4LCB5LCBTSVpFKTsKCiAgICAgICAgLy8g44K544Op44Kk44OJ44Gu44Ki44Or44K044Oq44K644Og44Gr5b6T44GE44CB56ysMeaIkOWIhuOCkuWfuua6lu+8iOS/guaVsO+8ieOBqOOBl+OBpuaKveWHugogICAgICAgIGxhbWJkYV9uZXcgPSB5WzBdOyAKCiAgICAgICAgLy8g56ysMeaIkOWIhuOBjCAxLjAg44Gr44Gq44KL44KI44GG44Gr5YWo5L2T44KS5q2j6KaP5YyWCiAgICAgICAgaWYgKGZhYnMobGFtYmRhX25ldykgPCAxZS0xMikgewogICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBTSVpFOyBpKyspIHsKICAgICAgICAgICAgeVtpXSAvPSBsYW1iZGFfbmV3OwogICAgICAgIH0KCiAgICAgICAgLy8g5YmN44Gu44K544OG44OD44OX44GL44KJ44Gu5aSJ5YyW6YeP44KS566X5Ye6CiAgICAgICAgZG91YmxlIGRpZmYgPSBmYWJzKGxhbWJkYV9uZXcgLSBsYW1iZGFfb2xkKTsKCiAgICAgICAgLy8g5Y+O5p2f6YGO56iL44Gu6KGo56S6ICjmnIDliJ3jga415Zue44CBNeWbnuOBlOOBqOOAgeOBiuOCiOOBs+acgOe1guOCueODhuODg+ODlykKICAgICAgICBpZiAoaXRlciA8PSA1IHx8IGl0ZXIgJSA1ID09IDApIHsKICAgICAgICAgICAgcHJpbnRmKCIlLTVkIHwgJS0xNC4xMGYgfCAlLTE0LjRlIHwgWyUuNmYsICUuNmYsICUuNmYsICUuNmZdXG4iLCAKICAgICAgICAgICAgICAgICAgIGl0ZXIsIGxhbWJkYV9uZXcsIGRpZmYsIHlbMF0sIHlbMV0sIHlbMl0sIHlbM10pOwogICAgICAgIH0KCiAgICAgICAgLy8g5Y+O5p2f5Yik5a6a5p2h5Lu244Gu44OB44Kn44OD44KvCiAgICAgICAgaWYgKGRpZmYgPCBFUFNJTE9OKSB7CiAgICAgICAgICAgIGlmIChpdGVyICUgNSAhPSAwICYmIGl0ZXIgPiA1KSB7CiAgICAgICAgICAgICAgICBwcmludGYoIiUtNWQgfCAlLTE0LjEwZiB8ICUtMTQuNGUgfCBbJS42ZiwgJS42ZiwgJS42ZiwgJS42Zl1cbiIsIAogICAgICAgICAgICAgICAgICAgICAgIGl0ZXIsIGxhbWJkYV9uZXcsIGRpZmYsIHlbMF0sIHlbMV0sIHlbMl0sIHlbM10pOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KCiAgICAgICAgLy8g5qyh44Gu5Y+N5b6p44Gu44Gf44KB44Gr44OZ44Kv44OI44Or44Go5YCk44KS5pu05pawCiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBTSVpFOyBpKyspIHsKICAgICAgICAgICAgeFtpXSA9IHlbaV07CiAgICAgICAgfQogICAgICAgIGxhbWJkYV9vbGQgPSBsYW1iZGFfbmV3OwogICAgfQoKICAgIHByaW50ZigiLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuIik7CiAgICBwcmludGYoIuWPjeW+qeWbnuaVsCAlZCDlm57jgaflj47mnZ/liKTlrprmnaHku7bjgpLmuoDjgZ/jgZfjgb7jgZfjgZ/jgIJcbiIsIGFjdHVhbF9pdGVycyk7CgogICAgLy8gPT09IOacgOe1guioiOeul+e1kOaenOOBruWHuuWKmyA9PT0KICAgIHByaW50ZigiXG49PT0g5pyA57WC57WQ5p6cID09PVxuIik7CiAgICBwcmludGYoIuacgOWkp+WbuuacieWApCAozrsxKSAgICAgICAgICA6ICUuMTBmXG4iLCBsYW1iZGFfbmV3KTsKICAgIHByaW50Zigi5a++5b+c44GZ44KL5Zu65pyJ44OZ44Kv44OI44OrICh4MSkgOiBbIik7CiAgICBmb3IgKGludCBpID0gMDsgaSA8IFNJWkU7IGkrKykgewogICAgICAgIHByaW50ZigiJS4xMGYlcyIsIHlbaV0sIChpID09IFNJWkUgLSAxKSA/ICJdXG4iIDogIiwgIik7CiAgICB9CgogICAgLy8gPT09IEF4ID0gzrt4IOOBruaknOiovOWHuuWKmyA9PT0KICAgIHByaW50ZigiXG49PT0g5Zu65pyJ5YCk44O75Zu65pyJ44OZ44Kv44OI44Or44Gn44GC44KL44GT44Go44Gu5qSc6Ki8IChBeCA9IM67eCkgPT09XG4iKTsKICAgIG1hdF92ZWNfbXVsKEEsIHksIEF4LCBTSVpFKTsgCiAgICBwcmludGYoIkF4ICAgIDogWyIpOwogICAgZm9yIChpbnQgaSA9IDA7IGkgPCBTSVpFOyBpKyspIHsKICAgICAgICBwcmludGYoIiUuNmYlcyIsIEF4W2ldLCAoaSA9PSBTSVpFIC0gMSkgPyAiXVxuIiA6ICIsICIpOwogICAgfQogICAgcHJpbnRmKCLOuyAqIHggOiBbIik7CiAgICBmb3IgKGludCBpID0gMDsgaSA8IFNJWkU7IGkrKykgewogICAgICAgIHByaW50ZigiJS42ZiVzIiwgbGFtYmRhX25ldyAqIHlbaV0sIChpID09IFNJWkUgLSAxKSA/ICJdXG4iIDogIiwgIik7CiAgICB9CgogICAgcmV0dXJuIDA7Cn0=
=== べき乗法の計算および収束状況 ===
初期ベクトル x(0): [1.0, 1.0, 1.0, 1.0]
Iter | 固有値の近似値 | 変化量(差分) | 固有ベクトル x(k)
----------------------------------------------------------------------------
1 | 11.0000000000 | 1.1000e+01 | [1.000000, 0.272727, 0.909091, 1.181818]
2 | 10.1818181818 | 8.1818e-01 | [1.000000, 0.714286, 0.214286, 0.758929]
3 | 6.8660714286 | 3.3157e+00 | [1.000000, 0.390117, 1.063719, 1.109233]
4 | 10.5175552666 | 3.6515e+00 | [1.000000, 0.622774, 0.378709, 0.864738]
5 | 7.7053659743 | 2.8122e+00 | [1.000000, 0.483272, 0.801255, 1.004364]
10 | 8.7981535734 | 2.6057e-01 | [1.000000, 0.546856, 0.609357, 0.942157]
15 | 8.6860605584 | 2.6271e-02 | [1.000000, 0.540849, 0.627060, 0.947951]
20 | 8.6972331750 | 2.6313e-03 | [1.000000, 0.541454, 0.625276, 0.947367]
25 | 8.6961128229 | 2.6369e-04 | [1.000000, 0.541394, 0.625455, 0.947425]
30 | 8.6962250867 | 2.6425e-05 | [1.000000, 0.541400, 0.625437, 0.947420]
35 | 8.6962138365 | 2.6481e-06 | [1.000000, 0.541399, 0.625439, 0.947420]
40 | 8.6962149639 | 2.6536e-07 | [1.000000, 0.541399, 0.625439, 0.947420]
45 | 8.6962148509 | 2.6592e-08 | [1.000000, 0.541399, 0.625439, 0.947420]
50 | 8.6962148623 | 2.6649e-09 | [1.000000, 0.541399, 0.625439, 0.947420]
53 | 8.6962148610 | 6.7023e-10 | [1.000000, 0.541399, 0.625439, 0.947420]
----------------------------------------------------------------------------
反復回数 53 回で収束判定条件を満たしました。
=== 最終結果 ===
最大固有値 (λ1) : 8.6962148610
対応する固有ベクトル (x1) : [1.0000000000, 0.5413991519, 0.6254386680, 0.9474201107]
=== 固有値・固有ベクトルであることの検証 (Ax = λx) ===
Ax : [8.696215, 4.708123, 5.438949, 8.238969]
λ * x : [8.696215, 4.708123, 5.438949, 8.238969]