fork download
  1. #include <stdio.h>
  2. #include <math.h>
  3. #include <complex.h>
  4. #define N 4
  5. #define EPS 1e-8
  6. #define MAX_ITER 100
  7.  
  8. double complex A[N][N] = {
  9. {1.0, 2.0, 3.0, 5.0},
  10. {3.0, -5.0, 1.0, 4.0},
  11. {5.0, 9.0, 2.0, -6.0},
  12. {1.0, 7.0, 4.0, 1.0}
  13. };
  14.  
  15. void lu_decomposition(double complex B[N][N],
  16. double complex L[N][N],
  17. double complex U[N][N])
  18. {
  19. for(int i=0;i<N;i++){
  20. for(int j=0;j<N;j++){
  21. L[i][j]=(i==j)?1.0+0.0*I:0.0+0.0*I;
  22. U[i][j]=0.0+0.0*I;
  23. }
  24. }
  25.  
  26. for(int i=0;i<N;i++){
  27.  
  28. for(int j=i;j<N;j++){
  29. double complex sum = 0.0 + 0.0*I;
  30.  
  31. for(int k=0;k<i;k++)
  32. sum += L[i][k]*U[k][j];
  33.  
  34. U[i][j] = B[i][j] - sum;
  35. }
  36.  
  37. for(int j=i+1;j<N;j++){
  38. double complex sum = 0.0 + 0.0*I;
  39.  
  40. for(int k=0;k<i;k++)
  41. sum += L[j][k]*U[k][i];
  42.  
  43. L[j][i] = (B[j][i]-sum)/U[i][i];
  44. }
  45. }
  46. }
  47.  
  48. /* 前進代入 */
  49. void forward_substitution(double complex L[N][N],
  50. double complex x[N],
  51. double complex y[N])
  52. {
  53. for(int i=0;i<N;i++){
  54.  
  55. double complex sum = 0.0 + 0.0*I;
  56.  
  57. for(int j=0;j<i;j++)
  58. sum += L[i][j]*y[j];
  59.  
  60. y[i] = x[i] - sum;
  61. }
  62. }
  63.  
  64. /* 後退代入 */
  65. void backward_substitution(double complex U[N][N],
  66. double complex y[N],
  67. double complex x[N])
  68. {
  69. for(int i=N-1;i>=0;i--){
  70.  
  71. double complex sum = 0.0 + 0.0*I;
  72.  
  73. for(int j=i+1;j<N;j++)
  74. sum += U[i][j]*x[j];
  75.  
  76. x[i] = (y[i]-sum)/U[i][i];
  77. }
  78. }
  79.  
  80. void inverse_iteration(double complex lambda_hat)
  81. {
  82. double complex B[N][N];
  83. double complex L[N][N];
  84. double complex U[N][N];
  85.  
  86. double complex x[N] =
  87. {
  88. 1.0+0.0*I,
  89. 1.0+0.0*I,
  90. 1.0+0.0*I,
  91. 1.0+0.0*I
  92. };
  93.  
  94. double complex y[N];
  95. double complex x_next[N];
  96.  
  97. for(int i=0;i<N;i++){
  98. for(int j=0;j<N;j++){
  99.  
  100. B[i][j] = A[i][j];
  101.  
  102. if(i==j)
  103. B[i][j] -= lambda_hat;
  104. }
  105. }
  106.  
  107. lu_decomposition(B,L,U);
  108.  
  109. printf("\n 近似固有値 lambda_hat = %.3f %+.3fi)\n",
  110. creal(lambda_hat), cimag(lambda_hat));
  111.  
  112.  
  113. int iter=0;
  114. double diff;
  115. double complex lambda = 0.0 + 0.0*I;
  116.  
  117. do{
  118.  
  119. forward_substitution(L,x,y);
  120. backward_substitution(U,y,x_next);
  121.  
  122. double max_mag = 0.0;
  123. int idx = 0;
  124.  
  125. for(int i=0;i<N;i++){
  126. if(cabs(x_next[i]) > max_mag){
  127. max_mag = cabs(x_next[i]);
  128. idx = i;
  129. }
  130. }
  131.  
  132. double complex scale = x_next[idx];
  133.  
  134. for(int i=0;i<N;i++)
  135. x_next[i] /= scale;
  136.  
  137. diff = 0.0;
  138.  
  139. for(int i=0;i<N;i++)
  140. diff += cabs(x_next[i]-x[i]);
  141.  
  142. for(int i=0;i<N;i++)
  143. x[i]=x_next[i];
  144.  
  145. lambda = lambda_hat + 1.0/scale;
  146.  
  147. printf("反復 %2d: x = [(%.3f%+.3fi), (%.3f%+.3fi), (%.3f%+.3fi), (%.3f%+.3fi)], 固有値 = %.4f%+.4fi\n",
  148. iter + 1,
  149. creal(x[0]), cimag(x[0]),
  150. creal(x[1]), cimag(x[1]),
  151. creal(x[2]), cimag(x[2]),
  152. creal(x[3]), cimag(x[3]),
  153. creal(lambda), cimag(lambda));
  154.  
  155. iter++;
  156.  
  157. }while(diff>EPS && iter<MAX_ITER);
  158.  
  159.  
  160. printf(" 収束固有値 = %10.6f %+.6fi\n", creal(lambda), cimag(lambda));
  161. printf(" 収束固有ベクトル (x) = [(%.4f%+.4fi), (%.4f%+.4fi), (%.4f%+.4fi), (%.5f%+.4fi)]\n",
  162. creal(x[0]), cimag(x[0]),
  163. creal(x[1]), cimag(x[1]),
  164. creal(x[2]), cimag(x[2]),
  165. creal(x[3]), cimag(x[3]));
  166.  
  167. printf("\n 固有対の検証チェック (A*x - lambda*x):\n");
  168. for (int i = 0; i < N; i++) {
  169. double complex ax_i = 0.0 + 0.0*I;
  170. for (int j = 0; j < N; j++) {
  171. ax_i += A[i][j] * x[j];
  172. }
  173. double complex lx_i = lambda * x[i];
  174. double complex residue = ax_i - lx_i;
  175. printf(" 第%d行: A*x = (%9.5f%+.5fi), lambda*x = (%9.5f%+.5fi), 残差絶対値 = %e\n",
  176. i + 1,
  177. creal(ax_i), cimag(ax_i),
  178. creal(lx_i), cimag(lx_i),
  179. cabs(residue));
  180. }
  181. printf("\n");
  182. }
  183.  
  184. int main()
  185. {
  186. inverse_iteration(-5.4 + 0.0*I);
  187. inverse_iteration(-2.1 + 1.7*I);
  188. inverse_iteration(-2.1 - 1.7*I);
  189.  
  190. return 0;
  191. }
  192.  
Success #stdin #stdout 0.01s 5308KB
stdin
Standard input is empty
stdout
             近似固有値 lambda_hat = -5.400 +0.000i)
反復  1: x = [(-0.335+0.000i), (-0.582-0.000i), (1.000+0.000i), (0.072+0.000i)], 固有値 = -5.3508+0.0000i
反復  2: x = [(-0.338-0.000i), (-0.594-0.000i), (1.000-0.000i), (0.076-0.000i)], 固有値 = -5.4926+0.0000i
反復  3: x = [(-0.338+0.000i), (-0.594-0.000i), (1.000-0.000i), (0.076-0.000i)], 固有値 = -5.4892+0.0000i
反復  4: x = [(-0.338-0.000i), (-0.594-0.000i), (1.000-0.000i), (0.076-0.000i)], 固有値 = -5.4893+0.0000i
反復  5: x = [(-0.338+0.000i), (-0.594-0.000i), (1.000-0.000i), (0.076-0.000i)], 固有値 = -5.4893+0.0000i
反復  6: x = [(-0.338-0.000i), (-0.594-0.000i), (1.000-0.000i), (0.076-0.000i)], 固有値 = -5.4893+0.0000i
 収束固有値   =  -5.489254 +0.000000i
 収束固有ベクトル (x)  = [(-0.3379-0.0000i), (-0.5937-0.0000i), (1.0000-0.0000i), (0.07607-0.0000i)]

 固有対の検証チェック (A*x - lambda*x):
 第1行: A*x = (  1.85508+0.00000i), lambda*x = (  1.85508+0.00000i), 残差絶対値 = 8.030443e-11
 第2行: A*x = (  3.25883+0.00000i), lambda*x = (  3.25883+0.00000i), 残差絶対値 = 2.493117e-12
 第3行: A*x = ( -5.48925+0.00000i), lambda*x = ( -5.48925+0.00000i), 残差絶対値 = 0.000000e+00
 第4行: A*x = ( -0.41759+0.00000i), lambda*x = ( -0.41759+0.00000i), 残差絶対値 = 1.728266e-10


             近似固有値 lambda_hat = -2.100 +1.700i)
反復  1: x = [(-0.418+0.065i), (-0.370+0.022i), (1.000-0.000i), (-0.218-0.194i)], 固有値 = -2.1153+1.6857i
反復  2: x = [(-0.414+0.067i), (-0.371+0.022i), (1.000+0.000i), (-0.217-0.189i)], 固有値 = -2.1037+1.6744i
反復  3: x = [(-0.414+0.067i), (-0.371+0.022i), (1.000+0.000i), (-0.217-0.189i)], 固有値 = -2.1035+1.6741i
反復  4: x = [(-0.414+0.067i), (-0.371+0.022i), (1.000+0.000i), (-0.217-0.189i)], 固有値 = -2.1035+1.6741i
反復  5: x = [(-0.414+0.067i), (-0.371+0.022i), (1.000+0.000i), (-0.217-0.189i)], 固有値 = -2.1035+1.6741i
 収束固有値   =  -2.103481 +1.674115i
 収束固有ベクトル (x)  = [(-0.4141+0.0673i), (-0.3707+0.0224i), (1.0000+0.0000i), (-0.21721-0.1894i)]

 固有対の検証チェック (A*x - lambda*x):
 第1行: A*x = (  0.75849-0.83477i), lambda*x = (  0.75849-0.83477i), 残差絶対値 = 4.659298e-12
 第2行: A*x = (  0.74222-0.66768i), lambda*x = (  0.74222-0.66768i), 残差絶対値 = 2.149513e-11
 第3行: A*x = ( -2.10348+1.67411i), lambda*x = ( -2.10348+1.67411i), 残差絶対値 = 8.005932e-16
 第4行: A*x = (  0.77391+0.03470i), lambda*x = (  0.77391+0.03470i), 残差絶対値 = 5.726044e-11


             近似固有値 lambda_hat = -2.100 -1.700i)
反復  1: x = [(-0.418-0.065i), (-0.370-0.022i), (1.000-0.000i), (-0.218+0.194i)], 固有値 = -2.1153-1.6857i
反復  2: x = [(-0.414-0.067i), (-0.371-0.022i), (1.000-0.000i), (-0.217+0.189i)], 固有値 = -2.1037-1.6744i
反復  3: x = [(-0.414-0.067i), (-0.371-0.022i), (1.000-0.000i), (-0.217+0.189i)], 固有値 = -2.1035-1.6741i
反復  4: x = [(-0.414-0.067i), (-0.371-0.022i), (1.000-0.000i), (-0.217+0.189i)], 固有値 = -2.1035-1.6741i
反復  5: x = [(-0.414-0.067i), (-0.371-0.022i), (1.000-0.000i), (-0.217+0.189i)], 固有値 = -2.1035-1.6741i
 収束固有値   =  -2.103481 -1.674115i
 収束固有ベクトル (x)  = [(-0.4141-0.0673i), (-0.3707-0.0224i), (1.0000-0.0000i), (-0.21721+0.1894i)]

 固有対の検証チェック (A*x - lambda*x):
 第1行: A*x = (  0.75849+0.83477i), lambda*x = (  0.75849+0.83477i), 残差絶対値 = 4.659298e-12
 第2行: A*x = (  0.74222+0.66768i), lambda*x = (  0.74222+0.66768i), 残差絶対値 = 2.149513e-11
 第3行: A*x = ( -2.10348-1.67411i), lambda*x = ( -2.10348-1.67411i), 残差絶対値 = 8.005932e-16
 第4行: A*x = (  0.77391-0.03470i), lambda*x = (  0.77391-0.03470i), 残差絶対値 = 5.726044e-11