1 // 菊地文雄, 山本昌宏「微分方程式と計算機演習」, 山海堂 (1991), p. 98
2 /* ** INVERSE ITERATION METHOD **
3 N : ORDER OF MATRIX
4 A : COEFFICIENT MATRIX
5 EPS : THRESHOLD VALUE FOR ERROR
6 M : MAXIMUM NO. OF ITERATIONS
7 EVAL : EIGENVALUE
8 X : EIGENVECTOR
9 NITER : NO. OF ITERATIONS
10 */
11
12 #include <stdio.h>
13 #include <stdlib.h>
14 #include <math.h>
15
16 void gauss(int ndim, double a[][ndim], double f[], int N, int ID);
17 void inpr(double x[], double y[], int n, double *s);
18
19 #define NDIM (100)
20
21 int main(void)
22 {
23 int n, m, i, j, niter;
24 double eps, eval, s, t, enew, error;
25 double a[NDIM][NDIM], x[NDIM], y[NDIM];
26 // INPUT
27 printf("INPUT : N= \n");
28 scanf("%d", &n);
29 if (n <= 1) exit(1);
30 printf("INPUT: EPS=\n");
31 scanf("%lf", &eps);
32 printf("INPUT : M= \n");
33 scanf("%d", &m);
34 for (i = 0; i < n; i++) {
35 for (j=0; j < n; j++) {
36 printf("INPUT : A(%3d,%3d)=\n", i+1, j+1);
37 scanf("%lf", &a[i][j]);
38 }
39 }
40 for (i=0; i<n; i++) {
41 printf("INPUT:X(%3d)=\n",i+1);
42 scanf("%lf", &x[i]);
43 }
44 // ITERATION
45 niter = 0;
46 eval = 0.0;
47 do {
48 for (i=0; i<n; i++)
49 y[i] = x[i];
50 gauss(NDIM,a,y,n,niter);
51 inpr(x,y,n,&s);
52 inpr(y,y,n,&t);
53 enew = s / t;
54 t = sqrt(t);
55 for (i=0; i<n; i++)
56 x[i] = y[i] / t;
57 error = fabs((enew-eval)/enew);
58 eval = enew;
59 niter++;
60 printf("(NITER,EVAL,ERROR)=%d %g %g\n", niter, eval, error);
61 if (niter == m) break;
62 }
63 while (error > eps);
64 // OUTPUT
65 printf("NO. OF ITERATIONS = %3d EPS=%12.4e\n", niter, eps);
66 printf("EIGENVALUE=%12.4e\n", eval);
67 printf("**EIGENVECTOR**\n");
68 for (i = 0; i < 5; i++)
69 printf(" I X(I) ");
70 printf("\n");
71 for (i=0; i<n; i++) {
72 printf("%3d%12.4e ", i+1, x[i]);
73 if ((i+1) % 5 == 0 || (i+1) == n)
74 printf("\n");
75 }
76 }
77
78 void gauss(int ndim, double a[][ndim], double f[], int n, int id)
79 {
80 int i, j, k;
81 double aa;
82 // FORWARD ELIMINATION
83 for (i=0; i<n-1; i++) {
84 for (j=i+1; j<n; j++) {
85 aa = a[j][i] / a[i][i];
86 if (id == 0) {
87 for (k=i+1; k<n; k++)
88 a[j][k] -= aa * a[i][k];
89 }
90 f[j] -= aa * f[i];
91 }
92 }
93 // BACKWARD SUBSTITUTION
94 f[n-1] /= a[n-1][n-1];
95 for (i=n-2; i>= 0; i--) {
96 for (j=i+1; j<n; j++)
97 f[i] -= a[i][j] * f[j];
98 f[i] /= a[i][i];
99 }
100 }
101
102 void inpr(double x[], double y[], int n, double *s)
103 {
104 int i;
105 // INNER PRODUCT
106 *s = 0.0;
107 for (i=0; i<n; i++)
108 *s += x[i] * y[i];
109 }
桂田 祐史
2018-06-08