fork(1) download
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <math.h>
  4.  
  5. #define SIZE 4
  6. #define EPSILON 1e-9
  7. #define MAX_ITER 1000
  8.  
  9. double vector_norm(double *v, int n) {
  10. double sum = 0.0;
  11. for (int i = 0; i < n; i++) {
  12. sum += v[i] * v[i];
  13. }
  14. return sqrt(sum);
  15. }
  16.  
  17. void mat_vec_mul(double A[SIZE][SIZE], double *x, double *y, int n) {
  18. for (int i = 0; i < n; i++) {
  19. y[i] = 0.0;
  20. for (int j = 0; j < n; j++) {
  21. y[i] += A[i][j] * x[j];
  22. }
  23. }
  24. }
  25.  
  26. int main() {
  27. double A[SIZE][SIZE] = {
  28. {2.0, 3.0, 2.0, 5.0},
  29. {3.0, -3.0, 1.0, 6.0},
  30. {0.0, 1.0, 2.0, 7.0},
  31. {1.0, 7.0, 3.0, 1.0}
  32. };
  33.  
  34. double x[SIZE], y[SIZE], Ax[SIZE];
  35. double lambda_old = 0.0, lambda_new = 0.0;
  36.  
  37. for (int i = 0; i < SIZE; i++) {
  38. x[i] = 1.0;
  39. }
  40.  
  41. printf("初期ベクトル x(0): [%.1f, %.1f, %.1f, %.1f]\n\n", x[0], x[1], x[2], x[3]);
  42. printf("%-5s | %-12s | %-12s | %-30s\n", "Iter", "固有値(新)", "差分値", "固有ベクトルx(k)");
  43. int actual_iters = 0;
  44. for (int iter = 1; iter <= MAX_ITER; iter++) {
  45. actual_iters = iter;
  46. mat_vec_mul(A, x, y, SIZE);
  47.  
  48. double norm_y = vector_norm(y, SIZE);
  49. if (norm_y < 1e-12) break;
  50. for (int i = 0; i < SIZE; i++) {
  51. y[i] /= norm_y;
  52. }
  53.  
  54. mat_vec_mul(A, y, Ax, SIZE);
  55. double num = 0.0, den = 0.0;
  56. for (int i = 0; i < SIZE; i++) {
  57. num += y[i] * Ax[i];
  58. den += y[i] * y[i];
  59. }
  60. lambda_new = num / den;
  61. double diff = fabs(lambda_new - lambda_old);
  62.  
  63.  
  64. if (iter <= 5 || iter % 5 == 0) {
  65. printf("%-5d | %-12.8f | %-12.4e | [%.5f, %.5f, %.5f, %.5f]\n",
  66. iter, lambda_new, diff, y[0], y[1], y[2], y[3]);
  67. }
  68.  
  69. if (diff < EPSILON) {
  70. if (iter % 5 != 0 && iter > 5) { // 最終ステップを確実に表示させる
  71. printf("%-5d | %-12.8f | %-12.4e | [%.5f, %.5f, %.5f, %.5f]\n",
  72. iter, lambda_new, diff, y[0], y[1], y[2], y[3]);
  73. }
  74. break;
  75. }
  76.  
  77. // 次のステップに向けて x を更新
  78. for (int i = 0; i < SIZE; i++) {
  79. x[i] = y[i];
  80. }
  81. lambda_old = lambda_new;
  82. }
  83.  
  84.  
  85. printf("反復回数 %d 回で収束しました。\n", actual_iters);
  86. printf("\n最大固有値 (λ1) : %.10f\n", lambda_new);
  87. printf("対応する固有ベクトル (x1) : [");
  88. for (int i = 0; i < SIZE; i++) {
  89. printf("%.10f%s", y[i], (i == SIZE - 1) ? "]\n" : ", ");
  90. }
  91.  
  92. printf("\n 検証: Ax と λx の比較 \n");
  93. mat_vec_mul(A, y, Ax, SIZE); // Axを再計算
  94. printf("Ax : [");
  95. for (int i = 0; i < SIZE; i++) {
  96. printf("%.6f%s", Ax[i], (i == SIZE - 1) ? "]\n" : ", ");
  97. }
  98. printf("λ * x : [");
  99. for (int i = 0; i < SIZE; i++) {
  100. printf("%.6f%s", lambda_new * y[i], (i == SIZE - 1) ? "]\n" : ", ");
  101. }
  102.  
  103. return 0;
  104. }
  105.  
  106.  
Success #stdin #stdout 0s 5320KB
stdin
Standard input is empty
stdout
初期ベクトル x(0): [1.0, 1.0, 1.0, 1.0]

Iter  | 固有値(新) | 差分値    | 固有ベクトルx(k)        
1     | 10.35469108  | 1.0355e+01   | [0.57404, 0.33486, 0.47836, 0.57404]
2     | 10.04442916  | 3.1026e-01   | [0.57076, 0.44291, 0.50683, 0.47030]
3     | 10.39548053  | 3.5105e-01   | [0.57655, 0.36677, 0.46918, 0.55941]
4     | 10.16061868  | 2.3486e-01   | [0.57338, 0.42653, 0.49987, 0.48933]
5     | 10.37411255  | 2.1349e-01   | [0.57633, 0.38042, 0.47612, 0.54446]
10    | 10.27840563  | 5.7555e-02   | [0.57506, 0.40692, 0.48998, 0.51346]
15    | 10.31313134  | 1.7133e-02   | [0.57554, 0.39933, 0.48606, 0.52253]
20    | 10.30361668  | 4.9442e-03   | [0.57541, 0.40154, 0.48721, 0.51990]
25    | 10.30643009  | 1.4395e-03   | [0.57545, 0.40090, 0.48687, 0.52066]
30    | 10.30561673  | 4.1802e-04   | [0.57544, 0.40109, 0.48697, 0.52044]
35    | 10.30585341  | 1.2148e-04   | [0.57544, 0.40103, 0.48694, 0.52051]
40    | 10.30578466  | 3.5297e-05   | [0.57544, 0.40105, 0.48695, 0.52049]
45    | 10.30580464  | 1.0256e-05   | [0.57544, 0.40104, 0.48695, 0.52049]
50    | 10.30579884  | 2.9800e-06   | [0.57544, 0.40105, 0.48695, 0.52049]
55    | 10.30580052  | 8.6589e-07   | [0.57544, 0.40104, 0.48695, 0.52049]
60    | 10.30580003  | 2.5160e-07   | [0.57544, 0.40105, 0.48695, 0.52049]
65    | 10.30580018  | 7.3105e-08   | [0.57544, 0.40105, 0.48695, 0.52049]
70    | 10.30580013  | 2.1242e-08   | [0.57544, 0.40105, 0.48695, 0.52049]
75    | 10.30580015  | 6.1721e-09   | [0.57544, 0.40105, 0.48695, 0.52049]
80    | 10.30580014  | 1.7934e-09   | [0.57544, 0.40105, 0.48695, 0.52049]
83    | 10.30580014  | 8.5431e-10   | [0.57544, 0.40105, 0.48695, 0.52049]
反復回数 83 回で収束しました。

最大固有値 (λ1)          : 10.3058001440
対応する固有ベクトル (x1) : [0.5754405791, 0.4010450677, 0.4869480753, 0.5204926182]

   検証: Ax と λx の比較   
Ax    : [5.930376, 4.133090, 5.018390, 5.364093]
λ * x : [5.930376, 4.133090, 5.018390, 5.364093]