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