ooura_fft 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,3528 @@
1
+ /*
2
+ Fast Fourier/Cosine/Sine Transform
3
+ dimension :one
4
+ data length :power of 2
5
+ decimation :frequency
6
+ radix :split-radix
7
+ data :inplace
8
+ table :use
9
+ functions
10
+ cdft: Complex Discrete Fourier Transform
11
+ rdft: Real Discrete Fourier Transform
12
+ ddct: Discrete Cosine Transform
13
+ ddst: Discrete Sine Transform
14
+ dfct: Cosine Transform of RDFT (Real Symmetric DFT)
15
+ dfst: Sine Transform of RDFT (Real Anti-symmetric DFT)
16
+ function prototypes
17
+ void cdft(int, int, double *, int *, double *);
18
+ void rdft(int, int, double *, int *, double *);
19
+ void ddct(int, int, double *, int *, double *);
20
+ void ddst(int, int, double *, int *, double *);
21
+ void dfct(int, double *, double *, int *, double *);
22
+ void dfst(int, double *, double *, int *, double *);
23
+ macro definitions
24
+ USE_CDFT_PTHREADS : default=not defined
25
+ CDFT_THREADS_BEGIN_N : must be >= 512, default=8192
26
+ CDFT_4THREADS_BEGIN_N : must be >= 512, default=65536
27
+ USE_CDFT_WINTHREADS : default=not defined
28
+ CDFT_THREADS_BEGIN_N : must be >= 512, default=32768
29
+ CDFT_4THREADS_BEGIN_N : must be >= 512, default=524288
30
+
31
+
32
+ -------- Complex DFT (Discrete Fourier Transform) --------
33
+ [definition]
34
+ <case1>
35
+ X[k] = sum_j=0^n-1 x[j]*exp(2*pi*i*j*k/n), 0<=k<n
36
+ <case2>
37
+ X[k] = sum_j=0^n-1 x[j]*exp(-2*pi*i*j*k/n), 0<=k<n
38
+ (notes: sum_j=0^n-1 is a summation from j=0 to n-1)
39
+ [usage]
40
+ <case1>
41
+ ip[0] = 0; // first time only
42
+ cdft(2*n, 1, a, ip, w);
43
+ <case2>
44
+ ip[0] = 0; // first time only
45
+ cdft(2*n, -1, a, ip, w);
46
+ [parameters]
47
+ 2*n :data length (int)
48
+ n >= 1, n = power of 2
49
+ a[0...2*n-1] :input/output data (double *)
50
+ input data
51
+ a[2*j] = Re(x[j]),
52
+ a[2*j+1] = Im(x[j]), 0<=j<n
53
+ output data
54
+ a[2*k] = Re(X[k]),
55
+ a[2*k+1] = Im(X[k]), 0<=k<n
56
+ ip[0...*] :work area for bit reversal (int *)
57
+ length of ip >= 2+sqrt(n)
58
+ strictly,
59
+ length of ip >=
60
+ 2+(1<<(int)(log(n+0.5)/log(2))/2).
61
+ ip[0],ip[1] are pointers of the cos/sin table.
62
+ w[0...n/2-1] :cos/sin table (double *)
63
+ w[],ip[] are initialized if ip[0] == 0.
64
+ [remark]
65
+ Inverse of
66
+ cdft(2*n, -1, a, ip, w);
67
+ is
68
+ cdft(2*n, 1, a, ip, w);
69
+ for (j = 0; j <= 2 * n - 1; j++) {
70
+ a[j] *= 1.0 / n;
71
+ }
72
+ .
73
+
74
+
75
+ -------- Real DFT / Inverse of Real DFT --------
76
+ [definition]
77
+ <case1> RDFT
78
+ R[k] = sum_j=0^n-1 a[j]*cos(2*pi*j*k/n), 0<=k<=n/2
79
+ I[k] = sum_j=0^n-1 a[j]*sin(2*pi*j*k/n), 0<k<n/2
80
+ <case2> IRDFT (excluding scale)
81
+ a[k] = (R[0] + R[n/2]*cos(pi*k))/2 +
82
+ sum_j=1^n/2-1 R[j]*cos(2*pi*j*k/n) +
83
+ sum_j=1^n/2-1 I[j]*sin(2*pi*j*k/n), 0<=k<n
84
+ [usage]
85
+ <case1>
86
+ ip[0] = 0; // first time only
87
+ rdft(n, 1, a, ip, w);
88
+ <case2>
89
+ ip[0] = 0; // first time only
90
+ rdft(n, -1, a, ip, w);
91
+ [parameters]
92
+ n :data length (int)
93
+ n >= 2, n = power of 2
94
+ a[0...n-1] :input/output data (double *)
95
+ <case1>
96
+ output data
97
+ a[2*k] = R[k], 0<=k<n/2
98
+ a[2*k+1] = I[k], 0<k<n/2
99
+ a[1] = R[n/2]
100
+ <case2>
101
+ input data
102
+ a[2*j] = R[j], 0<=j<n/2
103
+ a[2*j+1] = I[j], 0<j<n/2
104
+ a[1] = R[n/2]
105
+ ip[0...*] :work area for bit reversal (int *)
106
+ length of ip >= 2+sqrt(n/2)
107
+ strictly,
108
+ length of ip >=
109
+ 2+(1<<(int)(log(n/2+0.5)/log(2))/2).
110
+ ip[0],ip[1] are pointers of the cos/sin table.
111
+ w[0...n/2-1] :cos/sin table (double *)
112
+ w[],ip[] are initialized if ip[0] == 0.
113
+ [remark]
114
+ Inverse of
115
+ rdft(n, 1, a, ip, w);
116
+ is
117
+ rdft(n, -1, a, ip, w);
118
+ for (j = 0; j <= n - 1; j++) {
119
+ a[j] *= 2.0 / n;
120
+ }
121
+ .
122
+
123
+
124
+ -------- DCT (Discrete Cosine Transform) / Inverse of DCT --------
125
+ [definition]
126
+ <case1> IDCT (excluding scale)
127
+ C[k] = sum_j=0^n-1 a[j]*cos(pi*j*(k+1/2)/n), 0<=k<n
128
+ <case2> DCT
129
+ C[k] = sum_j=0^n-1 a[j]*cos(pi*(j+1/2)*k/n), 0<=k<n
130
+ [usage]
131
+ <case1>
132
+ ip[0] = 0; // first time only
133
+ ddct(n, 1, a, ip, w);
134
+ <case2>
135
+ ip[0] = 0; // first time only
136
+ ddct(n, -1, a, ip, w);
137
+ [parameters]
138
+ n :data length (int)
139
+ n >= 2, n = power of 2
140
+ a[0...n-1] :input/output data (double *)
141
+ output data
142
+ a[k] = C[k], 0<=k<n
143
+ ip[0...*] :work area for bit reversal (int *)
144
+ length of ip >= 2+sqrt(n/2)
145
+ strictly,
146
+ length of ip >=
147
+ 2+(1<<(int)(log(n/2+0.5)/log(2))/2).
148
+ ip[0],ip[1] are pointers of the cos/sin table.
149
+ w[0...n*5/4-1] :cos/sin table (double *)
150
+ w[],ip[] are initialized if ip[0] == 0.
151
+ [remark]
152
+ Inverse of
153
+ ddct(n, -1, a, ip, w);
154
+ is
155
+ a[0] *= 0.5;
156
+ ddct(n, 1, a, ip, w);
157
+ for (j = 0; j <= n - 1; j++) {
158
+ a[j] *= 2.0 / n;
159
+ }
160
+ .
161
+
162
+
163
+ -------- DST (Discrete Sine Transform) / Inverse of DST --------
164
+ [definition]
165
+ <case1> IDST (excluding scale)
166
+ S[k] = sum_j=1^n A[j]*sin(pi*j*(k+1/2)/n), 0<=k<n
167
+ <case2> DST
168
+ S[k] = sum_j=0^n-1 a[j]*sin(pi*(j+1/2)*k/n), 0<k<=n
169
+ [usage]
170
+ <case1>
171
+ ip[0] = 0; // first time only
172
+ ddst(n, 1, a, ip, w);
173
+ <case2>
174
+ ip[0] = 0; // first time only
175
+ ddst(n, -1, a, ip, w);
176
+ [parameters]
177
+ n :data length (int)
178
+ n >= 2, n = power of 2
179
+ a[0...n-1] :input/output data (double *)
180
+ <case1>
181
+ input data
182
+ a[j] = A[j], 0<j<n
183
+ a[0] = A[n]
184
+ output data
185
+ a[k] = S[k], 0<=k<n
186
+ <case2>
187
+ output data
188
+ a[k] = S[k], 0<k<n
189
+ a[0] = S[n]
190
+ ip[0...*] :work area for bit reversal (int *)
191
+ length of ip >= 2+sqrt(n/2)
192
+ strictly,
193
+ length of ip >=
194
+ 2+(1<<(int)(log(n/2+0.5)/log(2))/2).
195
+ ip[0],ip[1] are pointers of the cos/sin table.
196
+ w[0...n*5/4-1] :cos/sin table (double *)
197
+ w[],ip[] are initialized if ip[0] == 0.
198
+ [remark]
199
+ Inverse of
200
+ ddst(n, -1, a, ip, w);
201
+ is
202
+ a[0] *= 0.5;
203
+ ddst(n, 1, a, ip, w);
204
+ for (j = 0; j <= n - 1; j++) {
205
+ a[j] *= 2.0 / n;
206
+ }
207
+ .
208
+
209
+
210
+ -------- Cosine Transform of RDFT (Real Symmetric DFT) --------
211
+ [definition]
212
+ C[k] = sum_j=0^n a[j]*cos(pi*j*k/n), 0<=k<=n
213
+ [usage]
214
+ ip[0] = 0; // first time only
215
+ dfct(n, a, t, ip, w);
216
+ [parameters]
217
+ n :data length - 1 (int)
218
+ n >= 2, n = power of 2
219
+ a[0...n] :input/output data (double *)
220
+ output data
221
+ a[k] = C[k], 0<=k<=n
222
+ t[0...n/2] :work area (double *)
223
+ ip[0...*] :work area for bit reversal (int *)
224
+ length of ip >= 2+sqrt(n/4)
225
+ strictly,
226
+ length of ip >=
227
+ 2+(1<<(int)(log(n/4+0.5)/log(2))/2).
228
+ ip[0],ip[1] are pointers of the cos/sin table.
229
+ w[0...n*5/8-1] :cos/sin table (double *)
230
+ w[],ip[] are initialized if ip[0] == 0.
231
+ [remark]
232
+ Inverse of
233
+ a[0] *= 0.5;
234
+ a[n] *= 0.5;
235
+ dfct(n, a, t, ip, w);
236
+ is
237
+ a[0] *= 0.5;
238
+ a[n] *= 0.5;
239
+ dfct(n, a, t, ip, w);
240
+ for (j = 0; j <= n; j++) {
241
+ a[j] *= 2.0 / n;
242
+ }
243
+ .
244
+
245
+
246
+ -------- Sine Transform of RDFT (Real Anti-symmetric DFT) --------
247
+ [definition]
248
+ S[k] = sum_j=1^n-1 a[j]*sin(pi*j*k/n), 0<k<n
249
+ [usage]
250
+ ip[0] = 0; // first time only
251
+ dfst(n, a, t, ip, w);
252
+ [parameters]
253
+ n :data length + 1 (int)
254
+ n >= 2, n = power of 2
255
+ a[0...n-1] :input/output data (double *)
256
+ output data
257
+ a[k] = S[k], 0<k<n
258
+ (a[0] is used for work area)
259
+ t[0...n/2-1] :work area (double *)
260
+ ip[0...*] :work area for bit reversal (int *)
261
+ length of ip >= 2+sqrt(n/4)
262
+ strictly,
263
+ length of ip >=
264
+ 2+(1<<(int)(log(n/4+0.5)/log(2))/2).
265
+ ip[0],ip[1] are pointers of the cos/sin table.
266
+ w[0...n*5/8-1] :cos/sin table (double *)
267
+ w[],ip[] are initialized if ip[0] == 0.
268
+ [remark]
269
+ Inverse of
270
+ dfst(n, a, t, ip, w);
271
+ is
272
+ dfst(n, a, t, ip, w);
273
+ for (j = 1; j <= n - 1; j++) {
274
+ a[j] *= 2.0 / n;
275
+ }
276
+ .
277
+
278
+
279
+ Appendix :
280
+ The cos/sin table is recalculated when the larger table required.
281
+ w[] and ip[] are compatible with all routines.
282
+ */
283
+
284
+ #include <ruby.h>
285
+ #include "fftsg.h"
286
+
287
+ void
288
+ cdft(int n, int isgn, double *a, int *ip, double *w)
289
+ {
290
+ void makewt(int nw, int *ip, double *w);
291
+ void cftfsub(int n, double *a, int *ip, int nw, double *w);
292
+ void cftbsub(int n, double *a, int *ip, int nw, double *w);
293
+ int nw;
294
+
295
+ nw = ip[0];
296
+ if (n > (nw << 2))
297
+ {
298
+ nw = n >> 2;
299
+ makewt(nw, ip, w);
300
+ }
301
+ if (isgn >= 0)
302
+ {
303
+ cftfsub(n, a, ip, nw, w);
304
+ }
305
+ else
306
+ {
307
+ cftbsub(n, a, ip, nw, w);
308
+ }
309
+ }
310
+
311
+
312
+ void
313
+ rdft(int n, int isgn, double *a, int *ip, double *w)
314
+ {
315
+ void makewt(int nw, int *ip, double *w);
316
+ void makect(int nc, int *ip, double *c);
317
+ void cftfsub(int n, double *a, int *ip, int nw, double *w);
318
+ void cftbsub(int n, double *a, int *ip, int nw, double *w);
319
+ void rftfsub(int n, double *a, int nc, double *c);
320
+ void rftbsub(int n, double *a, int nc, double *c);
321
+ int nw, nc;
322
+ double xi;
323
+
324
+ nw = ip[0];
325
+ if (n > (nw << 2))
326
+ {
327
+ nw = n >> 2;
328
+ makewt(nw, ip, w);
329
+ }
330
+ nc = ip[1];
331
+ if (n > (nc << 2))
332
+ {
333
+ nc = n >> 2;
334
+ makect(nc, ip, w + nw);
335
+ }
336
+ if (isgn >= 0)
337
+ {
338
+ if (n > 4)
339
+ {
340
+ cftfsub(n, a, ip, nw, w);
341
+ rftfsub(n, a, nc, w + nw);
342
+ }
343
+ else if (n == 4)
344
+ {
345
+ cftfsub(n, a, ip, nw, w);
346
+ }
347
+ xi = a[0] - a[1];
348
+ a[0] += a[1];
349
+ a[1] = xi;
350
+ }
351
+ else
352
+ {
353
+ a[1] = 0.5 * (a[0] - a[1]);
354
+ a[0] -= a[1];
355
+ if (n > 4)
356
+ {
357
+ rftbsub(n, a, nc, w + nw);
358
+ cftbsub(n, a, ip, nw, w);
359
+ }
360
+ else if (n == 4)
361
+ {
362
+ cftbsub(n, a, ip, nw, w);
363
+ }
364
+ }
365
+ }
366
+
367
+
368
+ void
369
+ ddct(int n, int isgn, double *a, int *ip, double *w)
370
+ {
371
+ void makewt(int nw, int *ip, double *w);
372
+ void makect(int nc, int *ip, double *c);
373
+ void cftfsub(int n, double *a, int *ip, int nw, double *w);
374
+ void cftbsub(int n, double *a, int *ip, int nw, double *w);
375
+ void rftfsub(int n, double *a, int nc, double *c);
376
+ void rftbsub(int n, double *a, int nc, double *c);
377
+ void dctsub(int n, double *a, int nc, double *c);
378
+ int j, nw, nc;
379
+ double xr;
380
+
381
+ nw = ip[0];
382
+ if (n > (nw << 2))
383
+ {
384
+ nw = n >> 2;
385
+ makewt(nw, ip, w);
386
+ }
387
+ nc = ip[1];
388
+ if (n > nc)
389
+ {
390
+ nc = n;
391
+ makect(nc, ip, w + nw);
392
+ }
393
+ if (isgn < 0)
394
+ {
395
+ xr = a[n - 1];
396
+ for (j = n - 2; j >= 2; j -= 2)
397
+ {
398
+ a[j + 1] = a[j] - a[j - 1];
399
+ a[j] += a[j - 1];
400
+ }
401
+ a[1] = a[0] - xr;
402
+ a[0] += xr;
403
+ if (n > 4)
404
+ {
405
+ rftbsub(n, a, nc, w + nw);
406
+ cftbsub(n, a, ip, nw, w);
407
+ }
408
+ else if (n == 4)
409
+ {
410
+ cftbsub(n, a, ip, nw, w);
411
+ }
412
+ }
413
+ dctsub(n, a, nc, w + nw);
414
+ if (isgn >= 0)
415
+ {
416
+ if (n > 4)
417
+ {
418
+ cftfsub(n, a, ip, nw, w);
419
+ rftfsub(n, a, nc, w + nw);
420
+ }
421
+ else if (n == 4)
422
+ {
423
+ cftfsub(n, a, ip, nw, w);
424
+ }
425
+ xr = a[0] - a[1];
426
+ a[0] += a[1];
427
+ for (j = 2; j < n; j += 2)
428
+ {
429
+ a[j - 1] = a[j] - a[j + 1];
430
+ a[j] += a[j + 1];
431
+ }
432
+ a[n - 1] = xr;
433
+ }
434
+ }
435
+
436
+
437
+ void
438
+ ddst(int n, int isgn, double *a, int *ip, double *w)
439
+ {
440
+ void makewt(int nw, int *ip, double *w);
441
+ void makect(int nc, int *ip, double *c);
442
+ void cftfsub(int n, double *a, int *ip, int nw, double *w);
443
+ void cftbsub(int n, double *a, int *ip, int nw, double *w);
444
+ void rftfsub(int n, double *a, int nc, double *c);
445
+ void rftbsub(int n, double *a, int nc, double *c);
446
+ void dstsub(int n, double *a, int nc, double *c);
447
+ int j, nw, nc;
448
+ double xr;
449
+
450
+ nw = ip[0];
451
+ if (n > (nw << 2))
452
+ {
453
+ nw = n >> 2;
454
+ makewt(nw, ip, w);
455
+ }
456
+ nc = ip[1];
457
+ if (n > nc)
458
+ {
459
+ nc = n;
460
+ makect(nc, ip, w + nw);
461
+ }
462
+ if (isgn < 0)
463
+ {
464
+ xr = a[n - 1];
465
+ for (j = n - 2; j >= 2; j -= 2)
466
+ {
467
+ a[j + 1] = -a[j] - a[j - 1];
468
+ a[j] -= a[j - 1];
469
+ }
470
+ a[1] = a[0] + xr;
471
+ a[0] -= xr;
472
+ if (n > 4)
473
+ {
474
+ rftbsub(n, a, nc, w + nw);
475
+ cftbsub(n, a, ip, nw, w);
476
+ }
477
+ else if (n == 4)
478
+ {
479
+ cftbsub(n, a, ip, nw, w);
480
+ }
481
+ }
482
+ dstsub(n, a, nc, w + nw);
483
+ if (isgn >= 0)
484
+ {
485
+ if (n > 4)
486
+ {
487
+ cftfsub(n, a, ip, nw, w);
488
+ rftfsub(n, a, nc, w + nw);
489
+ }
490
+ else if (n == 4)
491
+ {
492
+ cftfsub(n, a, ip, nw, w);
493
+ }
494
+ xr = a[0] - a[1];
495
+ a[0] += a[1];
496
+ for (j = 2; j < n; j += 2)
497
+ {
498
+ a[j - 1] = -a[j] - a[j + 1];
499
+ a[j] -= a[j + 1];
500
+ }
501
+ a[n - 1] = -xr;
502
+ }
503
+ }
504
+
505
+
506
+ void
507
+ dfct(int n, double *a, double *t, int *ip, double *w)
508
+ {
509
+ void makewt(int nw, int *ip, double *w);
510
+ void makect(int nc, int *ip, double *c);
511
+ void cftfsub(int n, double *a, int *ip, int nw, double *w);
512
+ void rftfsub(int n, double *a, int nc, double *c);
513
+ void dctsub(int n, double *a, int nc, double *c);
514
+ int j, k, l, m, mh, nw, nc;
515
+ double xr, xi, yr, yi;
516
+
517
+ nw = ip[0];
518
+ if (n > (nw << 3))
519
+ {
520
+ nw = n >> 3;
521
+ makewt(nw, ip, w);
522
+ }
523
+ nc = ip[1];
524
+ if (n > (nc << 1))
525
+ {
526
+ nc = n >> 1;
527
+ makect(nc, ip, w + nw);
528
+ }
529
+ m = n >> 1;
530
+ yi = a[m];
531
+ xi = a[0] + a[n];
532
+ a[0] -= a[n];
533
+ t[0] = xi - yi;
534
+ t[m] = xi + yi;
535
+ if (n > 2)
536
+ {
537
+ mh = m >> 1;
538
+ for (j = 1; j < mh; j++)
539
+ {
540
+ k = m - j;
541
+ xr = a[j] - a[n - j];
542
+ xi = a[j] + a[n - j];
543
+ yr = a[k] - a[n - k];
544
+ yi = a[k] + a[n - k];
545
+ a[j] = xr;
546
+ a[k] = yr;
547
+ t[j] = xi - yi;
548
+ t[k] = xi + yi;
549
+ }
550
+ t[mh] = a[mh] + a[n - mh];
551
+ a[mh] -= a[n - mh];
552
+ dctsub(m, a, nc, w + nw);
553
+ if (m > 4)
554
+ {
555
+ cftfsub(m, a, ip, nw, w);
556
+ rftfsub(m, a, nc, w + nw);
557
+ }
558
+ else if (m == 4)
559
+ {
560
+ cftfsub(m, a, ip, nw, w);
561
+ }
562
+ a[n - 1] = a[0] - a[1];
563
+ a[1] = a[0] + a[1];
564
+ for (j = m - 2; j >= 2; j -= 2)
565
+ {
566
+ a[2 * j + 1] = a[j] + a[j + 1];
567
+ a[2 * j - 1] = a[j] - a[j + 1];
568
+ }
569
+ l = 2;
570
+ m = mh;
571
+ while (m >= 2)
572
+ {
573
+ dctsub(m, t, nc, w + nw);
574
+ if (m > 4)
575
+ {
576
+ cftfsub(m, t, ip, nw, w);
577
+ rftfsub(m, t, nc, w + nw);
578
+ }
579
+ else if (m == 4)
580
+ {
581
+ cftfsub(m, t, ip, nw, w);
582
+ }
583
+ a[n - l] = t[0] - t[1];
584
+ a[l] = t[0] + t[1];
585
+ k = 0;
586
+ for (j = 2; j < m; j += 2)
587
+ {
588
+ k += l << 2;
589
+ a[k - l] = t[j] - t[j + 1];
590
+ a[k + l] = t[j] + t[j + 1];
591
+ }
592
+ l <<= 1;
593
+ mh = m >> 1;
594
+ for (j = 0; j < mh; j++)
595
+ {
596
+ k = m - j;
597
+ t[j] = t[m + k] - t[m + j];
598
+ t[k] = t[m + k] + t[m + j];
599
+ }
600
+ t[mh] = t[m + mh];
601
+ m = mh;
602
+ }
603
+ a[l] = t[0];
604
+ a[n] = t[2] - t[1];
605
+ a[0] = t[2] + t[1];
606
+ }
607
+ else
608
+ {
609
+ a[1] = a[0];
610
+ a[2] = t[0];
611
+ a[0] = t[1];
612
+ }
613
+ }
614
+
615
+
616
+ void
617
+ dfst(int n, double *a, double *t, int *ip, double *w)
618
+ {
619
+ void makewt(int nw, int *ip, double *w);
620
+ void makect(int nc, int *ip, double *c);
621
+ void cftfsub(int n, double *a, int *ip, int nw, double *w);
622
+ void rftfsub(int n, double *a, int nc, double *c);
623
+ void dstsub(int n, double *a, int nc, double *c);
624
+ int j, k, l, m, mh, nw, nc;
625
+ double xr, xi, yr, yi;
626
+
627
+ nw = ip[0];
628
+ if (n > (nw << 3))
629
+ {
630
+ nw = n >> 3;
631
+ makewt(nw, ip, w);
632
+ }
633
+ nc = ip[1];
634
+ if (n > (nc << 1))
635
+ {
636
+ nc = n >> 1;
637
+ makect(nc, ip, w + nw);
638
+ }
639
+ if (n > 2)
640
+ {
641
+ m = n >> 1;
642
+ mh = m >> 1;
643
+ for (j = 1; j < mh; j++)
644
+ {
645
+ k = m - j;
646
+ xr = a[j] + a[n - j];
647
+ xi = a[j] - a[n - j];
648
+ yr = a[k] + a[n - k];
649
+ yi = a[k] - a[n - k];
650
+ a[j] = xr;
651
+ a[k] = yr;
652
+ t[j] = xi + yi;
653
+ t[k] = xi - yi;
654
+ }
655
+ t[0] = a[mh] - a[n - mh];
656
+ a[mh] += a[n - mh];
657
+ a[0] = a[m];
658
+ dstsub(m, a, nc, w + nw);
659
+ if (m > 4)
660
+ {
661
+ cftfsub(m, a, ip, nw, w);
662
+ rftfsub(m, a, nc, w + nw);
663
+ }
664
+ else if (m == 4)
665
+ {
666
+ cftfsub(m, a, ip, nw, w);
667
+ }
668
+ a[n - 1] = a[1] - a[0];
669
+ a[1] = a[0] + a[1];
670
+ for (j = m - 2; j >= 2; j -= 2)
671
+ {
672
+ a[2 * j + 1] = a[j] - a[j + 1];
673
+ a[2 * j - 1] = -a[j] - a[j + 1];
674
+ }
675
+ l = 2;
676
+ m = mh;
677
+ while (m >= 2)
678
+ {
679
+ dstsub(m, t, nc, w + nw);
680
+ if (m > 4)
681
+ {
682
+ cftfsub(m, t, ip, nw, w);
683
+ rftfsub(m, t, nc, w + nw);
684
+ }
685
+ else if (m == 4)
686
+ {
687
+ cftfsub(m, t, ip, nw, w);
688
+ }
689
+ a[n - l] = t[1] - t[0];
690
+ a[l] = t[0] + t[1];
691
+ k = 0;
692
+ for (j = 2; j < m; j += 2)
693
+ {
694
+ k += l << 2;
695
+ a[k - l] = -t[j] - t[j + 1];
696
+ a[k + l] = t[j] - t[j + 1];
697
+ }
698
+ l <<= 1;
699
+ mh = m >> 1;
700
+ for (j = 1; j < mh; j++)
701
+ {
702
+ k = m - j;
703
+ t[j] = t[m + k] + t[m + j];
704
+ t[k] = t[m + k] - t[m + j];
705
+ }
706
+ t[0] = t[m + mh];
707
+ m = mh;
708
+ }
709
+ a[l] = t[0];
710
+ }
711
+ a[0] = 0;
712
+ }
713
+
714
+
715
+ /* -------- initializing routines -------- */
716
+
717
+
718
+ // #include <math.h>
719
+
720
+ void
721
+ makewt(int nw, int *ip, double *w)
722
+ {
723
+ void makeipt(int nw, int *ip);
724
+ int j, nwh, nw0, nw1;
725
+ double delta, wn4r, wk1r, wk1i, wk3r, wk3i;
726
+
727
+ ip[0] = nw;
728
+ ip[1] = 1;
729
+ if (nw > 2)
730
+ {
731
+ nwh = nw >> 1;
732
+ delta = atan(1.0) / nwh;
733
+ wn4r = cos(delta * nwh);
734
+ w[0] = 1;
735
+ w[1] = wn4r;
736
+ if (nwh == 4)
737
+ {
738
+ w[2] = cos(delta * 2);
739
+ w[3] = sin(delta * 2);
740
+ }
741
+ else if (nwh > 4)
742
+ {
743
+ makeipt(nw, ip);
744
+ w[2] = 0.5 / cos(delta * 2);
745
+ w[3] = 0.5 / cos(delta * 6);
746
+ for (j = 4; j < nwh; j += 4)
747
+ {
748
+ w[j] = cos(delta * j);
749
+ w[j + 1] = sin(delta * j);
750
+ w[j + 2] = cos(3 * delta * j);
751
+ w[j + 3] = -sin(3 * delta * j);
752
+ }
753
+ }
754
+ nw0 = 0;
755
+ while (nwh > 2)
756
+ {
757
+ nw1 = nw0 + nwh;
758
+ nwh >>= 1;
759
+ w[nw1] = 1;
760
+ w[nw1 + 1] = wn4r;
761
+ if (nwh == 4)
762
+ {
763
+ wk1r = w[nw0 + 4];
764
+ wk1i = w[nw0 + 5];
765
+ w[nw1 + 2] = wk1r;
766
+ w[nw1 + 3] = wk1i;
767
+ }
768
+ else if (nwh > 4)
769
+ {
770
+ wk1r = w[nw0 + 4];
771
+ wk3r = w[nw0 + 6];
772
+ w[nw1 + 2] = 0.5 / wk1r;
773
+ w[nw1 + 3] = 0.5 / wk3r;
774
+ for (j = 4; j < nwh; j += 4)
775
+ {
776
+ wk1r = w[nw0 + 2 * j];
777
+ wk1i = w[nw0 + 2 * j + 1];
778
+ wk3r = w[nw0 + 2 * j + 2];
779
+ wk3i = w[nw0 + 2 * j + 3];
780
+ w[nw1 + j] = wk1r;
781
+ w[nw1 + j + 1] = wk1i;
782
+ w[nw1 + j + 2] = wk3r;
783
+ w[nw1 + j + 3] = wk3i;
784
+ }
785
+ }
786
+ nw0 = nw1;
787
+ }
788
+ }
789
+ }
790
+
791
+
792
+ void
793
+ makeipt(int nw, int *ip)
794
+ {
795
+ int j, l, m, m2, p, q;
796
+
797
+ ip[2] = 0;
798
+ ip[3] = 16;
799
+ m = 2;
800
+ for (l = nw; l > 32; l >>= 2)
801
+ {
802
+ m2 = m << 1;
803
+ q = m2 << 3;
804
+ for (j = m; j < m2; j++)
805
+ {
806
+ p = ip[j] << 2;
807
+ ip[m + j] = p;
808
+ ip[m2 + j] = p + q;
809
+ }
810
+ m = m2;
811
+ }
812
+ }
813
+
814
+
815
+ void
816
+ makect(int nc, int *ip, double *c)
817
+ {
818
+ int j, nch;
819
+ double delta;
820
+
821
+ ip[1] = nc;
822
+ if (nc > 1)
823
+ {
824
+ nch = nc >> 1;
825
+ delta = atan(1.0) / nch;
826
+ c[0] = cos(delta * nch);
827
+ c[nch] = 0.5 * c[0];
828
+ for (j = 1; j < nch; j++)
829
+ {
830
+ c[j] = 0.5 * cos(delta * j);
831
+ c[nc - j] = 0.5 * sin(delta * j);
832
+ }
833
+ }
834
+ }
835
+
836
+
837
+ /* -------- child routines -------- */
838
+
839
+
840
+ #ifdef USE_CDFT_PTHREADS
841
+ # define USE_CDFT_THREADS
842
+ # ifndef CDFT_THREADS_BEGIN_N
843
+ # define CDFT_THREADS_BEGIN_N 8192
844
+ # endif
845
+ # ifndef CDFT_4THREADS_BEGIN_N
846
+ # define CDFT_4THREADS_BEGIN_N 65536
847
+ # endif
848
+ # include <pthread.h>
849
+ # include <stdio.h>
850
+ # include <stdlib.h>
851
+ # define cdft_thread_t pthread_t
852
+ # define cdft_thread_create(thp,func,argp) { \
853
+ if (pthread_create(thp, NULL, func, (void *) argp) != 0) { \
854
+ rb_raise(rb_eThreadError, "cdft thread error\n"); \
855
+ } \
856
+ }
857
+ # define cdft_thread_wait(th) { \
858
+ if (pthread_join(th, NULL) != 0) { \
859
+ rb_raise(rb_eThreadError, "cdft thread error\n"); \
860
+ } \
861
+ }
862
+ #endif /* USE_CDFT_PTHREADS */
863
+
864
+
865
+ #ifdef USE_CDFT_WINTHREADS
866
+ # define USE_CDFT_THREADS
867
+ # ifndef CDFT_THREADS_BEGIN_N
868
+ # define CDFT_THREADS_BEGIN_N 32768
869
+ # endif
870
+ # ifndef CDFT_4THREADS_BEGIN_N
871
+ # define CDFT_4THREADS_BEGIN_N 524288
872
+ # endif
873
+ # include <windows.h>
874
+ # include <stdio.h>
875
+ # include <stdlib.h>
876
+ # define cdft_thread_t HANDLE
877
+ # define cdft_thread_create(thp,func,argp) { \
878
+ DWORD thid; \
879
+ *(thp) = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) func, (LPVOID) argp, 0, &thid); \
880
+ if (*(thp) == 0) { \
881
+ rb_raise(rb_eThreadError, "cdft thread error\n"); \
882
+ } \
883
+ }
884
+ # define cdft_thread_wait(th) { \
885
+ WaitForSingleObject(th, INFINITE); \
886
+ CloseHandle(th); \
887
+ }
888
+ #endif /* USE_CDFT_WINTHREADS */
889
+
890
+
891
+ void
892
+ cftfsub(int n, double *a, int *ip, int nw, double *w)
893
+ {
894
+ void bitrv2(int n, int *ip, double *a);
895
+ void bitrv216(double *a);
896
+ void bitrv208(double *a);
897
+ void cftf1st(int n, double *a, double *w);
898
+ void cftrec4(int n, double *a, int nw, double *w);
899
+ void cftleaf(int n, int isplt, double *a, int nw, double *w);
900
+ void cftfx41(int n, double *a, int nw, double *w);
901
+ void cftf161(double *a, double *w);
902
+ void cftf081(double *a, double *w);
903
+ void cftf040(double *a);
904
+ void cftx020(double *a);
905
+ #ifdef USE_CDFT_THREADS
906
+ void cftrec4_th(int n, double *a, int nw, double *w);
907
+ #endif /* USE_CDFT_THREADS */
908
+
909
+ if (n > 8)
910
+ {
911
+ if (n > 32)
912
+ {
913
+ cftf1st(n, a, &w[nw - (n >> 2)]);
914
+ #ifdef USE_CDFT_THREADS
915
+ if (n > CDFT_THREADS_BEGIN_N)
916
+ {
917
+ cftrec4_th(n, a, nw, w);
918
+ } else
919
+ #endif /* USE_CDFT_THREADS */
920
+ if (n > 512)
921
+ {
922
+ cftrec4(n, a, nw, w);
923
+ }
924
+ else if (n > 128)
925
+ {
926
+ cftleaf(n, 1, a, nw, w);
927
+ }
928
+ else
929
+ {
930
+ cftfx41(n, a, nw, w);
931
+ }
932
+ bitrv2(n, ip, a);
933
+ }
934
+ else if (n == 32)
935
+ {
936
+ cftf161(a, &w[nw - 8]);
937
+ bitrv216(a);
938
+ }
939
+ else
940
+ {
941
+ cftf081(a, w);
942
+ bitrv208(a);
943
+ }
944
+ }
945
+ else if (n == 8)
946
+ {
947
+ cftf040(a);
948
+ }
949
+ else if (n == 4)
950
+ {
951
+ cftx020(a);
952
+ }
953
+ }
954
+
955
+
956
+ void
957
+ cftbsub(int n, double *a, int *ip, int nw, double *w)
958
+ {
959
+ void bitrv2conj(int n, int *ip, double *a);
960
+ void bitrv216neg(double *a);
961
+ void bitrv208neg(double *a);
962
+ void cftb1st(int n, double *a, double *w);
963
+ void cftrec4(int n, double *a, int nw, double *w);
964
+ void cftleaf(int n, int isplt, double *a, int nw, double *w);
965
+ void cftfx41(int n, double *a, int nw, double *w);
966
+ void cftf161(double *a, double *w);
967
+ void cftf081(double *a, double *w);
968
+ void cftb040(double *a);
969
+ void cftx020(double *a);
970
+ #ifdef USE_CDFT_THREADS
971
+ void cftrec4_th(int n, double *a, int nw, double *w);
972
+ #endif /* USE_CDFT_THREADS */
973
+
974
+ if (n > 8)
975
+ {
976
+ if (n > 32)
977
+ {
978
+ cftb1st(n, a, &w[nw - (n >> 2)]);
979
+ #ifdef USE_CDFT_THREADS
980
+ if (n > CDFT_THREADS_BEGIN_N)
981
+ {
982
+ cftrec4_th(n, a, nw, w);
983
+ }
984
+ else
985
+ #endif /* USE_CDFT_THREADS */
986
+ if (n > 512)
987
+ {
988
+ cftrec4(n, a, nw, w);
989
+ }
990
+ else if (n > 128)
991
+ {
992
+ cftleaf(n, 1, a, nw, w);
993
+ }
994
+ else
995
+ {
996
+ cftfx41(n, a, nw, w);
997
+ }
998
+ bitrv2conj(n, ip, a);
999
+ }
1000
+ else if (n == 32)
1001
+ {
1002
+ cftf161(a, &w[nw - 8]);
1003
+ bitrv216neg(a);
1004
+ }
1005
+ else
1006
+ {
1007
+ cftf081(a, w);
1008
+ bitrv208neg(a);
1009
+ }
1010
+ }
1011
+ else if (n == 8)
1012
+ {
1013
+ cftb040(a);
1014
+ }
1015
+ else if (n == 4)
1016
+ {
1017
+ cftx020(a);
1018
+ }
1019
+ }
1020
+
1021
+
1022
+ void
1023
+ bitrv2(int n, int *ip, double *a)
1024
+ {
1025
+ int j, j1, k, k1, l, m, nh, nm;
1026
+ double xr, xi, yr, yi;
1027
+
1028
+ m = 1;
1029
+ for (l = n >> 2; l > 8; l >>= 2)
1030
+ {
1031
+ m <<= 1;
1032
+ }
1033
+ nh = n >> 1;
1034
+ nm = 4 * m;
1035
+ if (l == 8)
1036
+ {
1037
+ for (k = 0; k < m; k++)
1038
+ {
1039
+ for (j = 0; j < k; j++)
1040
+ {
1041
+ j1 = 4 * j + 2 * ip[m + k];
1042
+ k1 = 4 * k + 2 * ip[m + j];
1043
+ xr = a[j1];
1044
+ xi = a[j1 + 1];
1045
+ yr = a[k1];
1046
+ yi = a[k1 + 1];
1047
+ a[j1] = yr;
1048
+ a[j1 + 1] = yi;
1049
+ a[k1] = xr;
1050
+ a[k1 + 1] = xi;
1051
+ j1 += nm;
1052
+ k1 += 2 * nm;
1053
+ xr = a[j1];
1054
+ xi = a[j1 + 1];
1055
+ yr = a[k1];
1056
+ yi = a[k1 + 1];
1057
+ a[j1] = yr;
1058
+ a[j1 + 1] = yi;
1059
+ a[k1] = xr;
1060
+ a[k1 + 1] = xi;
1061
+ j1 += nm;
1062
+ k1 -= nm;
1063
+ xr = a[j1];
1064
+ xi = a[j1 + 1];
1065
+ yr = a[k1];
1066
+ yi = a[k1 + 1];
1067
+ a[j1] = yr;
1068
+ a[j1 + 1] = yi;
1069
+ a[k1] = xr;
1070
+ a[k1 + 1] = xi;
1071
+ j1 += nm;
1072
+ k1 += 2 * nm;
1073
+ xr = a[j1];
1074
+ xi = a[j1 + 1];
1075
+ yr = a[k1];
1076
+ yi = a[k1 + 1];
1077
+ a[j1] = yr;
1078
+ a[j1 + 1] = yi;
1079
+ a[k1] = xr;
1080
+ a[k1 + 1] = xi;
1081
+ j1 += nh;
1082
+ k1 += 2;
1083
+ xr = a[j1];
1084
+ xi = a[j1 + 1];
1085
+ yr = a[k1];
1086
+ yi = a[k1 + 1];
1087
+ a[j1] = yr;
1088
+ a[j1 + 1] = yi;
1089
+ a[k1] = xr;
1090
+ a[k1 + 1] = xi;
1091
+ j1 -= nm;
1092
+ k1 -= 2 * nm;
1093
+ xr = a[j1];
1094
+ xi = a[j1 + 1];
1095
+ yr = a[k1];
1096
+ yi = a[k1 + 1];
1097
+ a[j1] = yr;
1098
+ a[j1 + 1] = yi;
1099
+ a[k1] = xr;
1100
+ a[k1 + 1] = xi;
1101
+ j1 -= nm;
1102
+ k1 += nm;
1103
+ xr = a[j1];
1104
+ xi = a[j1 + 1];
1105
+ yr = a[k1];
1106
+ yi = a[k1 + 1];
1107
+ a[j1] = yr;
1108
+ a[j1 + 1] = yi;
1109
+ a[k1] = xr;
1110
+ a[k1 + 1] = xi;
1111
+ j1 -= nm;
1112
+ k1 -= 2 * nm;
1113
+ xr = a[j1];
1114
+ xi = a[j1 + 1];
1115
+ yr = a[k1];
1116
+ yi = a[k1 + 1];
1117
+ a[j1] = yr;
1118
+ a[j1 + 1] = yi;
1119
+ a[k1] = xr;
1120
+ a[k1 + 1] = xi;
1121
+ j1 += 2;
1122
+ k1 += nh;
1123
+ xr = a[j1];
1124
+ xi = a[j1 + 1];
1125
+ yr = a[k1];
1126
+ yi = a[k1 + 1];
1127
+ a[j1] = yr;
1128
+ a[j1 + 1] = yi;
1129
+ a[k1] = xr;
1130
+ a[k1 + 1] = xi;
1131
+ j1 += nm;
1132
+ k1 += 2 * nm;
1133
+ xr = a[j1];
1134
+ xi = a[j1 + 1];
1135
+ yr = a[k1];
1136
+ yi = a[k1 + 1];
1137
+ a[j1] = yr;
1138
+ a[j1 + 1] = yi;
1139
+ a[k1] = xr;
1140
+ a[k1 + 1] = xi;
1141
+ j1 += nm;
1142
+ k1 -= nm;
1143
+ xr = a[j1];
1144
+ xi = a[j1 + 1];
1145
+ yr = a[k1];
1146
+ yi = a[k1 + 1];
1147
+ a[j1] = yr;
1148
+ a[j1 + 1] = yi;
1149
+ a[k1] = xr;
1150
+ a[k1 + 1] = xi;
1151
+ j1 += nm;
1152
+ k1 += 2 * nm;
1153
+ xr = a[j1];
1154
+ xi = a[j1 + 1];
1155
+ yr = a[k1];
1156
+ yi = a[k1 + 1];
1157
+ a[j1] = yr;
1158
+ a[j1 + 1] = yi;
1159
+ a[k1] = xr;
1160
+ a[k1 + 1] = xi;
1161
+ j1 -= nh;
1162
+ k1 -= 2;
1163
+ xr = a[j1];
1164
+ xi = a[j1 + 1];
1165
+ yr = a[k1];
1166
+ yi = a[k1 + 1];
1167
+ a[j1] = yr;
1168
+ a[j1 + 1] = yi;
1169
+ a[k1] = xr;
1170
+ a[k1 + 1] = xi;
1171
+ j1 -= nm;
1172
+ k1 -= 2 * nm;
1173
+ xr = a[j1];
1174
+ xi = a[j1 + 1];
1175
+ yr = a[k1];
1176
+ yi = a[k1 + 1];
1177
+ a[j1] = yr;
1178
+ a[j1 + 1] = yi;
1179
+ a[k1] = xr;
1180
+ a[k1 + 1] = xi;
1181
+ j1 -= nm;
1182
+ k1 += nm;
1183
+ xr = a[j1];
1184
+ xi = a[j1 + 1];
1185
+ yr = a[k1];
1186
+ yi = a[k1 + 1];
1187
+ a[j1] = yr;
1188
+ a[j1 + 1] = yi;
1189
+ a[k1] = xr;
1190
+ a[k1 + 1] = xi;
1191
+ j1 -= nm;
1192
+ k1 -= 2 * nm;
1193
+ xr = a[j1];
1194
+ xi = a[j1 + 1];
1195
+ yr = a[k1];
1196
+ yi = a[k1 + 1];
1197
+ a[j1] = yr;
1198
+ a[j1 + 1] = yi;
1199
+ a[k1] = xr;
1200
+ a[k1 + 1] = xi;
1201
+ }
1202
+ k1 = 4 * k + 2 * ip[m + k];
1203
+ j1 = k1 + 2;
1204
+ k1 += nh;
1205
+ xr = a[j1];
1206
+ xi = a[j1 + 1];
1207
+ yr = a[k1];
1208
+ yi = a[k1 + 1];
1209
+ a[j1] = yr;
1210
+ a[j1 + 1] = yi;
1211
+ a[k1] = xr;
1212
+ a[k1 + 1] = xi;
1213
+ j1 += nm;
1214
+ k1 += 2 * nm;
1215
+ xr = a[j1];
1216
+ xi = a[j1 + 1];
1217
+ yr = a[k1];
1218
+ yi = a[k1 + 1];
1219
+ a[j1] = yr;
1220
+ a[j1 + 1] = yi;
1221
+ a[k1] = xr;
1222
+ a[k1 + 1] = xi;
1223
+ j1 += nm;
1224
+ k1 -= nm;
1225
+ xr = a[j1];
1226
+ xi = a[j1 + 1];
1227
+ yr = a[k1];
1228
+ yi = a[k1 + 1];
1229
+ a[j1] = yr;
1230
+ a[j1 + 1] = yi;
1231
+ a[k1] = xr;
1232
+ a[k1 + 1] = xi;
1233
+ j1 -= 2;
1234
+ k1 -= nh;
1235
+ xr = a[j1];
1236
+ xi = a[j1 + 1];
1237
+ yr = a[k1];
1238
+ yi = a[k1 + 1];
1239
+ a[j1] = yr;
1240
+ a[j1 + 1] = yi;
1241
+ a[k1] = xr;
1242
+ a[k1 + 1] = xi;
1243
+ j1 += nh + 2;
1244
+ k1 += nh + 2;
1245
+ xr = a[j1];
1246
+ xi = a[j1 + 1];
1247
+ yr = a[k1];
1248
+ yi = a[k1 + 1];
1249
+ a[j1] = yr;
1250
+ a[j1 + 1] = yi;
1251
+ a[k1] = xr;
1252
+ a[k1 + 1] = xi;
1253
+ j1 -= nh - nm;
1254
+ k1 += 2 * nm - 2;
1255
+ xr = a[j1];
1256
+ xi = a[j1 + 1];
1257
+ yr = a[k1];
1258
+ yi = a[k1 + 1];
1259
+ a[j1] = yr;
1260
+ a[j1 + 1] = yi;
1261
+ a[k1] = xr;
1262
+ a[k1 + 1] = xi;
1263
+ }
1264
+ }
1265
+ else
1266
+ {
1267
+ for (k = 0; k < m; k++)
1268
+ {
1269
+ for (j = 0; j < k; j++)
1270
+ {
1271
+ j1 = 4 * j + ip[m + k];
1272
+ k1 = 4 * k + ip[m + j];
1273
+ xr = a[j1];
1274
+ xi = a[j1 + 1];
1275
+ yr = a[k1];
1276
+ yi = a[k1 + 1];
1277
+ a[j1] = yr;
1278
+ a[j1 + 1] = yi;
1279
+ a[k1] = xr;
1280
+ a[k1 + 1] = xi;
1281
+ j1 += nm;
1282
+ k1 += nm;
1283
+ xr = a[j1];
1284
+ xi = a[j1 + 1];
1285
+ yr = a[k1];
1286
+ yi = a[k1 + 1];
1287
+ a[j1] = yr;
1288
+ a[j1 + 1] = yi;
1289
+ a[k1] = xr;
1290
+ a[k1 + 1] = xi;
1291
+ j1 += nh;
1292
+ k1 += 2;
1293
+ xr = a[j1];
1294
+ xi = a[j1 + 1];
1295
+ yr = a[k1];
1296
+ yi = a[k1 + 1];
1297
+ a[j1] = yr;
1298
+ a[j1 + 1] = yi;
1299
+ a[k1] = xr;
1300
+ a[k1 + 1] = xi;
1301
+ j1 -= nm;
1302
+ k1 -= nm;
1303
+ xr = a[j1];
1304
+ xi = a[j1 + 1];
1305
+ yr = a[k1];
1306
+ yi = a[k1 + 1];
1307
+ a[j1] = yr;
1308
+ a[j1 + 1] = yi;
1309
+ a[k1] = xr;
1310
+ a[k1 + 1] = xi;
1311
+ j1 += 2;
1312
+ k1 += nh;
1313
+ xr = a[j1];
1314
+ xi = a[j1 + 1];
1315
+ yr = a[k1];
1316
+ yi = a[k1 + 1];
1317
+ a[j1] = yr;
1318
+ a[j1 + 1] = yi;
1319
+ a[k1] = xr;
1320
+ a[k1 + 1] = xi;
1321
+ j1 += nm;
1322
+ k1 += nm;
1323
+ xr = a[j1];
1324
+ xi = a[j1 + 1];
1325
+ yr = a[k1];
1326
+ yi = a[k1 + 1];
1327
+ a[j1] = yr;
1328
+ a[j1 + 1] = yi;
1329
+ a[k1] = xr;
1330
+ a[k1 + 1] = xi;
1331
+ j1 -= nh;
1332
+ k1 -= 2;
1333
+ xr = a[j1];
1334
+ xi = a[j1 + 1];
1335
+ yr = a[k1];
1336
+ yi = a[k1 + 1];
1337
+ a[j1] = yr;
1338
+ a[j1 + 1] = yi;
1339
+ a[k1] = xr;
1340
+ a[k1 + 1] = xi;
1341
+ j1 -= nm;
1342
+ k1 -= nm;
1343
+ xr = a[j1];
1344
+ xi = a[j1 + 1];
1345
+ yr = a[k1];
1346
+ yi = a[k1 + 1];
1347
+ a[j1] = yr;
1348
+ a[j1 + 1] = yi;
1349
+ a[k1] = xr;
1350
+ a[k1 + 1] = xi;
1351
+ }
1352
+ k1 = 4 * k + ip[m + k];
1353
+ j1 = k1 + 2;
1354
+ k1 += nh;
1355
+ xr = a[j1];
1356
+ xi = a[j1 + 1];
1357
+ yr = a[k1];
1358
+ yi = a[k1 + 1];
1359
+ a[j1] = yr;
1360
+ a[j1 + 1] = yi;
1361
+ a[k1] = xr;
1362
+ a[k1 + 1] = xi;
1363
+ j1 += nm;
1364
+ k1 += nm;
1365
+ xr = a[j1];
1366
+ xi = a[j1 + 1];
1367
+ yr = a[k1];
1368
+ yi = a[k1 + 1];
1369
+ a[j1] = yr;
1370
+ a[j1 + 1] = yi;
1371
+ a[k1] = xr;
1372
+ a[k1 + 1] = xi;
1373
+ }
1374
+ }
1375
+ }
1376
+
1377
+
1378
+ void
1379
+ bitrv2conj(int n, int *ip, double *a)
1380
+ {
1381
+ int j, j1, k, k1, l, m, nh, nm;
1382
+ double xr, xi, yr, yi;
1383
+
1384
+ m = 1;
1385
+ for (l = n >> 2; l > 8; l >>= 2)
1386
+ {
1387
+ m <<= 1;
1388
+ }
1389
+ nh = n >> 1;
1390
+ nm = 4 * m;
1391
+ if (l == 8)
1392
+ {
1393
+ for (k = 0; k < m; k++)
1394
+ {
1395
+ for (j = 0; j < k; j++)
1396
+ {
1397
+ j1 = 4 * j + 2 * ip[m + k];
1398
+ k1 = 4 * k + 2 * ip[m + j];
1399
+ xr = a[j1];
1400
+ xi = -a[j1 + 1];
1401
+ yr = a[k1];
1402
+ yi = -a[k1 + 1];
1403
+ a[j1] = yr;
1404
+ a[j1 + 1] = yi;
1405
+ a[k1] = xr;
1406
+ a[k1 + 1] = xi;
1407
+ j1 += nm;
1408
+ k1 += 2 * nm;
1409
+ xr = a[j1];
1410
+ xi = -a[j1 + 1];
1411
+ yr = a[k1];
1412
+ yi = -a[k1 + 1];
1413
+ a[j1] = yr;
1414
+ a[j1 + 1] = yi;
1415
+ a[k1] = xr;
1416
+ a[k1 + 1] = xi;
1417
+ j1 += nm;
1418
+ k1 -= nm;
1419
+ xr = a[j1];
1420
+ xi = -a[j1 + 1];
1421
+ yr = a[k1];
1422
+ yi = -a[k1 + 1];
1423
+ a[j1] = yr;
1424
+ a[j1 + 1] = yi;
1425
+ a[k1] = xr;
1426
+ a[k1 + 1] = xi;
1427
+ j1 += nm;
1428
+ k1 += 2 * nm;
1429
+ xr = a[j1];
1430
+ xi = -a[j1 + 1];
1431
+ yr = a[k1];
1432
+ yi = -a[k1 + 1];
1433
+ a[j1] = yr;
1434
+ a[j1 + 1] = yi;
1435
+ a[k1] = xr;
1436
+ a[k1 + 1] = xi;
1437
+ j1 += nh;
1438
+ k1 += 2;
1439
+ xr = a[j1];
1440
+ xi = -a[j1 + 1];
1441
+ yr = a[k1];
1442
+ yi = -a[k1 + 1];
1443
+ a[j1] = yr;
1444
+ a[j1 + 1] = yi;
1445
+ a[k1] = xr;
1446
+ a[k1 + 1] = xi;
1447
+ j1 -= nm;
1448
+ k1 -= 2 * nm;
1449
+ xr = a[j1];
1450
+ xi = -a[j1 + 1];
1451
+ yr = a[k1];
1452
+ yi = -a[k1 + 1];
1453
+ a[j1] = yr;
1454
+ a[j1 + 1] = yi;
1455
+ a[k1] = xr;
1456
+ a[k1 + 1] = xi;
1457
+ j1 -= nm;
1458
+ k1 += nm;
1459
+ xr = a[j1];
1460
+ xi = -a[j1 + 1];
1461
+ yr = a[k1];
1462
+ yi = -a[k1 + 1];
1463
+ a[j1] = yr;
1464
+ a[j1 + 1] = yi;
1465
+ a[k1] = xr;
1466
+ a[k1 + 1] = xi;
1467
+ j1 -= nm;
1468
+ k1 -= 2 * nm;
1469
+ xr = a[j1];
1470
+ xi = -a[j1 + 1];
1471
+ yr = a[k1];
1472
+ yi = -a[k1 + 1];
1473
+ a[j1] = yr;
1474
+ a[j1 + 1] = yi;
1475
+ a[k1] = xr;
1476
+ a[k1 + 1] = xi;
1477
+ j1 += 2;
1478
+ k1 += nh;
1479
+ xr = a[j1];
1480
+ xi = -a[j1 + 1];
1481
+ yr = a[k1];
1482
+ yi = -a[k1 + 1];
1483
+ a[j1] = yr;
1484
+ a[j1 + 1] = yi;
1485
+ a[k1] = xr;
1486
+ a[k1 + 1] = xi;
1487
+ j1 += nm;
1488
+ k1 += 2 * nm;
1489
+ xr = a[j1];
1490
+ xi = -a[j1 + 1];
1491
+ yr = a[k1];
1492
+ yi = -a[k1 + 1];
1493
+ a[j1] = yr;
1494
+ a[j1 + 1] = yi;
1495
+ a[k1] = xr;
1496
+ a[k1 + 1] = xi;
1497
+ j1 += nm;
1498
+ k1 -= nm;
1499
+ xr = a[j1];
1500
+ xi = -a[j1 + 1];
1501
+ yr = a[k1];
1502
+ yi = -a[k1 + 1];
1503
+ a[j1] = yr;
1504
+ a[j1 + 1] = yi;
1505
+ a[k1] = xr;
1506
+ a[k1 + 1] = xi;
1507
+ j1 += nm;
1508
+ k1 += 2 * nm;
1509
+ xr = a[j1];
1510
+ xi = -a[j1 + 1];
1511
+ yr = a[k1];
1512
+ yi = -a[k1 + 1];
1513
+ a[j1] = yr;
1514
+ a[j1 + 1] = yi;
1515
+ a[k1] = xr;
1516
+ a[k1 + 1] = xi;
1517
+ j1 -= nh;
1518
+ k1 -= 2;
1519
+ xr = a[j1];
1520
+ xi = -a[j1 + 1];
1521
+ yr = a[k1];
1522
+ yi = -a[k1 + 1];
1523
+ a[j1] = yr;
1524
+ a[j1 + 1] = yi;
1525
+ a[k1] = xr;
1526
+ a[k1 + 1] = xi;
1527
+ j1 -= nm;
1528
+ k1 -= 2 * nm;
1529
+ xr = a[j1];
1530
+ xi = -a[j1 + 1];
1531
+ yr = a[k1];
1532
+ yi = -a[k1 + 1];
1533
+ a[j1] = yr;
1534
+ a[j1 + 1] = yi;
1535
+ a[k1] = xr;
1536
+ a[k1 + 1] = xi;
1537
+ j1 -= nm;
1538
+ k1 += nm;
1539
+ xr = a[j1];
1540
+ xi = -a[j1 + 1];
1541
+ yr = a[k1];
1542
+ yi = -a[k1 + 1];
1543
+ a[j1] = yr;
1544
+ a[j1 + 1] = yi;
1545
+ a[k1] = xr;
1546
+ a[k1 + 1] = xi;
1547
+ j1 -= nm;
1548
+ k1 -= 2 * nm;
1549
+ xr = a[j1];
1550
+ xi = -a[j1 + 1];
1551
+ yr = a[k1];
1552
+ yi = -a[k1 + 1];
1553
+ a[j1] = yr;
1554
+ a[j1 + 1] = yi;
1555
+ a[k1] = xr;
1556
+ a[k1 + 1] = xi;
1557
+ }
1558
+ k1 = 4 * k + 2 * ip[m + k];
1559
+ j1 = k1 + 2;
1560
+ k1 += nh;
1561
+ a[j1 - 1] = -a[j1 - 1];
1562
+ xr = a[j1];
1563
+ xi = -a[j1 + 1];
1564
+ yr = a[k1];
1565
+ yi = -a[k1 + 1];
1566
+ a[j1] = yr;
1567
+ a[j1 + 1] = yi;
1568
+ a[k1] = xr;
1569
+ a[k1 + 1] = xi;
1570
+ a[k1 + 3] = -a[k1 + 3];
1571
+ j1 += nm;
1572
+ k1 += 2 * nm;
1573
+ xr = a[j1];
1574
+ xi = -a[j1 + 1];
1575
+ yr = a[k1];
1576
+ yi = -a[k1 + 1];
1577
+ a[j1] = yr;
1578
+ a[j1 + 1] = yi;
1579
+ a[k1] = xr;
1580
+ a[k1 + 1] = xi;
1581
+ j1 += nm;
1582
+ k1 -= nm;
1583
+ xr = a[j1];
1584
+ xi = -a[j1 + 1];
1585
+ yr = a[k1];
1586
+ yi = -a[k1 + 1];
1587
+ a[j1] = yr;
1588
+ a[j1 + 1] = yi;
1589
+ a[k1] = xr;
1590
+ a[k1 + 1] = xi;
1591
+ j1 -= 2;
1592
+ k1 -= nh;
1593
+ xr = a[j1];
1594
+ xi = -a[j1 + 1];
1595
+ yr = a[k1];
1596
+ yi = -a[k1 + 1];
1597
+ a[j1] = yr;
1598
+ a[j1 + 1] = yi;
1599
+ a[k1] = xr;
1600
+ a[k1 + 1] = xi;
1601
+ j1 += nh + 2;
1602
+ k1 += nh + 2;
1603
+ xr = a[j1];
1604
+ xi = -a[j1 + 1];
1605
+ yr = a[k1];
1606
+ yi = -a[k1 + 1];
1607
+ a[j1] = yr;
1608
+ a[j1 + 1] = yi;
1609
+ a[k1] = xr;
1610
+ a[k1 + 1] = xi;
1611
+ j1 -= nh - nm;
1612
+ k1 += 2 * nm - 2;
1613
+ a[j1 - 1] = -a[j1 - 1];
1614
+ xr = a[j1];
1615
+ xi = -a[j1 + 1];
1616
+ yr = a[k1];
1617
+ yi = -a[k1 + 1];
1618
+ a[j1] = yr;
1619
+ a[j1 + 1] = yi;
1620
+ a[k1] = xr;
1621
+ a[k1 + 1] = xi;
1622
+ a[k1 + 3] = -a[k1 + 3];
1623
+ }
1624
+ }
1625
+ else
1626
+ {
1627
+ for (k = 0; k < m; k++)
1628
+ {
1629
+ for (j = 0; j < k; j++)
1630
+ {
1631
+ j1 = 4 * j + ip[m + k];
1632
+ k1 = 4 * k + ip[m + j];
1633
+ xr = a[j1];
1634
+ xi = -a[j1 + 1];
1635
+ yr = a[k1];
1636
+ yi = -a[k1 + 1];
1637
+ a[j1] = yr;
1638
+ a[j1 + 1] = yi;
1639
+ a[k1] = xr;
1640
+ a[k1 + 1] = xi;
1641
+ j1 += nm;
1642
+ k1 += nm;
1643
+ xr = a[j1];
1644
+ xi = -a[j1 + 1];
1645
+ yr = a[k1];
1646
+ yi = -a[k1 + 1];
1647
+ a[j1] = yr;
1648
+ a[j1 + 1] = yi;
1649
+ a[k1] = xr;
1650
+ a[k1 + 1] = xi;
1651
+ j1 += nh;
1652
+ k1 += 2;
1653
+ xr = a[j1];
1654
+ xi = -a[j1 + 1];
1655
+ yr = a[k1];
1656
+ yi = -a[k1 + 1];
1657
+ a[j1] = yr;
1658
+ a[j1 + 1] = yi;
1659
+ a[k1] = xr;
1660
+ a[k1 + 1] = xi;
1661
+ j1 -= nm;
1662
+ k1 -= nm;
1663
+ xr = a[j1];
1664
+ xi = -a[j1 + 1];
1665
+ yr = a[k1];
1666
+ yi = -a[k1 + 1];
1667
+ a[j1] = yr;
1668
+ a[j1 + 1] = yi;
1669
+ a[k1] = xr;
1670
+ a[k1 + 1] = xi;
1671
+ j1 += 2;
1672
+ k1 += nh;
1673
+ xr = a[j1];
1674
+ xi = -a[j1 + 1];
1675
+ yr = a[k1];
1676
+ yi = -a[k1 + 1];
1677
+ a[j1] = yr;
1678
+ a[j1 + 1] = yi;
1679
+ a[k1] = xr;
1680
+ a[k1 + 1] = xi;
1681
+ j1 += nm;
1682
+ k1 += nm;
1683
+ xr = a[j1];
1684
+ xi = -a[j1 + 1];
1685
+ yr = a[k1];
1686
+ yi = -a[k1 + 1];
1687
+ a[j1] = yr;
1688
+ a[j1 + 1] = yi;
1689
+ a[k1] = xr;
1690
+ a[k1 + 1] = xi;
1691
+ j1 -= nh;
1692
+ k1 -= 2;
1693
+ xr = a[j1];
1694
+ xi = -a[j1 + 1];
1695
+ yr = a[k1];
1696
+ yi = -a[k1 + 1];
1697
+ a[j1] = yr;
1698
+ a[j1 + 1] = yi;
1699
+ a[k1] = xr;
1700
+ a[k1 + 1] = xi;
1701
+ j1 -= nm;
1702
+ k1 -= nm;
1703
+ xr = a[j1];
1704
+ xi = -a[j1 + 1];
1705
+ yr = a[k1];
1706
+ yi = -a[k1 + 1];
1707
+ a[j1] = yr;
1708
+ a[j1 + 1] = yi;
1709
+ a[k1] = xr;
1710
+ a[k1 + 1] = xi;
1711
+ }
1712
+ k1 = 4 * k + ip[m + k];
1713
+ j1 = k1 + 2;
1714
+ k1 += nh;
1715
+ a[j1 - 1] = -a[j1 - 1];
1716
+ xr = a[j1];
1717
+ xi = -a[j1 + 1];
1718
+ yr = a[k1];
1719
+ yi = -a[k1 + 1];
1720
+ a[j1] = yr;
1721
+ a[j1 + 1] = yi;
1722
+ a[k1] = xr;
1723
+ a[k1 + 1] = xi;
1724
+ a[k1 + 3] = -a[k1 + 3];
1725
+ j1 += nm;
1726
+ k1 += nm;
1727
+ a[j1 - 1] = -a[j1 - 1];
1728
+ xr = a[j1];
1729
+ xi = -a[j1 + 1];
1730
+ yr = a[k1];
1731
+ yi = -a[k1 + 1];
1732
+ a[j1] = yr;
1733
+ a[j1 + 1] = yi;
1734
+ a[k1] = xr;
1735
+ a[k1 + 1] = xi;
1736
+ a[k1 + 3] = -a[k1 + 3];
1737
+ }
1738
+ }
1739
+ }
1740
+
1741
+
1742
+ void
1743
+ bitrv216(double *a)
1744
+ {
1745
+ double x1r, x1i, x2r, x2i, x3r, x3i, x4r, x4i,
1746
+ x5r, x5i, x7r, x7i, x8r, x8i, x10r, x10i,
1747
+ x11r, x11i, x12r, x12i, x13r, x13i, x14r, x14i;
1748
+
1749
+ x1r = a[2];
1750
+ x1i = a[3];
1751
+ x2r = a[4];
1752
+ x2i = a[5];
1753
+ x3r = a[6];
1754
+ x3i = a[7];
1755
+ x4r = a[8];
1756
+ x4i = a[9];
1757
+ x5r = a[10];
1758
+ x5i = a[11];
1759
+ x7r = a[14];
1760
+ x7i = a[15];
1761
+ x8r = a[16];
1762
+ x8i = a[17];
1763
+ x10r = a[20];
1764
+ x10i = a[21];
1765
+ x11r = a[22];
1766
+ x11i = a[23];
1767
+ x12r = a[24];
1768
+ x12i = a[25];
1769
+ x13r = a[26];
1770
+ x13i = a[27];
1771
+ x14r = a[28];
1772
+ x14i = a[29];
1773
+ a[2] = x8r;
1774
+ a[3] = x8i;
1775
+ a[4] = x4r;
1776
+ a[5] = x4i;
1777
+ a[6] = x12r;
1778
+ a[7] = x12i;
1779
+ a[8] = x2r;
1780
+ a[9] = x2i;
1781
+ a[10] = x10r;
1782
+ a[11] = x10i;
1783
+ a[14] = x14r;
1784
+ a[15] = x14i;
1785
+ a[16] = x1r;
1786
+ a[17] = x1i;
1787
+ a[20] = x5r;
1788
+ a[21] = x5i;
1789
+ a[22] = x13r;
1790
+ a[23] = x13i;
1791
+ a[24] = x3r;
1792
+ a[25] = x3i;
1793
+ a[26] = x11r;
1794
+ a[27] = x11i;
1795
+ a[28] = x7r;
1796
+ a[29] = x7i;
1797
+ }
1798
+
1799
+
1800
+ void
1801
+ bitrv216neg(double *a)
1802
+ {
1803
+ double x1r, x1i, x2r, x2i, x3r, x3i, x4r, x4i,
1804
+ x5r, x5i, x6r, x6i, x7r, x7i, x8r, x8i,
1805
+ x9r, x9i, x10r, x10i, x11r, x11i, x12r, x12i,
1806
+ x13r, x13i, x14r, x14i, x15r, x15i;
1807
+
1808
+ x1r = a[2];
1809
+ x1i = a[3];
1810
+ x2r = a[4];
1811
+ x2i = a[5];
1812
+ x3r = a[6];
1813
+ x3i = a[7];
1814
+ x4r = a[8];
1815
+ x4i = a[9];
1816
+ x5r = a[10];
1817
+ x5i = a[11];
1818
+ x6r = a[12];
1819
+ x6i = a[13];
1820
+ x7r = a[14];
1821
+ x7i = a[15];
1822
+ x8r = a[16];
1823
+ x8i = a[17];
1824
+ x9r = a[18];
1825
+ x9i = a[19];
1826
+ x10r = a[20];
1827
+ x10i = a[21];
1828
+ x11r = a[22];
1829
+ x11i = a[23];
1830
+ x12r = a[24];
1831
+ x12i = a[25];
1832
+ x13r = a[26];
1833
+ x13i = a[27];
1834
+ x14r = a[28];
1835
+ x14i = a[29];
1836
+ x15r = a[30];
1837
+ x15i = a[31];
1838
+ a[2] = x15r;
1839
+ a[3] = x15i;
1840
+ a[4] = x7r;
1841
+ a[5] = x7i;
1842
+ a[6] = x11r;
1843
+ a[7] = x11i;
1844
+ a[8] = x3r;
1845
+ a[9] = x3i;
1846
+ a[10] = x13r;
1847
+ a[11] = x13i;
1848
+ a[12] = x5r;
1849
+ a[13] = x5i;
1850
+ a[14] = x9r;
1851
+ a[15] = x9i;
1852
+ a[16] = x1r;
1853
+ a[17] = x1i;
1854
+ a[18] = x14r;
1855
+ a[19] = x14i;
1856
+ a[20] = x6r;
1857
+ a[21] = x6i;
1858
+ a[22] = x10r;
1859
+ a[23] = x10i;
1860
+ a[24] = x2r;
1861
+ a[25] = x2i;
1862
+ a[26] = x12r;
1863
+ a[27] = x12i;
1864
+ a[28] = x4r;
1865
+ a[29] = x4i;
1866
+ a[30] = x8r;
1867
+ a[31] = x8i;
1868
+ }
1869
+
1870
+
1871
+ void
1872
+ bitrv208(double *a)
1873
+ {
1874
+ double x1r, x1i, x3r, x3i, x4r, x4i, x6r, x6i;
1875
+
1876
+ x1r = a[2];
1877
+ x1i = a[3];
1878
+ x3r = a[6];
1879
+ x3i = a[7];
1880
+ x4r = a[8];
1881
+ x4i = a[9];
1882
+ x6r = a[12];
1883
+ x6i = a[13];
1884
+ a[2] = x4r;
1885
+ a[3] = x4i;
1886
+ a[6] = x6r;
1887
+ a[7] = x6i;
1888
+ a[8] = x1r;
1889
+ a[9] = x1i;
1890
+ a[12] = x3r;
1891
+ a[13] = x3i;
1892
+ }
1893
+
1894
+
1895
+ void
1896
+ bitrv208neg(double *a)
1897
+ {
1898
+ double x1r, x1i, x2r, x2i, x3r, x3i, x4r, x4i,
1899
+ x5r, x5i, x6r, x6i, x7r, x7i;
1900
+
1901
+ x1r = a[2];
1902
+ x1i = a[3];
1903
+ x2r = a[4];
1904
+ x2i = a[5];
1905
+ x3r = a[6];
1906
+ x3i = a[7];
1907
+ x4r = a[8];
1908
+ x4i = a[9];
1909
+ x5r = a[10];
1910
+ x5i = a[11];
1911
+ x6r = a[12];
1912
+ x6i = a[13];
1913
+ x7r = a[14];
1914
+ x7i = a[15];
1915
+ a[2] = x7r;
1916
+ a[3] = x7i;
1917
+ a[4] = x3r;
1918
+ a[5] = x3i;
1919
+ a[6] = x5r;
1920
+ a[7] = x5i;
1921
+ a[8] = x1r;
1922
+ a[9] = x1i;
1923
+ a[10] = x6r;
1924
+ a[11] = x6i;
1925
+ a[12] = x2r;
1926
+ a[13] = x2i;
1927
+ a[14] = x4r;
1928
+ a[15] = x4i;
1929
+ }
1930
+
1931
+
1932
+ void
1933
+ cftf1st(int n, double *a, double *w)
1934
+ {
1935
+ int j, j0, j1, j2, j3, k, m, mh;
1936
+ double wn4r, csc1, csc3, wk1r, wk1i, wk3r, wk3i,
1937
+ wd1r, wd1i, wd3r, wd3i;
1938
+ double x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i,
1939
+ y0r, y0i, y1r, y1i, y2r, y2i, y3r, y3i;
1940
+
1941
+ mh = n >> 3;
1942
+ m = 2 * mh;
1943
+ j1 = m;
1944
+ j2 = j1 + m;
1945
+ j3 = j2 + m;
1946
+ x0r = a[0] + a[j2];
1947
+ x0i = a[1] + a[j2 + 1];
1948
+ x1r = a[0] - a[j2];
1949
+ x1i = a[1] - a[j2 + 1];
1950
+ x2r = a[j1] + a[j3];
1951
+ x2i = a[j1 + 1] + a[j3 + 1];
1952
+ x3r = a[j1] - a[j3];
1953
+ x3i = a[j1 + 1] - a[j3 + 1];
1954
+ a[0] = x0r + x2r;
1955
+ a[1] = x0i + x2i;
1956
+ a[j1] = x0r - x2r;
1957
+ a[j1 + 1] = x0i - x2i;
1958
+ a[j2] = x1r - x3i;
1959
+ a[j2 + 1] = x1i + x3r;
1960
+ a[j3] = x1r + x3i;
1961
+ a[j3 + 1] = x1i - x3r;
1962
+ wn4r = w[1];
1963
+ csc1 = w[2];
1964
+ csc3 = w[3];
1965
+ wd1r = 1;
1966
+ wd1i = 0;
1967
+ wd3r = 1;
1968
+ wd3i = 0;
1969
+ k = 0;
1970
+ for (j = 2; j < mh - 2; j += 4)
1971
+ {
1972
+ k += 4;
1973
+ wk1r = csc1 * (wd1r + w[k]);
1974
+ wk1i = csc1 * (wd1i + w[k + 1]);
1975
+ wk3r = csc3 * (wd3r + w[k + 2]);
1976
+ wk3i = csc3 * (wd3i + w[k + 3]);
1977
+ wd1r = w[k];
1978
+ wd1i = w[k + 1];
1979
+ wd3r = w[k + 2];
1980
+ wd3i = w[k + 3];
1981
+ j1 = j + m;
1982
+ j2 = j1 + m;
1983
+ j3 = j2 + m;
1984
+ x0r = a[j] + a[j2];
1985
+ x0i = a[j + 1] + a[j2 + 1];
1986
+ x1r = a[j] - a[j2];
1987
+ x1i = a[j + 1] - a[j2 + 1];
1988
+ y0r = a[j + 2] + a[j2 + 2];
1989
+ y0i = a[j + 3] + a[j2 + 3];
1990
+ y1r = a[j + 2] - a[j2 + 2];
1991
+ y1i = a[j + 3] - a[j2 + 3];
1992
+ x2r = a[j1] + a[j3];
1993
+ x2i = a[j1 + 1] + a[j3 + 1];
1994
+ x3r = a[j1] - a[j3];
1995
+ x3i = a[j1 + 1] - a[j3 + 1];
1996
+ y2r = a[j1 + 2] + a[j3 + 2];
1997
+ y2i = a[j1 + 3] + a[j3 + 3];
1998
+ y3r = a[j1 + 2] - a[j3 + 2];
1999
+ y3i = a[j1 + 3] - a[j3 + 3];
2000
+ a[j] = x0r + x2r;
2001
+ a[j + 1] = x0i + x2i;
2002
+ a[j + 2] = y0r + y2r;
2003
+ a[j + 3] = y0i + y2i;
2004
+ a[j1] = x0r - x2r;
2005
+ a[j1 + 1] = x0i - x2i;
2006
+ a[j1 + 2] = y0r - y2r;
2007
+ a[j1 + 3] = y0i - y2i;
2008
+ x0r = x1r - x3i;
2009
+ x0i = x1i + x3r;
2010
+ a[j2] = wk1r * x0r - wk1i * x0i;
2011
+ a[j2 + 1] = wk1r * x0i + wk1i * x0r;
2012
+ x0r = y1r - y3i;
2013
+ x0i = y1i + y3r;
2014
+ a[j2 + 2] = wd1r * x0r - wd1i * x0i;
2015
+ a[j2 + 3] = wd1r * x0i + wd1i * x0r;
2016
+ x0r = x1r + x3i;
2017
+ x0i = x1i - x3r;
2018
+ a[j3] = wk3r * x0r + wk3i * x0i;
2019
+ a[j3 + 1] = wk3r * x0i - wk3i * x0r;
2020
+ x0r = y1r + y3i;
2021
+ x0i = y1i - y3r;
2022
+ a[j3 + 2] = wd3r * x0r + wd3i * x0i;
2023
+ a[j3 + 3] = wd3r * x0i - wd3i * x0r;
2024
+ j0 = m - j;
2025
+ j1 = j0 + m;
2026
+ j2 = j1 + m;
2027
+ j3 = j2 + m;
2028
+ x0r = a[j0] + a[j2];
2029
+ x0i = a[j0 + 1] + a[j2 + 1];
2030
+ x1r = a[j0] - a[j2];
2031
+ x1i = a[j0 + 1] - a[j2 + 1];
2032
+ y0r = a[j0 - 2] + a[j2 - 2];
2033
+ y0i = a[j0 - 1] + a[j2 - 1];
2034
+ y1r = a[j0 - 2] - a[j2 - 2];
2035
+ y1i = a[j0 - 1] - a[j2 - 1];
2036
+ x2r = a[j1] + a[j3];
2037
+ x2i = a[j1 + 1] + a[j3 + 1];
2038
+ x3r = a[j1] - a[j3];
2039
+ x3i = a[j1 + 1] - a[j3 + 1];
2040
+ y2r = a[j1 - 2] + a[j3 - 2];
2041
+ y2i = a[j1 - 1] + a[j3 - 1];
2042
+ y3r = a[j1 - 2] - a[j3 - 2];
2043
+ y3i = a[j1 - 1] - a[j3 - 1];
2044
+ a[j0] = x0r + x2r;
2045
+ a[j0 + 1] = x0i + x2i;
2046
+ a[j0 - 2] = y0r + y2r;
2047
+ a[j0 - 1] = y0i + y2i;
2048
+ a[j1] = x0r - x2r;
2049
+ a[j1 + 1] = x0i - x2i;
2050
+ a[j1 - 2] = y0r - y2r;
2051
+ a[j1 - 1] = y0i - y2i;
2052
+ x0r = x1r - x3i;
2053
+ x0i = x1i + x3r;
2054
+ a[j2] = wk1i * x0r - wk1r * x0i;
2055
+ a[j2 + 1] = wk1i * x0i + wk1r * x0r;
2056
+ x0r = y1r - y3i;
2057
+ x0i = y1i + y3r;
2058
+ a[j2 - 2] = wd1i * x0r - wd1r * x0i;
2059
+ a[j2 - 1] = wd1i * x0i + wd1r * x0r;
2060
+ x0r = x1r + x3i;
2061
+ x0i = x1i - x3r;
2062
+ a[j3] = wk3i * x0r + wk3r * x0i;
2063
+ a[j3 + 1] = wk3i * x0i - wk3r * x0r;
2064
+ x0r = y1r + y3i;
2065
+ x0i = y1i - y3r;
2066
+ a[j3 - 2] = wd3i * x0r + wd3r * x0i;
2067
+ a[j3 - 1] = wd3i * x0i - wd3r * x0r;
2068
+ }
2069
+ wk1r = csc1 * (wd1r + wn4r);
2070
+ wk1i = csc1 * (wd1i + wn4r);
2071
+ wk3r = csc3 * (wd3r - wn4r);
2072
+ wk3i = csc3 * (wd3i - wn4r);
2073
+ j0 = mh;
2074
+ j1 = j0 + m;
2075
+ j2 = j1 + m;
2076
+ j3 = j2 + m;
2077
+ x0r = a[j0 - 2] + a[j2 - 2];
2078
+ x0i = a[j0 - 1] + a[j2 - 1];
2079
+ x1r = a[j0 - 2] - a[j2 - 2];
2080
+ x1i = a[j0 - 1] - a[j2 - 1];
2081
+ x2r = a[j1 - 2] + a[j3 - 2];
2082
+ x2i = a[j1 - 1] + a[j3 - 1];
2083
+ x3r = a[j1 - 2] - a[j3 - 2];
2084
+ x3i = a[j1 - 1] - a[j3 - 1];
2085
+ a[j0 - 2] = x0r + x2r;
2086
+ a[j0 - 1] = x0i + x2i;
2087
+ a[j1 - 2] = x0r - x2r;
2088
+ a[j1 - 1] = x0i - x2i;
2089
+ x0r = x1r - x3i;
2090
+ x0i = x1i + x3r;
2091
+ a[j2 - 2] = wk1r * x0r - wk1i * x0i;
2092
+ a[j2 - 1] = wk1r * x0i + wk1i * x0r;
2093
+ x0r = x1r + x3i;
2094
+ x0i = x1i - x3r;
2095
+ a[j3 - 2] = wk3r * x0r + wk3i * x0i;
2096
+ a[j3 - 1] = wk3r * x0i - wk3i * x0r;
2097
+ x0r = a[j0] + a[j2];
2098
+ x0i = a[j0 + 1] + a[j2 + 1];
2099
+ x1r = a[j0] - a[j2];
2100
+ x1i = a[j0 + 1] - a[j2 + 1];
2101
+ x2r = a[j1] + a[j3];
2102
+ x2i = a[j1 + 1] + a[j3 + 1];
2103
+ x3r = a[j1] - a[j3];
2104
+ x3i = a[j1 + 1] - a[j3 + 1];
2105
+ a[j0] = x0r + x2r;
2106
+ a[j0 + 1] = x0i + x2i;
2107
+ a[j1] = x0r - x2r;
2108
+ a[j1 + 1] = x0i - x2i;
2109
+ x0r = x1r - x3i;
2110
+ x0i = x1i + x3r;
2111
+ a[j2] = wn4r * (x0r - x0i);
2112
+ a[j2 + 1] = wn4r * (x0i + x0r);
2113
+ x0r = x1r + x3i;
2114
+ x0i = x1i - x3r;
2115
+ a[j3] = -wn4r * (x0r + x0i);
2116
+ a[j3 + 1] = -wn4r * (x0i - x0r);
2117
+ x0r = a[j0 + 2] + a[j2 + 2];
2118
+ x0i = a[j0 + 3] + a[j2 + 3];
2119
+ x1r = a[j0 + 2] - a[j2 + 2];
2120
+ x1i = a[j0 + 3] - a[j2 + 3];
2121
+ x2r = a[j1 + 2] + a[j3 + 2];
2122
+ x2i = a[j1 + 3] + a[j3 + 3];
2123
+ x3r = a[j1 + 2] - a[j3 + 2];
2124
+ x3i = a[j1 + 3] - a[j3 + 3];
2125
+ a[j0 + 2] = x0r + x2r;
2126
+ a[j0 + 3] = x0i + x2i;
2127
+ a[j1 + 2] = x0r - x2r;
2128
+ a[j1 + 3] = x0i - x2i;
2129
+ x0r = x1r - x3i;
2130
+ x0i = x1i + x3r;
2131
+ a[j2 + 2] = wk1i * x0r - wk1r * x0i;
2132
+ a[j2 + 3] = wk1i * x0i + wk1r * x0r;
2133
+ x0r = x1r + x3i;
2134
+ x0i = x1i - x3r;
2135
+ a[j3 + 2] = wk3i * x0r + wk3r * x0i;
2136
+ a[j3 + 3] = wk3i * x0i - wk3r * x0r;
2137
+ }
2138
+
2139
+
2140
+ void
2141
+ cftb1st(int n, double *a, double *w)
2142
+ {
2143
+ int j, j0, j1, j2, j3, k, m, mh;
2144
+ double wn4r, csc1, csc3, wk1r, wk1i, wk3r, wk3i,
2145
+ wd1r, wd1i, wd3r, wd3i;
2146
+ double x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i,
2147
+ y0r, y0i, y1r, y1i, y2r, y2i, y3r, y3i;
2148
+
2149
+ mh = n >> 3;
2150
+ m = 2 * mh;
2151
+ j1 = m;
2152
+ j2 = j1 + m;
2153
+ j3 = j2 + m;
2154
+ x0r = a[0] + a[j2];
2155
+ x0i = -a[1] - a[j2 + 1];
2156
+ x1r = a[0] - a[j2];
2157
+ x1i = -a[1] + a[j2 + 1];
2158
+ x2r = a[j1] + a[j3];
2159
+ x2i = a[j1 + 1] + a[j3 + 1];
2160
+ x3r = a[j1] - a[j3];
2161
+ x3i = a[j1 + 1] - a[j3 + 1];
2162
+ a[0] = x0r + x2r;
2163
+ a[1] = x0i - x2i;
2164
+ a[j1] = x0r - x2r;
2165
+ a[j1 + 1] = x0i + x2i;
2166
+ a[j2] = x1r + x3i;
2167
+ a[j2 + 1] = x1i + x3r;
2168
+ a[j3] = x1r - x3i;
2169
+ a[j3 + 1] = x1i - x3r;
2170
+ wn4r = w[1];
2171
+ csc1 = w[2];
2172
+ csc3 = w[3];
2173
+ wd1r = 1;
2174
+ wd1i = 0;
2175
+ wd3r = 1;
2176
+ wd3i = 0;
2177
+ k = 0;
2178
+ for (j = 2; j < mh - 2; j += 4)
2179
+ {
2180
+ k += 4;
2181
+ wk1r = csc1 * (wd1r + w[k]);
2182
+ wk1i = csc1 * (wd1i + w[k + 1]);
2183
+ wk3r = csc3 * (wd3r + w[k + 2]);
2184
+ wk3i = csc3 * (wd3i + w[k + 3]);
2185
+ wd1r = w[k];
2186
+ wd1i = w[k + 1];
2187
+ wd3r = w[k + 2];
2188
+ wd3i = w[k + 3];
2189
+ j1 = j + m;
2190
+ j2 = j1 + m;
2191
+ j3 = j2 + m;
2192
+ x0r = a[j] + a[j2];
2193
+ x0i = -a[j + 1] - a[j2 + 1];
2194
+ x1r = a[j] - a[j2];
2195
+ x1i = -a[j + 1] + a[j2 + 1];
2196
+ y0r = a[j + 2] + a[j2 + 2];
2197
+ y0i = -a[j + 3] - a[j2 + 3];
2198
+ y1r = a[j + 2] - a[j2 + 2];
2199
+ y1i = -a[j + 3] + a[j2 + 3];
2200
+ x2r = a[j1] + a[j3];
2201
+ x2i = a[j1 + 1] + a[j3 + 1];
2202
+ x3r = a[j1] - a[j3];
2203
+ x3i = a[j1 + 1] - a[j3 + 1];
2204
+ y2r = a[j1 + 2] + a[j3 + 2];
2205
+ y2i = a[j1 + 3] + a[j3 + 3];
2206
+ y3r = a[j1 + 2] - a[j3 + 2];
2207
+ y3i = a[j1 + 3] - a[j3 + 3];
2208
+ a[j] = x0r + x2r;
2209
+ a[j + 1] = x0i - x2i;
2210
+ a[j + 2] = y0r + y2r;
2211
+ a[j + 3] = y0i - y2i;
2212
+ a[j1] = x0r - x2r;
2213
+ a[j1 + 1] = x0i + x2i;
2214
+ a[j1 + 2] = y0r - y2r;
2215
+ a[j1 + 3] = y0i + y2i;
2216
+ x0r = x1r + x3i;
2217
+ x0i = x1i + x3r;
2218
+ a[j2] = wk1r * x0r - wk1i * x0i;
2219
+ a[j2 + 1] = wk1r * x0i + wk1i * x0r;
2220
+ x0r = y1r + y3i;
2221
+ x0i = y1i + y3r;
2222
+ a[j2 + 2] = wd1r * x0r - wd1i * x0i;
2223
+ a[j2 + 3] = wd1r * x0i + wd1i * x0r;
2224
+ x0r = x1r - x3i;
2225
+ x0i = x1i - x3r;
2226
+ a[j3] = wk3r * x0r + wk3i * x0i;
2227
+ a[j3 + 1] = wk3r * x0i - wk3i * x0r;
2228
+ x0r = y1r - y3i;
2229
+ x0i = y1i - y3r;
2230
+ a[j3 + 2] = wd3r * x0r + wd3i * x0i;
2231
+ a[j3 + 3] = wd3r * x0i - wd3i * x0r;
2232
+ j0 = m - j;
2233
+ j1 = j0 + m;
2234
+ j2 = j1 + m;
2235
+ j3 = j2 + m;
2236
+ x0r = a[j0] + a[j2];
2237
+ x0i = -a[j0 + 1] - a[j2 + 1];
2238
+ x1r = a[j0] - a[j2];
2239
+ x1i = -a[j0 + 1] + a[j2 + 1];
2240
+ y0r = a[j0 - 2] + a[j2 - 2];
2241
+ y0i = -a[j0 - 1] - a[j2 - 1];
2242
+ y1r = a[j0 - 2] - a[j2 - 2];
2243
+ y1i = -a[j0 - 1] + a[j2 - 1];
2244
+ x2r = a[j1] + a[j3];
2245
+ x2i = a[j1 + 1] + a[j3 + 1];
2246
+ x3r = a[j1] - a[j3];
2247
+ x3i = a[j1 + 1] - a[j3 + 1];
2248
+ y2r = a[j1 - 2] + a[j3 - 2];
2249
+ y2i = a[j1 - 1] + a[j3 - 1];
2250
+ y3r = a[j1 - 2] - a[j3 - 2];
2251
+ y3i = a[j1 - 1] - a[j3 - 1];
2252
+ a[j0] = x0r + x2r;
2253
+ a[j0 + 1] = x0i - x2i;
2254
+ a[j0 - 2] = y0r + y2r;
2255
+ a[j0 - 1] = y0i - y2i;
2256
+ a[j1] = x0r - x2r;
2257
+ a[j1 + 1] = x0i + x2i;
2258
+ a[j1 - 2] = y0r - y2r;
2259
+ a[j1 - 1] = y0i + y2i;
2260
+ x0r = x1r + x3i;
2261
+ x0i = x1i + x3r;
2262
+ a[j2] = wk1i * x0r - wk1r * x0i;
2263
+ a[j2 + 1] = wk1i * x0i + wk1r * x0r;
2264
+ x0r = y1r + y3i;
2265
+ x0i = y1i + y3r;
2266
+ a[j2 - 2] = wd1i * x0r - wd1r * x0i;
2267
+ a[j2 - 1] = wd1i * x0i + wd1r * x0r;
2268
+ x0r = x1r - x3i;
2269
+ x0i = x1i - x3r;
2270
+ a[j3] = wk3i * x0r + wk3r * x0i;
2271
+ a[j3 + 1] = wk3i * x0i - wk3r * x0r;
2272
+ x0r = y1r - y3i;
2273
+ x0i = y1i - y3r;
2274
+ a[j3 - 2] = wd3i * x0r + wd3r * x0i;
2275
+ a[j3 - 1] = wd3i * x0i - wd3r * x0r;
2276
+ }
2277
+ wk1r = csc1 * (wd1r + wn4r);
2278
+ wk1i = csc1 * (wd1i + wn4r);
2279
+ wk3r = csc3 * (wd3r - wn4r);
2280
+ wk3i = csc3 * (wd3i - wn4r);
2281
+ j0 = mh;
2282
+ j1 = j0 + m;
2283
+ j2 = j1 + m;
2284
+ j3 = j2 + m;
2285
+ x0r = a[j0 - 2] + a[j2 - 2];
2286
+ x0i = -a[j0 - 1] - a[j2 - 1];
2287
+ x1r = a[j0 - 2] - a[j2 - 2];
2288
+ x1i = -a[j0 - 1] + a[j2 - 1];
2289
+ x2r = a[j1 - 2] + a[j3 - 2];
2290
+ x2i = a[j1 - 1] + a[j3 - 1];
2291
+ x3r = a[j1 - 2] - a[j3 - 2];
2292
+ x3i = a[j1 - 1] - a[j3 - 1];
2293
+ a[j0 - 2] = x0r + x2r;
2294
+ a[j0 - 1] = x0i - x2i;
2295
+ a[j1 - 2] = x0r - x2r;
2296
+ a[j1 - 1] = x0i + x2i;
2297
+ x0r = x1r + x3i;
2298
+ x0i = x1i + x3r;
2299
+ a[j2 - 2] = wk1r * x0r - wk1i * x0i;
2300
+ a[j2 - 1] = wk1r * x0i + wk1i * x0r;
2301
+ x0r = x1r - x3i;
2302
+ x0i = x1i - x3r;
2303
+ a[j3 - 2] = wk3r * x0r + wk3i * x0i;
2304
+ a[j3 - 1] = wk3r * x0i - wk3i * x0r;
2305
+ x0r = a[j0] + a[j2];
2306
+ x0i = -a[j0 + 1] - a[j2 + 1];
2307
+ x1r = a[j0] - a[j2];
2308
+ x1i = -a[j0 + 1] + a[j2 + 1];
2309
+ x2r = a[j1] + a[j3];
2310
+ x2i = a[j1 + 1] + a[j3 + 1];
2311
+ x3r = a[j1] - a[j3];
2312
+ x3i = a[j1 + 1] - a[j3 + 1];
2313
+ a[j0] = x0r + x2r;
2314
+ a[j0 + 1] = x0i - x2i;
2315
+ a[j1] = x0r - x2r;
2316
+ a[j1 + 1] = x0i + x2i;
2317
+ x0r = x1r + x3i;
2318
+ x0i = x1i + x3r;
2319
+ a[j2] = wn4r * (x0r - x0i);
2320
+ a[j2 + 1] = wn4r * (x0i + x0r);
2321
+ x0r = x1r - x3i;
2322
+ x0i = x1i - x3r;
2323
+ a[j3] = -wn4r * (x0r + x0i);
2324
+ a[j3 + 1] = -wn4r * (x0i - x0r);
2325
+ x0r = a[j0 + 2] + a[j2 + 2];
2326
+ x0i = -a[j0 + 3] - a[j2 + 3];
2327
+ x1r = a[j0 + 2] - a[j2 + 2];
2328
+ x1i = -a[j0 + 3] + a[j2 + 3];
2329
+ x2r = a[j1 + 2] + a[j3 + 2];
2330
+ x2i = a[j1 + 3] + a[j3 + 3];
2331
+ x3r = a[j1 + 2] - a[j3 + 2];
2332
+ x3i = a[j1 + 3] - a[j3 + 3];
2333
+ a[j0 + 2] = x0r + x2r;
2334
+ a[j0 + 3] = x0i - x2i;
2335
+ a[j1 + 2] = x0r - x2r;
2336
+ a[j1 + 3] = x0i + x2i;
2337
+ x0r = x1r + x3i;
2338
+ x0i = x1i + x3r;
2339
+ a[j2 + 2] = wk1i * x0r - wk1r * x0i;
2340
+ a[j2 + 3] = wk1i * x0i + wk1r * x0r;
2341
+ x0r = x1r - x3i;
2342
+ x0i = x1i - x3r;
2343
+ a[j3 + 2] = wk3i * x0r + wk3r * x0i;
2344
+ a[j3 + 3] = wk3i * x0i - wk3r * x0r;
2345
+ }
2346
+
2347
+
2348
+ #ifdef USE_CDFT_THREADS
2349
+ struct cdft_arg_st {
2350
+ int n0;
2351
+ int n;
2352
+ double *a;
2353
+ int nw;
2354
+ double *w;
2355
+ };
2356
+ typedef struct cdft_arg_st cdft_arg_t;
2357
+
2358
+
2359
+ void
2360
+ cftrec4_th(int n, double *a, int nw, double *w)
2361
+ {
2362
+ void *cftrec1_th(void *p);
2363
+ void *cftrec2_th(void *p);
2364
+ int i, idiv4, m, nthread;
2365
+ cdft_thread_t th[4];
2366
+ cdft_arg_t ag[4];
2367
+
2368
+ nthread = 2;
2369
+ idiv4 = 0;
2370
+ m = n >> 1;
2371
+ if (n > CDFT_4THREADS_BEGIN_N)
2372
+ {
2373
+ nthread = 4;
2374
+ idiv4 = 1;
2375
+ m >>= 1;
2376
+ }
2377
+ for (i = 0; i < nthread; i++)
2378
+ {
2379
+ ag[i].n0 = n;
2380
+ ag[i].n = m;
2381
+ ag[i].a = &a[i * m];
2382
+ ag[i].nw = nw;
2383
+ ag[i].w = w;
2384
+ if (i != idiv4)
2385
+ {
2386
+ cdft_thread_create(&th[i], cftrec1_th, &ag[i]);
2387
+ }
2388
+ else
2389
+ {
2390
+ cdft_thread_create(&th[i], cftrec2_th, &ag[i]);
2391
+ }
2392
+ }
2393
+ for (i = 0; i < nthread; i++)
2394
+ {
2395
+ cdft_thread_wait(th[i]);
2396
+ }
2397
+ }
2398
+
2399
+
2400
+ void *
2401
+ cftrec1_th(void *p)
2402
+ {
2403
+ int cfttree(int n, int j, int k, double *a, int nw, double *w);
2404
+ void cftleaf(int n, int isplt, double *a, int nw, double *w);
2405
+ void cftmdl1(int n, double *a, double *w);
2406
+ int isplt, j, k, m, n, n0, nw;
2407
+ double *a, *w;
2408
+
2409
+ n0 = ((cdft_arg_t *) p)->n0;
2410
+ n = ((cdft_arg_t *) p)->n;
2411
+ a = ((cdft_arg_t *) p)->a;
2412
+ nw = ((cdft_arg_t *) p)->nw;
2413
+ w = ((cdft_arg_t *) p)->w;
2414
+ m = n0;
2415
+ while (m > 512)
2416
+ {
2417
+ m >>= 2;
2418
+ cftmdl1(m, &a[n - m], &w[nw - (m >> 1)]);
2419
+ }
2420
+ cftleaf(m, 1, &a[n - m], nw, w);
2421
+ k = 0;
2422
+ for (j = n - m; j > 0; j -= m)
2423
+ {
2424
+ k++;
2425
+ isplt = cfttree(m, j, k, a, nw, w);
2426
+ cftleaf(m, isplt, &a[j - m], nw, w);
2427
+ }
2428
+ return (void *) 0;
2429
+ }
2430
+
2431
+
2432
+ void *
2433
+ cftrec2_th(void *p)
2434
+ {
2435
+ int cfttree(int n, int j, int k, double *a, int nw, double *w);
2436
+ void cftleaf(int n, int isplt, double *a, int nw, double *w);
2437
+ void cftmdl2(int n, double *a, double *w);
2438
+ int isplt, j, k, m, n, n0, nw;
2439
+ double *a, *w;
2440
+
2441
+ n0 = ((cdft_arg_t *) p)->n0;
2442
+ n = ((cdft_arg_t *) p)->n;
2443
+ a = ((cdft_arg_t *) p)->a;
2444
+ nw = ((cdft_arg_t *) p)->nw;
2445
+ w = ((cdft_arg_t *) p)->w;
2446
+ k = 1;
2447
+ m = n0;
2448
+ while (m > 512)
2449
+ {
2450
+ m >>= 2;
2451
+ k <<= 2;
2452
+ cftmdl2(m, &a[n - m], &w[nw - m]);
2453
+ }
2454
+ cftleaf(m, 0, &a[n - m], nw, w);
2455
+ k >>= 1;
2456
+ for (j = n - m; j > 0; j -= m)
2457
+ {
2458
+ k++;
2459
+ isplt = cfttree(m, j, k, a, nw, w);
2460
+ cftleaf(m, isplt, &a[j - m], nw, w);
2461
+ }
2462
+ return (void *) 0;
2463
+ }
2464
+ #endif /* USE_CDFT_THREADS */
2465
+
2466
+
2467
+ void
2468
+ cftrec4(int n, double *a, int nw, double *w)
2469
+ {
2470
+ int cfttree(int n, int j, int k, double *a, int nw, double *w);
2471
+ void cftleaf(int n, int isplt, double *a, int nw, double *w);
2472
+ void cftmdl1(int n, double *a, double *w);
2473
+ int isplt, j, k, m;
2474
+
2475
+ m = n;
2476
+ while (m > 512)
2477
+ {
2478
+ m >>= 2;
2479
+ cftmdl1(m, &a[n - m], &w[nw - (m >> 1)]);
2480
+ }
2481
+ cftleaf(m, 1, &a[n - m], nw, w);
2482
+ k = 0;
2483
+ for (j = n - m; j > 0; j -= m)
2484
+ {
2485
+ k++;
2486
+ isplt = cfttree(m, j, k, a, nw, w);
2487
+ cftleaf(m, isplt, &a[j - m], nw, w);
2488
+ }
2489
+ }
2490
+
2491
+
2492
+ int
2493
+ cfttree(int n, int j, int k, double *a, int nw, double *w)
2494
+ {
2495
+ void cftmdl1(int n, double *a, double *w);
2496
+ void cftmdl2(int n, double *a, double *w);
2497
+ int i, isplt, m;
2498
+
2499
+ if ((k & 3) != 0)
2500
+ {
2501
+ isplt = k & 1;
2502
+ if (isplt != 0)
2503
+ {
2504
+ cftmdl1(n, &a[j - n], &w[nw - (n >> 1)]);
2505
+ }
2506
+ else
2507
+ {
2508
+ cftmdl2(n, &a[j - n], &w[nw - n]);
2509
+ }
2510
+ }
2511
+ else
2512
+ {
2513
+ m = n;
2514
+ for (i = k; (i & 3) == 0; i >>= 2)
2515
+ {
2516
+ m <<= 2;
2517
+ }
2518
+ isplt = i & 1;
2519
+ if (isplt != 0)
2520
+ {
2521
+ while (m > 128)
2522
+ {
2523
+ cftmdl1(m, &a[j - m], &w[nw - (m >> 1)]);
2524
+ m >>= 2;
2525
+ }
2526
+ }
2527
+ else
2528
+ {
2529
+ while (m > 128)
2530
+ {
2531
+ cftmdl2(m, &a[j - m], &w[nw - m]);
2532
+ m >>= 2;
2533
+ }
2534
+ }
2535
+ }
2536
+ return isplt;
2537
+ }
2538
+
2539
+
2540
+ void
2541
+ cftleaf(int n, int isplt, double *a, int nw, double *w)
2542
+ {
2543
+ void cftmdl1(int n, double *a, double *w);
2544
+ void cftmdl2(int n, double *a, double *w);
2545
+ void cftf161(double *a, double *w);
2546
+ void cftf162(double *a, double *w);
2547
+ void cftf081(double *a, double *w);
2548
+ void cftf082(double *a, double *w);
2549
+
2550
+ if (n == 512)
2551
+ {
2552
+ cftmdl1(128, a, &w[nw - 64]);
2553
+ cftf161(a, &w[nw - 8]);
2554
+ cftf162(&a[32], &w[nw - 32]);
2555
+ cftf161(&a[64], &w[nw - 8]);
2556
+ cftf161(&a[96], &w[nw - 8]);
2557
+ cftmdl2(128, &a[128], &w[nw - 128]);
2558
+ cftf161(&a[128], &w[nw - 8]);
2559
+ cftf162(&a[160], &w[nw - 32]);
2560
+ cftf161(&a[192], &w[nw - 8]);
2561
+ cftf162(&a[224], &w[nw - 32]);
2562
+ cftmdl1(128, &a[256], &w[nw - 64]);
2563
+ cftf161(&a[256], &w[nw - 8]);
2564
+ cftf162(&a[288], &w[nw - 32]);
2565
+ cftf161(&a[320], &w[nw - 8]);
2566
+ cftf161(&a[352], &w[nw - 8]);
2567
+ if (isplt != 0)
2568
+ {
2569
+ cftmdl1(128, &a[384], &w[nw - 64]);
2570
+ cftf161(&a[480], &w[nw - 8]);
2571
+ }
2572
+ else
2573
+ {
2574
+ cftmdl2(128, &a[384], &w[nw - 128]);
2575
+ cftf162(&a[480], &w[nw - 32]);
2576
+ }
2577
+ cftf161(&a[384], &w[nw - 8]);
2578
+ cftf162(&a[416], &w[nw - 32]);
2579
+ cftf161(&a[448], &w[nw - 8]);
2580
+ }
2581
+ else
2582
+ {
2583
+ cftmdl1(64, a, &w[nw - 32]);
2584
+ cftf081(a, &w[nw - 8]);
2585
+ cftf082(&a[16], &w[nw - 8]);
2586
+ cftf081(&a[32], &w[nw - 8]);
2587
+ cftf081(&a[48], &w[nw - 8]);
2588
+ cftmdl2(64, &a[64], &w[nw - 64]);
2589
+ cftf081(&a[64], &w[nw - 8]);
2590
+ cftf082(&a[80], &w[nw - 8]);
2591
+ cftf081(&a[96], &w[nw - 8]);
2592
+ cftf082(&a[112], &w[nw - 8]);
2593
+ cftmdl1(64, &a[128], &w[nw - 32]);
2594
+ cftf081(&a[128], &w[nw - 8]);
2595
+ cftf082(&a[144], &w[nw - 8]);
2596
+ cftf081(&a[160], &w[nw - 8]);
2597
+ cftf081(&a[176], &w[nw - 8]);
2598
+ if (isplt != 0)
2599
+ {
2600
+ cftmdl1(64, &a[192], &w[nw - 32]);
2601
+ cftf081(&a[240], &w[nw - 8]);
2602
+ }
2603
+ else
2604
+ {
2605
+ cftmdl2(64, &a[192], &w[nw - 64]);
2606
+ cftf082(&a[240], &w[nw - 8]);
2607
+ }
2608
+ cftf081(&a[192], &w[nw - 8]);
2609
+ cftf082(&a[208], &w[nw - 8]);
2610
+ cftf081(&a[224], &w[nw - 8]);
2611
+ }
2612
+ }
2613
+
2614
+
2615
+ void
2616
+ cftmdl1(int n, double *a, double *w)
2617
+ {
2618
+ int j, j0, j1, j2, j3, k, m, mh;
2619
+ double wn4r, wk1r, wk1i, wk3r, wk3i;
2620
+ double x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i;
2621
+
2622
+ mh = n >> 3;
2623
+ m = 2 * mh;
2624
+ j1 = m;
2625
+ j2 = j1 + m;
2626
+ j3 = j2 + m;
2627
+ x0r = a[0] + a[j2];
2628
+ x0i = a[1] + a[j2 + 1];
2629
+ x1r = a[0] - a[j2];
2630
+ x1i = a[1] - a[j2 + 1];
2631
+ x2r = a[j1] + a[j3];
2632
+ x2i = a[j1 + 1] + a[j3 + 1];
2633
+ x3r = a[j1] - a[j3];
2634
+ x3i = a[j1 + 1] - a[j3 + 1];
2635
+ a[0] = x0r + x2r;
2636
+ a[1] = x0i + x2i;
2637
+ a[j1] = x0r - x2r;
2638
+ a[j1 + 1] = x0i - x2i;
2639
+ a[j2] = x1r - x3i;
2640
+ a[j2 + 1] = x1i + x3r;
2641
+ a[j3] = x1r + x3i;
2642
+ a[j3 + 1] = x1i - x3r;
2643
+ wn4r = w[1];
2644
+ k = 0;
2645
+ for (j = 2; j < mh; j += 2)
2646
+ {
2647
+ k += 4;
2648
+ wk1r = w[k];
2649
+ wk1i = w[k + 1];
2650
+ wk3r = w[k + 2];
2651
+ wk3i = w[k + 3];
2652
+ j1 = j + m;
2653
+ j2 = j1 + m;
2654
+ j3 = j2 + m;
2655
+ x0r = a[j] + a[j2];
2656
+ x0i = a[j + 1] + a[j2 + 1];
2657
+ x1r = a[j] - a[j2];
2658
+ x1i = a[j + 1] - a[j2 + 1];
2659
+ x2r = a[j1] + a[j3];
2660
+ x2i = a[j1 + 1] + a[j3 + 1];
2661
+ x3r = a[j1] - a[j3];
2662
+ x3i = a[j1 + 1] - a[j3 + 1];
2663
+ a[j] = x0r + x2r;
2664
+ a[j + 1] = x0i + x2i;
2665
+ a[j1] = x0r - x2r;
2666
+ a[j1 + 1] = x0i - x2i;
2667
+ x0r = x1r - x3i;
2668
+ x0i = x1i + x3r;
2669
+ a[j2] = wk1r * x0r - wk1i * x0i;
2670
+ a[j2 + 1] = wk1r * x0i + wk1i * x0r;
2671
+ x0r = x1r + x3i;
2672
+ x0i = x1i - x3r;
2673
+ a[j3] = wk3r * x0r + wk3i * x0i;
2674
+ a[j3 + 1] = wk3r * x0i - wk3i * x0r;
2675
+ j0 = m - j;
2676
+ j1 = j0 + m;
2677
+ j2 = j1 + m;
2678
+ j3 = j2 + m;
2679
+ x0r = a[j0] + a[j2];
2680
+ x0i = a[j0 + 1] + a[j2 + 1];
2681
+ x1r = a[j0] - a[j2];
2682
+ x1i = a[j0 + 1] - a[j2 + 1];
2683
+ x2r = a[j1] + a[j3];
2684
+ x2i = a[j1 + 1] + a[j3 + 1];
2685
+ x3r = a[j1] - a[j3];
2686
+ x3i = a[j1 + 1] - a[j3 + 1];
2687
+ a[j0] = x0r + x2r;
2688
+ a[j0 + 1] = x0i + x2i;
2689
+ a[j1] = x0r - x2r;
2690
+ a[j1 + 1] = x0i - x2i;
2691
+ x0r = x1r - x3i;
2692
+ x0i = x1i + x3r;
2693
+ a[j2] = wk1i * x0r - wk1r * x0i;
2694
+ a[j2 + 1] = wk1i * x0i + wk1r * x0r;
2695
+ x0r = x1r + x3i;
2696
+ x0i = x1i - x3r;
2697
+ a[j3] = wk3i * x0r + wk3r * x0i;
2698
+ a[j3 + 1] = wk3i * x0i - wk3r * x0r;
2699
+ }
2700
+ j0 = mh;
2701
+ j1 = j0 + m;
2702
+ j2 = j1 + m;
2703
+ j3 = j2 + m;
2704
+ x0r = a[j0] + a[j2];
2705
+ x0i = a[j0 + 1] + a[j2 + 1];
2706
+ x1r = a[j0] - a[j2];
2707
+ x1i = a[j0 + 1] - a[j2 + 1];
2708
+ x2r = a[j1] + a[j3];
2709
+ x2i = a[j1 + 1] + a[j3 + 1];
2710
+ x3r = a[j1] - a[j3];
2711
+ x3i = a[j1 + 1] - a[j3 + 1];
2712
+ a[j0] = x0r + x2r;
2713
+ a[j0 + 1] = x0i + x2i;
2714
+ a[j1] = x0r - x2r;
2715
+ a[j1 + 1] = x0i - x2i;
2716
+ x0r = x1r - x3i;
2717
+ x0i = x1i + x3r;
2718
+ a[j2] = wn4r * (x0r - x0i);
2719
+ a[j2 + 1] = wn4r * (x0i + x0r);
2720
+ x0r = x1r + x3i;
2721
+ x0i = x1i - x3r;
2722
+ a[j3] = -wn4r * (x0r + x0i);
2723
+ a[j3 + 1] = -wn4r * (x0i - x0r);
2724
+ }
2725
+
2726
+
2727
+ void
2728
+ cftmdl2(int n, double *a, double *w)
2729
+ {
2730
+ int j, j0, j1, j2, j3, k, kr, m, mh;
2731
+ double wn4r, wk1r, wk1i, wk3r, wk3i, wd1r, wd1i, wd3r, wd3i;
2732
+ double x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i, y0r, y0i, y2r, y2i;
2733
+
2734
+ mh = n >> 3;
2735
+ m = 2 * mh;
2736
+ wn4r = w[1];
2737
+ j1 = m;
2738
+ j2 = j1 + m;
2739
+ j3 = j2 + m;
2740
+ x0r = a[0] - a[j2 + 1];
2741
+ x0i = a[1] + a[j2];
2742
+ x1r = a[0] + a[j2 + 1];
2743
+ x1i = a[1] - a[j2];
2744
+ x2r = a[j1] - a[j3 + 1];
2745
+ x2i = a[j1 + 1] + a[j3];
2746
+ x3r = a[j1] + a[j3 + 1];
2747
+ x3i = a[j1 + 1] - a[j3];
2748
+ y0r = wn4r * (x2r - x2i);
2749
+ y0i = wn4r * (x2i + x2r);
2750
+ a[0] = x0r + y0r;
2751
+ a[1] = x0i + y0i;
2752
+ a[j1] = x0r - y0r;
2753
+ a[j1 + 1] = x0i - y0i;
2754
+ y0r = wn4r * (x3r - x3i);
2755
+ y0i = wn4r * (x3i + x3r);
2756
+ a[j2] = x1r - y0i;
2757
+ a[j2 + 1] = x1i + y0r;
2758
+ a[j3] = x1r + y0i;
2759
+ a[j3 + 1] = x1i - y0r;
2760
+ k = 0;
2761
+ kr = 2 * m;
2762
+ for (j = 2; j < mh; j += 2)
2763
+ {
2764
+ k += 4;
2765
+ wk1r = w[k];
2766
+ wk1i = w[k + 1];
2767
+ wk3r = w[k + 2];
2768
+ wk3i = w[k + 3];
2769
+ kr -= 4;
2770
+ wd1i = w[kr];
2771
+ wd1r = w[kr + 1];
2772
+ wd3i = w[kr + 2];
2773
+ wd3r = w[kr + 3];
2774
+ j1 = j + m;
2775
+ j2 = j1 + m;
2776
+ j3 = j2 + m;
2777
+ x0r = a[j] - a[j2 + 1];
2778
+ x0i = a[j + 1] + a[j2];
2779
+ x1r = a[j] + a[j2 + 1];
2780
+ x1i = a[j + 1] - a[j2];
2781
+ x2r = a[j1] - a[j3 + 1];
2782
+ x2i = a[j1 + 1] + a[j3];
2783
+ x3r = a[j1] + a[j3 + 1];
2784
+ x3i = a[j1 + 1] - a[j3];
2785
+ y0r = wk1r * x0r - wk1i * x0i;
2786
+ y0i = wk1r * x0i + wk1i * x0r;
2787
+ y2r = wd1r * x2r - wd1i * x2i;
2788
+ y2i = wd1r * x2i + wd1i * x2r;
2789
+ a[j] = y0r + y2r;
2790
+ a[j + 1] = y0i + y2i;
2791
+ a[j1] = y0r - y2r;
2792
+ a[j1 + 1] = y0i - y2i;
2793
+ y0r = wk3r * x1r + wk3i * x1i;
2794
+ y0i = wk3r * x1i - wk3i * x1r;
2795
+ y2r = wd3r * x3r + wd3i * x3i;
2796
+ y2i = wd3r * x3i - wd3i * x3r;
2797
+ a[j2] = y0r + y2r;
2798
+ a[j2 + 1] = y0i + y2i;
2799
+ a[j3] = y0r - y2r;
2800
+ a[j3 + 1] = y0i - y2i;
2801
+ j0 = m - j;
2802
+ j1 = j0 + m;
2803
+ j2 = j1 + m;
2804
+ j3 = j2 + m;
2805
+ x0r = a[j0] - a[j2 + 1];
2806
+ x0i = a[j0 + 1] + a[j2];
2807
+ x1r = a[j0] + a[j2 + 1];
2808
+ x1i = a[j0 + 1] - a[j2];
2809
+ x2r = a[j1] - a[j3 + 1];
2810
+ x2i = a[j1 + 1] + a[j3];
2811
+ x3r = a[j1] + a[j3 + 1];
2812
+ x3i = a[j1 + 1] - a[j3];
2813
+ y0r = wd1i * x0r - wd1r * x0i;
2814
+ y0i = wd1i * x0i + wd1r * x0r;
2815
+ y2r = wk1i * x2r - wk1r * x2i;
2816
+ y2i = wk1i * x2i + wk1r * x2r;
2817
+ a[j0] = y0r + y2r;
2818
+ a[j0 + 1] = y0i + y2i;
2819
+ a[j1] = y0r - y2r;
2820
+ a[j1 + 1] = y0i - y2i;
2821
+ y0r = wd3i * x1r + wd3r * x1i;
2822
+ y0i = wd3i * x1i - wd3r * x1r;
2823
+ y2r = wk3i * x3r + wk3r * x3i;
2824
+ y2i = wk3i * x3i - wk3r * x3r;
2825
+ a[j2] = y0r + y2r;
2826
+ a[j2 + 1] = y0i + y2i;
2827
+ a[j3] = y0r - y2r;
2828
+ a[j3 + 1] = y0i - y2i;
2829
+ }
2830
+ wk1r = w[m];
2831
+ wk1i = w[m + 1];
2832
+ j0 = mh;
2833
+ j1 = j0 + m;
2834
+ j2 = j1 + m;
2835
+ j3 = j2 + m;
2836
+ x0r = a[j0] - a[j2 + 1];
2837
+ x0i = a[j0 + 1] + a[j2];
2838
+ x1r = a[j0] + a[j2 + 1];
2839
+ x1i = a[j0 + 1] - a[j2];
2840
+ x2r = a[j1] - a[j3 + 1];
2841
+ x2i = a[j1 + 1] + a[j3];
2842
+ x3r = a[j1] + a[j3 + 1];
2843
+ x3i = a[j1 + 1] - a[j3];
2844
+ y0r = wk1r * x0r - wk1i * x0i;
2845
+ y0i = wk1r * x0i + wk1i * x0r;
2846
+ y2r = wk1i * x2r - wk1r * x2i;
2847
+ y2i = wk1i * x2i + wk1r * x2r;
2848
+ a[j0] = y0r + y2r;
2849
+ a[j0 + 1] = y0i + y2i;
2850
+ a[j1] = y0r - y2r;
2851
+ a[j1 + 1] = y0i - y2i;
2852
+ y0r = wk1i * x1r - wk1r * x1i;
2853
+ y0i = wk1i * x1i + wk1r * x1r;
2854
+ y2r = wk1r * x3r - wk1i * x3i;
2855
+ y2i = wk1r * x3i + wk1i * x3r;
2856
+ a[j2] = y0r - y2r;
2857
+ a[j2 + 1] = y0i - y2i;
2858
+ a[j3] = y0r + y2r;
2859
+ a[j3 + 1] = y0i + y2i;
2860
+ }
2861
+
2862
+
2863
+ void
2864
+ cftfx41(int n, double *a, int nw, double *w)
2865
+ {
2866
+ void cftf161(double *a, double *w);
2867
+ void cftf162(double *a, double *w);
2868
+ void cftf081(double *a, double *w);
2869
+ void cftf082(double *a, double *w);
2870
+
2871
+ if (n == 128)
2872
+ {
2873
+ cftf161(a, &w[nw - 8]);
2874
+ cftf162(&a[32], &w[nw - 32]);
2875
+ cftf161(&a[64], &w[nw - 8]);
2876
+ cftf161(&a[96], &w[nw - 8]);
2877
+ }
2878
+ else
2879
+ {
2880
+ cftf081(a, &w[nw - 8]);
2881
+ cftf082(&a[16], &w[nw - 8]);
2882
+ cftf081(&a[32], &w[nw - 8]);
2883
+ cftf081(&a[48], &w[nw - 8]);
2884
+ }
2885
+ }
2886
+
2887
+
2888
+ void
2889
+ cftf161(double *a, double *w)
2890
+ {
2891
+ double wn4r, wk1r, wk1i,
2892
+ x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i,
2893
+ y0r, y0i, y1r, y1i, y2r, y2i, y3r, y3i,
2894
+ y4r, y4i, y5r, y5i, y6r, y6i, y7r, y7i,
2895
+ y8r, y8i, y9r, y9i, y10r, y10i, y11r, y11i,
2896
+ y12r, y12i, y13r, y13i, y14r, y14i, y15r, y15i;
2897
+
2898
+ wn4r = w[1];
2899
+ wk1r = w[2];
2900
+ wk1i = w[3];
2901
+ x0r = a[0] + a[16];
2902
+ x0i = a[1] + a[17];
2903
+ x1r = a[0] - a[16];
2904
+ x1i = a[1] - a[17];
2905
+ x2r = a[8] + a[24];
2906
+ x2i = a[9] + a[25];
2907
+ x3r = a[8] - a[24];
2908
+ x3i = a[9] - a[25];
2909
+ y0r = x0r + x2r;
2910
+ y0i = x0i + x2i;
2911
+ y4r = x0r - x2r;
2912
+ y4i = x0i - x2i;
2913
+ y8r = x1r - x3i;
2914
+ y8i = x1i + x3r;
2915
+ y12r = x1r + x3i;
2916
+ y12i = x1i - x3r;
2917
+ x0r = a[2] + a[18];
2918
+ x0i = a[3] + a[19];
2919
+ x1r = a[2] - a[18];
2920
+ x1i = a[3] - a[19];
2921
+ x2r = a[10] + a[26];
2922
+ x2i = a[11] + a[27];
2923
+ x3r = a[10] - a[26];
2924
+ x3i = a[11] - a[27];
2925
+ y1r = x0r + x2r;
2926
+ y1i = x0i + x2i;
2927
+ y5r = x0r - x2r;
2928
+ y5i = x0i - x2i;
2929
+ x0r = x1r - x3i;
2930
+ x0i = x1i + x3r;
2931
+ y9r = wk1r * x0r - wk1i * x0i;
2932
+ y9i = wk1r * x0i + wk1i * x0r;
2933
+ x0r = x1r + x3i;
2934
+ x0i = x1i - x3r;
2935
+ y13r = wk1i * x0r - wk1r * x0i;
2936
+ y13i = wk1i * x0i + wk1r * x0r;
2937
+ x0r = a[4] + a[20];
2938
+ x0i = a[5] + a[21];
2939
+ x1r = a[4] - a[20];
2940
+ x1i = a[5] - a[21];
2941
+ x2r = a[12] + a[28];
2942
+ x2i = a[13] + a[29];
2943
+ x3r = a[12] - a[28];
2944
+ x3i = a[13] - a[29];
2945
+ y2r = x0r + x2r;
2946
+ y2i = x0i + x2i;
2947
+ y6r = x0r - x2r;
2948
+ y6i = x0i - x2i;
2949
+ x0r = x1r - x3i;
2950
+ x0i = x1i + x3r;
2951
+ y10r = wn4r * (x0r - x0i);
2952
+ y10i = wn4r * (x0i + x0r);
2953
+ x0r = x1r + x3i;
2954
+ x0i = x1i - x3r;
2955
+ y14r = wn4r * (x0r + x0i);
2956
+ y14i = wn4r * (x0i - x0r);
2957
+ x0r = a[6] + a[22];
2958
+ x0i = a[7] + a[23];
2959
+ x1r = a[6] - a[22];
2960
+ x1i = a[7] - a[23];
2961
+ x2r = a[14] + a[30];
2962
+ x2i = a[15] + a[31];
2963
+ x3r = a[14] - a[30];
2964
+ x3i = a[15] - a[31];
2965
+ y3r = x0r + x2r;
2966
+ y3i = x0i + x2i;
2967
+ y7r = x0r - x2r;
2968
+ y7i = x0i - x2i;
2969
+ x0r = x1r - x3i;
2970
+ x0i = x1i + x3r;
2971
+ y11r = wk1i * x0r - wk1r * x0i;
2972
+ y11i = wk1i * x0i + wk1r * x0r;
2973
+ x0r = x1r + x3i;
2974
+ x0i = x1i - x3r;
2975
+ y15r = wk1r * x0r - wk1i * x0i;
2976
+ y15i = wk1r * x0i + wk1i * x0r;
2977
+ x0r = y12r - y14r;
2978
+ x0i = y12i - y14i;
2979
+ x1r = y12r + y14r;
2980
+ x1i = y12i + y14i;
2981
+ x2r = y13r - y15r;
2982
+ x2i = y13i - y15i;
2983
+ x3r = y13r + y15r;
2984
+ x3i = y13i + y15i;
2985
+ a[24] = x0r + x2r;
2986
+ a[25] = x0i + x2i;
2987
+ a[26] = x0r - x2r;
2988
+ a[27] = x0i - x2i;
2989
+ a[28] = x1r - x3i;
2990
+ a[29] = x1i + x3r;
2991
+ a[30] = x1r + x3i;
2992
+ a[31] = x1i - x3r;
2993
+ x0r = y8r + y10r;
2994
+ x0i = y8i + y10i;
2995
+ x1r = y8r - y10r;
2996
+ x1i = y8i - y10i;
2997
+ x2r = y9r + y11r;
2998
+ x2i = y9i + y11i;
2999
+ x3r = y9r - y11r;
3000
+ x3i = y9i - y11i;
3001
+ a[16] = x0r + x2r;
3002
+ a[17] = x0i + x2i;
3003
+ a[18] = x0r - x2r;
3004
+ a[19] = x0i - x2i;
3005
+ a[20] = x1r - x3i;
3006
+ a[21] = x1i + x3r;
3007
+ a[22] = x1r + x3i;
3008
+ a[23] = x1i - x3r;
3009
+ x0r = y5r - y7i;
3010
+ x0i = y5i + y7r;
3011
+ x2r = wn4r * (x0r - x0i);
3012
+ x2i = wn4r * (x0i + x0r);
3013
+ x0r = y5r + y7i;
3014
+ x0i = y5i - y7r;
3015
+ x3r = wn4r * (x0r - x0i);
3016
+ x3i = wn4r * (x0i + x0r);
3017
+ x0r = y4r - y6i;
3018
+ x0i = y4i + y6r;
3019
+ x1r = y4r + y6i;
3020
+ x1i = y4i - y6r;
3021
+ a[8] = x0r + x2r;
3022
+ a[9] = x0i + x2i;
3023
+ a[10] = x0r - x2r;
3024
+ a[11] = x0i - x2i;
3025
+ a[12] = x1r - x3i;
3026
+ a[13] = x1i + x3r;
3027
+ a[14] = x1r + x3i;
3028
+ a[15] = x1i - x3r;
3029
+ x0r = y0r + y2r;
3030
+ x0i = y0i + y2i;
3031
+ x1r = y0r - y2r;
3032
+ x1i = y0i - y2i;
3033
+ x2r = y1r + y3r;
3034
+ x2i = y1i + y3i;
3035
+ x3r = y1r - y3r;
3036
+ x3i = y1i - y3i;
3037
+ a[0] = x0r + x2r;
3038
+ a[1] = x0i + x2i;
3039
+ a[2] = x0r - x2r;
3040
+ a[3] = x0i - x2i;
3041
+ a[4] = x1r - x3i;
3042
+ a[5] = x1i + x3r;
3043
+ a[6] = x1r + x3i;
3044
+ a[7] = x1i - x3r;
3045
+ }
3046
+
3047
+
3048
+ void
3049
+ cftf162(double *a, double *w)
3050
+ {
3051
+ double wn4r, wk1r, wk1i, wk2r, wk2i, wk3r, wk3i,
3052
+ x0r, x0i, x1r, x1i, x2r, x2i,
3053
+ y0r, y0i, y1r, y1i, y2r, y2i, y3r, y3i,
3054
+ y4r, y4i, y5r, y5i, y6r, y6i, y7r, y7i,
3055
+ y8r, y8i, y9r, y9i, y10r, y10i, y11r, y11i,
3056
+ y12r, y12i, y13r, y13i, y14r, y14i, y15r, y15i;
3057
+
3058
+ wn4r = w[1];
3059
+ wk1r = w[4];
3060
+ wk1i = w[5];
3061
+ wk3r = w[6];
3062
+ wk3i = -w[7];
3063
+ wk2r = w[8];
3064
+ wk2i = w[9];
3065
+ x1r = a[0] - a[17];
3066
+ x1i = a[1] + a[16];
3067
+ x0r = a[8] - a[25];
3068
+ x0i = a[9] + a[24];
3069
+ x2r = wn4r * (x0r - x0i);
3070
+ x2i = wn4r * (x0i + x0r);
3071
+ y0r = x1r + x2r;
3072
+ y0i = x1i + x2i;
3073
+ y4r = x1r - x2r;
3074
+ y4i = x1i - x2i;
3075
+ x1r = a[0] + a[17];
3076
+ x1i = a[1] - a[16];
3077
+ x0r = a[8] + a[25];
3078
+ x0i = a[9] - a[24];
3079
+ x2r = wn4r * (x0r - x0i);
3080
+ x2i = wn4r * (x0i + x0r);
3081
+ y8r = x1r - x2i;
3082
+ y8i = x1i + x2r;
3083
+ y12r = x1r + x2i;
3084
+ y12i = x1i - x2r;
3085
+ x0r = a[2] - a[19];
3086
+ x0i = a[3] + a[18];
3087
+ x1r = wk1r * x0r - wk1i * x0i;
3088
+ x1i = wk1r * x0i + wk1i * x0r;
3089
+ x0r = a[10] - a[27];
3090
+ x0i = a[11] + a[26];
3091
+ x2r = wk3i * x0r - wk3r * x0i;
3092
+ x2i = wk3i * x0i + wk3r * x0r;
3093
+ y1r = x1r + x2r;
3094
+ y1i = x1i + x2i;
3095
+ y5r = x1r - x2r;
3096
+ y5i = x1i - x2i;
3097
+ x0r = a[2] + a[19];
3098
+ x0i = a[3] - a[18];
3099
+ x1r = wk3r * x0r - wk3i * x0i;
3100
+ x1i = wk3r * x0i + wk3i * x0r;
3101
+ x0r = a[10] + a[27];
3102
+ x0i = a[11] - a[26];
3103
+ x2r = wk1r * x0r + wk1i * x0i;
3104
+ x2i = wk1r * x0i - wk1i * x0r;
3105
+ y9r = x1r - x2r;
3106
+ y9i = x1i - x2i;
3107
+ y13r = x1r + x2r;
3108
+ y13i = x1i + x2i;
3109
+ x0r = a[4] - a[21];
3110
+ x0i = a[5] + a[20];
3111
+ x1r = wk2r * x0r - wk2i * x0i;
3112
+ x1i = wk2r * x0i + wk2i * x0r;
3113
+ x0r = a[12] - a[29];
3114
+ x0i = a[13] + a[28];
3115
+ x2r = wk2i * x0r - wk2r * x0i;
3116
+ x2i = wk2i * x0i + wk2r * x0r;
3117
+ y2r = x1r + x2r;
3118
+ y2i = x1i + x2i;
3119
+ y6r = x1r - x2r;
3120
+ y6i = x1i - x2i;
3121
+ x0r = a[4] + a[21];
3122
+ x0i = a[5] - a[20];
3123
+ x1r = wk2i * x0r - wk2r * x0i;
3124
+ x1i = wk2i * x0i + wk2r * x0r;
3125
+ x0r = a[12] + a[29];
3126
+ x0i = a[13] - a[28];
3127
+ x2r = wk2r * x0r - wk2i * x0i;
3128
+ x2i = wk2r * x0i + wk2i * x0r;
3129
+ y10r = x1r - x2r;
3130
+ y10i = x1i - x2i;
3131
+ y14r = x1r + x2r;
3132
+ y14i = x1i + x2i;
3133
+ x0r = a[6] - a[23];
3134
+ x0i = a[7] + a[22];
3135
+ x1r = wk3r * x0r - wk3i * x0i;
3136
+ x1i = wk3r * x0i + wk3i * x0r;
3137
+ x0r = a[14] - a[31];
3138
+ x0i = a[15] + a[30];
3139
+ x2r = wk1i * x0r - wk1r * x0i;
3140
+ x2i = wk1i * x0i + wk1r * x0r;
3141
+ y3r = x1r + x2r;
3142
+ y3i = x1i + x2i;
3143
+ y7r = x1r - x2r;
3144
+ y7i = x1i - x2i;
3145
+ x0r = a[6] + a[23];
3146
+ x0i = a[7] - a[22];
3147
+ x1r = wk1i * x0r + wk1r * x0i;
3148
+ x1i = wk1i * x0i - wk1r * x0r;
3149
+ x0r = a[14] + a[31];
3150
+ x0i = a[15] - a[30];
3151
+ x2r = wk3i * x0r - wk3r * x0i;
3152
+ x2i = wk3i * x0i + wk3r * x0r;
3153
+ y11r = x1r + x2r;
3154
+ y11i = x1i + x2i;
3155
+ y15r = x1r - x2r;
3156
+ y15i = x1i - x2i;
3157
+ x1r = y0r + y2r;
3158
+ x1i = y0i + y2i;
3159
+ x2r = y1r + y3r;
3160
+ x2i = y1i + y3i;
3161
+ a[0] = x1r + x2r;
3162
+ a[1] = x1i + x2i;
3163
+ a[2] = x1r - x2r;
3164
+ a[3] = x1i - x2i;
3165
+ x1r = y0r - y2r;
3166
+ x1i = y0i - y2i;
3167
+ x2r = y1r - y3r;
3168
+ x2i = y1i - y3i;
3169
+ a[4] = x1r - x2i;
3170
+ a[5] = x1i + x2r;
3171
+ a[6] = x1r + x2i;
3172
+ a[7] = x1i - x2r;
3173
+ x1r = y4r - y6i;
3174
+ x1i = y4i + y6r;
3175
+ x0r = y5r - y7i;
3176
+ x0i = y5i + y7r;
3177
+ x2r = wn4r * (x0r - x0i);
3178
+ x2i = wn4r * (x0i + x0r);
3179
+ a[8] = x1r + x2r;
3180
+ a[9] = x1i + x2i;
3181
+ a[10] = x1r - x2r;
3182
+ a[11] = x1i - x2i;
3183
+ x1r = y4r + y6i;
3184
+ x1i = y4i - y6r;
3185
+ x0r = y5r + y7i;
3186
+ x0i = y5i - y7r;
3187
+ x2r = wn4r * (x0r - x0i);
3188
+ x2i = wn4r * (x0i + x0r);
3189
+ a[12] = x1r - x2i;
3190
+ a[13] = x1i + x2r;
3191
+ a[14] = x1r + x2i;
3192
+ a[15] = x1i - x2r;
3193
+ x1r = y8r + y10r;
3194
+ x1i = y8i + y10i;
3195
+ x2r = y9r - y11r;
3196
+ x2i = y9i - y11i;
3197
+ a[16] = x1r + x2r;
3198
+ a[17] = x1i + x2i;
3199
+ a[18] = x1r - x2r;
3200
+ a[19] = x1i - x2i;
3201
+ x1r = y8r - y10r;
3202
+ x1i = y8i - y10i;
3203
+ x2r = y9r + y11r;
3204
+ x2i = y9i + y11i;
3205
+ a[20] = x1r - x2i;
3206
+ a[21] = x1i + x2r;
3207
+ a[22] = x1r + x2i;
3208
+ a[23] = x1i - x2r;
3209
+ x1r = y12r - y14i;
3210
+ x1i = y12i + y14r;
3211
+ x0r = y13r + y15i;
3212
+ x0i = y13i - y15r;
3213
+ x2r = wn4r * (x0r - x0i);
3214
+ x2i = wn4r * (x0i + x0r);
3215
+ a[24] = x1r + x2r;
3216
+ a[25] = x1i + x2i;
3217
+ a[26] = x1r - x2r;
3218
+ a[27] = x1i - x2i;
3219
+ x1r = y12r + y14i;
3220
+ x1i = y12i - y14r;
3221
+ x0r = y13r - y15i;
3222
+ x0i = y13i + y15r;
3223
+ x2r = wn4r * (x0r - x0i);
3224
+ x2i = wn4r * (x0i + x0r);
3225
+ a[28] = x1r - x2i;
3226
+ a[29] = x1i + x2r;
3227
+ a[30] = x1r + x2i;
3228
+ a[31] = x1i - x2r;
3229
+ }
3230
+
3231
+
3232
+ void
3233
+ cftf081(double *a, double *w)
3234
+ {
3235
+ double wn4r, x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i,
3236
+ y0r, y0i, y1r, y1i, y2r, y2i, y3r, y3i,
3237
+ y4r, y4i, y5r, y5i, y6r, y6i, y7r, y7i;
3238
+
3239
+ wn4r = w[1];
3240
+ x0r = a[0] + a[8];
3241
+ x0i = a[1] + a[9];
3242
+ x1r = a[0] - a[8];
3243
+ x1i = a[1] - a[9];
3244
+ x2r = a[4] + a[12];
3245
+ x2i = a[5] + a[13];
3246
+ x3r = a[4] - a[12];
3247
+ x3i = a[5] - a[13];
3248
+ y0r = x0r + x2r;
3249
+ y0i = x0i + x2i;
3250
+ y2r = x0r - x2r;
3251
+ y2i = x0i - x2i;
3252
+ y1r = x1r - x3i;
3253
+ y1i = x1i + x3r;
3254
+ y3r = x1r + x3i;
3255
+ y3i = x1i - x3r;
3256
+ x0r = a[2] + a[10];
3257
+ x0i = a[3] + a[11];
3258
+ x1r = a[2] - a[10];
3259
+ x1i = a[3] - a[11];
3260
+ x2r = a[6] + a[14];
3261
+ x2i = a[7] + a[15];
3262
+ x3r = a[6] - a[14];
3263
+ x3i = a[7] - a[15];
3264
+ y4r = x0r + x2r;
3265
+ y4i = x0i + x2i;
3266
+ y6r = x0r - x2r;
3267
+ y6i = x0i - x2i;
3268
+ x0r = x1r - x3i;
3269
+ x0i = x1i + x3r;
3270
+ x2r = x1r + x3i;
3271
+ x2i = x1i - x3r;
3272
+ y5r = wn4r * (x0r - x0i);
3273
+ y5i = wn4r * (x0r + x0i);
3274
+ y7r = wn4r * (x2r - x2i);
3275
+ y7i = wn4r * (x2r + x2i);
3276
+ a[8] = y1r + y5r;
3277
+ a[9] = y1i + y5i;
3278
+ a[10] = y1r - y5r;
3279
+ a[11] = y1i - y5i;
3280
+ a[12] = y3r - y7i;
3281
+ a[13] = y3i + y7r;
3282
+ a[14] = y3r + y7i;
3283
+ a[15] = y3i - y7r;
3284
+ a[0] = y0r + y4r;
3285
+ a[1] = y0i + y4i;
3286
+ a[2] = y0r - y4r;
3287
+ a[3] = y0i - y4i;
3288
+ a[4] = y2r - y6i;
3289
+ a[5] = y2i + y6r;
3290
+ a[6] = y2r + y6i;
3291
+ a[7] = y2i - y6r;
3292
+ }
3293
+
3294
+
3295
+ void
3296
+ cftf082(double *a, double *w)
3297
+ {
3298
+ double wn4r, wk1r, wk1i, x0r, x0i, x1r, x1i,
3299
+ y0r, y0i, y1r, y1i, y2r, y2i, y3r, y3i,
3300
+ y4r, y4i, y5r, y5i, y6r, y6i, y7r, y7i;
3301
+
3302
+ wn4r = w[1];
3303
+ wk1r = w[2];
3304
+ wk1i = w[3];
3305
+ y0r = a[0] - a[9];
3306
+ y0i = a[1] + a[8];
3307
+ y1r = a[0] + a[9];
3308
+ y1i = a[1] - a[8];
3309
+ x0r = a[4] - a[13];
3310
+ x0i = a[5] + a[12];
3311
+ y2r = wn4r * (x0r - x0i);
3312
+ y2i = wn4r * (x0i + x0r);
3313
+ x0r = a[4] + a[13];
3314
+ x0i = a[5] - a[12];
3315
+ y3r = wn4r * (x0r - x0i);
3316
+ y3i = wn4r * (x0i + x0r);
3317
+ x0r = a[2] - a[11];
3318
+ x0i = a[3] + a[10];
3319
+ y4r = wk1r * x0r - wk1i * x0i;
3320
+ y4i = wk1r * x0i + wk1i * x0r;
3321
+ x0r = a[2] + a[11];
3322
+ x0i = a[3] - a[10];
3323
+ y5r = wk1i * x0r - wk1r * x0i;
3324
+ y5i = wk1i * x0i + wk1r * x0r;
3325
+ x0r = a[6] - a[15];
3326
+ x0i = a[7] + a[14];
3327
+ y6r = wk1i * x0r - wk1r * x0i;
3328
+ y6i = wk1i * x0i + wk1r * x0r;
3329
+ x0r = a[6] + a[15];
3330
+ x0i = a[7] - a[14];
3331
+ y7r = wk1r * x0r - wk1i * x0i;
3332
+ y7i = wk1r * x0i + wk1i * x0r;
3333
+ x0r = y0r + y2r;
3334
+ x0i = y0i + y2i;
3335
+ x1r = y4r + y6r;
3336
+ x1i = y4i + y6i;
3337
+ a[0] = x0r + x1r;
3338
+ a[1] = x0i + x1i;
3339
+ a[2] = x0r - x1r;
3340
+ a[3] = x0i - x1i;
3341
+ x0r = y0r - y2r;
3342
+ x0i = y0i - y2i;
3343
+ x1r = y4r - y6r;
3344
+ x1i = y4i - y6i;
3345
+ a[4] = x0r - x1i;
3346
+ a[5] = x0i + x1r;
3347
+ a[6] = x0r + x1i;
3348
+ a[7] = x0i - x1r;
3349
+ x0r = y1r - y3i;
3350
+ x0i = y1i + y3r;
3351
+ x1r = y5r - y7r;
3352
+ x1i = y5i - y7i;
3353
+ a[8] = x0r + x1r;
3354
+ a[9] = x0i + x1i;
3355
+ a[10] = x0r - x1r;
3356
+ a[11] = x0i - x1i;
3357
+ x0r = y1r + y3i;
3358
+ x0i = y1i - y3r;
3359
+ x1r = y5r + y7r;
3360
+ x1i = y5i + y7i;
3361
+ a[12] = x0r - x1i;
3362
+ a[13] = x0i + x1r;
3363
+ a[14] = x0r + x1i;
3364
+ a[15] = x0i - x1r;
3365
+ }
3366
+
3367
+
3368
+ void
3369
+ cftf040(double *a)
3370
+ {
3371
+ double x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i;
3372
+
3373
+ x0r = a[0] + a[4];
3374
+ x0i = a[1] + a[5];
3375
+ x1r = a[0] - a[4];
3376
+ x1i = a[1] - a[5];
3377
+ x2r = a[2] + a[6];
3378
+ x2i = a[3] + a[7];
3379
+ x3r = a[2] - a[6];
3380
+ x3i = a[3] - a[7];
3381
+ a[0] = x0r + x2r;
3382
+ a[1] = x0i + x2i;
3383
+ a[2] = x1r - x3i;
3384
+ a[3] = x1i + x3r;
3385
+ a[4] = x0r - x2r;
3386
+ a[5] = x0i - x2i;
3387
+ a[6] = x1r + x3i;
3388
+ a[7] = x1i - x3r;
3389
+ }
3390
+
3391
+
3392
+ void
3393
+ cftb040(double *a)
3394
+ {
3395
+ double x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i;
3396
+
3397
+ x0r = a[0] + a[4];
3398
+ x0i = a[1] + a[5];
3399
+ x1r = a[0] - a[4];
3400
+ x1i = a[1] - a[5];
3401
+ x2r = a[2] + a[6];
3402
+ x2i = a[3] + a[7];
3403
+ x3r = a[2] - a[6];
3404
+ x3i = a[3] - a[7];
3405
+ a[0] = x0r + x2r;
3406
+ a[1] = x0i + x2i;
3407
+ a[2] = x1r + x3i;
3408
+ a[3] = x1i - x3r;
3409
+ a[4] = x0r - x2r;
3410
+ a[5] = x0i - x2i;
3411
+ a[6] = x1r - x3i;
3412
+ a[7] = x1i + x3r;
3413
+ }
3414
+
3415
+
3416
+ void
3417
+ cftx020(double *a)
3418
+ {
3419
+ double x0r, x0i;
3420
+
3421
+ x0r = a[0] - a[2];
3422
+ x0i = a[1] - a[3];
3423
+ a[0] += a[2];
3424
+ a[1] += a[3];
3425
+ a[2] = x0r;
3426
+ a[3] = x0i;
3427
+ }
3428
+
3429
+
3430
+ void
3431
+ rftfsub(int n, double *a, int nc, double *c)
3432
+ {
3433
+ int j, k, kk, ks, m;
3434
+ double wkr, wki, xr, xi, yr, yi;
3435
+
3436
+ m = n >> 1;
3437
+ ks = 2 * nc / m;
3438
+ kk = 0;
3439
+ for (j = 2; j < m; j += 2)
3440
+ {
3441
+ k = n - j;
3442
+ kk += ks;
3443
+ wkr = 0.5 - c[nc - kk];
3444
+ wki = c[kk];
3445
+ xr = a[j] - a[k];
3446
+ xi = a[j + 1] + a[k + 1];
3447
+ yr = wkr * xr - wki * xi;
3448
+ yi = wkr * xi + wki * xr;
3449
+ a[j] -= yr;
3450
+ a[j + 1] -= yi;
3451
+ a[k] += yr;
3452
+ a[k + 1] -= yi;
3453
+ }
3454
+ }
3455
+
3456
+
3457
+ void
3458
+ rftbsub(int n, double *a, int nc, double *c)
3459
+ {
3460
+ int j, k, kk, ks, m;
3461
+ double wkr, wki, xr, xi, yr, yi;
3462
+
3463
+ m = n >> 1;
3464
+ ks = 2 * nc / m;
3465
+ kk = 0;
3466
+ for (j = 2; j < m; j += 2)
3467
+ {
3468
+ k = n - j;
3469
+ kk += ks;
3470
+ wkr = 0.5 - c[nc - kk];
3471
+ wki = c[kk];
3472
+ xr = a[j] - a[k];
3473
+ xi = a[j + 1] + a[k + 1];
3474
+ yr = wkr * xr + wki * xi;
3475
+ yi = wkr * xi - wki * xr;
3476
+ a[j] -= yr;
3477
+ a[j + 1] -= yi;
3478
+ a[k] += yr;
3479
+ a[k + 1] -= yi;
3480
+ }
3481
+ }
3482
+
3483
+
3484
+ void
3485
+ dctsub(int n, double *a, int nc, double *c)
3486
+ {
3487
+ int j, k, kk, ks, m;
3488
+ double wkr, wki, xr;
3489
+
3490
+ m = n >> 1;
3491
+ ks = nc / n;
3492
+ kk = 0;
3493
+ for (j = 1; j < m; j++)
3494
+ {
3495
+ k = n - j;
3496
+ kk += ks;
3497
+ wkr = c[kk] - c[nc - kk];
3498
+ wki = c[kk] + c[nc - kk];
3499
+ xr = wki * a[j] - wkr * a[k];
3500
+ a[j] = wkr * a[j] + wki * a[k];
3501
+ a[k] = xr;
3502
+ }
3503
+ a[m] *= c[0];
3504
+ }
3505
+
3506
+
3507
+ void
3508
+ dstsub(int n, double *a, int nc, double *c)
3509
+ {
3510
+ int j, k, kk, ks, m;
3511
+ double wkr, wki, xr;
3512
+
3513
+ m = n >> 1;
3514
+ ks = nc / n;
3515
+ kk = 0;
3516
+ for (j = 1; j < m; j++)
3517
+ {
3518
+ k = n - j;
3519
+ kk += ks;
3520
+ wkr = c[kk] - c[nc - kk];
3521
+ wki = c[kk] + c[nc - kk];
3522
+ xr = wki * a[k] - wkr * a[j];
3523
+ a[k] = wkr * a[k] + wki * a[j];
3524
+ a[j] = xr;
3525
+ }
3526
+ a[m] *= c[0];
3527
+ }
3528
+