fork download
  1. #include <stdio.h>
  2. #include <math.h>
  3. #define N 4
  4. #define EPS 1e-6
  5. #define MAX_ITER 100
  6.  
  7. double A[N][N] = {
  8. {2.0, 1.0, 2.0, 5.0},
  9. {3.0, -3.0, 1.0, 6.0},
  10. {0.0, 1.0, 2.0, 7.0},
  11. {1.0, 1.0, 3.0, 1.0}
  12. };
  13.  
  14. void lu_decomposition(double B[N][N], double L[N][N], double U[N][N]) {
  15. for (int i = 0; i < N; i++) {
  16. for (int j = 0; j < N; j++) {
  17. L[i][j] = (i == j) ? 1.0 : 0.0;
  18. U[i][j] = 0.0;
  19. }
  20. }
  21.  
  22. for (int i = 0; i < N; i++) {
  23. for (int j = i; j < N; j++) {
  24. double sum = 0.0;
  25. for (int k = 0; k < i; k++) sum += L[i][k] * U[k][j];
  26. U[i][j] = B[i][j] - sum;
  27. }
  28. for (int j = i + 1; j < N; j++) {
  29. double sum = 0.0;
  30. for (int k = 0; k < i; k++) sum += L[j][k] * U[k][i];
  31. L[j][i] = (B[j][i] - sum) / U[i][i];
  32. }
  33. }
  34. }
  35.  
  36. void forward_substitution(double L[N][N], double x[N], double y[N]) {
  37. for (int i = 0; i < N; i++) {
  38. double sum = 0.0;
  39. for (int j = 0; j < i; j++) sum += L[i][j] * y[j];
  40. y[i] = x[i] - sum;
  41. }
  42. }
  43.  
  44. void backward_substitution(double U[N][N], double y[N], double x[N]) {
  45. for (int i = N - 1; i >= 0; i--) {
  46. double sum = 0.0;
  47. for (int j = i + 1; j < N; j++) sum += U[i][j] * x[j];
  48. x[i] = (y[i] - sum) / U[i][i];
  49. }
  50. }
  51.  
  52. void find_remaining_eigen(double lambda_hat) {
  53. double B[N][N], L[N][N], U[N][N];
  54. double y[N], x_next[N];
  55. double x[N] = {1.0, 1.0, 1.0, 1.0};
  56.  
  57. for (int i = 0; i < N; i++) {
  58. for (int j = 0; j < N; j++) {
  59. B[i][j] = A[i][j] - (i == j ? lambda_hat : 0.0);
  60. }
  61. }
  62. lu_decomposition(B, L, U);
  63. printf("\n 近似固有値 = %.3f)\n", lambda_hat);
  64.  
  65. int iter = 0;
  66. double diff;
  67. double lambda = 0.0;
  68.  
  69. do {
  70. forward_substitution(L, x, y);
  71. backward_substitution(U, y, x_next);
  72. double max_val = 0.0;
  73. for (int i = 0; i < N; i++) {
  74. if (fabs(x_next[i]) > fabs(max_val)) {
  75. max_val = x_next[i];
  76. }
  77. }
  78.  
  79. for (int i = 0; i < N; i++) {
  80. x_next[i] /= max_val;
  81. }
  82.  
  83. diff = 0.0;
  84. for (int i = 0; i < N; i++) {
  85. diff += fabs(x_next[i] - x[i]);
  86. }
  87.  
  88. for (int i = 0; i < N; i++) {
  89. x[i] = x_next[i];
  90. }
  91.  
  92. lambda = lambda_hat + (1.0 / max_val);
  93. printf("反復 %2d: x = [%.4f, %.4f, %.4f, %.4f], 固有値 = %.6f\n",
  94. iter + 1, x[0], x[1], x[2], x[3], lambda);
  95.  
  96. iter++;
  97. } while (diff > EPS && iter < MAX_ITER);
  98.  
  99. printf(" 収束固有値 = %10.6f\n", lambda);
  100. printf(" 収束固有ベクトル (x) = [%.4f, %.4f, %.4f, %.4f]\n", x[0], x[1], x[2], x[3]);
  101. printf("\n 固有対の検証チェック (A*x - lambda*x):\n");
  102. for (int i = 0; i < N; i++) {
  103. double ax_i = 0.0;
  104. for (int j = 0; j < N; j++) {
  105. ax_i += A[i][j] * x[j];
  106. }
  107. double lx_i = lambda * x[i];
  108. printf(" 第%d行: A*x = %10.6f, lambda*x = %10.6f, 残差絶対値 = %e\n",
  109. i + 1, ax_i, lx_i, fabs(ax_i - lx_i));
  110. }
  111. }
  112.  
  113. int main() {
  114. find_remaining_eigen(-5.0);
  115. find_remaining_eigen(-2.0);
  116. find_remaining_eigen(1.5);
  117.  
  118. return 0;
  119. }
Success #stdin #stdout 0s 5324KB
stdin
Standard input is empty
stdout
               近似固有値 = -5.000)
反復  1: x = [0.1304, -0.6957, -0.2174, 1.0000], 固有値 = -0.217391
反復  2: x = [0.0335, 1.0000, 0.2098, -0.3408], 固有値 = -5.381829
反復  3: x = [0.0130, 1.0000, 0.1468, -0.2732], 固有値 = -4.453684
反復  4: x = [0.0066, 1.0000, 0.1288, -0.2592], 固有値 = -4.406512
反復  5: x = [0.0049, 1.0000, 0.1238, -0.2555], 固有値 = -4.394737
反復  6: x = [0.0044, 1.0000, 0.1224, -0.2545], 固有値 = -4.391544
反復  7: x = [0.0043, 1.0000, 0.1220, -0.2542], 固有値 = -4.390666
反復  8: x = [0.0042, 1.0000, 0.1219, -0.2542], 固有値 = -4.390424
反復  9: x = [0.0042, 1.0000, 0.1219, -0.2542], 固有値 = -4.390358
反復 10: x = [0.0042, 1.0000, 0.1219, -0.2541], 固有値 = -4.390339
反復 11: x = [0.0042, 1.0000, 0.1219, -0.2541], 固有値 = -4.390334
反復 12: x = [0.0042, 1.0000, 0.1219, -0.2541], 固有値 = -4.390333
反復 13: x = [0.0042, 1.0000, 0.1219, -0.2541], 固有値 = -4.390333
 収束固有値  =  -4.390333
 収束固有ベクトル (x)  = [0.0042, 1.0000, 0.1219, -0.2541]

 固有対の検証チェック (A*x - lambda*x):
 第1行: A*x =  -0.018493, lambda*x =  -0.018493, 残差絶対値 = 3.370022e-08
 第2行: A*x =  -4.390333, lambda*x =  -4.390333, 残差絶対値 = 0.000000e+00
 第3行: A*x =  -0.535209, lambda*x =  -0.535209, 残差絶対値 = 1.000340e-07
 第4行: A*x =   1.115785, lambda*x =   1.115785, 残差絶対値 = 7.247127e-08

               近似固有値 = -2.000)
反復  1: x = [0.4286, -0.7857, 1.0000, -0.1429], 固有値 = 0.214286
反復  2: x = [-0.2471, 1.0000, -0.5765, 0.2908], 固有値 = -1.270588
反復  3: x = [-0.2272, 1.0000, -0.5825, 0.2519], 固有値 = -2.752458
反復  4: x = [-0.2300, 1.0000, -0.5689, 0.2469], 固有値 = -2.777532
反復  5: x = [-0.2272, 1.0000, -0.5663, 0.2443], 固有値 = -2.782267
反復  6: x = [-0.2273, 1.0000, -0.5651, 0.2436], 固有値 = -2.785448
反復  7: x = [-0.2271, 1.0000, -0.5648, 0.2433], 固有値 = -2.786043
反復  8: x = [-0.2271, 1.0000, -0.5647, 0.2433], 固有値 = -2.786349
反復  9: x = [-0.2271, 1.0000, -0.5647, 0.2432], 固有値 = -2.786424
反復 10: x = [-0.2271, 1.0000, -0.5646, 0.2432], 固有値 = -2.786454
反復 11: x = [-0.2271, 1.0000, -0.5646, 0.2432], 固有値 = -2.786463
反復 12: x = [-0.2271, 1.0000, -0.5646, 0.2432], 固有値 = -2.786466
反復 13: x = [-0.2271, 1.0000, -0.5646, 0.2432], 固有値 = -2.786467
 収束固有値  =  -2.786467
 収束固有ベクトル (x)  = [-0.2271, 1.0000, -0.5646, 0.2432]

 固有対の検証チェック (A*x - lambda*x):
 第1行: A*x =   0.632735, lambda*x =   0.632735, 残差絶対値 = 1.267989e-07
 第2行: A*x =  -2.786467, lambda*x =  -2.786467, 残差絶対値 = 0.000000e+00
 第3行: A*x =   1.573349, lambda*x =   1.573349, 残差絶対値 = 3.343676e-07
 第4行: A*x =  -0.677760, lambda*x =  -0.677759, 残差絶対値 = 2.459525e-07

               近似固有値 = 1.500)
反復  1: x = [1.0000, 0.5127, -0.2800, 0.0400], 固有値 = 2.152727
反復  2: x = [1.0000, 0.5281, -0.5169, -0.0319], 固有値 = 1.334764
反復  3: x = [1.0000, 0.5306, -0.5135, -0.0288], 固有値 = 1.359754
反復  4: x = [1.0000, 0.5307, -0.5137, -0.0288], 固有値 = 1.359320
反復  5: x = [1.0000, 0.5307, -0.5137, -0.0288], 固有値 = 1.359333
反復  6: x = [1.0000, 0.5307, -0.5137, -0.0288], 固有値 = 1.359333
 収束固有値  =   1.359333
 収束固有ベクトル (x)  = [1.0000, 0.5307, -0.5137, -0.0288]

 固有対の検証チェック (A*x - lambda*x):
 第1行: A*x =   1.359333, lambda*x =   1.359333, 残差絶対値 = 0.000000e+00
 第2行: A*x =   0.721403, lambda*x =   0.721403, 残差絶対値 = 1.044082e-08
 第3行: A*x =  -0.698268, lambda*x =  -0.698268, 残差絶対値 = 1.577842e-08
 第4行: A*x =  -0.039149, lambda*x =  -0.039149, 残差絶対値 = 6.677112e-10