Added script front-end for primer-design code
[htsworkflow.git] / htswanalysis / MACS / lib / gsl / gsl-1.11 / fft / hc_pass_n.c
1 /* fft/hc_pass_n.c
2  * 
3  * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough
4  * 
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 3 of the License, or (at
8  * your option) any later version.
9  * 
10  * This program is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * General Public License for more details.
14  * 
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18  */
19
20 static void
21 FUNCTION(fft_halfcomplex,pass_n) (const BASE in[],
22                                   const size_t istride,
23                                   BASE out[],
24                                   const size_t ostride,
25                                   const size_t factor,
26                                   const size_t product,
27                                   const size_t n,
28                                   const TYPE(gsl_complex) twiddle[])
29 {
30
31   size_t k, k1;
32
33   const size_t m = n / factor;
34   const size_t q = n / product;
35   const size_t product_1 = product / factor;
36
37   size_t e1, e2;
38
39   const double d_theta = 2.0 * M_PI / ((double) factor);
40   const ATOMIC cos_d_theta = cos (d_theta);
41   const ATOMIC sin_d_theta = sin (d_theta);
42
43   for (k1 = 0; k1 < product_1; k1++)
44     {
45       /* compute z = W(factor) x, for x halfcomplex */
46
47       ATOMIC dw_real = 1.0, dw_imag = 0.0;
48
49       for (e1 = 0; e1 < factor; e1++)
50         {
51           ATOMIC sum_real = 0.0;
52           ATOMIC w_real = 1.0, w_imag = 0.0;
53
54           if (e1 > 0)
55             {
56               ATOMIC tmp_real = dw_real * cos_d_theta - dw_imag * sin_d_theta;
57               ATOMIC tmp_imag = dw_real * sin_d_theta + dw_imag * cos_d_theta;
58               dw_real = tmp_real;
59               dw_imag = tmp_imag;
60             }
61
62           for (e2 = 0; e2 <= factor - e2; e2++)
63             {
64               ATOMIC z_real, z_imag;
65
66               if (e2 > 0)
67                 {
68                   ATOMIC tmp_real = dw_real * w_real - dw_imag * w_imag;
69                   ATOMIC tmp_imag = dw_real * w_imag + dw_imag * w_real;
70                   w_real = tmp_real;
71                   w_imag = tmp_imag;
72                 }
73
74               if (e2 == 0)
75                 {
76                   size_t from_idx = factor * k1 * q;
77                   z_real = VECTOR(in,istride,from_idx);
78                   z_imag = 0.0;
79                   sum_real += w_real * z_real - w_imag * z_imag;
80                 }
81               else if (e2 == factor - e2)
82                 {
83                   size_t from_idx = factor * q * k1 + 2 * e2 * q - 1;
84                   z_real = VECTOR(in,istride,from_idx);
85                   z_imag = 0.0;
86                   sum_real += w_real * z_real;
87                 }
88               else
89                 {
90                   size_t from_idx = factor * q * k1 + 2 * e2 * q - 1;
91                   z_real = VECTOR(in,istride,from_idx);
92                   z_imag = VECTOR(in,istride,from_idx + 1);
93                   sum_real += 2 * (w_real * z_real - w_imag * z_imag);
94                 }
95
96             }
97
98           {
99             const size_t to_idx = q * k1 + e1 * m;
100             VECTOR(out,ostride,to_idx) = sum_real;
101           }
102         }
103     }
104
105   if (q == 1)
106     return;
107
108   for (k = 1; k < (q + 1) / 2; k++)
109     {
110       for (k1 = 0; k1 < product_1; k1++)
111         {
112
113           ATOMIC dw_real = 1.0, dw_imag = 0.0;
114
115           for (e1 = 0; e1 < factor; e1++)
116             {
117               ATOMIC z_real, z_imag;
118               ATOMIC sum_real = 0.0;
119               ATOMIC sum_imag = 0.0;
120               ATOMIC w_real = 1.0, w_imag = 0.0;
121
122               if (e1 > 0)
123                 {
124                   ATOMIC t_real = dw_real * cos_d_theta - dw_imag * sin_d_theta;
125                   ATOMIC t_imag = dw_real * sin_d_theta + dw_imag * cos_d_theta;
126                   dw_real = t_real;
127                   dw_imag = t_imag;
128                 }
129
130               for (e2 = 0; e2 < factor; e2++)
131                 {
132
133                   if (e2 > 0)
134                     {
135                       ATOMIC tmp_real = dw_real * w_real - dw_imag * w_imag;
136                       ATOMIC tmp_imag = dw_real * w_imag + dw_imag * w_real;
137                       w_real = tmp_real;
138                       w_imag = tmp_imag;
139                     }
140
141                   if (e2 < factor - e2)
142                     {
143                       const size_t from0 = factor * k1 * q + 2 * k + 2 * e2 * q - 1;
144                       z_real = VECTOR(in,istride,from0);
145                       z_imag = VECTOR(in,istride,from0 + 1);
146                     }
147                   else
148                     {
149                       const size_t from0 = factor * k1 * q - 2 * k + 2 * (factor - e2) * q - 1;
150                       z_real = VECTOR(in,istride,from0);
151                       z_imag = -VECTOR(in,istride,from0 + 1);
152                     }
153
154                   sum_real += w_real * z_real - w_imag * z_imag;
155                   sum_imag += w_real * z_imag + w_imag * z_real;
156                 }
157
158               if (k == 0 || e1 == 0)
159                 {
160                   w_real = 1.0;
161                   w_imag = 0.0;
162                 }
163               else
164                 {
165                   size_t tskip = (q + 1) / 2 - 1;
166                   w_real = GSL_REAL(twiddle[k - 1 + tskip * (e1 - 1)]);
167                   w_imag = GSL_IMAG(twiddle[k - 1 + tskip * (e1 - 1)]);
168                 }
169
170               {
171                 const size_t to0 = k1 * q + 2 * k + e1 * m - 1;
172                 VECTOR(out,ostride,to0) = w_real * sum_real - w_imag * sum_imag;
173                 VECTOR(out,ostride,to0 + 1) = w_real * sum_imag + w_imag * sum_real;
174               }
175
176             }
177         }
178     }
179
180
181   if (q % 2 == 1)
182     return;
183
184   {
185     double tw_arg = M_PI / ((double) factor);
186     ATOMIC cos_tw_arg = cos (tw_arg);
187     ATOMIC sin_tw_arg = sin (tw_arg);
188
189     for (k1 = 0; k1 < product_1; k1++)
190       {
191
192         ATOMIC dw_real = 1.0, dw_imag = 0.0;
193         ATOMIC tw_real = 1.0, tw_imag = 0.0;
194
195         for (e1 = 0; e1 < factor; e1++)
196           {
197             ATOMIC w_real, w_imag, z_real, z_imag;
198
199             ATOMIC sum_real = 0.0;
200
201             if (e1 > 0)
202               {
203                 ATOMIC tmp_real = tw_real * cos_tw_arg - tw_imag * sin_tw_arg;
204                 ATOMIC tmp_imag = tw_real * sin_tw_arg + tw_imag * cos_tw_arg;
205                 tw_real = tmp_real;
206                 tw_imag = tmp_imag;
207               }
208
209             w_real = tw_real;
210             w_imag = tw_imag;
211
212             if (e1 > 0)
213               {
214                 ATOMIC t_real = dw_real * cos_d_theta - dw_imag * sin_d_theta;
215                 ATOMIC t_imag = dw_real * sin_d_theta + dw_imag * cos_d_theta;
216                 dw_real = t_real;
217                 dw_imag = t_imag;
218               }
219
220             for (e2 = 0; e2 <= factor - e2 - 1; e2++)
221               {
222
223                 if (e2 > 0)
224                   {
225                     ATOMIC tmp_real = dw_real * w_real - dw_imag * w_imag;
226                     ATOMIC tmp_imag = dw_real * w_imag + dw_imag * w_real;
227                     w_real = tmp_real;
228                     w_imag = tmp_imag;
229                   }
230
231
232                 if (e2 == factor - e2 - 1)
233                   {
234                     const size_t from0 = factor * k1 * q + q + 2 * e2 * q - 1;
235                     z_real = VECTOR(in,istride,from0);
236                     z_imag = 0.0;
237                     sum_real += w_real * z_real - w_imag * z_imag;
238                   }
239                 else
240                   {
241                     const size_t from0 = factor * k1 * q + q + 2 * e2 * q - 1;
242                     z_real = VECTOR(in,istride,from0);
243                     z_imag = VECTOR(in,istride,from0 + 1);
244                     sum_real += 2 * (w_real * z_real - w_imag * z_imag);
245                   }
246
247               }
248
249             {
250               const size_t to0 = k1 * q + q + e1 * m - 1;
251               VECTOR(out,ostride,to0) = sum_real;
252             }
253           }
254       }
255   }
256   return;
257 }