#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define SIZE 4
#define EPSILON 1e-9
#define MAX_ITER 1000
double vector_norm(double *v, int n) {
double sum = 0.0;
for (int i = 0; i < n; i++) {
sum += v[i] * v[i];
}
}
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() {
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;
for (int i = 0; i < SIZE; i++) {
x[i] = 1.0;
}
printf("初期ベクトル x(0): [%.1f, %.1f, %.1f, %.1f]\n\n", x
[0], x
[1], x
[2], x
[3]); printf("%-5s | %-12s | %-12s | %-30s\n", "Iter", "固有値(新)", "差分値", "固有ベクトルx(k)"); int actual_iters = 0;
for (int iter = 1; iter <= MAX_ITER; iter++) {
actual_iters = iter;
mat_vec_mul(A, x, y, SIZE);
double norm_y = vector_norm(y, SIZE);
if (norm_y < 1e-12) break;
for (int i = 0; i < SIZE; i++) {
y[i] /= norm_y;
}
mat_vec_mul(A, y, Ax, SIZE);
double num = 0.0, den = 0.0;
for (int i = 0; i < SIZE; i++) {
num += y[i] * Ax[i];
den += y[i] * y[i];
}
lambda_new = num / den;
double diff
= fabs(lambda_new
- lambda_old
);
if (iter <= 5 || iter % 5 == 0) {
printf("%-5d | %-12.8f | %-12.4e | [%.5f, %.5f, %.5f, %.5f]\n", iter, lambda_new, diff, y[0], y[1], y[2], y[3]);
}
if (diff < EPSILON) {
if (iter % 5 != 0 && iter > 5) { // 最終ステップを確実に表示させる
printf("%-5d | %-12.8f | %-12.4e | [%.5f, %.5f, %.5f, %.5f]\n", iter, lambda_new, diff, y[0], y[1], y[2], y[3]);
}
break;
}
// 次のステップに向けて x を更新
for (int i = 0; i < SIZE; i++) {
x[i] = y[i];
}
lambda_old = lambda_new;
}
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" : ", "); }
printf("\n 検証: Ax と λx の比較 \n"); mat_vec_mul(A, y, Ax, SIZE); // Axを再計算
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+CiNpbmNsdWRlIDxzdGRsaWIuaD4KI2luY2x1ZGUgPG1hdGguaD4KCiNkZWZpbmUgU0laRSA0CiNkZWZpbmUgRVBTSUxPTiAxZS05ICAgCiNkZWZpbmUgTUFYX0lURVIgMTAwMCAgCgpkb3VibGUgdmVjdG9yX25vcm0oZG91YmxlICp2LCBpbnQgbikgewogICAgZG91YmxlIHN1bSA9IDAuMDsKICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbjsgaSsrKSB7CiAgICAgICAgc3VtICs9IHZbaV0gKiB2W2ldOwogICAgfQogICAgcmV0dXJuIHNxcnQoc3VtKTsKfQoKdm9pZCBtYXRfdmVjX211bChkb3VibGUgQVtTSVpFXVtTSVpFXSwgZG91YmxlICp4LCBkb3VibGUgKnksIGludCBuKSB7CiAgICBmb3IgKGludCBpID0gMDsgaSA8IG47IGkrKykgewogICAgICAgIHlbaV0gPSAwLjA7CiAgICAgICAgZm9yIChpbnQgaiA9IDA7IGogPCBuOyBqKyspIHsKICAgICAgICAgICAgeVtpXSArPSBBW2ldW2pdICogeFtqXTsKICAgICAgICB9CiAgICB9Cn0KCmludCBtYWluKCkgewogICAgZG91YmxlIEFbU0laRV1bU0laRV0gPSB7CiAgICAgICAgezEuMCwgIDIuMCwgMy4wLCAgNS4wfSwKICAgICAgICB7My4wLCAtNS4wLCAxLjAsICA0LjB9LAogICAgICAgIHs1LjAsICA5LjAsIDIuMCwgLTYuMH0sCiAgICAgICAgezEuMCwgIDcuMCwgNC4wLCAgMS4wfQogICAgfTsKCiAgICBkb3VibGUgeFtTSVpFXSwgeVtTSVpFXSwgQXhbU0laRV07CiAgICBkb3VibGUgbGFtYmRhX29sZCA9IDAuMCwgbGFtYmRhX25ldyA9IDAuMDsKCiAgICBmb3IgKGludCBpID0gMDsgaSA8IFNJWkU7IGkrKykgewogICAgICAgIHhbaV0gPSAxLjA7CiAgICB9CgogICAgcHJpbnRmKCLliJ3mnJ/jg5njgq/jg4jjg6sgeCgwKTogWyUuMWYsICUuMWYsICUuMWYsICUuMWZdXG5cbiIsIHhbMF0sIHhbMV0sIHhbMl0sIHhbM10pOwogICAgcHJpbnRmKCIlLTVzIHwgJS0xMnMgfCAlLTEycyB8ICUtMzBzXG4iLCAiSXRlciIsICLlm7rmnInlgKQo5pawKSIsICLlt67liIblgKQiLCAi5Zu65pyJ44OZ44Kv44OI44OreChrKSIpOwogICAgaW50IGFjdHVhbF9pdGVycyA9IDA7CiAgICBmb3IgKGludCBpdGVyID0gMTsgaXRlciA8PSBNQVhfSVRFUjsgaXRlcisrKSB7CiAgICAgICAgYWN0dWFsX2l0ZXJzID0gaXRlcjsKICAgICAgICBtYXRfdmVjX211bChBLCB4LCB5LCBTSVpFKTsKCiAgICAgICAgZG91YmxlIG5vcm1feSA9IHZlY3Rvcl9ub3JtKHksIFNJWkUpOwogICAgICAgIGlmIChub3JtX3kgPCAxZS0xMikgYnJlYWs7CiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBTSVpFOyBpKyspIHsKICAgICAgICAgICAgeVtpXSAvPSBub3JtX3k7CiAgICAgICAgfQoKICAgICAgICBtYXRfdmVjX211bChBLCB5LCBBeCwgU0laRSk7CiAgICAgICAgZG91YmxlIG51bSA9IDAuMCwgZGVuID0gMC4wOwogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgU0laRTsgaSsrKSB7CiAgICAgICAgICAgIG51bSArPSB5W2ldICogQXhbaV07CiAgICAgICAgICAgIGRlbiArPSB5W2ldICogeVtpXTsKICAgICAgICB9CiAgICAgICAgbGFtYmRhX25ldyA9IG51bSAvIGRlbjsKICAgICAgICBkb3VibGUgZGlmZiA9IGZhYnMobGFtYmRhX25ldyAtIGxhbWJkYV9vbGQpOwoKICAgCiAgICAgICAgaWYgKGl0ZXIgPD0gNSB8fCBpdGVyICUgNSA9PSAwKSB7CiAgICAgICAgICAgIHByaW50ZigiJS01ZCB8ICUtMTIuOGYgfCAlLTEyLjRlIHwgWyUuNWYsICUuNWYsICUuNWYsICUuNWZdXG4iLCAKICAgICAgICAgICAgICAgICAgIGl0ZXIsIGxhbWJkYV9uZXcsIGRpZmYsIHlbMF0sIHlbMV0sIHlbMl0sIHlbM10pOwogICAgICAgIH0KCiAgICAgICAgaWYgKGRpZmYgPCBFUFNJTE9OKSB7CiAgICAgICAgICAgIGlmIChpdGVyICUgNSAhPSAwICYmIGl0ZXIgPiA1KSB7IC8vIOacgOe1guOCueODhuODg+ODl+OCkueiuuWun+OBq+ihqOekuuOBleOBm+OCiwogICAgICAgICAgICAgICAgcHJpbnRmKCIlLTVkIHwgJS0xMi44ZiB8ICUtMTIuNGUgfCBbJS41ZiwgJS41ZiwgJS41ZiwgJS41Zl1cbiIsIAogICAgICAgICAgICAgICAgICAgICAgIGl0ZXIsIGxhbWJkYV9uZXcsIGRpZmYsIHlbMF0sIHlbMV0sIHlbMl0sIHlbM10pOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KCiAgICAgICAgLy8g5qyh44Gu44K544OG44OD44OX44Gr5ZCR44GR44GmIHgg44KS5pu05pawCiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBTSVpFOyBpKyspIHsKICAgICAgICAgICAgeFtpXSA9IHlbaV07CiAgICAgICAgfQogICAgICAgIGxhbWJkYV9vbGQgPSBsYW1iZGFfbmV3OwogICAgfQoKICAgIAogICAgcHJpbnRmKCLlj43lvqnlm57mlbAgJWQg5Zue44Gn5Y+O5p2f44GX44G+44GX44Gf44CCXG4iLCBhY3R1YWxfaXRlcnMpOwogICAgcHJpbnRmKCLmnIDlpKflm7rmnInlgKQgKM67MSkgICAgICAgICAgOiAlLjEwZlxuIiwgbGFtYmRhX25ldyk7CiAgICBwcmludGYoIuWvvuW/nOOBmeOCi+WbuuacieODmeOCr+ODiOODqyAoeDEpIDogWyIpOwogICAgZm9yIChpbnQgaSA9IDA7IGkgPCBTSVpFOyBpKyspIHsKICAgICAgICBwcmludGYoIiUuMTBmJXMiLCB5W2ldLCAoaSA9PSBTSVpFIC0gMSkgPyAiXVxuIiA6ICIsICIpOwogICAgfQoKICAgIHByaW50ZigiXG4gICDmpJzoqLw6IEF4IOOBqCDOu3gg44Gu5q+U6LyDICAgXG4iKTsKICAgIG1hdF92ZWNfbXVsKEEsIHksIEF4LCBTSVpFKTsgLy8gQXjjgpLlho3oqIjnrpcKICAgIHByaW50ZigiQXggICAgOiBbIik7CiAgICBmb3IgKGludCBpID0gMDsgaSA8IFNJWkU7IGkrKykgewogICAgICAgIHByaW50ZigiJS42ZiVzIiwgQXhbaV0sIChpID09IFNJWkUgLSAxKSA/ICJdXG4iIDogIiwgIik7CiAgICB9CiAgICBwcmludGYoIs67ICogeCA6IFsiKTsKICAgIGZvciAoaW50IGkgPSAwOyBpIDwgU0laRTsgaSsrKSB7CiAgICAgICAgcHJpbnRmKCIlLjZmJXMiLCBsYW1iZGFfbmV3ICogeVtpXSwgKGkgPT0gU0laRSAtIDEpID8gIl1cbiIgOiAiLCAiKTsKICAgIH0KCiAgICByZXR1cm4gMDsKfQoK
初期ベクトル x(0): [1.0, 1.0, 1.0, 1.0]
Iter | 固有値(新) | 差分値 | 固有ベクトルx(k)
1 | 7.06015038 | 7.0602e+00 | [0.55069, 0.15019, 0.50063, 0.65081]
2 | 7.56272200 | 5.0257e-01 | [0.68485, 0.48918, 0.14675, 0.51975]
3 | 7.79665790 | 2.3394e-01 | [0.53345, 0.20811, 0.56744, 0.59172]
4 | 8.36088120 | 5.6422e-01 | [0.66241, 0.41253, 0.25086, 0.57281]
5 | 8.52180634 | 1.6093e-01 | [0.58882, 0.28456, 0.47179, 0.59139]
10 | 8.69758623 | 9.4221e-03 | [0.62524, 0.34192, 0.38099, 0.58908]
15 | 8.69591999 | 7.0277e-04 | [0.62205, 0.33644, 0.39006, 0.58967]
20 | 8.69624282 | 7.2845e-05 | [0.62237, 0.33699, 0.38916, 0.58962]
25 | 8.69621204 | 7.2757e-06 | [0.62234, 0.33693, 0.38925, 0.58962]
30 | 8.69621514 | 7.2934e-07 | [0.62235, 0.33694, 0.38924, 0.58962]
35 | 8.69621483 | 7.3086e-08 | [0.62234, 0.33694, 0.38924, 0.58962]
40 | 8.69621486 | 7.3240e-09 | [0.62234, 0.33694, 0.38924, 0.58962]
45 | 8.69621486 | 7.3395e-10 | [0.62234, 0.33694, 0.38924, 0.58962]
反復回数 45 回で収束しました。
最大固有値 (λ1) : 8.6962148610
対応する固有ベクトル (x1) : [0.6223447229, 0.3369369049, 0.3892384556, 0.5896219066]
検証: Ax と λx の比較
Ax : [5.412043, 2.930076, 3.384901, 5.127479]
λ * x : [5.412043, 2.930076, 3.384901, 5.127479]