Next version of JABA
[jabaws.git] / binaries / src / mafft / core / fft.c
1 #include "mltaln.h"
2 #include "mtxutl.h"
3
4 /*
5   {\tt fft()}.
6 */
7 static void make_sintbl(int n, float sintbl[])
8 {
9         int i, n2, n4, n8;
10         double c, s, dc, ds, t;
11
12         n2 = n / 2;  n4 = n / 4;  n8 = n / 8;
13         t = sin(PI / n);
14         dc = 2 * t * t;  ds = sqrt(dc * (2 - dc));
15         t = 2 * dc;  c = sintbl[n4] = 1;  s = sintbl[0] = 0;
16         for (i = 1; i < n8; i++) {
17                 c -= dc;  dc += t * c;
18                 s += ds;  ds -= t * s;
19                 sintbl[i] = s;  sintbl[n4 - i] = c;
20         }
21         if (n8 != 0) sintbl[n8] = sqrt(0.5);
22         for (i = 0; i < n4; i++)
23                 sintbl[n2 - i] = sintbl[i];
24         for (i = 0; i < n2 + n4; i++)
25                 sintbl[i + n2] = - sintbl[i];
26 }
27 /*
28   {\tt fft()}.
29 */
30 static void make_bitrev(int n, int bitrev[])
31 {
32         int i, j, k, n2;
33
34         n2 = n / 2;  i = j = 0;
35         for ( ; ; ) {
36                 bitrev[i] = j;
37                 if (++i >= n) break;
38                 k = n2;
39                 while (k <= j) {  j -= k;  k /= 2;  }
40                 j += k;
41         }
42 }
43 /*
44 */
45 int fft(int n, Fukusosuu *x, int dum)
46 {
47         static int    last_n = 0;    /*  {\tt n} */
48         static int   *bitrev = NULL; /*  */
49         static float *sintbl = NULL; /*  */
50         int i, j, k, ik, h, d, k2, n4, inverse;
51         float t, s, c, dR, dI;
52
53         /*  */
54         if (n < 0) {
55                 n = -n;  inverse = 1;  /*  */
56         } else inverse = 0;
57         n4 = n / 4;
58         if (n != last_n || n == 0) {
59                 last_n = n;
60 #if 0
61                 if (sintbl != NULL) {
62                                         free(sintbl);
63                                         sintbl = NULL;
64                                 }
65                 if (bitrev != NULL) {
66                                         free(bitrev);
67                                         bitrev = NULL;
68                                 }
69                 if (n == 0) return 0;  /*  */
70                 sintbl = (float *)malloc((n + n4) * sizeof(float));
71                 bitrev = (int *)malloc(n * sizeof(int));
72 #else /* by T. Nishiyama */
73                                 sintbl = realloc(sintbl, (n + n4) * sizeof(float));
74                                 bitrev = realloc(bitrev, n * sizeof(int));
75 #endif
76                 if (sintbl == NULL || bitrev == NULL) {
77                         fprintf(stderr, "\n");  return 1;
78                 }
79                 make_sintbl(n, sintbl);
80                 make_bitrev(n, bitrev);
81         }
82         for (i = 0; i < n; i++) {    /*  */
83                 j = bitrev[i];
84                 if (i < j) {
85                         t = x[i].R;  x[i].R = x[j].R;  x[j].R = t;
86                         t = x[i].I;  x[i].I = x[j].I;  x[j].I = t;
87                 }
88         }
89         for (k = 1; k < n; k = k2) {    /*  */
90 #if 0
91                                 fprintf( stderr, "%d / %d\n", k, n );
92 #endif
93                 h = 0;  k2 = k + k;  d = n / k2;
94                 for (j = 0; j < k; j++) {
95 #if 0
96                                         if( j % 1 == 0 )
97                                                 fprintf( stderr, "%d / %d\r", j, k );
98 #endif
99                         c = sintbl[h + n4];
100                         if (inverse) s = - sintbl[h];
101                         else         s =   sintbl[h];
102                         for (i = j; i < n; i += k2) {
103 #if 0
104                                                                 if( k>=4194000 ) fprintf( stderr, "in loop %d -  %d < %d, k2=%d\r", j, i, n, k2 );
105 #endif
106                                 ik = i + k;
107                                 dR = s * x[ik].I + c * x[ik].R;
108                                 dI = c * x[ik].I - s * x[ik].R;
109                                 x[ik].R = x[i].R - dR;  x[i].R += dR;
110                                 x[ik].I = x[i].I - dI;  x[i].I += dI;
111                         }
112                         h += d;
113                 }
114         }
115         if (! inverse)    /* n */
116                 for (i = 0; i < n; i++) {  x[i].R /= n;  x[i].I /= n;  }
117         return 0;  /*  */
118 }