001/* ***** BEGIN LICENSE BLOCK *****
002 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
003 *
004 * The contents of this file are subject to the Mozilla Public License Version
005 * 1.1 (the "License"); you may not use this file except in compliance with
006 * the License. You may obtain a copy of the License at
007 * http://www.mozilla.org/MPL/
008 *
009 * Software distributed under the License is distributed on an "AS IS" basis,
010 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
011 * for the specific language governing rights and limitations under the
012 * License.
013 *
014 * The Original Code is JTransforms.
015 *
016 * The Initial Developer of the Original Code is
017 * Piotr Wendykier, Emory University.
018 * Portions created by the Initial Developer are Copyright (C) 2007-2009
019 * the Initial Developer. All Rights Reserved.
020 *
021 * Alternatively, the contents of this file may be used under the terms of
022 * either the GNU General Public License Version 2 or later (the "GPL"), or
023 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
024 * in which case the provisions of the GPL or the LGPL are applicable instead
025 * of those above. If you wish to allow use of your version of this file only
026 * under the terms of either the GPL or the LGPL, and not to allow others to
027 * use your version of this file under the terms of the MPL, indicate your
028 * decision by deleting the provisions above and replace them with the notice
029 * and other provisions required by the GPL or the LGPL. If you do not delete
030 * the provisions above, a recipient may use your version of this file under
031 * the terms of any one of the MPL, the GPL or the LGPL.
032 *
033 * ***** END LICENSE BLOCK ***** */
034
035package edu.emory.mathcs.jtransforms.fft;
036
037import java.util.concurrent.Future;
038
039import edu.emory.mathcs.utils.ConcurrencyUtils;
040
041/**
042 * Computes 1D Discrete Fourier Transform (DFT) of complex and real, double
043 * precision data. The size of the data can be an arbitrary number. This is a
044 * parallel implementation of split-radix and mixed-radix algorithms optimized
045 * for SMP systems. <br>
046 * <br>
047 * This code is derived from General Purpose FFT Package written by Takuya Ooura
048 * (http://www.kurims.kyoto-u.ac.jp/~ooura/fft.html) and from JFFTPack written
049 * by Baoshe Zhang (http://jfftpack.sourceforge.net/)
050 * 
051 * @author Piotr Wendykier (piotr.wendykier@gmail.com)
052 * 
053 */
054public class DoubleFFT_1D {
055
056    private static enum Plans {
057        SPLIT_RADIX, MIXED_RADIX, BLUESTEIN
058    }
059
060    private int n;
061
062    private int nBluestein;
063
064    private int[] ip;
065
066    private double[] w;
067
068    private int nw;
069
070    private int nc;
071
072    private double[] wtable;
073
074    private double[] wtable_r;
075
076    private double[] bk1;
077
078    private double[] bk2;
079
080    private Plans plan;
081
082    private static final int[] factors = { 4, 2, 3, 5 };
083
084    private static final double PI = 3.14159265358979311599796346854418516;
085
086    private static final double TWO_PI = 6.28318530717958623199592693708837032;
087
088    /**
089     * Creates new instance of DoubleFFT_1D.
090     * 
091     * @param n
092     *            size of data
093     */
094    public DoubleFFT_1D(int n) {
095        if (n < 1) {
096            throw new IllegalArgumentException("n must be greater than 0");
097        }
098        this.n = n;
099
100        if (!ConcurrencyUtils.isPowerOf2(n)) {
101            if (getReminder(n, factors) >= 211) {
102                plan = Plans.BLUESTEIN;
103                nBluestein = ConcurrencyUtils.nextPow2(n * 2 - 1);
104                bk1 = new double[2 * nBluestein];
105                bk2 = new double[2 * nBluestein];
106                this.ip = new int[2 + (int) Math.ceil(2 + (1 << (int) (Math.log(nBluestein + 0.5) / Math.log(2)) / 2))];
107                this.w = new double[nBluestein];
108                int twon = 2 * nBluestein;
109                nw = ip[0];
110                if (twon > (nw << 2)) {
111                    nw = twon >> 2;
112                    makewt(nw);
113                }
114                nc = ip[1];
115                if (nBluestein > (nc << 2)) {
116                    nc = nBluestein >> 2;
117                    makect(nc, w, nw);
118                }
119                bluesteini();
120            } else {
121                plan = Plans.MIXED_RADIX;
122                wtable = new double[4 * n + 15];
123                wtable_r = new double[2 * n + 15];
124                cffti();
125                rffti();
126            }
127        } else {
128            plan = Plans.SPLIT_RADIX;
129            this.ip = new int[2 + (int) Math.ceil(2 + (1 << (int) (Math.log(n + 0.5) / Math.log(2)) / 2))];
130            this.w = new double[n];
131            int twon = 2 * n;
132            nw = ip[0];
133            if (twon > (nw << 2)) {
134                nw = twon >> 2;
135                makewt(nw);
136            }
137            nc = ip[1];
138            if (n > (nc << 2)) {
139                nc = n >> 2;
140                makect(nc, w, nw);
141            }
142        }
143    }
144
145    /**
146     * Computes 1D forward DFT of complex data leaving the result in
147     * <code>a</code>. Complex number is stored as two double values in
148     * sequence: the real and imaginary part, i.e. the size of the input array
149     * must be greater or equal 2*n. The physical layout of the input data has
150     * to be as follows:<br>
151     * 
152     * <pre>
153     * a[2*k] = Re[k], 
154     * a[2*k+1] = Im[k], 0&lt;=k&lt;n
155     * </pre>
156     * 
157     * @param a
158     *            data to transform
159     */
160    public void complexForward(double[] a) {
161        complexForward(a, 0);
162    }
163
164    /**
165     * Computes 1D forward DFT of complex data leaving the result in
166     * <code>a</code>. Complex number is stored as two double values in
167     * sequence: the real and imaginary part, i.e. the size of the input array
168     * must be greater or equal 2*n. The physical layout of the input data has
169     * to be as follows:<br>
170     * 
171     * <pre>
172     * a[offa+2*k] = Re[k], 
173     * a[offa+2*k+1] = Im[k], 0&lt;=k&lt;n
174     * </pre>
175     * 
176     * @param a
177     *            data to transform
178     * @param offa
179     *            index of the first element in array <code>a</code>
180     */
181    public void complexForward(double[] a, int offa) {
182        if (n == 1)
183            return;
184        switch (plan) {
185        case SPLIT_RADIX:
186            cftbsub(2 * n, a, offa, ip, nw, w);
187            break;
188        case MIXED_RADIX:
189            cfftf(a, offa, -1);
190            break;
191        case BLUESTEIN:
192            bluestein_complex(a, offa, -1);
193            break;
194        }
195    }
196
197    /**
198     * Computes 1D inverse DFT of complex data leaving the result in
199     * <code>a</code>. Complex number is stored as two double values in
200     * sequence: the real and imaginary part, i.e. the size of the input array
201     * must be greater or equal 2*n. The physical layout of the input data has
202     * to be as follows:<br>
203     * 
204     * <pre>
205     * a[2*k] = Re[k], 
206     * a[2*k+1] = Im[k], 0&lt;=k&lt;n
207     * </pre>
208     * 
209     * @param a
210     *            data to transform
211     * @param scale
212     *            if true then scaling is performed
213     */
214    public void complexInverse(double[] a, boolean scale) {
215        complexInverse(a, 0, scale);
216    }
217
218    /**
219     * Computes 1D inverse DFT of complex data leaving the result in
220     * <code>a</code>. Complex number is stored as two double values in
221     * sequence: the real and imaginary part, i.e. the size of the input array
222     * must be greater or equal 2*n. The physical layout of the input data has
223     * to be as follows:<br>
224     * 
225     * <pre>
226     * a[offa+2*k] = Re[k], 
227     * a[offa+2*k+1] = Im[k], 0&lt;=k&lt;n
228     * </pre>
229     * 
230     * @param a
231     *            data to transform
232     * @param offa
233     *            index of the first element in array <code>a</code>
234     * @param scale
235     *            if true then scaling is performed
236     */
237    public void complexInverse(double[] a, int offa, boolean scale) {
238        if (n == 1)
239            return;
240        switch (plan) {
241        case SPLIT_RADIX:
242            cftfsub(2 * n, a, offa, ip, nw, w);
243            break;
244        case MIXED_RADIX:
245            cfftf(a, offa, +1);
246            break;
247        case BLUESTEIN:
248            bluestein_complex(a, offa, 1);
249            break;
250        }
251        if (scale) {
252            scale(n, a, offa, true);
253        }
254    }
255
256    /**
257     * Computes 1D forward DFT of real data leaving the result in <code>a</code>
258     * . The physical layout of the output data is as follows:<br>
259     * 
260     * if n is even then
261     * 
262     * <pre>
263     * a[2*k] = Re[k], 0&lt;=k&lt;n/2
264     * a[2*k+1] = Im[k], 0&lt;k&lt;n/2
265     * a[1] = Re[n/2]
266     * </pre>
267     * 
268     * if n is odd then
269     * 
270     * <pre>
271     * a[2*k] = Re[k], 0&lt;=k&lt;(n+1)/2
272     * a[2*k+1] = Im[k], 0&lt;k&lt;(n-1)/2
273     * a[1] = Im[(n-1)/2]
274     * </pre>
275     * 
276     * This method computes only half of the elements of the real transform. The
277     * other half satisfies the symmetry condition. If you want the full real
278     * forward transform, use <code>realForwardFull</code>. To get back the
279     * original data, use <code>realInverse</code> on the output of this method.
280     * 
281     * @param a
282     *            data to transform
283     */
284    public void realForward(double[] a) {
285        realForward(a, 0);
286    }
287
288    /**
289     * Computes 1D forward DFT of real data leaving the result in <code>a</code>
290     * . The physical layout of the output data is as follows:<br>
291     * 
292     * if n is even then
293     * 
294     * <pre>
295     * a[offa+2*k] = Re[k], 0&lt;=k&lt;n/2
296     * a[offa+2*k+1] = Im[k], 0&lt;k&lt;n/2
297     * a[offa+1] = Re[n/2]
298     * </pre>
299     * 
300     * if n is odd then
301     * 
302     * <pre>
303     * a[offa+2*k] = Re[k], 0&lt;=k&lt;(n+1)/2
304     * a[offa+2*k+1] = Im[k], 0&lt;k&lt;(n-1)/2
305     * a[offa+1] = Im[(n-1)/2]
306     * </pre>
307     * 
308     * This method computes only half of the elements of the real transform. The
309     * other half satisfies the symmetry condition. If you want the full real
310     * forward transform, use <code>realForwardFull</code>. To get back the
311     * original data, use <code>realInverse</code> on the output of this method.
312     * 
313     * @param a
314     *            data to transform
315     * @param offa
316     *            index of the first element in array <code>a</code>
317     */
318    public void realForward(double[] a, int offa) {
319        if (n == 1)
320            return;
321
322        switch (plan) {
323        case SPLIT_RADIX:
324            double xi;
325
326            if (n > 4) {
327                cftfsub(n, a, offa, ip, nw, w);
328                rftfsub(n, a, offa, nc, w, nw);
329            } else if (n == 4) {
330                cftx020(a, offa);
331            }
332            xi = a[offa] - a[offa + 1];
333            a[offa] += a[offa + 1];
334            a[offa + 1] = xi;
335            break;
336        case MIXED_RADIX:
337            rfftf(a, offa);
338            for (int k = n - 1; k >= 2; k--) {
339                int idx = offa + k;
340                double tmp = a[idx];
341                a[idx] = a[idx - 1];
342                a[idx - 1] = tmp;
343            }
344            break;
345        case BLUESTEIN:
346            bluestein_real_forward(a, offa);
347            break;
348        }
349    }
350
351    /**
352     * Computes 1D forward DFT of real data leaving the result in <code>a</code>
353     * . This method computes the full real forward transform, i.e. you will get
354     * the same result as from <code>complexForward</code> called with all
355     * imaginary parts equal 0. Because the result is stored in <code>a</code>,
356     * the size of the input array must greater or equal 2*n, with only the
357     * first n elements filled with real data. To get back the original data,
358     * use <code>complexInverse</code> on the output of this method.
359     * 
360     * @param a
361     *            data to transform
362     */
363    public void realForwardFull(double[] a) {
364        realForwardFull(a, 0);
365    }
366
367    /**
368     * Computes 1D forward DFT of real data leaving the result in <code>a</code>
369     * . This method computes the full real forward transform, i.e. you will get
370     * the same result as from <code>complexForward</code> called with all
371     * imaginary part equal 0. Because the result is stored in <code>a</code>,
372     * the size of the input array must greater or equal 2*n, with only the
373     * first n elements filled with real data. To get back the original data,
374     * use <code>complexInverse</code> on the output of this method.
375     * 
376     * @param a
377     *            data to transform
378     * @param offa
379     *            index of the first element in array <code>a</code>
380     */
381    public void realForwardFull(final double[] a, final int offa) {
382
383        final int twon = 2 * n;
384        switch (plan) {
385        case SPLIT_RADIX:
386            realForward(a, offa);
387            int nthreads = ConcurrencyUtils.getNumberOfThreads();
388            if ((nthreads > 1) && (n / 2 > ConcurrencyUtils.getThreadsBeginN_1D_FFT_2Threads())) {
389                Future<?>[] futures = new Future[nthreads];
390                int k = n / 2 / nthreads;
391                for (int i = 0; i < nthreads; i++) {
392                    final int firstIdx = i * k;
393                    final int lastIdx = (i == (nthreads - 1)) ? n / 2 : firstIdx + k;
394                    futures[i] = ConcurrencyUtils.submit(new Runnable() {
395                        public void run() {
396                            int idx1, idx2;
397                            for (int k = firstIdx; k < lastIdx; k++) {
398                                idx1 = 2 * k;
399                                idx2 = offa + ((twon - idx1) % twon);
400                                a[idx2] = a[offa + idx1];
401                                a[idx2 + 1] = -a[offa + idx1 + 1];
402                            }
403                        }
404                    });
405                }
406                ConcurrencyUtils.waitForCompletion(futures);
407            } else {
408                int idx1, idx2;
409                for (int k = 0; k < n / 2; k++) {
410                    idx1 = 2 * k;
411                    idx2 = offa + ((twon - idx1) % twon);
412                    a[idx2] = a[offa + idx1];
413                    a[idx2 + 1] = -a[offa + idx1 + 1];
414                }
415            }
416            a[offa + n] = -a[offa + 1];
417            a[offa + 1] = 0;
418            break;
419        case MIXED_RADIX:
420            rfftf(a, offa);
421            int m;
422            if (n % 2 == 0) {
423                m = n / 2;
424            } else {
425                m = (n + 1) / 2;
426            }
427            for (int k = 1; k < m; k++) {
428                int idx1 = offa + twon - 2 * k;
429                int idx2 = offa + 2 * k;
430                a[idx1 + 1] = -a[idx2];
431                a[idx1] = a[idx2 - 1];
432            }
433            for (int k = 1; k < n; k++) {
434                int idx = offa + n - k;
435                double tmp = a[idx + 1];
436                a[idx + 1] = a[idx];
437                a[idx] = tmp;
438            }
439            a[offa + 1] = 0;
440            break;
441        case BLUESTEIN:
442            bluestein_real_full(a, offa, -1);
443            break;
444        }
445    }
446
447    /**
448     * Computes 1D inverse DFT of real data leaving the result in <code>a</code>
449     * . The physical layout of the input data has to be as follows:<br>
450     * 
451     * if n is even then
452     * 
453     * <pre>
454     * a[2*k] = Re[k], 0&lt;=k&lt;n/2
455     * a[2*k+1] = Im[k], 0&lt;k&lt;n/2
456     * a[1] = Re[n/2]
457     * </pre>
458     * 
459     * if n is odd then
460     * 
461     * <pre>
462     * a[2*k] = Re[k], 0&lt;=k&lt;(n+1)/2
463     * a[2*k+1] = Im[k], 0&lt;k&lt;(n-1)/2
464     * a[1] = Im[(n-1)/2]
465     * </pre>
466     * 
467     * This method computes only half of the elements of the real transform. The
468     * other half satisfies the symmetry condition. If you want the full real
469     * inverse transform, use <code>realInverseFull</code>.
470     * 
471     * @param a
472     *            data to transform
473     * 
474     * @param scale
475     *            if true then scaling is performed
476     * 
477     */
478    public void realInverse(double[] a, boolean scale) {
479        realInverse(a, 0, scale);
480    }
481
482    /**
483     * Computes 1D inverse DFT of real data leaving the result in <code>a</code>
484     * . The physical layout of the input data has to be as follows:<br>
485     * 
486     * if n is even then
487     * 
488     * <pre>
489     * a[offa+2*k] = Re[k], 0&lt;=k&lt;n/2
490     * a[offa+2*k+1] = Im[k], 0&lt;k&lt;n/2
491     * a[offa+1] = Re[n/2]
492     * </pre>
493     * 
494     * if n is odd then
495     * 
496     * <pre>
497     * a[offa+2*k] = Re[k], 0&lt;=k&lt;(n+1)/2
498     * a[offa+2*k+1] = Im[k], 0&lt;k&lt;(n-1)/2
499     * a[offa+1] = Im[(n-1)/2]
500     * </pre>
501     * 
502     * This method computes only half of the elements of the real transform. The
503     * other half satisfies the symmetry condition. If you want the full real
504     * inverse transform, use <code>realInverseFull</code>.
505     * 
506     * @param a
507     *            data to transform
508     * @param offa
509     *            index of the first element in array <code>a</code>
510     * @param scale
511     *            if true then scaling is performed
512     * 
513     */
514    public void realInverse(double[] a, int offa, boolean scale) {
515        if (n == 1)
516            return;
517        switch (plan) {
518        case SPLIT_RADIX:
519            a[offa + 1] = 0.5 * (a[offa] - a[offa + 1]);
520            a[offa] -= a[offa + 1];
521            if (n > 4) {
522                rftfsub(n, a, offa, nc, w, nw);
523                cftbsub(n, a, offa, ip, nw, w);
524            } else if (n == 4) {
525                cftxc020(a, offa);
526            }
527            if (scale) {
528                scale(n / 2, a, offa, false);
529            }
530            break;
531        case MIXED_RADIX:
532            for (int k = 2; k < n; k++) {
533                int idx = offa + k;
534                double tmp = a[idx - 1];
535                a[idx - 1] = a[idx];
536                a[idx] = tmp;
537            }
538            rfftb(a, offa);
539            if (scale) {
540                scale(n, a, offa, false);
541            }
542            break;
543        case BLUESTEIN:
544            bluestein_real_inverse(a, offa);
545            if (scale) {
546                scale(n, a, offa, false);
547            }
548            break;
549        }
550
551    }
552
553    /**
554     * Computes 1D inverse DFT of real data leaving the result in <code>a</code>
555     * . This method computes the full real inverse transform, i.e. you will get
556     * the same result as from <code>complexInverse</code> called with all
557     * imaginary part equal 0. Because the result is stored in <code>a</code>,
558     * the size of the input array must greater or equal 2*n, with only the
559     * first n elements filled with real data.
560     * 
561     * @param a
562     *            data to transform
563     * @param scale
564     *            if true then scaling is performed
565     */
566    public void realInverseFull(double[] a, boolean scale) {
567        realInverseFull(a, 0, scale);
568    }
569
570    /**
571     * Computes 1D inverse DFT of real data leaving the result in <code>a</code>
572     * . This method computes the full real inverse transform, i.e. you will get
573     * the same result as from <code>complexInverse</code> called with all
574     * imaginary part equal 0. Because the result is stored in <code>a</code>,
575     * the size of the input array must greater or equal 2*n, with only the
576     * first n elements filled with real data.
577     * 
578     * @param a
579     *            data to transform
580     * @param offa
581     *            index of the first element in array <code>a</code>
582     * @param scale
583     *            if true then scaling is performed
584     */
585    public void realInverseFull(final double[] a, final int offa, boolean scale) {
586        final int twon = 2 * n;
587        switch (plan) {
588        case SPLIT_RADIX:
589            realInverse2(a, offa, scale);
590            int nthreads = ConcurrencyUtils.getNumberOfThreads();
591            if ((nthreads > 1) && (n / 2 > ConcurrencyUtils.getThreadsBeginN_1D_FFT_2Threads())) {
592                Future<?>[] futures = new Future[nthreads];
593                int k = n / 2 / nthreads;
594                for (int i = 0; i < nthreads; i++) {
595                    final int firstIdx = i * k;
596                    final int lastIdx = (i == (nthreads - 1)) ? n / 2 : firstIdx + k;
597                    futures[i] = ConcurrencyUtils.submit(new Runnable() {
598                        public void run() {
599                            int idx1, idx2;
600                            for (int k = firstIdx; k < lastIdx; k++) {
601                                idx1 = 2 * k;
602                                idx2 = offa + ((twon - idx1) % twon);
603                                a[idx2] = a[offa + idx1];
604                                a[idx2 + 1] = -a[offa + idx1 + 1];
605                            }
606                        }
607                    });
608                }
609                ConcurrencyUtils.waitForCompletion(futures);
610            } else {
611                int idx1, idx2;
612                for (int k = 0; k < n / 2; k++) {
613                    idx1 = 2 * k;
614                    idx2 = offa + ((twon - idx1) % twon);
615                    a[idx2] = a[offa + idx1];
616                    a[idx2 + 1] = -a[offa + idx1 + 1];
617                }
618            }
619            a[offa + n] = -a[offa + 1];
620            a[offa + 1] = 0;
621            break;
622        case MIXED_RADIX:
623            rfftf(a, offa);
624            if (scale) {
625                scale(n, a, offa, false);
626            }
627            int m;
628            if (n % 2 == 0) {
629                m = n / 2;
630            } else {
631                m = (n + 1) / 2;
632            }
633            for (int k = 1; k < m; k++) {
634                int idx1 = offa + 2 * k;
635                int idx2 = offa + twon - 2 * k;
636                a[idx1] = -a[idx1];
637                a[idx2 + 1] = -a[idx1];
638                a[idx2] = a[idx1 - 1];
639            }
640            for (int k = 1; k < n; k++) {
641                int idx = offa + n - k;
642                double tmp = a[idx + 1];
643                a[idx + 1] = a[idx];
644                a[idx] = tmp;
645            }
646            a[offa + 1] = 0;
647            break;
648        case BLUESTEIN:
649            bluestein_real_full(a, offa, 1);
650            if (scale) {
651                scale(n, a, offa, true);
652            }
653            break;
654        }
655    }
656
657    protected void realInverse2(double[] a, int offa, boolean scale) {
658        if (n == 1)
659            return;
660        switch (plan) {
661        case SPLIT_RADIX:
662            double xi;
663
664            if (n > 4) {
665                cftfsub(n, a, offa, ip, nw, w);
666                rftbsub(n, a, offa, nc, w, nw);
667            } else if (n == 4) {
668                cftbsub(n, a, offa, ip, nw, w);
669            }
670            xi = a[offa] - a[offa + 1];
671            a[offa] += a[offa + 1];
672            a[offa + 1] = xi;
673            if (scale) {
674                scale(n, a, offa, false);
675            }
676            break;
677        case MIXED_RADIX:
678            rfftf(a, offa);
679            for (int k = n - 1; k >= 2; k--) {
680                int idx = offa + k;
681                double tmp = a[idx];
682                a[idx] = a[idx - 1];
683                a[idx - 1] = tmp;
684            }
685            if (scale) {
686                scale(n, a, offa, false);
687            }
688            int m;
689            if (n % 2 == 0) {
690                m = n / 2;
691                for (int i = 1; i < m; i++) {
692                    int idx = offa + 2 * i + 1;
693                    a[idx] = -a[idx];
694                }
695            } else {
696                m = (n - 1) / 2;
697                for (int i = 0; i < m; i++) {
698                    int idx = offa + 2 * i + 1;
699                    a[idx] = -a[idx];
700                }
701            }
702            break;
703        case BLUESTEIN:
704            bluestein_real_inverse2(a, offa);
705            if (scale) {
706                scale(n, a, offa, false);
707            }
708            break;
709        }
710    }
711
712    private static int getReminder(int n, int factors[]) {
713        int reminder = n;
714
715        if (n <= 0) {
716            throw new IllegalArgumentException("n must be positive integer");
717        }
718
719        for (int i = 0; i < factors.length && reminder != 1; i++) {
720            int factor = factors[i];
721            while ((reminder % factor) == 0) {
722                reminder /= factor;
723            }
724        }
725        return reminder;
726    }
727
728    /* -------- initializing routines -------- */
729
730    /*---------------------------------------------------------
731       cffti: initialization of Complex FFT
732      --------------------------------------------------------*/
733
734    void cffti(int n, int offw) {
735        if (n == 1)
736            return;
737
738        final int twon = 2 * n;
739        final int fourn = 4 * n;
740        double argh;
741        int idot, ntry = 0, i, j;
742        double argld;
743        int i1, k1, l1, l2, ib;
744        double fi;
745        int ld, ii, nf, ip, nl, nq, nr;
746        double arg;
747        int ido, ipm;
748
749        nl = n;
750        nf = 0;
751        j = 0;
752
753        factorize_loop: while (true) {
754            j++;
755            if (j <= 4)
756                ntry = factors[j - 1];
757            else
758                ntry += 2;
759            do {
760                nq = nl / ntry;
761                nr = nl - ntry * nq;
762                if (nr != 0)
763                    continue factorize_loop;
764                nf++;
765                wtable[offw + nf + 1 + fourn] = ntry;
766                nl = nq;
767                if (ntry == 2 && nf != 1) {
768                    for (i = 2; i <= nf; i++) {
769                        ib = nf - i + 2;
770                        int idx = ib + fourn;
771                        wtable[offw + idx + 1] = wtable[offw + idx];
772                    }
773                    wtable[offw + 2 + fourn] = 2;
774                }
775            } while (nl != 1);
776            break factorize_loop;
777        }
778        wtable[offw + fourn] = n;
779        wtable[offw + 1 + fourn] = nf;
780        argh = TWO_PI / (double) n;
781        i = 1;
782        l1 = 1;
783        for (k1 = 1; k1 <= nf; k1++) {
784            ip = (int) wtable[offw + k1 + 1 + fourn];
785            ld = 0;
786            l2 = l1 * ip;
787            ido = n / l2;
788            idot = ido + ido + 2;
789            ipm = ip - 1;
790            for (j = 1; j <= ipm; j++) {
791                i1 = i;
792                wtable[offw + i - 1 + twon] = 1;
793                wtable[offw + i + twon] = 0;
794                ld += l1;
795                fi = 0;
796                argld = ld * argh;
797                for (ii = 4; ii <= idot; ii += 2) {
798                    i += 2;
799                    fi += 1;
800                    arg = fi * argld;
801                    int idx = i + twon;
802                    wtable[offw + idx - 1] = Math.cos(arg);
803                    wtable[offw + idx] = Math.sin(arg);
804                }
805                if (ip > 5) {
806                    int idx1 = i1 + twon;
807                    int idx2 = i + twon;
808                    wtable[offw + idx1 - 1] = wtable[offw + idx2 - 1];
809                    wtable[offw + idx1] = wtable[offw + idx2];
810                }
811            }
812            l1 = l2;
813        }
814
815    }
816
817    void cffti() {
818        if (n == 1)
819            return;
820
821        final int twon = 2 * n;
822        final int fourn = 4 * n;
823        double argh;
824        int idot, ntry = 0, i, j;
825        double argld;
826        int i1, k1, l1, l2, ib;
827        double fi;
828        int ld, ii, nf, ip, nl, nq, nr;
829        double arg;
830        int ido, ipm;
831
832        nl = n;
833        nf = 0;
834        j = 0;
835
836        factorize_loop: while (true) {
837            j++;
838            if (j <= 4)
839                ntry = factors[j - 1];
840            else
841                ntry += 2;
842            do {
843                nq = nl / ntry;
844                nr = nl - ntry * nq;
845                if (nr != 0)
846                    continue factorize_loop;
847                nf++;
848                wtable[nf + 1 + fourn] = ntry;
849                nl = nq;
850                if (ntry == 2 && nf != 1) {
851                    for (i = 2; i <= nf; i++) {
852                        ib = nf - i + 2;
853                        int idx = ib + fourn;
854                        wtable[idx + 1] = wtable[idx];
855                    }
856                    wtable[2 + fourn] = 2;
857                }
858            } while (nl != 1);
859            break factorize_loop;
860        }
861        wtable[fourn] = n;
862        wtable[1 + fourn] = nf;
863        argh = TWO_PI / (double) n;
864        i = 1;
865        l1 = 1;
866        for (k1 = 1; k1 <= nf; k1++) {
867            ip = (int) wtable[k1 + 1 + fourn];
868            ld = 0;
869            l2 = l1 * ip;
870            ido = n / l2;
871            idot = ido + ido + 2;
872            ipm = ip - 1;
873            for (j = 1; j <= ipm; j++) {
874                i1 = i;
875                wtable[i - 1 + twon] = 1;
876                wtable[i + twon] = 0;
877                ld += l1;
878                fi = 0;
879                argld = ld * argh;
880                for (ii = 4; ii <= idot; ii += 2) {
881                    i += 2;
882                    fi += 1;
883                    arg = fi * argld;
884                    int idx = i + twon;
885                    wtable[idx - 1] = Math.cos(arg);
886                    wtable[idx] = Math.sin(arg);
887                }
888                if (ip > 5) {
889                    int idx1 = i1 + twon;
890                    int idx2 = i + twon;
891                    wtable[idx1 - 1] = wtable[idx2 - 1];
892                    wtable[idx1] = wtable[idx2];
893                }
894            }
895            l1 = l2;
896        }
897
898    }
899
900    void rffti() {
901
902        if (n == 1)
903            return;
904        final int twon = 2 * n;
905        double argh;
906        int ntry = 0, i, j;
907        double argld;
908        int k1, l1, l2, ib;
909        double fi;
910        int ld, ii, nf, ip, nl, is, nq, nr;
911        double arg;
912        int ido, ipm;
913        int nfm1;
914
915        nl = n;
916        nf = 0;
917        j = 0;
918
919        factorize_loop: while (true) {
920            ++j;
921            if (j <= 4)
922                ntry = factors[j - 1];
923            else
924                ntry += 2;
925            do {
926                nq = nl / ntry;
927                nr = nl - ntry * nq;
928                if (nr != 0)
929                    continue factorize_loop;
930                ++nf;
931                wtable_r[nf + 1 + twon] = ntry;
932
933                nl = nq;
934                if (ntry == 2 && nf != 1) {
935                    for (i = 2; i <= nf; i++) {
936                        ib = nf - i + 2;
937                        int idx = ib + twon;
938                        wtable_r[idx + 1] = wtable_r[idx];
939                    }
940                    wtable_r[2 + twon] = 2;
941                }
942            } while (nl != 1);
943            break factorize_loop;
944        }
945        wtable_r[twon] = n;
946        wtable_r[1 + twon] = nf;
947        argh = TWO_PI / (double) (n);
948        is = 0;
949        nfm1 = nf - 1;
950        l1 = 1;
951        if (nfm1 == 0)
952            return;
953        for (k1 = 1; k1 <= nfm1; k1++) {
954            ip = (int) wtable_r[k1 + 1 + twon];
955            ld = 0;
956            l2 = l1 * ip;
957            ido = n / l2;
958            ipm = ip - 1;
959            for (j = 1; j <= ipm; ++j) {
960                ld += l1;
961                i = is;
962                argld = (double) ld * argh;
963
964                fi = 0;
965                for (ii = 3; ii <= ido; ii += 2) {
966                    i += 2;
967                    fi += 1;
968                    arg = fi * argld;
969                    int idx = i + n;
970                    wtable_r[idx - 2] = Math.cos(arg);
971                    wtable_r[idx - 1] = Math.sin(arg);
972                }
973                is += ido;
974            }
975            l1 = l2;
976        }
977    }
978
979    private void bluesteini() {
980        int k = 0;
981        double arg;
982        double pi_n = PI / n;
983        bk1[0] = 1;
984        bk1[1] = 0;
985        for (int i = 1; i < n; i++) {
986            k += 2 * i - 1;
987            if (k >= 2 * n)
988                k -= 2 * n;
989            arg = pi_n * k;
990            bk1[2 * i] = Math.cos(arg);
991            bk1[2 * i + 1] = Math.sin(arg);
992        }
993        double scale = 1.0 / nBluestein;
994        bk2[0] = bk1[0] * scale;
995        bk2[1] = bk1[1] * scale;
996        for (int i = 2; i < 2 * n; i += 2) {
997            bk2[i] = bk1[i] * scale;
998            bk2[i + 1] = bk1[i + 1] * scale;
999            bk2[2 * nBluestein - i] = bk2[i];
1000            bk2[2 * nBluestein - i + 1] = bk2[i + 1];
1001        }
1002        cftbsub(2 * nBluestein, bk2, 0, ip, nw, w);
1003    }
1004
1005    private void makewt(int nw) {
1006        int j, nwh, nw0, nw1;
1007        double delta, wn4r, wk1r, wk1i, wk3r, wk3i;
1008        double delta2, deltaj, deltaj3;
1009
1010        ip[0] = nw;
1011        ip[1] = 1;
1012        if (nw > 2) {
1013            nwh = nw >> 1;
1014            delta = 0.785398163397448278999490867136046290 / nwh;
1015            delta2 = delta * 2;
1016            wn4r = Math.cos(delta * nwh);
1017            w[0] = 1;
1018            w[1] = wn4r;
1019            if (nwh == 4) {
1020                w[2] = Math.cos(delta2);
1021                w[3] = Math.sin(delta2);
1022            } else if (nwh > 4) {
1023                makeipt(nw);
1024                w[2] = 0.5 / Math.cos(delta2);
1025                w[3] = 0.5 / Math.cos(delta * 6);
1026                for (j = 4; j < nwh; j += 4) {
1027                    deltaj = delta * j;
1028                    deltaj3 = 3 * deltaj;
1029                    w[j] = Math.cos(deltaj);
1030                    w[j + 1] = Math.sin(deltaj);
1031                    w[j + 2] = Math.cos(deltaj3);
1032                    w[j + 3] = -Math.sin(deltaj3);
1033                }
1034            }
1035            nw0 = 0;
1036            while (nwh > 2) {
1037                nw1 = nw0 + nwh;
1038                nwh >>= 1;
1039                w[nw1] = 1;
1040                w[nw1 + 1] = wn4r;
1041                if (nwh == 4) {
1042                    wk1r = w[nw0 + 4];
1043                    wk1i = w[nw0 + 5];
1044                    w[nw1 + 2] = wk1r;
1045                    w[nw1 + 3] = wk1i;
1046                } else if (nwh > 4) {
1047                    wk1r = w[nw0 + 4];
1048                    wk3r = w[nw0 + 6];
1049                    w[nw1 + 2] = 0.5 / wk1r;
1050                    w[nw1 + 3] = 0.5 / wk3r;
1051                    for (j = 4; j < nwh; j += 4) {
1052                        int idx1 = nw0 + 2 * j;
1053                        int idx2 = nw1 + j;
1054                        wk1r = w[idx1];
1055                        wk1i = w[idx1 + 1];
1056                        wk3r = w[idx1 + 2];
1057                        wk3i = w[idx1 + 3];
1058                        w[idx2] = wk1r;
1059                        w[idx2 + 1] = wk1i;
1060                        w[idx2 + 2] = wk3r;
1061                        w[idx2 + 3] = wk3i;
1062                    }
1063                }
1064                nw0 = nw1;
1065            }
1066        }
1067    }
1068
1069    private void makeipt(int nw) {
1070        int j, l, m, m2, p, q;
1071
1072        ip[2] = 0;
1073        ip[3] = 16;
1074        m = 2;
1075        for (l = nw; l > 32; l >>= 2) {
1076            m2 = m << 1;
1077            q = m2 << 3;
1078            for (j = m; j < m2; j++) {
1079                p = ip[j] << 2;
1080                ip[m + j] = p;
1081                ip[m2 + j] = p + q;
1082            }
1083            m = m2;
1084        }
1085    }
1086
1087    private void makect(int nc, double[] c, int startc) {
1088        int j, nch;
1089        double delta, deltaj;
1090
1091        ip[1] = nc;
1092        if (nc > 1) {
1093            nch = nc >> 1;
1094            delta = 0.785398163397448278999490867136046290 / nch;
1095            c[startc] = Math.cos(delta * nch);
1096            c[startc + nch] = 0.5 * c[startc];
1097            for (j = 1; j < nch; j++) {
1098                deltaj = delta * j;
1099                c[startc + j] = 0.5 * Math.cos(deltaj);
1100                c[startc + nc - j] = 0.5 * Math.sin(deltaj);
1101            }
1102        }
1103    }
1104
1105    private void bluestein_complex(final double[] a, final int offa, final int isign) {
1106        final double[] ak = new double[2 * nBluestein];
1107        int nthreads = 1;
1108        int threads = ConcurrencyUtils.getNumberOfThreads();
1109        if ((threads > 1) && (n > ConcurrencyUtils.getThreadsBeginN_1D_FFT_2Threads())) {
1110            nthreads = 2;
1111            if ((threads >= 4) && (n > ConcurrencyUtils.getThreadsBeginN_1D_FFT_4Threads())) {
1112                nthreads = 4;
1113            }
1114            Future<?>[] futures = new Future[nthreads];
1115            int k = n / nthreads;
1116            for (int i = 0; i < nthreads; i++) {
1117                final int firstIdx = i * k;
1118                final int lastIdx = (i == (nthreads - 1)) ? n : firstIdx + k;
1119                futures[i] = ConcurrencyUtils.submit(new Runnable() {
1120                    public void run() {
1121                        if (isign > 0) {
1122                            for (int i = firstIdx; i < lastIdx; i++) {
1123                                int idx1 = 2 * i;
1124                                int idx2 = idx1 + 1;
1125                                int idx3 = offa + idx1;
1126                                int idx4 = offa + idx2;
1127                                ak[idx1] = a[idx3] * bk1[idx1] - a[idx4] * bk1[idx2];
1128                                ak[idx2] = a[idx3] * bk1[idx2] + a[idx4] * bk1[idx1];
1129                            }
1130                        } else {
1131                            for (int i = firstIdx; i < lastIdx; i++) {
1132                                int idx1 = 2 * i;
1133                                int idx2 = idx1 + 1;
1134                                int idx3 = offa + idx1;
1135                                int idx4 = offa + idx2;
1136                                ak[idx1] = a[idx3] * bk1[idx1] + a[idx4] * bk1[idx2];
1137                                ak[idx2] = -a[idx3] * bk1[idx2] + a[idx4] * bk1[idx1];
1138                            }
1139                        }
1140                    }
1141                });
1142            }
1143            ConcurrencyUtils.waitForCompletion(futures);
1144
1145            cftbsub(2 * nBluestein, ak, 0, ip, nw, w);
1146
1147            k = nBluestein / nthreads;
1148            for (int i = 0; i < nthreads; i++) {
1149                final int firstIdx = i * k;
1150                final int lastIdx = (i == (nthreads - 1)) ? nBluestein : firstIdx + k;
1151                futures[i] = ConcurrencyUtils.submit(new Runnable() {
1152                    public void run() {
1153                        if (isign > 0) {
1154                            for (int i = firstIdx; i < lastIdx; i++) {
1155                                int idx1 = 2 * i;
1156                                int idx2 = idx1 + 1;
1157                                double im = -ak[idx1] * bk2[idx2] + ak[idx2] * bk2[idx1];
1158                                ak[idx1] = ak[idx1] * bk2[idx1] + ak[idx2] * bk2[idx2];
1159                                ak[idx2] = im;
1160                            }
1161                        } else {
1162                            for (int i = firstIdx; i < lastIdx; i++) {
1163                                int idx1 = 2 * i;
1164                                int idx2 = idx1 + 1;
1165                                double im = ak[idx1] * bk2[idx2] + ak[idx2] * bk2[idx1];
1166                                ak[idx1] = ak[idx1] * bk2[idx1] - ak[idx2] * bk2[idx2];
1167                                ak[idx2] = im;
1168                            }
1169                        }
1170                    }
1171                });
1172            }
1173            ConcurrencyUtils.waitForCompletion(futures);
1174
1175            cftfsub(2 * nBluestein, ak, 0, ip, nw, w);
1176
1177            k = n / nthreads;
1178            for (int i = 0; i < nthreads; i++) {
1179                final int firstIdx = i * k;
1180                final int lastIdx = (i == (nthreads - 1)) ? n : firstIdx + k;
1181                futures[i] = ConcurrencyUtils.submit(new Runnable() {
1182                    public void run() {
1183                        if (isign > 0) {
1184                            for (int i = firstIdx; i < lastIdx; i++) {
1185                                int idx1 = 2 * i;
1186                                int idx2 = idx1 + 1;
1187                                int idx3 = offa + idx1;
1188                                int idx4 = offa + idx2;
1189                                a[idx3] = bk1[idx1] * ak[idx1] - bk1[idx2] * ak[idx2];
1190                                a[idx4] = bk1[idx2] * ak[idx1] + bk1[idx1] * ak[idx2];
1191                            }
1192                        } else {
1193                            for (int i = firstIdx; i < lastIdx; i++) {
1194                                int idx1 = 2 * i;
1195                                int idx2 = idx1 + 1;
1196                                int idx3 = offa + idx1;
1197                                int idx4 = offa + idx2;
1198                                a[idx3] = bk1[idx1] * ak[idx1] + bk1[idx2] * ak[idx2];
1199                                a[idx4] = -bk1[idx2] * ak[idx1] + bk1[idx1] * ak[idx2];
1200                            }
1201                        }
1202                    }
1203                });
1204            }
1205            ConcurrencyUtils.waitForCompletion(futures);
1206        } else {
1207            if (isign > 0) {
1208                for (int i = 0; i < n; i++) {
1209                    int idx1 = 2 * i;
1210                    int idx2 = idx1 + 1;
1211                    int idx3 = offa + idx1;
1212                    int idx4 = offa + idx2;
1213                    ak[idx1] = a[idx3] * bk1[idx1] - a[idx4] * bk1[idx2];
1214                    ak[idx2] = a[idx3] * bk1[idx2] + a[idx4] * bk1[idx1];
1215                }
1216            } else {
1217                for (int i = 0; i < n; i++) {
1218                    int idx1 = 2 * i;
1219                    int idx2 = idx1 + 1;
1220                    int idx3 = offa + idx1;
1221                    int idx4 = offa + idx2;
1222                    ak[idx1] = a[idx3] * bk1[idx1] + a[idx4] * bk1[idx2];
1223                    ak[idx2] = -a[idx3] * bk1[idx2] + a[idx4] * bk1[idx1];
1224                }
1225            }
1226
1227            cftbsub(2 * nBluestein, ak, 0, ip, nw, w);
1228
1229            if (isign > 0) {
1230                for (int i = 0; i < nBluestein; i++) {
1231                    int idx1 = 2 * i;
1232                    int idx2 = idx1 + 1;
1233                    double im = -ak[idx1] * bk2[idx2] + ak[idx2] * bk2[idx1];
1234                    ak[idx1] = ak[idx1] * bk2[idx1] + ak[idx2] * bk2[idx2];
1235                    ak[idx2] = im;
1236                }
1237            } else {
1238                for (int i = 0; i < nBluestein; i++) {
1239                    int idx1 = 2 * i;
1240                    int idx2 = idx1 + 1;
1241                    double im = ak[idx1] * bk2[idx2] + ak[idx2] * bk2[idx1];
1242                    ak[idx1] = ak[idx1] * bk2[idx1] - ak[idx2] * bk2[idx2];
1243                    ak[idx2] = im;
1244                }
1245            }
1246
1247            cftfsub(2 * nBluestein, ak, 0, ip, nw, w);
1248            if (isign > 0) {
1249                for (int i = 0; i < n; i++) {
1250                    int idx1 = 2 * i;
1251                    int idx2 = idx1 + 1;
1252                    int idx3 = offa + idx1;
1253                    int idx4 = offa + idx2;
1254                    a[idx3] = bk1[idx1] * ak[idx1] - bk1[idx2] * ak[idx2];
1255                    a[idx4] = bk1[idx2] * ak[idx1] + bk1[idx1] * ak[idx2];
1256                }
1257            } else {
1258                for (int i = 0; i < n; i++) {
1259                    int idx1 = 2 * i;
1260                    int idx2 = idx1 + 1;
1261                    int idx3 = offa + idx1;
1262                    int idx4 = offa + idx2;
1263                    a[idx3] = bk1[idx1] * ak[idx1] + bk1[idx2] * ak[idx2];
1264                    a[idx4] = -bk1[idx2] * ak[idx1] + bk1[idx1] * ak[idx2];
1265                }
1266            }
1267        }
1268    }
1269
1270    private void bluestein_real_full(final double[] a, final int offa, final int isign) {
1271        final double[] ak = new double[2 * nBluestein];
1272        int nthreads = 1;
1273        int threads = ConcurrencyUtils.getNumberOfThreads();
1274        if ((threads > 1) && (n > ConcurrencyUtils.getThreadsBeginN_1D_FFT_2Threads())) {
1275            nthreads = 2;
1276            if ((threads >= 4) && (n > ConcurrencyUtils.getThreadsBeginN_1D_FFT_4Threads())) {
1277                nthreads = 4;
1278            }
1279            Future<?>[] futures = new Future[nthreads];
1280            int k = n / nthreads;
1281            for (int i = 0; i < nthreads; i++) {
1282                final int firstIdx = i * k;
1283                final int lastIdx = (i == (nthreads - 1)) ? n : firstIdx + k;
1284                futures[i] = ConcurrencyUtils.submit(new Runnable() {
1285                    public void run() {
1286                        if (isign > 0) {
1287                            for (int i = firstIdx; i < lastIdx; i++) {
1288                                int idx1 = 2 * i;
1289                                int idx2 = idx1 + 1;
1290                                int idx3 = offa + i;
1291                                ak[idx1] = a[idx3] * bk1[idx1];
1292                                ak[idx2] = a[idx3] * bk1[idx2];
1293                            }
1294                        } else {
1295                            for (int i = firstIdx; i < lastIdx; i++) {
1296                                int idx1 = 2 * i;
1297                                int idx2 = idx1 + 1;
1298                                int idx3 = offa + i;
1299                                ak[idx1] = a[idx3] * bk1[idx1];
1300                                ak[idx2] = -a[idx3] * bk1[idx2];
1301                            }
1302                        }
1303                    }
1304                });
1305            }
1306            ConcurrencyUtils.waitForCompletion(futures);
1307
1308            cftbsub(2 * nBluestein, ak, 0, ip, nw, w);
1309
1310            k = nBluestein / nthreads;
1311            for (int i = 0; i < nthreads; i++) {
1312                final int firstIdx = i * k;
1313                final int lastIdx = (i == (nthreads - 1)) ? nBluestein : firstIdx + k;
1314                futures[i] = ConcurrencyUtils.submit(new Runnable() {
1315                    public void run() {
1316                        if (isign > 0) {
1317                            for (int i = firstIdx; i < lastIdx; i++) {
1318                                int idx1 = 2 * i;
1319                                int idx2 = idx1 + 1;
1320                                double im = -ak[idx1] * bk2[idx2] + ak[idx2] * bk2[idx1];
1321                                ak[idx1] = ak[idx1] * bk2[idx1] + ak[idx2] * bk2[idx2];
1322                                ak[idx2] = im;
1323                            }
1324                        } else {
1325                            for (int i = firstIdx; i < lastIdx; i++) {
1326                                int idx1 = 2 * i;
1327                                int idx2 = idx1 + 1;
1328                                double im = ak[idx1] * bk2[idx2] + ak[idx2] * bk2[idx1];
1329                                ak[idx1] = ak[idx1] * bk2[idx1] - ak[idx2] * bk2[idx2];
1330                                ak[idx2] = im;
1331                            }
1332                        }
1333                    }
1334                });
1335            }
1336            ConcurrencyUtils.waitForCompletion(futures);
1337
1338            cftfsub(2 * nBluestein, ak, 0, ip, nw, w);
1339
1340            k = n / nthreads;
1341            for (int i = 0; i < nthreads; i++) {
1342                final int firstIdx = i * k;
1343                final int lastIdx = (i == (nthreads - 1)) ? n : firstIdx + k;
1344                futures[i] = ConcurrencyUtils.submit(new Runnable() {
1345                    public void run() {
1346                        if (isign > 0) {
1347                            for (int i = firstIdx; i < lastIdx; i++) {
1348                                int idx1 = 2 * i;
1349                                int idx2 = idx1 + 1;
1350                                a[offa + idx1] = bk1[idx1] * ak[idx1] - bk1[idx2] * ak[idx2];
1351                                a[offa + idx2] = bk1[idx2] * ak[idx1] + bk1[idx1] * ak[idx2];
1352                            }
1353                        } else {
1354                            for (int i = firstIdx; i < lastIdx; i++) {
1355                                int idx1 = 2 * i;
1356                                int idx2 = idx1 + 1;
1357                                a[offa + idx1] = bk1[idx1] * ak[idx1] + bk1[idx2] * ak[idx2];
1358                                a[offa + idx2] = -bk1[idx2] * ak[idx1] + bk1[idx1] * ak[idx2];
1359                            }
1360                        }
1361                    }
1362                });
1363            }
1364            ConcurrencyUtils.waitForCompletion(futures);
1365        } else {
1366            if (isign > 0) {
1367                for (int i = 0; i < n; i++) {
1368                    int idx1 = 2 * i;
1369                    int idx2 = idx1 + 1;
1370                    int idx3 = offa + i;
1371                    ak[idx1] = a[idx3] * bk1[idx1];
1372                    ak[idx2] = a[idx3] * bk1[idx2];
1373                }
1374            } else {
1375                for (int i = 0; i < n; i++) {
1376                    int idx1 = 2 * i;
1377                    int idx2 = idx1 + 1;
1378                    int idx3 = offa + i;
1379                    ak[idx1] = a[idx3] * bk1[idx1];
1380                    ak[idx2] = -a[idx3] * bk1[idx2];
1381                }
1382            }
1383
1384            cftbsub(2 * nBluestein, ak, 0, ip, nw, w);
1385
1386            if (isign > 0) {
1387                for (int i = 0; i < nBluestein; i++) {
1388                    int idx1 = 2 * i;
1389                    int idx2 = idx1 + 1;
1390                    double im = -ak[idx1] * bk2[idx2] + ak[idx2] * bk2[idx1];
1391                    ak[idx1] = ak[idx1] * bk2[idx1] + ak[idx2] * bk2[idx2];
1392                    ak[idx2] = im;
1393                }
1394            } else {
1395                for (int i = 0; i < nBluestein; i++) {
1396                    int idx1 = 2 * i;
1397                    int idx2 = idx1 + 1;
1398                    double im = ak[idx1] * bk2[idx2] + ak[idx2] * bk2[idx1];
1399                    ak[idx1] = ak[idx1] * bk2[idx1] - ak[idx2] * bk2[idx2];
1400                    ak[idx2] = im;
1401                }
1402            }
1403
1404            cftfsub(2 * nBluestein, ak, 0, ip, nw, w);
1405
1406            if (isign > 0) {
1407                for (int i = 0; i < n; i++) {
1408                    int idx1 = 2 * i;
1409                    int idx2 = idx1 + 1;
1410                    a[offa + idx1] = bk1[idx1] * ak[idx1] - bk1[idx2] * ak[idx2];
1411                    a[offa + idx2] = bk1[idx2] * ak[idx1] + bk1[idx1] * ak[idx2];
1412                }
1413            } else {
1414                for (int i = 0; i < n; i++) {
1415                    int idx1 = 2 * i;
1416                    int idx2 = idx1 + 1;
1417                    a[offa + idx1] = bk1[idx1] * ak[idx1] + bk1[idx2] * ak[idx2];
1418                    a[offa + idx2] = -bk1[idx2] * ak[idx1] + bk1[idx1] * ak[idx2];
1419                }
1420            }
1421        }
1422    }
1423
1424    private void bluestein_real_forward(final double[] a, final int offa) {
1425        final double[] ak = new double[2 * nBluestein];
1426        int nthreads = 1;
1427        int threads = ConcurrencyUtils.getNumberOfThreads();
1428        if ((threads > 1) && (n > ConcurrencyUtils.getThreadsBeginN_1D_FFT_2Threads())) {
1429            nthreads = 2;
1430            if ((threads >= 4) && (n > ConcurrencyUtils.getThreadsBeginN_1D_FFT_4Threads())) {
1431                nthreads = 4;
1432            }
1433            Future<?>[] futures = new Future[nthreads];
1434            int k = n / nthreads;
1435            for (int i = 0; i < nthreads; i++) {
1436                final int firstIdx = i * k;
1437                final int lastIdx = (i == (nthreads - 1)) ? n : firstIdx + k;
1438                futures[i] = ConcurrencyUtils.submit(new Runnable() {
1439                    public void run() {
1440                        for (int i = firstIdx; i < lastIdx; i++) {
1441                            int idx1 = 2 * i;
1442                            int idx2 = idx1 + 1;
1443                            int idx3 = offa + i;
1444                            ak[idx1] = a[idx3] * bk1[idx1];
1445                            ak[idx2] = -a[idx3] * bk1[idx2];
1446                        }
1447                    }
1448                });
1449            }
1450            ConcurrencyUtils.waitForCompletion(futures);
1451
1452            cftbsub(2 * nBluestein, ak, 0, ip, nw, w);
1453
1454            k = nBluestein / nthreads;
1455            for (int i = 0; i < nthreads; i++) {
1456                final int firstIdx = i * k;
1457                final int lastIdx = (i == (nthreads - 1)) ? nBluestein : firstIdx + k;
1458                futures[i] = ConcurrencyUtils.submit(new Runnable() {
1459                    public void run() {
1460                        for (int i = firstIdx; i < lastIdx; i++) {
1461                            int idx1 = 2 * i;
1462                            int idx2 = idx1 + 1;
1463                            double im = ak[idx1] * bk2[idx2] + ak[idx2] * bk2[idx1];
1464                            ak[idx1] = ak[idx1] * bk2[idx1] - ak[idx2] * bk2[idx2];
1465                            ak[idx2] = im;
1466                        }
1467                    }
1468                });
1469            }
1470            ConcurrencyUtils.waitForCompletion(futures);
1471
1472        } else {
1473
1474            for (int i = 0; i < n; i++) {
1475                int idx1 = 2 * i;
1476                int idx2 = idx1 + 1;
1477                int idx3 = offa + i;
1478                ak[idx1] = a[idx3] * bk1[idx1];
1479                ak[idx2] = -a[idx3] * bk1[idx2];
1480            }
1481
1482            cftbsub(2 * nBluestein, ak, 0, ip, nw, w);
1483
1484            for (int i = 0; i < nBluestein; i++) {
1485                int idx1 = 2 * i;
1486                int idx2 = idx1 + 1;
1487                double im = ak[idx1] * bk2[idx2] + ak[idx2] * bk2[idx1];
1488                ak[idx1] = ak[idx1] * bk2[idx1] - ak[idx2] * bk2[idx2];
1489                ak[idx2] = im;
1490            }
1491        }
1492
1493        cftfsub(2 * nBluestein, ak, 0, ip, nw, w);
1494
1495        if (n % 2 == 0) {
1496            a[offa] = bk1[0] * ak[0] + bk1[1] * ak[1];
1497            a[offa + 1] = bk1[n] * ak[n] + bk1[n + 1] * ak[n + 1];
1498            for (int i = 1; i < n / 2; i++) {
1499                int idx1 = 2 * i;
1500                int idx2 = idx1 + 1;
1501                a[offa + idx1] = bk1[idx1] * ak[idx1] + bk1[idx2] * ak[idx2];
1502                a[offa + idx2] = -bk1[idx2] * ak[idx1] + bk1[idx1] * ak[idx2];
1503            }
1504        } else {
1505            a[offa] = bk1[0] * ak[0] + bk1[1] * ak[1];
1506            a[offa + 1] = -bk1[n] * ak[n - 1] + bk1[n - 1] * ak[n];
1507            for (int i = 1; i < (n - 1) / 2; i++) {
1508                int idx1 = 2 * i;
1509                int idx2 = idx1 + 1;
1510                a[offa + idx1] = bk1[idx1] * ak[idx1] + bk1[idx2] * ak[idx2];
1511                a[offa + idx2] = -bk1[idx2] * ak[idx1] + bk1[idx1] * ak[idx2];
1512            }
1513            a[offa + n - 1] = bk1[n - 1] * ak[n - 1] + bk1[n] * ak[n];
1514        }
1515
1516    }
1517
1518    private void bluestein_real_inverse(final double[] a, final int offa) {
1519        final double[] ak = new double[2 * nBluestein];
1520        if (n % 2 == 0) {
1521            ak[0] = a[offa] * bk1[0];
1522            ak[1] = a[offa] * bk1[1];
1523
1524            for (int i = 1; i < n / 2; i++) {
1525                int idx1 = 2 * i;
1526                int idx2 = idx1 + 1;
1527                int idx3 = offa + idx1;
1528                int idx4 = offa + idx2;
1529                ak[idx1] = a[idx3] * bk1[idx1] - a[idx4] * bk1[idx2];
1530                ak[idx2] = a[idx3] * bk1[idx2] + a[idx4] * bk1[idx1];
1531            }
1532
1533            ak[n] = a[offa + 1] * bk1[n];
1534            ak[n + 1] = a[offa + 1] * bk1[n + 1];
1535
1536            for (int i = n / 2 + 1; i < n; i++) {
1537                int idx1 = 2 * i;
1538                int idx2 = idx1 + 1;
1539                int idx3 = offa + 2 * n - idx1;
1540                int idx4 = idx3 + 1;
1541                ak[idx1] = a[idx3] * bk1[idx1] + a[idx4] * bk1[idx2];
1542                ak[idx2] = a[idx3] * bk1[idx2] - a[idx4] * bk1[idx1];
1543            }
1544
1545        } else {
1546            ak[0] = a[offa] * bk1[0];
1547            ak[1] = a[offa] * bk1[1];
1548
1549            for (int i = 1; i < (n - 1) / 2; i++) {
1550                int idx1 = 2 * i;
1551                int idx2 = idx1 + 1;
1552                int idx3 = offa + idx1;
1553                int idx4 = offa + idx2;
1554                ak[idx1] = a[idx3] * bk1[idx1] - a[idx4] * bk1[idx2];
1555                ak[idx2] = a[idx3] * bk1[idx2] + a[idx4] * bk1[idx1];
1556            }
1557
1558            ak[n - 1] = a[offa + n - 1] * bk1[n - 1] - a[offa + 1] * bk1[n];
1559            ak[n] = a[offa + n - 1] * bk1[n] + a[offa + 1] * bk1[n - 1];
1560
1561            ak[n + 1] = a[offa + n - 1] * bk1[n + 1] + a[offa + 1] * bk1[n + 2];
1562            ak[n + 2] = a[offa + n - 1] * bk1[n + 2] - a[offa + 1] * bk1[n + 1];
1563
1564            for (int i = (n - 1) / 2 + 2; i < n; i++) {
1565                int idx1 = 2 * i;
1566                int idx2 = idx1 + 1;
1567                int idx3 = offa + 2 * n - idx1;
1568                int idx4 = idx3 + 1;
1569                ak[idx1] = a[idx3] * bk1[idx1] + a[idx4] * bk1[idx2];
1570                ak[idx2] = a[idx3] * bk1[idx2] - a[idx4] * bk1[idx1];
1571            }
1572        }
1573
1574        cftbsub(2 * nBluestein, ak, 0, ip, nw, w);
1575
1576        int nthreads = 1;
1577        int threads = ConcurrencyUtils.getNumberOfThreads();
1578        if ((threads > 1) && (n > ConcurrencyUtils.getThreadsBeginN_1D_FFT_2Threads())) {
1579            nthreads = 2;
1580            if ((threads >= 4) && (n > ConcurrencyUtils.getThreadsBeginN_1D_FFT_4Threads())) {
1581                nthreads = 4;
1582            }
1583            Future<?>[] futures = new Future[nthreads];
1584            int k = nBluestein / nthreads;
1585            for (int i = 0; i < nthreads; i++) {
1586                final int firstIdx = i * k;
1587                final int lastIdx = (i == (nthreads - 1)) ? nBluestein : firstIdx + k;
1588                futures[i] = ConcurrencyUtils.submit(new Runnable() {
1589                    public void run() {
1590                        for (int i = firstIdx; i < lastIdx; i++) {
1591                            int idx1 = 2 * i;
1592                            int idx2 = idx1 + 1;
1593                            double im = -ak[idx1] * bk2[idx2] + ak[idx2] * bk2[idx1];
1594                            ak[idx1] = ak[idx1] * bk2[idx1] + ak[idx2] * bk2[idx2];
1595                            ak[idx2] = im;
1596                        }
1597                    }
1598                });
1599            }
1600            ConcurrencyUtils.waitForCompletion(futures);
1601
1602            cftfsub(2 * nBluestein, ak, 0, ip, nw, w);
1603
1604            k = n / nthreads;
1605            for (int i = 0; i < nthreads; i++) {
1606                final int firstIdx = i * k;
1607                final int lastIdx = (i == (nthreads - 1)) ? n : firstIdx + k;
1608                futures[i] = ConcurrencyUtils.submit(new Runnable() {
1609                    public void run() {
1610                        for (int i = firstIdx; i < lastIdx; i++) {
1611                            int idx1 = 2 * i;
1612                            int idx2 = idx1 + 1;
1613                            a[offa + i] = bk1[idx1] * ak[idx1] - bk1[idx2] * ak[idx2];
1614                        }
1615                    }
1616                });
1617            }
1618            ConcurrencyUtils.waitForCompletion(futures);
1619
1620        } else {
1621
1622            for (int i = 0; i < nBluestein; i++) {
1623                int idx1 = 2 * i;
1624                int idx2 = idx1 + 1;
1625                double im = -ak[idx1] * bk2[idx2] + ak[idx2] * bk2[idx1];
1626                ak[idx1] = ak[idx1] * bk2[idx1] + ak[idx2] * bk2[idx2];
1627                ak[idx2] = im;
1628            }
1629
1630            cftfsub(2 * nBluestein, ak, 0, ip, nw, w);
1631
1632            for (int i = 0; i < n; i++) {
1633                int idx1 = 2 * i;
1634                int idx2 = idx1 + 1;
1635                a[offa + i] = bk1[idx1] * ak[idx1] - bk1[idx2] * ak[idx2];
1636            }
1637        }
1638    }
1639
1640    private void bluestein_real_inverse2(final double[] a, final int offa) {
1641        final double[] ak = new double[2 * nBluestein];
1642        int nthreads = 1;
1643        int threads = ConcurrencyUtils.getNumberOfThreads();
1644        if ((threads > 1) && (n > ConcurrencyUtils.getThreadsBeginN_1D_FFT_2Threads())) {
1645            nthreads = 2;
1646            if ((threads >= 4) && (n > ConcurrencyUtils.getThreadsBeginN_1D_FFT_4Threads())) {
1647                nthreads = 4;
1648            }
1649            Future<?>[] futures = new Future[nthreads];
1650            int k = n / nthreads;
1651            for (int i = 0; i < nthreads; i++) {
1652                final int firstIdx = i * k;
1653                final int lastIdx = (i == (nthreads - 1)) ? n : firstIdx + k;
1654                futures[i] = ConcurrencyUtils.submit(new Runnable() {
1655                    public void run() {
1656                        for (int i = firstIdx; i < lastIdx; i++) {
1657                            int idx1 = 2 * i;
1658                            int idx2 = idx1 + 1;
1659                            int idx3 = offa + i;
1660                            ak[idx1] = a[idx3] * bk1[idx1];
1661                            ak[idx2] = a[idx3] * bk1[idx2];
1662                        }
1663                    }
1664                });
1665            }
1666            ConcurrencyUtils.waitForCompletion(futures);
1667
1668            cftbsub(2 * nBluestein, ak, 0, ip, nw, w);
1669
1670            k = nBluestein / nthreads;
1671            for (int i = 0; i < nthreads; i++) {
1672                final int firstIdx = i * k;
1673                final int lastIdx = (i == (nthreads - 1)) ? nBluestein : firstIdx + k;
1674                futures[i] = ConcurrencyUtils.submit(new Runnable() {
1675                    public void run() {
1676                        for (int i = firstIdx; i < lastIdx; i++) {
1677                            int idx1 = 2 * i;
1678                            int idx2 = idx1 + 1;
1679                            double im = -ak[idx1] * bk2[idx2] + ak[idx2] * bk2[idx1];
1680                            ak[idx1] = ak[idx1] * bk2[idx1] + ak[idx2] * bk2[idx2];
1681                            ak[idx2] = im;
1682                        }
1683                    }
1684                });
1685            }
1686            ConcurrencyUtils.waitForCompletion(futures);
1687
1688        } else {
1689
1690            for (int i = 0; i < n; i++) {
1691                int idx1 = 2 * i;
1692                int idx2 = idx1 + 1;
1693                int idx3 = offa + i;
1694                ak[idx1] = a[idx3] * bk1[idx1];
1695                ak[idx2] = a[idx3] * bk1[idx2];
1696            }
1697
1698            cftbsub(2 * nBluestein, ak, 0, ip, nw, w);
1699
1700            for (int i = 0; i < nBluestein; i++) {
1701                int idx1 = 2 * i;
1702                int idx2 = idx1 + 1;
1703                double im = -ak[idx1] * bk2[idx2] + ak[idx2] * bk2[idx1];
1704                ak[idx1] = ak[idx1] * bk2[idx1] + ak[idx2] * bk2[idx2];
1705                ak[idx2] = im;
1706            }
1707        }
1708
1709        cftfsub(2 * nBluestein, ak, 0, ip, nw, w);
1710
1711        if (n % 2 == 0) {
1712            a[offa] = bk1[0] * ak[0] - bk1[1] * ak[1];
1713            a[offa + 1] = bk1[n] * ak[n] - bk1[n + 1] * ak[n + 1];
1714            for (int i = 1; i < n / 2; i++) {
1715                int idx1 = 2 * i;
1716                int idx2 = idx1 + 1;
1717                a[offa + idx1] = bk1[idx1] * ak[idx1] - bk1[idx2] * ak[idx2];
1718                a[offa + idx2] = bk1[idx2] * ak[idx1] + bk1[idx1] * ak[idx2];
1719            }
1720        } else {
1721            a[offa] = bk1[0] * ak[0] - bk1[1] * ak[1];
1722            a[offa + 1] = bk1[n] * ak[n - 1] + bk1[n - 1] * ak[n];
1723            for (int i = 1; i < (n - 1) / 2; i++) {
1724                int idx1 = 2 * i;
1725                int idx2 = idx1 + 1;
1726                a[offa + idx1] = bk1[idx1] * ak[idx1] - bk1[idx2] * ak[idx2];
1727                a[offa + idx2] = bk1[idx2] * ak[idx1] + bk1[idx1] * ak[idx2];
1728            }
1729            a[offa + n - 1] = bk1[n - 1] * ak[n - 1] - bk1[n] * ak[n];
1730        }
1731    }
1732
1733    /*---------------------------------------------------------
1734       rfftf1: further processing of Real forward FFT
1735      --------------------------------------------------------*/
1736    void rfftf(final double a[], final int offa) {
1737        if (n == 1)
1738            return;
1739        int l1, l2, na, kh, nf, ip, iw, ido, idl1;
1740
1741        final double[] ch = new double[n];
1742        final int twon = 2 * n;
1743        nf = (int) wtable_r[1 + twon];
1744        na = 1;
1745        l2 = n;
1746        iw = twon - 1;
1747        for (int k1 = 1; k1 <= nf; ++k1) {
1748            kh = nf - k1;
1749            ip = (int) wtable_r[kh + 2 + twon];
1750            l1 = l2 / ip;
1751            ido = n / l2;
1752            idl1 = ido * l1;
1753            iw -= (ip - 1) * ido;
1754            na = 1 - na;
1755            switch (ip) {
1756            case 2:
1757                if (na == 0) {
1758                    radf2(ido, l1, a, offa, ch, 0, iw);
1759                } else {
1760                    radf2(ido, l1, ch, 0, a, offa, iw);
1761                }
1762                break;
1763            case 3:
1764                if (na == 0) {
1765                    radf3(ido, l1, a, offa, ch, 0, iw);
1766                } else {
1767                    radf3(ido, l1, ch, 0, a, offa, iw);
1768                }
1769                break;
1770            case 4:
1771                if (na == 0) {
1772                    radf4(ido, l1, a, offa, ch, 0, iw);
1773                } else {
1774                    radf4(ido, l1, ch, 0, a, offa, iw);
1775                }
1776                break;
1777            case 5:
1778                if (na == 0) {
1779                    radf5(ido, l1, a, offa, ch, 0, iw);
1780                } else {
1781                    radf5(ido, l1, ch, 0, a, offa, iw);
1782                }
1783                break;
1784            default:
1785                if (ido == 1)
1786                    na = 1 - na;
1787                if (na == 0) {
1788                    radfg(ido, ip, l1, idl1, a, offa, ch, 0, iw);
1789                    na = 1;
1790                } else {
1791                    radfg(ido, ip, l1, idl1, ch, 0, a, offa, iw);
1792                    na = 0;
1793                }
1794                break;
1795            }
1796            l2 = l1;
1797        }
1798        if (na == 1)
1799            return;
1800        System.arraycopy(ch, 0, a, offa, n);
1801    }
1802
1803    /*---------------------------------------------------------
1804       rfftb1: further processing of Real backward FFT
1805      --------------------------------------------------------*/
1806    void rfftb(final double a[], final int offa) {
1807        if (n == 1)
1808            return;
1809        int l1, l2, na, nf, ip, iw, ido, idl1;
1810
1811        double[] ch = new double[n];
1812        final int twon = 2 * n;
1813        nf = (int) wtable_r[1 + twon];
1814        na = 0;
1815        l1 = 1;
1816        iw = n;
1817        for (int k1 = 1; k1 <= nf; k1++) {
1818            ip = (int) wtable_r[k1 + 1 + twon];
1819            l2 = ip * l1;
1820            ido = n / l2;
1821            idl1 = ido * l1;
1822            switch (ip) {
1823            case 2:
1824                if (na == 0) {
1825                    radb2(ido, l1, a, offa, ch, 0, iw);
1826                } else {
1827                    radb2(ido, l1, ch, 0, a, offa, iw);
1828                }
1829                na = 1 - na;
1830                break;
1831            case 3:
1832                if (na == 0) {
1833                    radb3(ido, l1, a, offa, ch, 0, iw);
1834                } else {
1835                    radb3(ido, l1, ch, 0, a, offa, iw);
1836                }
1837                na = 1 - na;
1838                break;
1839            case 4:
1840                if (na == 0) {
1841                    radb4(ido, l1, a, offa, ch, 0, iw);
1842                } else {
1843                    radb4(ido, l1, ch, 0, a, offa, iw);
1844                }
1845                na = 1 - na;
1846                break;
1847            case 5:
1848                if (na == 0) {
1849                    radb5(ido, l1, a, offa, ch, 0, iw);
1850                } else {
1851                    radb5(ido, l1, ch, 0, a, offa, iw);
1852                }
1853                na = 1 - na;
1854                break;
1855            default:
1856                if (na == 0) {
1857                    radbg(ido, ip, l1, idl1, a, offa, ch, 0, iw);
1858                } else {
1859                    radbg(ido, ip, l1, idl1, ch, 0, a, offa, iw);
1860                }
1861                if (ido == 1)
1862                    na = 1 - na;
1863                break;
1864            }
1865            l1 = l2;
1866            iw += (ip - 1) * ido;
1867        }
1868        if (na == 0)
1869            return;
1870        System.arraycopy(ch, 0, a, offa, n);
1871    }
1872
1873    /*-------------------------------------------------
1874       radf2: Real FFT's forward processing of factor 2
1875      -------------------------------------------------*/
1876    void radf2(final int ido, final int l1, final double in[], final int in_off, final double out[], final int out_off, final int offset) {
1877        int i, ic, idx0, idx1, idx2, idx3, idx4;
1878        double t1i, t1r, w1r, w1i;
1879        int iw1;
1880        iw1 = offset;
1881        idx0 = l1 * ido;
1882        idx1 = 2 * ido;
1883        for (int k = 0; k < l1; k++) {
1884            int oidx1 = out_off + k * idx1;
1885            int oidx2 = oidx1 + idx1 - 1;
1886            int iidx1 = in_off + k * ido;
1887            int iidx2 = iidx1 + idx0;
1888
1889            double i1r = in[iidx1];
1890            double i2r = in[iidx2];
1891
1892            out[oidx1] = i1r + i2r;
1893            out[oidx2] = i1r - i2r;
1894        }
1895        if (ido < 2)
1896            return;
1897        if (ido != 2) {
1898            for (int k = 0; k < l1; k++) {
1899                idx1 = k * ido;
1900                idx2 = 2 * idx1;
1901                idx3 = idx2 + ido;
1902                idx4 = idx1 + idx0;
1903                for (i = 2; i < ido; i += 2) {
1904                    ic = ido - i;
1905                    int widx1 = i - 1 + iw1;
1906                    int oidx1 = out_off + i + idx2;
1907                    int oidx2 = out_off + ic + idx3;
1908                    int iidx1 = in_off + i + idx1;
1909                    int iidx2 = in_off + i + idx4;
1910
1911                    double a1i = in[iidx1 - 1];
1912                    double a1r = in[iidx1];
1913                    double a2i = in[iidx2 - 1];
1914                    double a2r = in[iidx2];
1915
1916                    w1r = wtable_r[widx1 - 1];
1917                    w1i = wtable_r[widx1];
1918
1919                    t1r = w1r * a2i + w1i * a2r;
1920                    t1i = w1r * a2r - w1i * a2i;
1921
1922                    out[oidx1] = a1r + t1i;
1923                    out[oidx1 - 1] = a1i + t1r;
1924
1925                    out[oidx2] = t1i - a1r;
1926                    out[oidx2 - 1] = a1i - t1r;
1927                }
1928            }
1929            if (ido % 2 == 1)
1930                return;
1931        }
1932        idx2 = 2 * idx1;
1933        for (int k = 0; k < l1; k++) {
1934            idx1 = k * ido;
1935            int oidx1 = out_off + idx2 + ido;
1936            int iidx1 = in_off + ido - 1 + idx1;
1937
1938            out[oidx1] = -in[iidx1 + idx0];
1939            out[oidx1 - 1] = in[iidx1];
1940        }
1941    }
1942
1943    /*-------------------------------------------------
1944       radb2: Real FFT's backward processing of factor 2
1945      -------------------------------------------------*/
1946    void radb2(final int ido, final int l1, final double in[], final int in_off, final double out[], final int out_off, final int offset) {
1947        int i, ic;
1948        double t1i, t1r, w1r, w1i;
1949        int iw1 = offset;
1950
1951        int idx0 = l1 * ido;
1952        for (int k = 0; k < l1; k++) {
1953            int idx1 = k * ido;
1954            int idx2 = 2 * idx1;
1955            int idx3 = idx2 + ido;
1956            int oidx1 = out_off + idx1;
1957            int iidx1 = in_off + idx2;
1958            int iidx2 = in_off + ido - 1 + idx3;
1959            double i1r = in[iidx1];
1960            double i2r = in[iidx2];
1961            out[oidx1] = i1r + i2r;
1962            out[oidx1 + idx0] = i1r - i2r;
1963        }
1964        if (ido < 2)
1965            return;
1966        if (ido != 2) {
1967            for (int k = 0; k < l1; ++k) {
1968                int idx1 = k * ido;
1969                int idx2 = 2 * idx1;
1970                int idx3 = idx2 + ido;
1971                int idx4 = idx1 + idx0;
1972                for (i = 2; i < ido; i += 2) {
1973                    ic = ido - i;
1974                    int idx5 = i - 1 + iw1;
1975                    int idx6 = out_off + i;
1976                    int idx7 = in_off + i;
1977                    int idx8 = in_off + ic;
1978                    w1r = wtable_r[idx5 - 1];
1979                    w1i = wtable_r[idx5];
1980                    int iidx1 = idx7 + idx2;
1981                    int iidx2 = idx8 + idx3;
1982                    int oidx1 = idx6 + idx1;
1983                    int oidx2 = idx6 + idx4;
1984                    t1r = in[iidx1 - 1] - in[iidx2 - 1];
1985                    t1i = in[iidx1] + in[iidx2];
1986                    double i1i = in[iidx1];
1987                    double i1r = in[iidx1 - 1];
1988                    double i2i = in[iidx2];
1989                    double i2r = in[iidx2 - 1];
1990
1991                    out[oidx1 - 1] = i1r + i2r;
1992                    out[oidx1] = i1i - i2i;
1993                    out[oidx2 - 1] = w1r * t1r - w1i * t1i;
1994                    out[oidx2] = w1r * t1i + w1i * t1r;
1995                }
1996            }
1997            if (ido % 2 == 1)
1998                return;
1999        }
2000        for (int k = 0; k < l1; k++) {
2001            int idx1 = k * ido;
2002            int idx2 = 2 * idx1;
2003            int oidx1 = out_off + ido - 1 + idx1;
2004            int iidx1 = in_off + idx2 + ido;
2005            out[oidx1] = 2 * in[iidx1 - 1];
2006            out[oidx1 + idx0] = -2 * in[iidx1];
2007        }
2008    }
2009
2010    /*-------------------------------------------------
2011       radf3: Real FFT's forward processing of factor 3 
2012      -------------------------------------------------*/
2013    void radf3(final int ido, final int l1, final double in[], final int in_off, final double out[], final int out_off, final int offset) {
2014        final double taur = -0.5;
2015        final double taui = 0.866025403784438707610604524234076962;
2016        int i, ic;
2017        double ci2, di2, di3, cr2, dr2, dr3, ti2, ti3, tr2, tr3, w1r, w2r, w1i, w2i;
2018        int iw1, iw2;
2019        iw1 = offset;
2020        iw2 = iw1 + ido;
2021
2022        int idx0 = l1 * ido;
2023        for (int k = 0; k < l1; k++) {
2024            int idx1 = k * ido;
2025            int idx3 = 2 * idx0;
2026            int idx4 = (3 * k + 1) * ido;
2027            int iidx1 = in_off + idx1;
2028            int iidx2 = iidx1 + idx0;
2029            int iidx3 = iidx1 + idx3;
2030            double i1r = in[iidx1];
2031            double i2r = in[iidx2];
2032            double i3r = in[iidx3];
2033            cr2 = i2r + i3r;
2034            out[out_off + 3 * idx1] = i1r + cr2;
2035            out[out_off + idx4 + ido] = taui * (i3r - i2r);
2036            out[out_off + ido - 1 + idx4] = i1r + taur * cr2;
2037        }
2038        if (ido == 1)
2039            return;
2040        for (int k = 0; k < l1; k++) {
2041            int idx3 = k * ido;
2042            int idx4 = 3 * idx3;
2043            int idx5 = idx3 + idx0;
2044            int idx6 = idx5 + idx0;
2045            int idx7 = idx4 + ido;
2046            int idx8 = idx7 + ido;
2047            for (i = 2; i < ido; i += 2) {
2048                ic = ido - i;
2049                int widx1 = i - 1 + iw1;
2050                int widx2 = i - 1 + iw2;
2051
2052                w1r = wtable_r[widx1 - 1];
2053                w1i = wtable_r[widx1];
2054                w2r = wtable_r[widx2 - 1];
2055                w2i = wtable_r[widx2];
2056
2057                int idx9 = in_off + i;
2058                int idx10 = out_off + i;
2059                int idx11 = out_off + ic;
2060                int iidx1 = idx9 + idx3;
2061                int iidx2 = idx9 + idx5;
2062                int iidx3 = idx9 + idx6;
2063
2064                double i1i = in[iidx1 - 1];
2065                double i1r = in[iidx1];
2066                double i2i = in[iidx2 - 1];
2067                double i2r = in[iidx2];
2068                double i3i = in[iidx3 - 1];
2069                double i3r = in[iidx3];
2070
2071                dr2 = w1r * i2i + w1i * i2r;
2072                di2 = w1r * i2r - w1i * i2i;
2073                dr3 = w2r * i3i + w2i * i3r;
2074                di3 = w2r * i3r - w2i * i3i;
2075                cr2 = dr2 + dr3;
2076                ci2 = di2 + di3;
2077                tr2 = i1i + taur * cr2;
2078                ti2 = i1r + taur * ci2;
2079                tr3 = taui * (di2 - di3);
2080                ti3 = taui * (dr3 - dr2);
2081
2082                int oidx1 = idx10 + idx4;
2083                int oidx2 = idx11 + idx7;
2084                int oidx3 = idx10 + idx8;
2085
2086                out[oidx1 - 1] = i1i + cr2;
2087                out[oidx1] = i1r + ci2;
2088                out[oidx2 - 1] = tr2 - tr3;
2089                out[oidx2] = ti3 - ti2;
2090                out[oidx3 - 1] = tr2 + tr3;
2091                out[oidx3] = ti2 + ti3;
2092            }
2093        }
2094    }
2095
2096    /*-------------------------------------------------
2097       radb3: Real FFT's backward processing of factor 3
2098      -------------------------------------------------*/
2099    void radb3(final int ido, final int l1, final double in[], final int in_off, final double out[], final int out_off, final int offset) {
2100        final double taur = -0.5;
2101        final double taui = 0.866025403784438707610604524234076962;
2102        int i, ic;
2103        double ci2, ci3, di2, di3, cr2, cr3, dr2, dr3, ti2, tr2, w1r, w2r, w1i, w2i;
2104        int iw1, iw2;
2105        iw1 = offset;
2106        iw2 = iw1 + ido;
2107
2108        for (int k = 0; k < l1; k++) {
2109            int idx1 = k * ido;
2110            int iidx1 = in_off + 3 * idx1;
2111            int iidx2 = iidx1 + 2 * ido;
2112            double i1i = in[iidx1];
2113
2114            tr2 = 2 * in[iidx2 - 1];
2115            cr2 = i1i + taur * tr2;
2116            ci3 = 2 * taui * in[iidx2];
2117
2118            out[out_off + idx1] = i1i + tr2;
2119            out[out_off + (k + l1) * ido] = cr2 - ci3;
2120            out[out_off + (k + 2 * l1) * ido] = cr2 + ci3;
2121        }
2122        if (ido == 1)
2123            return;
2124        int idx0 = l1 * ido;
2125        for (int k = 0; k < l1; k++) {
2126            int idx1 = k * ido;
2127            int idx2 = 3 * idx1;
2128            int idx3 = idx2 + ido;
2129            int idx4 = idx3 + ido;
2130            int idx5 = idx1 + idx0;
2131            int idx6 = idx5 + idx0;
2132            for (i = 2; i < ido; i += 2) {
2133                ic = ido - i;
2134                int idx7 = in_off + i;
2135                int idx8 = in_off + ic;
2136                int idx9 = out_off + i;
2137                int iidx1 = idx7 + idx2;
2138                int iidx2 = idx7 + idx4;
2139                int iidx3 = idx8 + idx3;
2140
2141                double i1i = in[iidx1 - 1];
2142                double i1r = in[iidx1];
2143                double i2i = in[iidx2 - 1];
2144                double i2r = in[iidx2];
2145                double i3i = in[iidx3 - 1];
2146                double i3r = in[iidx3];
2147
2148                tr2 = i2i + i3i;
2149                cr2 = i1i + taur * tr2;
2150                ti2 = i2r - i3r;
2151                ci2 = i1r + taur * ti2;
2152                cr3 = taui * (i2i - i3i);
2153                ci3 = taui * (i2r + i3r);
2154                dr2 = cr2 - ci3;
2155                dr3 = cr2 + ci3;
2156                di2 = ci2 + cr3;
2157                di3 = ci2 - cr3;
2158
2159                int widx1 = i - 1 + iw1;
2160                int widx2 = i - 1 + iw2;
2161
2162                w1r = wtable_r[widx1 - 1];
2163                w1i = wtable_r[widx1];
2164                w2r = wtable_r[widx2 - 1];
2165                w2i = wtable_r[widx2];
2166
2167                int oidx1 = idx9 + idx1;
2168                int oidx2 = idx9 + idx5;
2169                int oidx3 = idx9 + idx6;
2170
2171                out[oidx1 - 1] = i1i + tr2;
2172                out[oidx1] = i1r + ti2;
2173                out[oidx2 - 1] = w1r * dr2 - w1i * di2;
2174                out[oidx2] = w1r * di2 + w1i * dr2;
2175                out[oidx3 - 1] = w2r * dr3 - w2i * di3;
2176                out[oidx3] = w2r * di3 + w2i * dr3;
2177            }
2178        }
2179    }
2180
2181    /*-------------------------------------------------
2182       radf4: Real FFT's forward processing of factor 4
2183      -------------------------------------------------*/
2184    void radf4(final int ido, final int l1, final double in[], final int in_off, final double out[], final int out_off, final int offset) {
2185        final double hsqt2 = 0.707106781186547572737310929369414225;
2186        int i, ic;
2187        double ci2, ci3, ci4, cr2, cr3, cr4, ti1, ti2, ti3, ti4, tr1, tr2, tr3, tr4, w1r, w1i, w2r, w2i, w3r, w3i;
2188        int iw1, iw2, iw3;
2189        iw1 = offset;
2190        iw2 = offset + ido;
2191        iw3 = iw2 + ido;
2192        int idx0 = l1 * ido;
2193        for (int k = 0; k < l1; k++) {
2194            int idx1 = k * ido;
2195            int idx2 = 4 * idx1;
2196            int idx3 = idx1 + idx0;
2197            int idx4 = idx3 + idx0;
2198            int idx5 = idx4 + idx0;
2199            int idx6 = idx2 + ido;
2200            double i1r = in[in_off + idx1];
2201            double i2r = in[in_off + idx3];
2202            double i3r = in[in_off + idx4];
2203            double i4r = in[in_off + idx5];
2204
2205            tr1 = i2r + i4r;
2206            tr2 = i1r + i3r;
2207
2208            int oidx1 = out_off + idx2;
2209            int oidx2 = out_off + idx6 + ido;
2210
2211            out[oidx1] = tr1 + tr2;
2212            out[oidx2 - 1 + ido + ido] = tr2 - tr1;
2213            out[oidx2 - 1] = i1r - i3r;
2214            out[oidx2] = i4r - i2r;
2215        }
2216        if (ido < 2)
2217            return;
2218        if (ido != 2) {
2219            for (int k = 0; k < l1; k++) {
2220                int idx1 = k * ido;
2221                int idx2 = idx1 + idx0;
2222                int idx3 = idx2 + idx0;
2223                int idx4 = idx3 + idx0;
2224                int idx5 = 4 * idx1;
2225                int idx6 = idx5 + ido;
2226                int idx7 = idx6 + ido;
2227                int idx8 = idx7 + ido;
2228                for (i = 2; i < ido; i += 2) {
2229                    ic = ido - i;
2230                    int widx1 = i - 1 + iw1;
2231                    int widx2 = i - 1 + iw2;
2232                    int widx3 = i - 1 + iw3;
2233                    w1r = wtable_r[widx1 - 1];
2234                    w1i = wtable_r[widx1];
2235                    w2r = wtable_r[widx2 - 1];
2236                    w2i = wtable_r[widx2];
2237                    w3r = wtable_r[widx3 - 1];
2238                    w3i = wtable_r[widx3];
2239
2240                    int idx9 = in_off + i;
2241                    int idx10 = out_off + i;
2242                    int idx11 = out_off + ic;
2243                    int iidx1 = idx9 + idx1;
2244                    int iidx2 = idx9 + idx2;
2245                    int iidx3 = idx9 + idx3;
2246                    int iidx4 = idx9 + idx4;
2247
2248                    double i1i = in[iidx1 - 1];
2249                    double i1r = in[iidx1];
2250                    double i2i = in[iidx2 - 1];
2251                    double i2r = in[iidx2];
2252                    double i3i = in[iidx3 - 1];
2253                    double i3r = in[iidx3];
2254                    double i4i = in[iidx4 - 1];
2255                    double i4r = in[iidx4];
2256
2257                    cr2 = w1r * i2i + w1i * i2r;
2258                    ci2 = w1r * i2r - w1i * i2i;
2259                    cr3 = w2r * i3i + w2i * i3r;
2260                    ci3 = w2r * i3r - w2i * i3i;
2261                    cr4 = w3r * i4i + w3i * i4r;
2262                    ci4 = w3r * i4r - w3i * i4i;
2263                    tr1 = cr2 + cr4;
2264                    tr4 = cr4 - cr2;
2265                    ti1 = ci2 + ci4;
2266                    ti4 = ci2 - ci4;
2267                    ti2 = i1r + ci3;
2268                    ti3 = i1r - ci3;
2269                    tr2 = i1i + cr3;
2270                    tr3 = i1i - cr3;
2271
2272                    int oidx1 = idx10 + idx5;
2273                    int oidx2 = idx11 + idx6;
2274                    int oidx3 = idx10 + idx7;
2275                    int oidx4 = idx11 + idx8;
2276
2277                    out[oidx1 - 1] = tr1 + tr2;
2278                    out[oidx4 - 1] = tr2 - tr1;
2279                    out[oidx1] = ti1 + ti2;
2280                    out[oidx4] = ti1 - ti2;
2281                    out[oidx3 - 1] = ti4 + tr3;
2282                    out[oidx2 - 1] = tr3 - ti4;
2283                    out[oidx3] = tr4 + ti3;
2284                    out[oidx2] = tr4 - ti3;
2285                }
2286            }
2287            if (ido % 2 == 1)
2288                return;
2289        }
2290        for (int k = 0; k < l1; k++) {
2291            int idx1 = k * ido;
2292            int idx2 = 4 * idx1;
2293            int idx3 = idx1 + idx0;
2294            int idx4 = idx3 + idx0;
2295            int idx5 = idx4 + idx0;
2296            int idx6 = idx2 + ido;
2297            int idx7 = idx6 + ido;
2298            int idx8 = idx7 + ido;
2299            int idx9 = in_off + ido;
2300            int idx10 = out_off + ido;
2301
2302            double i1i = in[idx9 - 1 + idx1];
2303            double i2i = in[idx9 - 1 + idx3];
2304            double i3i = in[idx9 - 1 + idx4];
2305            double i4i = in[idx9 - 1 + idx5];
2306
2307            ti1 = -hsqt2 * (i2i + i4i);
2308            tr1 = hsqt2 * (i2i - i4i);
2309
2310            out[idx10 - 1 + idx2] = tr1 + i1i;
2311            out[idx10 - 1 + idx7] = i1i - tr1;
2312            out[out_off + idx6] = ti1 - i3i;
2313            out[out_off + idx8] = ti1 + i3i;
2314        }
2315    }
2316
2317    /*-------------------------------------------------
2318       radb4: Real FFT's backward processing of factor 4
2319      -------------------------------------------------*/
2320    void radb4(final int ido, final int l1, final double in[], final int in_off, final double out[], final int out_off, final int offset) {
2321        final double sqrt2 = 1.41421356237309514547462185873882845;
2322        int i, ic;
2323        double ci2, ci3, ci4, cr2, cr3, cr4;
2324        double ti1, ti2, ti3, ti4, tr1, tr2, tr3, tr4, w1r, w1i, w2r, w2i, w3r, w3i;
2325        int iw1, iw2, iw3;
2326        iw1 = offset;
2327        iw2 = iw1 + ido;
2328        iw3 = iw2 + ido;
2329
2330        int idx0 = l1 * ido;
2331        for (int k = 0; k < l1; k++) {
2332            int idx1 = k * ido;
2333            int idx2 = 4 * idx1;
2334            int idx3 = idx1 + idx0;
2335            int idx4 = idx3 + idx0;
2336            int idx5 = idx4 + idx0;
2337            int idx6 = idx2 + ido;
2338            int idx7 = idx6 + ido;
2339            int idx8 = idx7 + ido;
2340
2341            double i1r = in[in_off + idx2];
2342            double i2r = in[in_off + idx7];
2343            double i3r = in[in_off + ido - 1 + idx8];
2344            double i4r = in[in_off + ido - 1 + idx6];
2345
2346            tr1 = i1r - i3r;
2347            tr2 = i1r + i3r;
2348            tr3 = i4r + i4r;
2349            tr4 = i2r + i2r;
2350
2351            out[out_off + idx1] = tr2 + tr3;
2352            out[out_off + idx3] = tr1 - tr4;
2353            out[out_off + idx4] = tr2 - tr3;
2354            out[out_off + idx5] = tr1 + tr4;
2355        }
2356        if (ido < 2)
2357            return;
2358        if (ido != 2) {
2359            for (int k = 0; k < l1; ++k) {
2360                int idx1 = k * ido;
2361                int idx2 = idx1 + idx0;
2362                int idx3 = idx2 + idx0;
2363                int idx4 = idx3 + idx0;
2364                int idx5 = 4 * idx1;
2365                int idx6 = idx5 + ido;
2366                int idx7 = idx6 + ido;
2367                int idx8 = idx7 + ido;
2368                for (i = 2; i < ido; i += 2) {
2369                    ic = ido - i;
2370                    int widx1 = i - 1 + iw1;
2371                    int widx2 = i - 1 + iw2;
2372                    int widx3 = i - 1 + iw3;
2373                    w1r = wtable_r[widx1 - 1];
2374                    w1i = wtable_r[widx1];
2375                    w2r = wtable_r[widx2 - 1];
2376                    w2i = wtable_r[widx2];
2377                    w3r = wtable_r[widx3 - 1];
2378                    w3i = wtable_r[widx3];
2379
2380                    int idx12 = in_off + i;
2381                    int idx13 = in_off + ic;
2382                    int idx14 = out_off + i;
2383
2384                    int iidx1 = idx12 + idx5;
2385                    int iidx2 = idx13 + idx6;
2386                    int iidx3 = idx12 + idx7;
2387                    int iidx4 = idx13 + idx8;
2388
2389                    double i1i = in[iidx1 - 1];
2390                    double i1r = in[iidx1];
2391                    double i2i = in[iidx2 - 1];
2392                    double i2r = in[iidx2];
2393                    double i3i = in[iidx3 - 1];
2394                    double i3r = in[iidx3];
2395                    double i4i = in[iidx4 - 1];
2396                    double i4r = in[iidx4];
2397
2398                    ti1 = i1r + i4r;
2399                    ti2 = i1r - i4r;
2400                    ti3 = i3r - i2r;
2401                    tr4 = i3r + i2r;
2402                    tr1 = i1i - i4i;
2403                    tr2 = i1i + i4i;
2404                    ti4 = i3i - i2i;
2405                    tr3 = i3i + i2i;
2406                    cr3 = tr2 - tr3;
2407                    ci3 = ti2 - ti3;
2408                    cr2 = tr1 - tr4;
2409                    cr4 = tr1 + tr4;
2410                    ci2 = ti1 + ti4;
2411                    ci4 = ti1 - ti4;
2412
2413                    int oidx1 = idx14 + idx1;
2414                    int oidx2 = idx14 + idx2;
2415                    int oidx3 = idx14 + idx3;
2416                    int oidx4 = idx14 + idx4;
2417
2418                    out[oidx1 - 1] = tr2 + tr3;
2419                    out[oidx1] = ti2 + ti3;
2420                    out[oidx2 - 1] = w1r * cr2 - w1i * ci2;
2421                    out[oidx2] = w1r * ci2 + w1i * cr2;
2422                    out[oidx3 - 1] = w2r * cr3 - w2i * ci3;
2423                    out[oidx3] = w2r * ci3 + w2i * cr3;
2424                    out[oidx4 - 1] = w3r * cr4 - w3i * ci4;
2425                    out[oidx4] = w3r * ci4 + w3i * cr4;
2426                }
2427            }
2428            if (ido % 2 == 1)
2429                return;
2430        }
2431        for (int k = 0; k < l1; k++) {
2432            int idx1 = k * ido;
2433            int idx2 = 4 * idx1;
2434            int idx3 = idx1 + idx0;
2435            int idx4 = idx3 + idx0;
2436            int idx5 = idx4 + idx0;
2437            int idx6 = idx2 + ido;
2438            int idx7 = idx6 + ido;
2439            int idx8 = idx7 + ido;
2440            int idx9 = in_off + ido;
2441            int idx10 = out_off + ido;
2442
2443            double i1r = in[idx9 - 1 + idx2];
2444            double i2r = in[idx9 - 1 + idx7];
2445            double i3r = in[in_off + idx6];
2446            double i4r = in[in_off + idx8];
2447
2448            ti1 = i3r + i4r;
2449            ti2 = i4r - i3r;
2450            tr1 = i1r - i2r;
2451            tr2 = i1r + i2r;
2452
2453            out[idx10 - 1 + idx1] = tr2 + tr2;
2454            out[idx10 - 1 + idx3] = sqrt2 * (tr1 - ti1);
2455            out[idx10 - 1 + idx4] = ti2 + ti2;
2456            out[idx10 - 1 + idx5] = -sqrt2 * (tr1 + ti1);
2457        }
2458    }
2459
2460    /*-------------------------------------------------
2461       radf5: Real FFT's forward processing of factor 5
2462      -------------------------------------------------*/
2463    void radf5(final int ido, final int l1, final double in[], final int in_off, final double out[], final int out_off, final int offset) {
2464        final double tr11 = 0.309016994374947451262869435595348477;
2465        final double ti11 = 0.951056516295153531181938433292089030;
2466        final double tr12 = -0.809016994374947340240566973079694435;
2467        final double ti12 = 0.587785252292473248125759255344746634;
2468        int i, ic;
2469        double ci2, di2, ci4, ci5, di3, di4, di5, ci3, cr2, cr3, dr2, dr3, dr4, dr5, cr5, cr4, ti2, ti3, ti5, ti4, tr2, tr3, tr4, tr5, w1r, w1i, w2r, w2i, w3r, w3i, w4r, w4i;
2470        int iw1, iw2, iw3, iw4;
2471        iw1 = offset;
2472        iw2 = iw1 + ido;
2473        iw3 = iw2 + ido;
2474        iw4 = iw3 + ido;
2475
2476        int idx0 = l1 * ido;
2477        for (int k = 0; k < l1; k++) {
2478            int idx1 = k * ido;
2479            int idx2 = 5 * idx1;
2480            int idx3 = idx2 + ido;
2481            int idx4 = idx3 + ido;
2482            int idx5 = idx4 + ido;
2483            int idx6 = idx5 + ido;
2484            int idx7 = idx1 + idx0;
2485            int idx8 = idx7 + idx0;
2486            int idx9 = idx8 + idx0;
2487            int idx10 = idx9 + idx0;
2488            int idx11 = out_off + ido - 1;
2489
2490            double i1r = in[in_off + idx1];
2491            double i2r = in[in_off + idx7];
2492            double i3r = in[in_off + idx8];
2493            double i4r = in[in_off + idx9];
2494            double i5r = in[in_off + idx10];
2495
2496            cr2 = i5r + i2r;
2497            ci5 = i5r - i2r;
2498            cr3 = i4r + i3r;
2499            ci4 = i4r - i3r;
2500
2501            out[out_off + idx2] = i1r + cr2 + cr3;
2502            out[idx11 + idx3] = i1r + tr11 * cr2 + tr12 * cr3;
2503            out[out_off + idx4] = ti11 * ci5 + ti12 * ci4;
2504            out[idx11 + idx5] = i1r + tr12 * cr2 + tr11 * cr3;
2505            out[out_off + idx6] = ti12 * ci5 - ti11 * ci4;
2506        }
2507        if (ido == 1)
2508            return;
2509        for (int k = 0; k < l1; ++k) {
2510            int idx1 = k * ido;
2511            int idx2 = 5 * idx1;
2512            int idx3 = idx2 + ido;
2513            int idx4 = idx3 + ido;
2514            int idx5 = idx4 + ido;
2515            int idx6 = idx5 + ido;
2516            int idx7 = idx1 + idx0;
2517            int idx8 = idx7 + idx0;
2518            int idx9 = idx8 + idx0;
2519            int idx10 = idx9 + idx0;
2520            for (i = 2; i < ido; i += 2) {
2521                int widx1 = i - 1 + iw1;
2522                int widx2 = i - 1 + iw2;
2523                int widx3 = i - 1 + iw3;
2524                int widx4 = i - 1 + iw4;
2525                w1r = wtable_r[widx1 - 1];
2526                w1i = wtable_r[widx1];
2527                w2r = wtable_r[widx2 - 1];
2528                w2i = wtable_r[widx2];
2529                w3r = wtable_r[widx3 - 1];
2530                w3i = wtable_r[widx3];
2531                w4r = wtable_r[widx4 - 1];
2532                w4i = wtable_r[widx4];
2533
2534                ic = ido - i;
2535                int idx15 = in_off + i;
2536                int idx16 = out_off + i;
2537                int idx17 = out_off + ic;
2538
2539                int iidx1 = idx15 + idx1;
2540                int iidx2 = idx15 + idx7;
2541                int iidx3 = idx15 + idx8;
2542                int iidx4 = idx15 + idx9;
2543                int iidx5 = idx15 + idx10;
2544
2545                double i1i = in[iidx1 - 1];
2546                double i1r = in[iidx1];
2547                double i2i = in[iidx2 - 1];
2548                double i2r = in[iidx2];
2549                double i3i = in[iidx3 - 1];
2550                double i3r = in[iidx3];
2551                double i4i = in[iidx4 - 1];
2552                double i4r = in[iidx4];
2553                double i5i = in[iidx5 - 1];
2554                double i5r = in[iidx5];
2555
2556                dr2 = w1r * i2i + w1i * i2r;
2557                di2 = w1r * i2r - w1i * i2i;
2558                dr3 = w2r * i3i + w2i * i3r;
2559                di3 = w2r * i3r - w2i * i3i;
2560                dr4 = w3r * i4i + w3i * i4r;
2561                di4 = w3r * i4r - w3i * i4i;
2562                dr5 = w4r * i5i + w4i * i5r;
2563                di5 = w4r * i5r - w4i * i5i;
2564
2565                cr2 = dr2 + dr5;
2566                ci5 = dr5 - dr2;
2567                cr5 = di2 - di5;
2568                ci2 = di2 + di5;
2569                cr3 = dr3 + dr4;
2570                ci4 = dr4 - dr3;
2571                cr4 = di3 - di4;
2572                ci3 = di3 + di4;
2573
2574                tr2 = i1i + tr11 * cr2 + tr12 * cr3;
2575                ti2 = i1r + tr11 * ci2 + tr12 * ci3;
2576                tr3 = i1i + tr12 * cr2 + tr11 * cr3;
2577                ti3 = i1r + tr12 * ci2 + tr11 * ci3;
2578                tr5 = ti11 * cr5 + ti12 * cr4;
2579                ti5 = ti11 * ci5 + ti12 * ci4;
2580                tr4 = ti12 * cr5 - ti11 * cr4;
2581                ti4 = ti12 * ci5 - ti11 * ci4;
2582
2583                int oidx1 = idx16 + idx2;
2584                int oidx2 = idx17 + idx3;
2585                int oidx3 = idx16 + idx4;
2586                int oidx4 = idx17 + idx5;
2587                int oidx5 = idx16 + idx6;
2588
2589                out[oidx1 - 1] = i1i + cr2 + cr3;
2590                out[oidx1] = i1r + ci2 + ci3;
2591                out[oidx3 - 1] = tr2 + tr5;
2592                out[oidx2 - 1] = tr2 - tr5;
2593                out[oidx3] = ti2 + ti5;
2594                out[oidx2] = ti5 - ti2;
2595                out[oidx5 - 1] = tr3 + tr4;
2596                out[oidx4 - 1] = tr3 - tr4;
2597                out[oidx5] = ti3 + ti4;
2598                out[oidx4] = ti4 - ti3;
2599            }
2600        }
2601    }
2602
2603    /*-------------------------------------------------
2604       radb5: Real FFT's backward processing of factor 5
2605      -------------------------------------------------*/
2606    void radb5(final int ido, final int l1, final double in[], final int in_off, final double out[], final int out_off, final int offset) {
2607        final double tr11 = 0.309016994374947451262869435595348477;
2608        final double ti11 = 0.951056516295153531181938433292089030;
2609        final double tr12 = -0.809016994374947340240566973079694435;
2610        final double ti12 = 0.587785252292473248125759255344746634;
2611        int i, ic;
2612        double ci2, ci3, ci4, ci5, di3, di4, di5, di2, cr2, cr3, cr5, cr4, ti2, ti3, ti4, ti5, dr3, dr4, dr5, dr2, tr2, tr3, tr4, tr5, w1r, w1i, w2r, w2i, w3r, w3i, w4r, w4i;
2613        int iw1, iw2, iw3, iw4;
2614        iw1 = offset;
2615        iw2 = iw1 + ido;
2616        iw3 = iw2 + ido;
2617        iw4 = iw3 + ido;
2618
2619        int idx0 = l1 * ido;
2620        for (int k = 0; k < l1; k++) {
2621            int idx1 = k * ido;
2622            int idx2 = 5 * idx1;
2623            int idx3 = idx2 + ido;
2624            int idx4 = idx3 + ido;
2625            int idx5 = idx4 + ido;
2626            int idx6 = idx5 + ido;
2627            int idx7 = idx1 + idx0;
2628            int idx8 = idx7 + idx0;
2629            int idx9 = idx8 + idx0;
2630            int idx10 = idx9 + idx0;
2631            int idx11 = in_off + ido - 1;
2632
2633            double i1r = in[in_off + idx2];
2634
2635            ti5 = 2 * in[in_off + idx4];
2636            ti4 = 2 * in[in_off + idx6];
2637            tr2 = 2 * in[idx11 + idx3];
2638            tr3 = 2 * in[idx11 + idx5];
2639            cr2 = i1r + tr11 * tr2 + tr12 * tr3;
2640            cr3 = i1r + tr12 * tr2 + tr11 * tr3;
2641            ci5 = ti11 * ti5 + ti12 * ti4;
2642            ci4 = ti12 * ti5 - ti11 * ti4;
2643
2644            out[out_off + idx1] = i1r + tr2 + tr3;
2645            out[out_off + idx7] = cr2 - ci5;
2646            out[out_off + idx8] = cr3 - ci4;
2647            out[out_off + idx9] = cr3 + ci4;
2648            out[out_off + idx10] = cr2 + ci5;
2649        }
2650        if (ido == 1)
2651            return;
2652        for (int k = 0; k < l1; ++k) {
2653            int idx1 = k * ido;
2654            int idx2 = 5 * idx1;
2655            int idx3 = idx2 + ido;
2656            int idx4 = idx3 + ido;
2657            int idx5 = idx4 + ido;
2658            int idx6 = idx5 + ido;
2659            int idx7 = idx1 + idx0;
2660            int idx8 = idx7 + idx0;
2661            int idx9 = idx8 + idx0;
2662            int idx10 = idx9 + idx0;
2663            for (i = 2; i < ido; i += 2) {
2664                ic = ido - i;
2665                int widx1 = i - 1 + iw1;
2666                int widx2 = i - 1 + iw2;
2667                int widx3 = i - 1 + iw3;
2668                int widx4 = i - 1 + iw4;
2669                w1r = wtable_r[widx1 - 1];
2670                w1i = wtable_r[widx1];
2671                w2r = wtable_r[widx2 - 1];
2672                w2i = wtable_r[widx2];
2673                w3r = wtable_r[widx3 - 1];
2674                w3i = wtable_r[widx3];
2675                w4r = wtable_r[widx4 - 1];
2676                w4i = wtable_r[widx4];
2677
2678                int idx15 = in_off + i;
2679                int idx16 = in_off + ic;
2680                int idx17 = out_off + i;
2681
2682                int iidx1 = idx15 + idx2;
2683                int iidx2 = idx16 + idx3;
2684                int iidx3 = idx15 + idx4;
2685                int iidx4 = idx16 + idx5;
2686                int iidx5 = idx15 + idx6;
2687
2688                double i1i = in[iidx1 - 1];
2689                double i1r = in[iidx1];
2690                double i2i = in[iidx2 - 1];
2691                double i2r = in[iidx2];
2692                double i3i = in[iidx3 - 1];
2693                double i3r = in[iidx3];
2694                double i4i = in[iidx4 - 1];
2695                double i4r = in[iidx4];
2696                double i5i = in[iidx5 - 1];
2697                double i5r = in[iidx5];
2698
2699                ti5 = i3r + i2r;
2700                ti2 = i3r - i2r;
2701                ti4 = i5r + i4r;
2702                ti3 = i5r - i4r;
2703                tr5 = i3i - i2i;
2704                tr2 = i3i + i2i;
2705                tr4 = i5i - i4i;
2706                tr3 = i5i + i4i;
2707
2708                cr2 = i1i + tr11 * tr2 + tr12 * tr3;
2709                ci2 = i1r + tr11 * ti2 + tr12 * ti3;
2710                cr3 = i1i + tr12 * tr2 + tr11 * tr3;
2711                ci3 = i1r + tr12 * ti2 + tr11 * ti3;
2712                cr5 = ti11 * tr5 + ti12 * tr4;
2713                ci5 = ti11 * ti5 + ti12 * ti4;
2714                cr4 = ti12 * tr5 - ti11 * tr4;
2715                ci4 = ti12 * ti5 - ti11 * ti4;
2716                dr3 = cr3 - ci4;
2717                dr4 = cr3 + ci4;
2718                di3 = ci3 + cr4;
2719                di4 = ci3 - cr4;
2720                dr5 = cr2 + ci5;
2721                dr2 = cr2 - ci5;
2722                di5 = ci2 - cr5;
2723                di2 = ci2 + cr5;
2724
2725                int oidx1 = idx17 + idx1;
2726                int oidx2 = idx17 + idx7;
2727                int oidx3 = idx17 + idx8;
2728                int oidx4 = idx17 + idx9;
2729                int oidx5 = idx17 + idx10;
2730
2731                out[oidx1 - 1] = i1i + tr2 + tr3;
2732                out[oidx1] = i1r + ti2 + ti3;
2733                out[oidx2 - 1] = w1r * dr2 - w1i * di2;
2734                out[oidx2] = w1r * di2 + w1i * dr2;
2735                out[oidx3 - 1] = w2r * dr3 - w2i * di3;
2736                out[oidx3] = w2r * di3 + w2i * dr3;
2737                out[oidx4 - 1] = w3r * dr4 - w3i * di4;
2738                out[oidx4] = w3r * di4 + w3i * dr4;
2739                out[oidx5 - 1] = w4r * dr5 - w4i * di5;
2740                out[oidx5] = w4r * di5 + w4i * dr5;
2741            }
2742        }
2743    }
2744
2745    /*---------------------------------------------------------
2746       radfg: Real FFT's forward processing of general factor
2747      --------------------------------------------------------*/
2748    void radfg(final int ido, final int ip, final int l1, final int idl1, final double in[], final int in_off, final double out[], final int out_off, final int offset) {
2749        int idij, ipph, j2, ic, jc, lc, is, nbd;
2750        double dc2, ai1, ai2, ar1, ar2, ds2, dcp, arg, dsp, ar1h, ar2h, w1r, w1i;
2751        int iw1 = offset;
2752
2753        arg = TWO_PI / (double) ip;
2754        dcp = Math.cos(arg);
2755        dsp = Math.sin(arg);
2756        ipph = (ip + 1) / 2;
2757        nbd = (ido - 1) / 2;
2758        if (ido != 1) {
2759            for (int ik = 0; ik < idl1; ik++)
2760                out[out_off + ik] = in[in_off + ik];
2761            for (int j = 1; j < ip; j++) {
2762                int idx1 = j * l1 * ido;
2763                for (int k = 0; k < l1; k++) {
2764                    int idx2 = k * ido + idx1;
2765                    out[out_off + idx2] = in[in_off + idx2];
2766                }
2767            }
2768            if (nbd <= l1) {
2769                is = -ido;
2770                for (int j = 1; j < ip; j++) {
2771                    is += ido;
2772                    idij = is - 1;
2773                    int idx1 = j * l1 * ido;
2774                    for (int i = 2; i < ido; i += 2) {
2775                        idij += 2;
2776                        int idx2 = idij + iw1;
2777                        int idx4 = in_off + i;
2778                        int idx5 = out_off + i;
2779                        w1r = wtable_r[idx2 - 1];
2780                        w1i = wtable_r[idx2];
2781                        for (int k = 0; k < l1; k++) {
2782                            int idx3 = k * ido + idx1;
2783                            int oidx1 = idx5 + idx3;
2784                            int iidx1 = idx4 + idx3;
2785                            double i1i = in[iidx1 - 1];
2786                            double i1r = in[iidx1];
2787
2788                            out[oidx1 - 1] = w1r * i1i + w1i * i1r;
2789                            out[oidx1] = w1r * i1r - w1i * i1i;
2790                        }
2791                    }
2792                }
2793            } else {
2794                is = -ido;
2795                for (int j = 1; j < ip; j++) {
2796                    is += ido;
2797                    int idx1 = j * l1 * ido;
2798                    for (int k = 0; k < l1; k++) {
2799                        idij = is - 1;
2800                        int idx3 = k * ido + idx1;
2801                        for (int i = 2; i < ido; i += 2) {
2802                            idij += 2;
2803                            int idx2 = idij + iw1;
2804                            w1r = wtable_r[idx2 - 1];
2805                            w1i = wtable_r[idx2];
2806                            int oidx1 = out_off + i + idx3;
2807                            int iidx1 = in_off + i + idx3;
2808                            double i1i = in[iidx1 - 1];
2809                            double i1r = in[iidx1];
2810
2811                            out[oidx1 - 1] = w1r * i1i + w1i * i1r;
2812                            out[oidx1] = w1r * i1r - w1i * i1i;
2813                        }
2814                    }
2815                }
2816            }
2817            if (nbd >= l1) {
2818                for (int j = 1; j < ipph; j++) {
2819                    jc = ip - j;
2820                    int idx1 = j * l1 * ido;
2821                    int idx2 = jc * l1 * ido;
2822                    for (int k = 0; k < l1; k++) {
2823                        int idx3 = k * ido + idx1;
2824                        int idx4 = k * ido + idx2;
2825                        for (int i = 2; i < ido; i += 2) {
2826                            int idx5 = in_off + i;
2827                            int idx6 = out_off + i;
2828                            int iidx1 = idx5 + idx3;
2829                            int iidx2 = idx5 + idx4;
2830                            int oidx1 = idx6 + idx3;
2831                            int oidx2 = idx6 + idx4;
2832                            double o1i = out[oidx1 - 1];
2833                            double o1r = out[oidx1];
2834                            double o2i = out[oidx2 - 1];
2835                            double o2r = out[oidx2];
2836
2837                            in[iidx1 - 1] = o1i + o2i;
2838                            in[iidx1] = o1r + o2r;
2839
2840                            in[iidx2 - 1] = o1r - o2r;
2841                            in[iidx2] = o2i - o1i;
2842                        }
2843                    }
2844                }
2845            } else {
2846                for (int j = 1; j < ipph; j++) {
2847                    jc = ip - j;
2848                    int idx1 = j * l1 * ido;
2849                    int idx2 = jc * l1 * ido;
2850                    for (int i = 2; i < ido; i += 2) {
2851                        int idx5 = in_off + i;
2852                        int idx6 = out_off + i;
2853                        for (int k = 0; k < l1; k++) {
2854                            int idx3 = k * ido + idx1;
2855                            int idx4 = k * ido + idx2;
2856                            int iidx1 = idx5 + idx3;
2857                            int iidx2 = idx5 + idx4;
2858                            int oidx1 = idx6 + idx3;
2859                            int oidx2 = idx6 + idx4;
2860                            double o1i = out[oidx1 - 1];
2861                            double o1r = out[oidx1];
2862                            double o2i = out[oidx2 - 1];
2863                            double o2r = out[oidx2];
2864
2865                            in[iidx1 - 1] = o1i + o2i;
2866                            in[iidx1] = o1r + o2r;
2867                            in[iidx2 - 1] = o1r - o2r;
2868                            in[iidx2] = o2i - o1i;
2869                        }
2870                    }
2871                }
2872            }
2873        } else {
2874            System.arraycopy(out, out_off, in, in_off, idl1);
2875        }
2876        for (int j = 1; j < ipph; j++) {
2877            jc = ip - j;
2878            int idx1 = j * l1 * ido;
2879            int idx2 = jc * l1 * ido;
2880            for (int k = 0; k < l1; k++) {
2881                int idx3 = k * ido + idx1;
2882                int idx4 = k * ido + idx2;
2883                int oidx1 = out_off + idx3;
2884                int oidx2 = out_off + idx4;
2885                double o1r = out[oidx1];
2886                double o2r = out[oidx2];
2887
2888                in[in_off + idx3] = o1r + o2r;
2889                in[in_off + idx4] = o2r - o1r;
2890            }
2891        }
2892
2893        ar1 = 1;
2894        ai1 = 0;
2895        int idx0 = (ip - 1) * idl1;
2896        for (int l = 1; l < ipph; l++) {
2897            lc = ip - l;
2898            ar1h = dcp * ar1 - dsp * ai1;
2899            ai1 = dcp * ai1 + dsp * ar1;
2900            ar1 = ar1h;
2901            int idx1 = l * idl1;
2902            int idx2 = lc * idl1;
2903            for (int ik = 0; ik < idl1; ik++) {
2904                int idx3 = out_off + ik;
2905                int idx4 = in_off + ik;
2906                out[idx3 + idx1] = in[idx4] + ar1 * in[idx4 + idl1];
2907                out[idx3 + idx2] = ai1 * in[idx4 + idx0];
2908            }
2909            dc2 = ar1;
2910            ds2 = ai1;
2911            ar2 = ar1;
2912            ai2 = ai1;
2913            for (int j = 2; j < ipph; j++) {
2914                jc = ip - j;
2915                ar2h = dc2 * ar2 - ds2 * ai2;
2916                ai2 = dc2 * ai2 + ds2 * ar2;
2917                ar2 = ar2h;
2918                int idx3 = j * idl1;
2919                int idx4 = jc * idl1;
2920                for (int ik = 0; ik < idl1; ik++) {
2921                    int idx5 = out_off + ik;
2922                    int idx6 = in_off + ik;
2923                    out[idx5 + idx1] += ar2 * in[idx6 + idx3];
2924                    out[idx5 + idx2] += ai2 * in[idx6 + idx4];
2925                }
2926            }
2927        }
2928        for (int j = 1; j < ipph; j++) {
2929            int idx1 = j * idl1;
2930            for (int ik = 0; ik < idl1; ik++) {
2931                out[out_off + ik] += in[in_off + ik + idx1];
2932            }
2933        }
2934
2935        if (ido >= l1) {
2936            for (int k = 0; k < l1; k++) {
2937                int idx1 = k * ido;
2938                int idx2 = idx1 * ip;
2939                for (int i = 0; i < ido; i++) {
2940                    in[in_off + i + idx2] = out[out_off + i + idx1];
2941                }
2942            }
2943        } else {
2944            for (int i = 0; i < ido; i++) {
2945                for (int k = 0; k < l1; k++) {
2946                    int idx1 = k * ido;
2947                    in[in_off + i + idx1 * ip] = out[out_off + i + idx1];
2948                }
2949            }
2950        }
2951        int idx01 = ip * ido;
2952        for (int j = 1; j < ipph; j++) {
2953            jc = ip - j;
2954            j2 = 2 * j;
2955            int idx1 = j * l1 * ido;
2956            int idx2 = jc * l1 * ido;
2957            int idx3 = j2 * ido;
2958            for (int k = 0; k < l1; k++) {
2959                int idx4 = k * ido;
2960                int idx5 = idx4 + idx1;
2961                int idx6 = idx4 + idx2;
2962                int idx7 = k * idx01;
2963                in[in_off + ido - 1 + idx3 - ido + idx7] = out[out_off + idx5];
2964                in[in_off + idx3 + idx7] = out[out_off + idx6];
2965            }
2966        }
2967        if (ido == 1)
2968            return;
2969        if (nbd >= l1) {
2970            for (int j = 1; j < ipph; j++) {
2971                jc = ip - j;
2972                j2 = 2 * j;
2973                int idx1 = j * l1 * ido;
2974                int idx2 = jc * l1 * ido;
2975                int idx3 = j2 * ido;
2976                for (int k = 0; k < l1; k++) {
2977                    int idx4 = k * idx01;
2978                    int idx5 = k * ido;
2979                    for (int i = 2; i < ido; i += 2) {
2980                        ic = ido - i;
2981                        int idx6 = in_off + i;
2982                        int idx7 = in_off + ic;
2983                        int idx8 = out_off + i;
2984                        int iidx1 = idx6 + idx3 + idx4;
2985                        int iidx2 = idx7 + idx3 - ido + idx4;
2986                        int oidx1 = idx8 + idx5 + idx1;
2987                        int oidx2 = idx8 + idx5 + idx2;
2988                        double o1i = out[oidx1 - 1];
2989                        double o1r = out[oidx1];
2990                        double o2i = out[oidx2 - 1];
2991                        double o2r = out[oidx2];
2992
2993                        in[iidx1 - 1] = o1i + o2i;
2994                        in[iidx2 - 1] = o1i - o2i;
2995                        in[iidx1] = o1r + o2r;
2996                        in[iidx2] = o2r - o1r;
2997                    }
2998                }
2999            }
3000        } else {
3001            for (int j = 1; j < ipph; j++) {
3002                jc = ip - j;
3003                j2 = 2 * j;
3004                int idx1 = j * l1 * ido;
3005                int idx2 = jc * l1 * ido;
3006                int idx3 = j2 * ido;
3007                for (int i = 2; i < ido; i += 2) {
3008                    ic = ido - i;
3009                    int idx6 = in_off + i;
3010                    int idx7 = in_off + ic;
3011                    int idx8 = out_off + i;
3012                    for (int k = 0; k < l1; k++) {
3013                        int idx4 = k * idx01;
3014                        int idx5 = k * ido;
3015                        int iidx1 = idx6 + idx3 + idx4;
3016                        int iidx2 = idx7 + idx3 - ido + idx4;
3017                        int oidx1 = idx8 + idx5 + idx1;
3018                        int oidx2 = idx8 + idx5 + idx2;
3019                        double o1i = out[oidx1 - 1];
3020                        double o1r = out[oidx1];
3021                        double o2i = out[oidx2 - 1];
3022                        double o2r = out[oidx2];
3023
3024                        in[iidx1 - 1] = o1i + o2i;
3025                        in[iidx2 - 1] = o1i - o2i;
3026                        in[iidx1] = o1r + o2r;
3027                        in[iidx2] = o2r - o1r;
3028                    }
3029                }
3030            }
3031        }
3032    }
3033
3034    /*---------------------------------------------------------
3035       radbg: Real FFT's backward processing of general factor
3036      --------------------------------------------------------*/
3037    void radbg(final int ido, final int ip, final int l1, final int idl1, final double in[], final int in_off, final double out[], final int out_off, final int offset) {
3038        int idij, ipph, j2, ic, jc, lc, is;
3039        double dc2, ai1, ai2, ar1, ar2, ds2, w1r, w1i;
3040        int nbd;
3041        double dcp, arg, dsp, ar1h, ar2h;
3042        int iw1 = offset;
3043
3044        arg = TWO_PI / (double) ip;
3045        dcp = Math.cos(arg);
3046        dsp = Math.sin(arg);
3047        nbd = (ido - 1) / 2;
3048        ipph = (ip + 1) / 2;
3049        int idx0 = ip * ido;
3050        if (ido >= l1) {
3051            for (int k = 0; k < l1; k++) {
3052                int idx1 = k * ido;
3053                int idx2 = k * idx0;
3054                for (int i = 0; i < ido; i++) {
3055                    out[out_off + i + idx1] = in[in_off + i + idx2];
3056                }
3057            }
3058        } else {
3059            for (int i = 0; i < ido; i++) {
3060                int idx1 = out_off + i;
3061                int idx2 = in_off + i;
3062                for (int k = 0; k < l1; k++) {
3063                    out[idx1 + k * ido] = in[idx2 + k * idx0];
3064                }
3065            }
3066        }
3067        int iidx0 = in_off + ido - 1;
3068        for (int j = 1; j < ipph; j++) {
3069            jc = ip - j;
3070            j2 = 2 * j;
3071            int idx1 = j * l1 * ido;
3072            int idx2 = jc * l1 * ido;
3073            int idx3 = j2 * ido;
3074            for (int k = 0; k < l1; k++) {
3075                int idx4 = k * ido;
3076                int idx5 = idx4 * ip;
3077                int iidx1 = iidx0 + idx3 + idx5 - ido;
3078                int iidx2 = in_off + idx3 + idx5;
3079                double i1r = in[iidx1];
3080                double i2r = in[iidx2];
3081
3082                out[out_off + idx4 + idx1] = i1r + i1r;
3083                out[out_off + idx4 + idx2] = i2r + i2r;
3084            }
3085        }
3086
3087        if (ido != 1) {
3088            if (nbd >= l1) {
3089                for (int j = 1; j < ipph; j++) {
3090                    jc = ip - j;
3091                    int idx1 = j * l1 * ido;
3092                    int idx2 = jc * l1 * ido;
3093                    int idx3 = 2 * j * ido;
3094                    for (int k = 0; k < l1; k++) {
3095                        int idx4 = k * ido + idx1;
3096                        int idx5 = k * ido + idx2;
3097                        int idx6 = k * ip * ido + idx3;
3098                        for (int i = 2; i < ido; i += 2) {
3099                            ic = ido - i;
3100                            int idx7 = out_off + i;
3101                            int idx8 = in_off + ic;
3102                            int idx9 = in_off + i;
3103                            int oidx1 = idx7 + idx4;
3104                            int oidx2 = idx7 + idx5;
3105                            int iidx1 = idx9 + idx6;
3106                            int iidx2 = idx8 + idx6 - ido;
3107                            double a1i = in[iidx1 - 1];
3108                            double a1r = in[iidx1];
3109                            double a2i = in[iidx2 - 1];
3110                            double a2r = in[iidx2];
3111
3112                            out[oidx1 - 1] = a1i + a2i;
3113                            out[oidx2 - 1] = a1i - a2i;
3114                            out[oidx1] = a1r - a2r;
3115                            out[oidx2] = a1r + a2r;
3116                        }
3117                    }
3118                }
3119            } else {
3120                for (int j = 1; j < ipph; j++) {
3121                    jc = ip - j;
3122                    int idx1 = j * l1 * ido;
3123                    int idx2 = jc * l1 * ido;
3124                    int idx3 = 2 * j * ido;
3125                    for (int i = 2; i < ido; i += 2) {
3126                        ic = ido - i;
3127                        int idx7 = out_off + i;
3128                        int idx8 = in_off + ic;
3129                        int idx9 = in_off + i;
3130                        for (int k = 0; k < l1; k++) {
3131                            int idx4 = k * ido + idx1;
3132                            int idx5 = k * ido + idx2;
3133                            int idx6 = k * ip * ido + idx3;
3134                            int oidx1 = idx7 + idx4;
3135                            int oidx2 = idx7 + idx5;
3136                            int iidx1 = idx9 + idx6;
3137                            int iidx2 = idx8 + idx6 - ido;
3138                            double a1i = in[iidx1 - 1];
3139                            double a1r = in[iidx1];
3140                            double a2i = in[iidx2 - 1];
3141                            double a2r = in[iidx2];
3142
3143                            out[oidx1 - 1] = a1i + a2i;
3144                            out[oidx2 - 1] = a1i - a2i;
3145                            out[oidx1] = a1r - a2r;
3146                            out[oidx2] = a1r + a2r;
3147                        }
3148                    }
3149                }
3150            }
3151        }
3152
3153        ar1 = 1;
3154        ai1 = 0;
3155        int idx01 = (ip - 1) * idl1;
3156        for (int l = 1; l < ipph; l++) {
3157            lc = ip - l;
3158            ar1h = dcp * ar1 - dsp * ai1;
3159            ai1 = dcp * ai1 + dsp * ar1;
3160            ar1 = ar1h;
3161            int idx1 = l * idl1;
3162            int idx2 = lc * idl1;
3163            for (int ik = 0; ik < idl1; ik++) {
3164                int idx3 = in_off + ik;
3165                int idx4 = out_off + ik;
3166                in[idx3 + idx1] = out[idx4] + ar1 * out[idx4 + idl1];
3167                in[idx3 + idx2] = ai1 * out[idx4 + idx01];
3168            }
3169            dc2 = ar1;
3170            ds2 = ai1;
3171            ar2 = ar1;
3172            ai2 = ai1;
3173            for (int j = 2; j < ipph; j++) {
3174                jc = ip - j;
3175                ar2h = dc2 * ar2 - ds2 * ai2;
3176                ai2 = dc2 * ai2 + ds2 * ar2;
3177                ar2 = ar2h;
3178                int idx5 = j * idl1;
3179                int idx6 = jc * idl1;
3180                for (int ik = 0; ik < idl1; ik++) {
3181                    int idx7 = in_off + ik;
3182                    int idx8 = out_off + ik;
3183                    in[idx7 + idx1] += ar2 * out[idx8 + idx5];
3184                    in[idx7 + idx2] += ai2 * out[idx8 + idx6];
3185                }
3186            }
3187        }
3188        for (int j = 1; j < ipph; j++) {
3189            int idx1 = j * idl1;
3190            for (int ik = 0; ik < idl1; ik++) {
3191                int idx2 = out_off + ik;
3192                out[idx2] += out[idx2 + idx1];
3193            }
3194        }
3195        for (int j = 1; j < ipph; j++) {
3196            jc = ip - j;
3197            int idx1 = j * l1 * ido;
3198            int idx2 = jc * l1 * ido;
3199            for (int k = 0; k < l1; k++) {
3200                int idx3 = k * ido;
3201                int oidx1 = out_off + idx3;
3202                int iidx1 = in_off + idx3 + idx1;
3203                int iidx2 = in_off + idx3 + idx2;
3204                double i1r = in[iidx1];
3205                double i2r = in[iidx2];
3206
3207                out[oidx1 + idx1] = i1r - i2r;
3208                out[oidx1 + idx2] = i1r + i2r;
3209            }
3210        }
3211
3212        if (ido == 1)
3213            return;
3214        if (nbd >= l1) {
3215            for (int j = 1; j < ipph; j++) {
3216                jc = ip - j;
3217                int idx1 = j * l1 * ido;
3218                int idx2 = jc * l1 * ido;
3219                for (int k = 0; k < l1; k++) {
3220                    int idx3 = k * ido;
3221                    for (int i = 2; i < ido; i += 2) {
3222                        int idx4 = out_off + i;
3223                        int idx5 = in_off + i;
3224                        int oidx1 = idx4 + idx3 + idx1;
3225                        int oidx2 = idx4 + idx3 + idx2;
3226                        int iidx1 = idx5 + idx3 + idx1;
3227                        int iidx2 = idx5 + idx3 + idx2;
3228                        double i1i = in[iidx1 - 1];
3229                        double i1r = in[iidx1];
3230                        double i2i = in[iidx2 - 1];
3231                        double i2r = in[iidx2];
3232
3233                        out[oidx1 - 1] = i1i - i2r;
3234                        out[oidx2 - 1] = i1i + i2r;
3235                        out[oidx1] = i1r + i2i;
3236                        out[oidx2] = i1r - i2i;
3237                    }
3238                }
3239            }
3240        } else {
3241            for (int j = 1; j < ipph; j++) {
3242                jc = ip - j;
3243                int idx1 = j * l1 * ido;
3244                int idx2 = jc * l1 * ido;
3245                for (int i = 2; i < ido; i += 2) {
3246                    int idx4 = out_off + i;
3247                    int idx5 = in_off + i;
3248                    for (int k = 0; k < l1; k++) {
3249                        int idx3 = k * ido;
3250                        int oidx1 = idx4 + idx3 + idx1;
3251                        int oidx2 = idx4 + idx3 + idx2;
3252                        int iidx1 = idx5 + idx3 + idx1;
3253                        int iidx2 = idx5 + idx3 + idx2;
3254                        double i1i = in[iidx1 - 1];
3255                        double i1r = in[iidx1];
3256                        double i2i = in[iidx2 - 1];
3257                        double i2r = in[iidx2];
3258
3259                        out[oidx1 - 1] = i1i - i2r;
3260                        out[oidx2 - 1] = i1i + i2r;
3261                        out[oidx1] = i1r + i2i;
3262                        out[oidx2] = i1r - i2i;
3263                    }
3264                }
3265            }
3266        }
3267        System.arraycopy(out, out_off, in, in_off, idl1);
3268        for (int j = 1; j < ip; j++) {
3269            int idx1 = j * l1 * ido;
3270            for (int k = 0; k < l1; k++) {
3271                int idx2 = k * ido + idx1;
3272                in[in_off + idx2] = out[out_off + idx2];
3273            }
3274        }
3275        if (nbd <= l1) {
3276            is = -ido;
3277            for (int j = 1; j < ip; j++) {
3278                is += ido;
3279                idij = is - 1;
3280                int idx1 = j * l1 * ido;
3281                for (int i = 2; i < ido; i += 2) {
3282                    idij += 2;
3283                    int idx2 = idij + iw1;
3284                    w1r = wtable_r[idx2 - 1];
3285                    w1i = wtable_r[idx2];
3286                    int idx4 = in_off + i;
3287                    int idx5 = out_off + i;
3288                    for (int k = 0; k < l1; k++) {
3289                        int idx3 = k * ido + idx1;
3290                        int iidx1 = idx4 + idx3;
3291                        int oidx1 = idx5 + idx3;
3292                        double o1i = out[oidx1 - 1];
3293                        double o1r = out[oidx1];
3294
3295                        in[iidx1 - 1] = w1r * o1i - w1i * o1r;
3296                        in[iidx1] = w1r * o1r + w1i * o1i;
3297                    }
3298                }
3299            }
3300        } else {
3301            is = -ido;
3302            for (int j = 1; j < ip; j++) {
3303                is += ido;
3304                int idx1 = j * l1 * ido;
3305                for (int k = 0; k < l1; k++) {
3306                    idij = is - 1;
3307                    int idx3 = k * ido + idx1;
3308                    for (int i = 2; i < ido; i += 2) {
3309                        idij += 2;
3310                        int idx2 = idij + iw1;
3311                        w1r = wtable_r[idx2 - 1];
3312                        w1i = wtable_r[idx2];
3313                        int idx4 = in_off + i;
3314                        int idx5 = out_off + i;
3315                        int iidx1 = idx4 + idx3;
3316                        int oidx1 = idx5 + idx3;
3317                        double o1i = out[oidx1 - 1];
3318                        double o1r = out[oidx1];
3319
3320                        in[iidx1 - 1] = w1r * o1i - w1i * o1r;
3321                        in[iidx1] = w1r * o1r + w1i * o1i;
3322
3323                    }
3324                }
3325            }
3326        }
3327    }
3328
3329    /*---------------------------------------------------------
3330       cfftf1: further processing of Complex forward FFT
3331      --------------------------------------------------------*/
3332    void cfftf(double a[], int offa, int isign) {
3333        int idot;
3334        int l1, l2;
3335        int na, nf, ip, iw, ido, idl1;
3336        int[] nac = new int[1];
3337        final int twon = 2 * n;
3338
3339        int iw1, iw2;
3340        double[] ch = new double[twon];
3341
3342        iw1 = twon;
3343        iw2 = 4 * n;
3344        nac[0] = 0;
3345        nf = (int) wtable[1 + iw2];
3346        na = 0;
3347        l1 = 1;
3348        iw = iw1;
3349        for (int k1 = 2; k1 <= nf + 1; k1++) {
3350            ip = (int) wtable[k1 + iw2];
3351            l2 = ip * l1;
3352            ido = n / l2;
3353            idot = ido + ido;
3354            idl1 = idot * l1;
3355            switch (ip) {
3356            case 4:
3357                if (na == 0) {
3358                    passf4(idot, l1, a, offa, ch, 0, iw, isign);
3359                } else {
3360                    passf4(idot, l1, ch, 0, a, offa, iw, isign);
3361                }
3362                na = 1 - na;
3363                break;
3364            case 2:
3365                if (na == 0) {
3366                    passf2(idot, l1, a, offa, ch, 0, iw, isign);
3367                } else {
3368                    passf2(idot, l1, ch, 0, a, offa, iw, isign);
3369                }
3370                na = 1 - na;
3371                break;
3372            case 3:
3373                if (na == 0) {
3374                    passf3(idot, l1, a, offa, ch, 0, iw, isign);
3375                } else {
3376                    passf3(idot, l1, ch, 0, a, offa, iw, isign);
3377                }
3378                na = 1 - na;
3379                break;
3380            case 5:
3381                if (na == 0) {
3382                    passf5(idot, l1, a, offa, ch, 0, iw, isign);
3383                } else {
3384                    passf5(idot, l1, ch, 0, a, offa, iw, isign);
3385                }
3386                na = 1 - na;
3387                break;
3388            default:
3389                if (na == 0) {
3390                    passfg(nac, idot, ip, l1, idl1, a, offa, ch, 0, iw, isign);
3391                } else {
3392                    passfg(nac, idot, ip, l1, idl1, ch, 0, a, offa, iw, isign);
3393                }
3394                if (nac[0] != 0)
3395                    na = 1 - na;
3396                break;
3397            }
3398            l1 = l2;
3399            iw += (ip - 1) * idot;
3400        }
3401        if (na == 0)
3402            return;
3403        System.arraycopy(ch, 0, a, offa, twon);
3404
3405    }
3406
3407    /*----------------------------------------------------------------------
3408       passf2: Complex FFT's forward/backward processing of factor 2;
3409       isign is +1 for backward and -1 for forward transforms
3410      ----------------------------------------------------------------------*/
3411
3412    void passf2(final int ido, final int l1, final double in[], final int in_off, final double out[], final int out_off, final int offset, final int isign) {
3413        double t1i, t1r;
3414        int iw1;
3415        iw1 = offset;
3416        int idx = ido * l1;
3417        if (ido <= 2) {
3418            for (int k = 0; k < l1; k++) {
3419                int idx0 = k * ido;
3420                int iidx1 = in_off + 2 * idx0;
3421                int iidx2 = iidx1 + ido;
3422                double a1r = in[iidx1];
3423                double a1i = in[iidx1 + 1];
3424                double a2r = in[iidx2];
3425                double a2i = in[iidx2 + 1];
3426
3427                int oidx1 = out_off + idx0;
3428                int oidx2 = oidx1 + idx;
3429                out[oidx1] = a1r + a2r;
3430                out[oidx1 + 1] = a1i + a2i;
3431                out[oidx2] = a1r - a2r;
3432                out[oidx2 + 1] = a1i - a2i;
3433            }
3434        } else {
3435            for (int k = 0; k < l1; k++) {
3436                for (int i = 0; i < ido - 1; i += 2) {
3437                    int idx0 = k * ido;
3438                    int iidx1 = in_off + i + 2 * idx0;
3439                    int iidx2 = iidx1 + ido;
3440                    double i1r = in[iidx1];
3441                    double i1i = in[iidx1 + 1];
3442                    double i2r = in[iidx2];
3443                    double i2i = in[iidx2 + 1];
3444
3445                    int widx1 = i + iw1;
3446                    double w1r = wtable[widx1];
3447                    double w1i = isign * wtable[widx1 + 1];
3448
3449                    t1r = i1r - i2r;
3450                    t1i = i1i - i2i;
3451
3452                    int oidx1 = out_off + i + idx0;
3453                    int oidx2 = oidx1 + idx;
3454                    out[oidx1] = i1r + i2r;
3455                    out[oidx1 + 1] = i1i + i2i;
3456                    out[oidx2] = w1r * t1r - w1i * t1i;
3457                    out[oidx2 + 1] = w1r * t1i + w1i * t1r;
3458                }
3459            }
3460        }
3461    }
3462
3463    /*----------------------------------------------------------------------
3464       passf3: Complex FFT's forward/backward processing of factor 3;
3465       isign is +1 for backward and -1 for forward transforms
3466      ----------------------------------------------------------------------*/
3467    void passf3(final int ido, final int l1, final double in[], final int in_off, final double out[], final int out_off, final int offset, final int isign) {
3468        final double taur = -0.5;
3469        final double taui = 0.866025403784438707610604524234076962;
3470        double ci2, ci3, di2, di3, cr2, cr3, dr2, dr3, ti2, tr2;
3471        int iw1, iw2;
3472
3473        iw1 = offset;
3474        iw2 = iw1 + ido;
3475
3476        final int idxt = l1 * ido;
3477
3478        if (ido == 2) {
3479            for (int k = 1; k <= l1; k++) {
3480                int iidx1 = in_off + (3 * k - 2) * ido;
3481                int iidx2 = iidx1 + ido;
3482                int iidx3 = iidx1 - ido;
3483                double i1r = in[iidx1];
3484                double i1i = in[iidx1 + 1];
3485                double i2r = in[iidx2];
3486                double i2i = in[iidx2 + 1];
3487                double i3r = in[iidx3];
3488                double i3i = in[iidx3 + 1];
3489
3490                tr2 = i1r + i2r;
3491                cr2 = i3r + taur * tr2;
3492                ti2 = i1i + i2i;
3493                ci2 = i3i + taur * ti2;
3494                cr3 = isign * taui * (i1r - i2r);
3495                ci3 = isign * taui * (i1i - i2i);
3496
3497                int oidx1 = out_off + (k - 1) * ido;
3498                int oidx2 = oidx1 + idxt;
3499                int oidx3 = oidx2 + idxt;
3500                out[oidx1] = in[iidx3] + tr2;
3501                out[oidx1 + 1] = i3i + ti2;
3502                out[oidx2] = cr2 - ci3;
3503                out[oidx2 + 1] = ci2 + cr3;
3504                out[oidx3] = cr2 + ci3;
3505                out[oidx3 + 1] = ci2 - cr3;
3506            }
3507        } else {
3508            for (int k = 1; k <= l1; k++) {
3509                int idx1 = in_off + (3 * k - 2) * ido;
3510                int idx2 = out_off + (k - 1) * ido;
3511                for (int i = 0; i < ido - 1; i += 2) {
3512                    int iidx1 = i + idx1;
3513                    int iidx2 = iidx1 + ido;
3514                    int iidx3 = iidx1 - ido;
3515                    double a1r = in[iidx1];
3516                    double a1i = in[iidx1 + 1];
3517                    double a2r = in[iidx2];
3518                    double a2i = in[iidx2 + 1];
3519                    double a3r = in[iidx3];
3520                    double a3i = in[iidx3 + 1];
3521
3522                    tr2 = a1r + a2r;
3523                    cr2 = a3r + taur * tr2;
3524                    ti2 = a1i + a2i;
3525                    ci2 = a3i + taur * ti2;
3526                    cr3 = isign * taui * (a1r - a2r);
3527                    ci3 = isign * taui * (a1i - a2i);
3528                    dr2 = cr2 - ci3;
3529                    dr3 = cr2 + ci3;
3530                    di2 = ci2 + cr3;
3531                    di3 = ci2 - cr3;
3532
3533                    int widx1 = i + iw1;
3534                    int widx2 = i + iw2;
3535                    double w1r = wtable[widx1];
3536                    double w1i = isign * wtable[widx1 + 1];
3537                    double w2r = wtable[widx2];
3538                    double w2i = isign * wtable[widx2 + 1];
3539
3540                    int oidx1 = i + idx2;
3541                    int oidx2 = oidx1 + idxt;
3542                    int oidx3 = oidx2 + idxt;
3543                    out[oidx1] = a3r + tr2;
3544                    out[oidx1 + 1] = a3i + ti2;
3545                    out[oidx2] = w1r * dr2 - w1i * di2;
3546                    out[oidx2 + 1] = w1r * di2 + w1i * dr2;
3547                    out[oidx3] = w2r * dr3 - w2i * di3;
3548                    out[oidx3 + 1] = w2r * di3 + w2i * dr3;
3549                }
3550            }
3551        }
3552    }
3553
3554    /*----------------------------------------------------------------------
3555       passf4: Complex FFT's forward/backward processing of factor 4;
3556       isign is +1 for backward and -1 for forward transforms
3557      ----------------------------------------------------------------------*/
3558    void passf4(final int ido, final int l1, final double in[], final int in_off, final double out[], final int out_off, final int offset, final int isign) {
3559        double ci2, ci3, ci4, cr2, cr3, cr4, ti1, ti2, ti3, ti4, tr1, tr2, tr3, tr4;
3560        int iw1, iw2, iw3;
3561        iw1 = offset;
3562        iw2 = iw1 + ido;
3563        iw3 = iw2 + ido;
3564
3565        int idx0 = l1 * ido;
3566        if (ido == 2) {
3567            for (int k = 0; k < l1; k++) {
3568                int idxt1 = k * ido;
3569                int iidx1 = in_off + 4 * idxt1 + 1;
3570                int iidx2 = iidx1 + ido;
3571                int iidx3 = iidx2 + ido;
3572                int iidx4 = iidx3 + ido;
3573
3574                double i1i = in[iidx1 - 1];
3575                double i1r = in[iidx1];
3576                double i2i = in[iidx2 - 1];
3577                double i2r = in[iidx2];
3578                double i3i = in[iidx3 - 1];
3579                double i3r = in[iidx3];
3580                double i4i = in[iidx4 - 1];
3581                double i4r = in[iidx4];
3582
3583                ti1 = i1r - i3r;
3584                ti2 = i1r + i3r;
3585                tr4 = i4r - i2r;
3586                ti3 = i2r + i4r;
3587                tr1 = i1i - i3i;
3588                tr2 = i1i + i3i;
3589                ti4 = i2i - i4i;
3590                tr3 = i2i + i4i;
3591
3592                int oidx1 = out_off + idxt1;
3593                int oidx2 = oidx1 + idx0;
3594                int oidx3 = oidx2 + idx0;
3595                int oidx4 = oidx3 + idx0;
3596                out[oidx1] = tr2 + tr3;
3597                out[oidx1 + 1] = ti2 + ti3;
3598                out[oidx2] = tr1 + isign * tr4;
3599                out[oidx2 + 1] = ti1 + isign * ti4;
3600                out[oidx3] = tr2 - tr3;
3601                out[oidx3 + 1] = ti2 - ti3;
3602                out[oidx4] = tr1 - isign * tr4;
3603                out[oidx4 + 1] = ti1 - isign * ti4;
3604            }
3605        } else {
3606            for (int k = 0; k < l1; k++) {
3607                int idx1 = k * ido;
3608                int idx2 = in_off + 1 + 4 * idx1;
3609                for (int i = 0; i < ido - 1; i += 2) {
3610                    int iidx1 = i + idx2;
3611                    int iidx2 = iidx1 + ido;
3612                    int iidx3 = iidx2 + ido;
3613                    int iidx4 = iidx3 + ido;
3614                    double i1i = in[iidx1 - 1];
3615                    double i1r = in[iidx1];
3616                    double i2i = in[iidx2 - 1];
3617                    double i2r = in[iidx2];
3618                    double i3i = in[iidx3 - 1];
3619                    double i3r = in[iidx3];
3620                    double i4i = in[iidx4 - 1];
3621                    double i4r = in[iidx4];
3622
3623                    ti1 = i1r - i3r;
3624                    ti2 = i1r + i3r;
3625                    ti3 = i2r + i4r;
3626                    tr4 = i4r - i2r;
3627                    tr1 = i1i - i3i;
3628                    tr2 = i1i + i3i;
3629                    ti4 = i2i - i4i;
3630                    tr3 = i2i + i4i;
3631                    cr3 = tr2 - tr3;
3632                    ci3 = ti2 - ti3;
3633                    cr2 = tr1 + isign * tr4;
3634                    cr4 = tr1 - isign * tr4;
3635                    ci2 = ti1 + isign * ti4;
3636                    ci4 = ti1 - isign * ti4;
3637
3638                    int widx1 = i + iw1;
3639                    int widx2 = i + iw2;
3640                    int widx3 = i + iw3;
3641                    double w1r = wtable[widx1];
3642                    double w1i = isign * wtable[widx1 + 1];
3643                    double w2r = wtable[widx2];
3644                    double w2i = isign * wtable[widx2 + 1];
3645                    double w3r = wtable[widx3];
3646                    double w3i = isign * wtable[widx3 + 1];
3647
3648                    int oidx1 = out_off + i + idx1;
3649                    int oidx2 = oidx1 + idx0;
3650                    int oidx3 = oidx2 + idx0;
3651                    int oidx4 = oidx3 + idx0;
3652                    out[oidx1] = tr2 + tr3;
3653                    out[oidx1 + 1] = ti2 + ti3;
3654                    out[oidx2] = w1r * cr2 - w1i * ci2;
3655                    out[oidx2 + 1] = w1r * ci2 + w1i * cr2;
3656                    out[oidx3] = w2r * cr3 - w2i * ci3;
3657                    out[oidx3 + 1] = w2r * ci3 + w2i * cr3;
3658                    out[oidx4] = w3r * cr4 - w3i * ci4;
3659                    out[oidx4 + 1] = w3r * ci4 + w3i * cr4;
3660                }
3661            }
3662        }
3663    }
3664
3665    /*----------------------------------------------------------------------
3666       passf5: Complex FFT's forward/backward processing of factor 5;
3667       isign is +1 for backward and -1 for forward transforms
3668      ----------------------------------------------------------------------*/
3669    void passf5(final int ido, final int l1, final double in[], final int in_off, final double out[], final int out_off, final int offset, final int isign)
3670    /* isign==-1 for forward transform and+1 for backward transform */
3671    {
3672        final double tr11 = 0.309016994374947451262869435595348477;
3673        final double ti11 = 0.951056516295153531181938433292089030;
3674        final double tr12 = -0.809016994374947340240566973079694435;
3675        final double ti12 = 0.587785252292473248125759255344746634;
3676        double ci2, ci3, ci4, ci5, di3, di4, di5, di2, cr2, cr3, cr5, cr4, ti2, ti3, ti4, ti5, dr3, dr4, dr5, dr2, tr2, tr3, tr4, tr5;
3677        int iw1, iw2, iw3, iw4;
3678
3679        iw1 = offset;
3680        iw2 = iw1 + ido;
3681        iw3 = iw2 + ido;
3682        iw4 = iw3 + ido;
3683
3684        int idx0 = l1 * ido;
3685
3686        if (ido == 2) {
3687            for (int k = 1; k <= l1; ++k) {
3688                int iidx1 = in_off + (5 * k - 4) * ido + 1;
3689                int iidx2 = iidx1 + ido;
3690                int iidx3 = iidx1 - ido;
3691                int iidx4 = iidx2 + ido;
3692                int iidx5 = iidx4 + ido;
3693
3694                double i1i = in[iidx1 - 1];
3695                double i1r = in[iidx1];
3696                double i2i = in[iidx2 - 1];
3697                double i2r = in[iidx2];
3698                double i3i = in[iidx3 - 1];
3699                double i3r = in[iidx3];
3700                double i4i = in[iidx4 - 1];
3701                double i4r = in[iidx4];
3702                double i5i = in[iidx5 - 1];
3703                double i5r = in[iidx5];
3704
3705                ti5 = i1r - i5r;
3706                ti2 = i1r + i5r;
3707                ti4 = i2r - i4r;
3708                ti3 = i2r + i4r;
3709                tr5 = i1i - i5i;
3710                tr2 = i1i + i5i;
3711                tr4 = i2i - i4i;
3712                tr3 = i2i + i4i;
3713                cr2 = i3i + tr11 * tr2 + tr12 * tr3;
3714                ci2 = i3r + tr11 * ti2 + tr12 * ti3;
3715                cr3 = i3i + tr12 * tr2 + tr11 * tr3;
3716                ci3 = i3r + tr12 * ti2 + tr11 * ti3;
3717                cr5 = isign * (ti11 * tr5 + ti12 * tr4);
3718                ci5 = isign * (ti11 * ti5 + ti12 * ti4);
3719                cr4 = isign * (ti12 * tr5 - ti11 * tr4);
3720                ci4 = isign * (ti12 * ti5 - ti11 * ti4);
3721
3722                int oidx1 = out_off + (k - 1) * ido;
3723                int oidx2 = oidx1 + idx0;
3724                int oidx3 = oidx2 + idx0;
3725                int oidx4 = oidx3 + idx0;
3726                int oidx5 = oidx4 + idx0;
3727                out[oidx1] = i3i + tr2 + tr3;
3728                out[oidx1 + 1] = i3r + ti2 + ti3;
3729                out[oidx2] = cr2 - ci5;
3730                out[oidx2 + 1] = ci2 + cr5;
3731                out[oidx3] = cr3 - ci4;
3732                out[oidx3 + 1] = ci3 + cr4;
3733                out[oidx4] = cr3 + ci4;
3734                out[oidx4 + 1] = ci3 - cr4;
3735                out[oidx5] = cr2 + ci5;
3736                out[oidx5 + 1] = ci2 - cr5;
3737            }
3738        } else {
3739            for (int k = 1; k <= l1; k++) {
3740                int idx1 = in_off + 1 + (k * 5 - 4) * ido;
3741                int idx2 = out_off + (k - 1) * ido;
3742                for (int i = 0; i < ido - 1; i += 2) {
3743                    int iidx1 = i + idx1;
3744                    int iidx2 = iidx1 + ido;
3745                    int iidx3 = iidx1 - ido;
3746                    int iidx4 = iidx2 + ido;
3747                    int iidx5 = iidx4 + ido;
3748                    double i1i = in[iidx1 - 1];
3749                    double i1r = in[iidx1];
3750                    double i2i = in[iidx2 - 1];
3751                    double i2r = in[iidx2];
3752                    double i3i = in[iidx3 - 1];
3753                    double i3r = in[iidx3];
3754                    double i4i = in[iidx4 - 1];
3755                    double i4r = in[iidx4];
3756                    double i5i = in[iidx5 - 1];
3757                    double i5r = in[iidx5];
3758
3759                    ti5 = i1r - i5r;
3760                    ti2 = i1r + i5r;
3761                    ti4 = i2r - i4r;
3762                    ti3 = i2r + i4r;
3763                    tr5 = i1i - i5i;
3764                    tr2 = i1i + i5i;
3765                    tr4 = i2i - i4i;
3766                    tr3 = i2i + i4i;
3767                    cr2 = i3i + tr11 * tr2 + tr12 * tr3;
3768                    ci2 = i3r + tr11 * ti2 + tr12 * ti3;
3769                    cr3 = i3i + tr12 * tr2 + tr11 * tr3;
3770                    ci3 = i3r + tr12 * ti2 + tr11 * ti3;
3771                    cr5 = isign * (ti11 * tr5 + ti12 * tr4);
3772                    ci5 = isign * (ti11 * ti5 + ti12 * ti4);
3773                    cr4 = isign * (ti12 * tr5 - ti11 * tr4);
3774                    ci4 = isign * (ti12 * ti5 - ti11 * ti4);
3775                    dr3 = cr3 - ci4;
3776                    dr4 = cr3 + ci4;
3777                    di3 = ci3 + cr4;
3778                    di4 = ci3 - cr4;
3779                    dr5 = cr2 + ci5;
3780                    dr2 = cr2 - ci5;
3781                    di5 = ci2 - cr5;
3782                    di2 = ci2 + cr5;
3783
3784                    int widx1 = i + iw1;
3785                    int widx2 = i + iw2;
3786                    int widx3 = i + iw3;
3787                    int widx4 = i + iw4;
3788                    double w1r = wtable[widx1];
3789                    double w1i = isign * wtable[widx1 + 1];
3790                    double w2r = wtable[widx2];
3791                    double w2i = isign * wtable[widx2 + 1];
3792                    double w3r = wtable[widx3];
3793                    double w3i = isign * wtable[widx3 + 1];
3794                    double w4r = wtable[widx4];
3795                    double w4i = isign * wtable[widx4 + 1];
3796
3797                    int oidx1 = i + idx2;
3798                    int oidx2 = oidx1 + idx0;
3799                    int oidx3 = oidx2 + idx0;
3800                    int oidx4 = oidx3 + idx0;
3801                    int oidx5 = oidx4 + idx0;
3802                    out[oidx1] = i3i + tr2 + tr3;
3803                    out[oidx1 + 1] = i3r + ti2 + ti3;
3804                    out[oidx2] = w1r * dr2 - w1i * di2;
3805                    out[oidx2 + 1] = w1r * di2 + w1i * dr2;
3806                    out[oidx3] = w2r * dr3 - w2i * di3;
3807                    out[oidx3 + 1] = w2r * di3 + w2i * dr3;
3808                    out[oidx4] = w3r * dr4 - w3i * di4;
3809                    out[oidx4 + 1] = w3r * di4 + w3i * dr4;
3810                    out[oidx5] = w4r * dr5 - w4i * di5;
3811                    out[oidx5 + 1] = w4r * di5 + w4i * dr5;
3812                }
3813            }
3814        }
3815    }
3816
3817    /*----------------------------------------------------------------------
3818       passfg: Complex FFT's forward/backward processing of general factor;
3819       isign is +1 for backward and -1 for forward transforms
3820      ----------------------------------------------------------------------*/
3821    void passfg(final int nac[], final int ido, final int ip, final int l1, final int idl1, final double in[], final int in_off, final double out[], final int out_off, final int offset, final int isign) {
3822        int idij, idlj, idot, ipph, l, jc, lc, idj, idl, inc, idp;
3823        double w1r, w1i, w2i, w2r;
3824        int iw1;
3825
3826        iw1 = offset;
3827        idot = ido / 2;
3828        ipph = (ip + 1) / 2;
3829        idp = ip * ido;
3830        if (ido >= l1) {
3831            for (int j = 1; j < ipph; j++) {
3832                jc = ip - j;
3833                int idx1 = j * ido;
3834                int idx2 = jc * ido;
3835                for (int k = 0; k < l1; k++) {
3836                    int idx3 = k * ido;
3837                    int idx4 = idx3 + idx1 * l1;
3838                    int idx5 = idx3 + idx2 * l1;
3839                    int idx6 = idx3 * ip;
3840                    for (int i = 0; i < ido; i++) {
3841                        int oidx1 = out_off + i;
3842                        double i1r = in[in_off + i + idx1 + idx6];
3843                        double i2r = in[in_off + i + idx2 + idx6];
3844                        out[oidx1 + idx4] = i1r + i2r;
3845                        out[oidx1 + idx5] = i1r - i2r;
3846                    }
3847                }
3848            }
3849            for (int k = 0; k < l1; k++) {
3850                int idxt1 = k * ido;
3851                int idxt2 = idxt1 * ip;
3852                for (int i = 0; i < ido; i++) {
3853                    out[out_off + i + idxt1] = in[in_off + i + idxt2];
3854                }
3855            }
3856        } else {
3857            for (int j = 1; j < ipph; j++) {
3858                jc = ip - j;
3859                int idxt1 = j * l1 * ido;
3860                int idxt2 = jc * l1 * ido;
3861                int idxt3 = j * ido;
3862                int idxt4 = jc * ido;
3863                for (int i = 0; i < ido; i++) {
3864                    for (int k = 0; k < l1; k++) {
3865                        int idx1 = k * ido;
3866                        int idx2 = idx1 * ip;
3867                        int idx3 = out_off + i;
3868                        int idx4 = in_off + i;
3869                        double i1r = in[idx4 + idxt3 + idx2];
3870                        double i2r = in[idx4 + idxt4 + idx2];
3871                        out[idx3 + idx1 + idxt1] = i1r + i2r;
3872                        out[idx3 + idx1 + idxt2] = i1r - i2r;
3873                    }
3874                }
3875            }
3876            for (int i = 0; i < ido; i++) {
3877                for (int k = 0; k < l1; k++) {
3878                    int idx1 = k * ido;
3879                    out[out_off + i + idx1] = in[in_off + i + idx1 * ip];
3880                }
3881            }
3882        }
3883
3884        idl = 2 - ido;
3885        inc = 0;
3886        int idxt0 = (ip - 1) * idl1;
3887        for (l = 1; l < ipph; l++) {
3888            lc = ip - l;
3889            idl += ido;
3890            int idxt1 = l * idl1;
3891            int idxt2 = lc * idl1;
3892            int idxt3 = idl + iw1;
3893            w1r = wtable[idxt3 - 2];
3894            w1i = isign * wtable[idxt3 - 1];
3895            for (int ik = 0; ik < idl1; ik++) {
3896                int idx1 = in_off + ik;
3897                int idx2 = out_off + ik;
3898                in[idx1 + idxt1] = out[idx2] + w1r * out[idx2 + idl1];
3899                in[idx1 + idxt2] = w1i * out[idx2 + idxt0];
3900            }
3901            idlj = idl;
3902            inc += ido;
3903            for (int j = 2; j < ipph; j++) {
3904                jc = ip - j;
3905                idlj += inc;
3906                if (idlj > idp)
3907                    idlj -= idp;
3908                int idxt4 = idlj + iw1;
3909                w2r = wtable[idxt4 - 2];
3910                w2i = isign * wtable[idxt4 - 1];
3911                int idxt5 = j * idl1;
3912                int idxt6 = jc * idl1;
3913                for (int ik = 0; ik < idl1; ik++) {
3914                    int idx1 = in_off + ik;
3915                    int idx2 = out_off + ik;
3916                    in[idx1 + idxt1] += w2r * out[idx2 + idxt5];
3917                    in[idx1 + idxt2] += w2i * out[idx2 + idxt6];
3918                }
3919            }
3920        }
3921        for (int j = 1; j < ipph; j++) {
3922            int idxt1 = j * idl1;
3923            for (int ik = 0; ik < idl1; ik++) {
3924                int idx1 = out_off + ik;
3925                out[idx1] += out[idx1 + idxt1];
3926            }
3927        }
3928        for (int j = 1; j < ipph; j++) {
3929            jc = ip - j;
3930            int idx1 = j * idl1;
3931            int idx2 = jc * idl1;
3932            for (int ik = 1; ik < idl1; ik += 2) {
3933                int idx3 = out_off + ik;
3934                int idx4 = in_off + ik;
3935                int iidx1 = idx4 + idx1;
3936                int iidx2 = idx4 + idx2;
3937                double i1i = in[iidx1 - 1];
3938                double i1r = in[iidx1];
3939                double i2i = in[iidx2 - 1];
3940                double i2r = in[iidx2];
3941
3942                int oidx1 = idx3 + idx1;
3943                int oidx2 = idx3 + idx2;
3944                out[oidx1 - 1] = i1i - i2r;
3945                out[oidx2 - 1] = i1i + i2r;
3946                out[oidx1] = i1r + i2i;
3947                out[oidx2] = i1r - i2i;
3948            }
3949        }
3950        nac[0] = 1;
3951        if (ido == 2)
3952            return;
3953        nac[0] = 0;
3954        System.arraycopy(out, out_off, in, in_off, idl1);
3955        int idx0 = l1 * ido;
3956        for (int j = 1; j < ip; j++) {
3957            int idx1 = j * idx0;
3958            for (int k = 0; k < l1; k++) {
3959                int idx2 = k * ido;
3960                int oidx1 = out_off + idx2 + idx1;
3961                int iidx1 = in_off + idx2 + idx1;
3962                in[iidx1] = out[oidx1];
3963                in[iidx1 + 1] = out[oidx1 + 1];
3964            }
3965        }
3966        if (idot <= l1) {
3967            idij = 0;
3968            for (int j = 1; j < ip; j++) {
3969                idij += 2;
3970                int idx1 = j * l1 * ido;
3971                for (int i = 3; i < ido; i += 2) {
3972                    idij += 2;
3973                    int idx2 = idij + iw1 - 1;
3974                    w1r = wtable[idx2 - 1];
3975                    w1i = isign * wtable[idx2];
3976                    int idx3 = in_off + i;
3977                    int idx4 = out_off + i;
3978                    for (int k = 0; k < l1; k++) {
3979                        int idx5 = k * ido + idx1;
3980                        int iidx1 = idx3 + idx5;
3981                        int oidx1 = idx4 + idx5;
3982                        double o1i = out[oidx1 - 1];
3983                        double o1r = out[oidx1];
3984                        in[iidx1 - 1] = w1r * o1i - w1i * o1r;
3985                        in[iidx1] = w1r * o1r + w1i * o1i;
3986                    }
3987                }
3988            }
3989        } else {
3990            idj = 2 - ido;
3991            for (int j = 1; j < ip; j++) {
3992                idj += ido;
3993                int idx1 = j * l1 * ido;
3994                for (int k = 0; k < l1; k++) {
3995                    idij = idj;
3996                    int idx3 = k * ido + idx1;
3997                    for (int i = 3; i < ido; i += 2) {
3998                        idij += 2;
3999                        int idx2 = idij - 1 + iw1;
4000                        w1r = wtable[idx2 - 1];
4001                        w1i = isign * wtable[idx2];
4002                        int iidx1 = in_off + i + idx3;
4003                        int oidx1 = out_off + i + idx3;
4004                        double o1i = out[oidx1 - 1];
4005                        double o1r = out[oidx1];
4006                        in[iidx1 - 1] = w1r * o1i - w1i * o1r;
4007                        in[iidx1] = w1r * o1r + w1i * o1i;
4008                    }
4009                }
4010            }
4011        }
4012    }
4013
4014    private void cftfsub(int n, double[] a, int offa, int[] ip, int nw, double[] w) {
4015        if (n > 8) {
4016            if (n > 32) {
4017                cftf1st(n, a, offa, w, nw - (n >> 2));
4018                if ((ConcurrencyUtils.getNumberOfThreads() > 1) && (n > ConcurrencyUtils.getThreadsBeginN_1D_FFT_2Threads())) {
4019                    cftrec4_th(n, a, offa, nw, w);
4020                } else if (n > 512) {
4021                    cftrec4(n, a, offa, nw, w);
4022                } else if (n > 128) {
4023                    cftleaf(n, 1, a, offa, nw, w);
4024                } else {
4025                    cftfx41(n, a, offa, nw, w);
4026                }
4027                bitrv2(n, ip, a, offa);
4028            } else if (n == 32) {
4029                cftf161(a, offa, w, nw - 8);
4030                bitrv216(a, offa);
4031            } else {
4032                cftf081(a, offa, w, 0);
4033                bitrv208(a, offa);
4034            }
4035        } else if (n == 8) {
4036            cftf040(a, offa);
4037        } else if (n == 4) {
4038            cftxb020(a, offa);
4039        }
4040    }
4041
4042    private void cftbsub(int n, double[] a, int offa, int[] ip, int nw, double[] w) {
4043        if (n > 8) {
4044            if (n > 32) {
4045                cftb1st(n, a, offa, w, nw - (n >> 2));
4046                if ((ConcurrencyUtils.getNumberOfThreads() > 1) && (n > ConcurrencyUtils.getThreadsBeginN_1D_FFT_2Threads())) {
4047                    cftrec4_th(n, a, offa, nw, w);
4048                } else if (n > 512) {
4049                    cftrec4(n, a, offa, nw, w);
4050                } else if (n > 128) {
4051                    cftleaf(n, 1, a, offa, nw, w);
4052                } else {
4053                    cftfx41(n, a, offa, nw, w);
4054                }
4055                bitrv2conj(n, ip, a, offa);
4056            } else if (n == 32) {
4057                cftf161(a, offa, w, nw - 8);
4058                bitrv216neg(a, offa);
4059            } else {
4060                cftf081(a, offa, w, 0);
4061                bitrv208neg(a, offa);
4062            }
4063        } else if (n == 8) {
4064            cftb040(a, offa);
4065        } else if (n == 4) {
4066            cftxb020(a, offa);
4067        }
4068    }
4069
4070    private void bitrv2(int n, int[] ip, double[] a, int offa) {
4071        int j1, k1, l, m, nh, nm;
4072        double xr, xi, yr, yi;
4073        int idx0, idx1, idx2;
4074
4075        m = 1;
4076        for (l = n >> 2; l > 8; l >>= 2) {
4077            m <<= 1;
4078        }
4079        nh = n >> 1;
4080        nm = 4 * m;
4081        if (l == 8) {
4082            for (int k = 0; k < m; k++) {
4083                idx0 = 4 * k;
4084                for (int j = 0; j < k; j++) {
4085                    j1 = 4 * j + 2 * ip[m + k];
4086                    k1 = idx0 + 2 * ip[m + j];
4087                    idx1 = offa + j1;
4088                    idx2 = offa + k1;
4089                    xr = a[idx1];
4090                    xi = a[idx1 + 1];
4091                    yr = a[idx2];
4092                    yi = a[idx2 + 1];
4093                    a[idx1] = yr;
4094                    a[idx1 + 1] = yi;
4095                    a[idx2] = xr;
4096                    a[idx2 + 1] = xi;
4097                    j1 += nm;
4098                    k1 += 2 * nm;
4099                    idx1 = offa + j1;
4100                    idx2 = offa + k1;
4101                    xr = a[idx1];
4102                    xi = a[idx1 + 1];
4103                    yr = a[idx2];
4104                    yi = a[idx2 + 1];
4105                    a[idx1] = yr;
4106                    a[idx1 + 1] = yi;
4107                    a[idx2] = xr;
4108                    a[idx2 + 1] = xi;
4109                    j1 += nm;
4110                    k1 -= nm;
4111                    idx1 = offa + j1;
4112                    idx2 = offa + k1;
4113                    xr = a[idx1];
4114                    xi = a[idx1 + 1];
4115                    yr = a[idx2];
4116                    yi = a[idx2 + 1];
4117                    a[idx1] = yr;
4118                    a[idx1 + 1] = yi;
4119                    a[idx2] = xr;
4120                    a[idx2 + 1] = xi;
4121                    j1 += nm;
4122                    k1 += 2 * nm;
4123                    idx1 = offa + j1;
4124                    idx2 = offa + k1;
4125                    xr = a[idx1];
4126                    xi = a[idx1 + 1];
4127                    yr = a[idx2];
4128                    yi = a[idx2 + 1];
4129                    a[idx1] = yr;
4130                    a[idx1 + 1] = yi;
4131                    a[idx2] = xr;
4132                    a[idx2 + 1] = xi;
4133                    j1 += nh;
4134                    k1 += 2;
4135                    idx1 = offa + j1;
4136                    idx2 = offa + k1;
4137                    xr = a[idx1];
4138                    xi = a[idx1 + 1];
4139                    yr = a[idx2];
4140                    yi = a[idx2 + 1];
4141                    a[idx1] = yr;
4142                    a[idx1 + 1] = yi;
4143                    a[idx2] = xr;
4144                    a[idx2 + 1] = xi;
4145                    j1 -= nm;
4146                    k1 -= 2 * nm;
4147                    idx1 = offa + j1;
4148                    idx2 = offa + k1;
4149                    xr = a[idx1];
4150                    xi = a[idx1 + 1];
4151                    yr = a[idx2];
4152                    yi = a[idx2 + 1];
4153                    a[idx1] = yr;
4154                    a[idx1 + 1] = yi;
4155                    a[idx2] = xr;
4156                    a[idx2 + 1] = xi;
4157                    j1 -= nm;
4158                    k1 += nm;
4159                    idx1 = offa + j1;
4160                    idx2 = offa + k1;
4161                    xr = a[idx1];
4162                    xi = a[idx1 + 1];
4163                    yr = a[idx2];
4164                    yi = a[idx2 + 1];
4165                    a[idx1] = yr;
4166                    a[idx1 + 1] = yi;
4167                    a[idx2] = xr;
4168                    a[idx2 + 1] = xi;
4169                    j1 -= nm;
4170                    k1 -= 2 * nm;
4171                    idx1 = offa + j1;
4172                    idx2 = offa + k1;
4173                    xr = a[idx1];
4174                    xi = a[idx1 + 1];
4175                    yr = a[idx2];
4176                    yi = a[idx2 + 1];
4177                    a[idx1] = yr;
4178                    a[idx1 + 1] = yi;
4179                    a[idx2] = xr;
4180                    a[idx2 + 1] = xi;
4181                    j1 += 2;
4182                    k1 += nh;
4183                    idx1 = offa + j1;
4184                    idx2 = offa + k1;
4185                    xr = a[idx1];
4186                    xi = a[idx1 + 1];
4187                    yr = a[idx2];
4188                    yi = a[idx2 + 1];
4189                    a[idx1] = yr;
4190                    a[idx1 + 1] = yi;
4191                    a[idx2] = xr;
4192                    a[idx2 + 1] = xi;
4193                    j1 += nm;
4194                    k1 += 2 * nm;
4195                    idx1 = offa + j1;
4196                    idx2 = offa + k1;
4197                    xr = a[idx1];
4198                    xi = a[idx1 + 1];
4199                    yr = a[idx2];
4200                    yi = a[idx2 + 1];
4201                    a[idx1] = yr;
4202                    a[idx1 + 1] = yi;
4203                    a[idx2] = xr;
4204                    a[idx2 + 1] = xi;
4205                    j1 += nm;
4206                    k1 -= nm;
4207                    idx1 = offa + j1;
4208                    idx2 = offa + k1;
4209                    xr = a[idx1];
4210                    xi = a[idx1 + 1];
4211                    yr = a[idx2];
4212                    yi = a[idx2 + 1];
4213                    a[idx1] = yr;
4214                    a[idx1 + 1] = yi;
4215                    a[idx2] = xr;
4216                    a[idx2 + 1] = xi;
4217                    j1 += nm;
4218                    k1 += 2 * nm;
4219                    idx1 = offa + j1;
4220                    idx2 = offa + k1;
4221                    xr = a[idx1];
4222                    xi = a[idx1 + 1];
4223                    yr = a[idx2];
4224                    yi = a[idx2 + 1];
4225                    a[idx1] = yr;
4226                    a[idx1 + 1] = yi;
4227                    a[idx2] = xr;
4228                    a[idx2 + 1] = xi;
4229                    j1 -= nh;
4230                    k1 -= 2;
4231                    idx1 = offa + j1;
4232                    idx2 = offa + k1;
4233                    xr = a[idx1];
4234                    xi = a[idx1 + 1];
4235                    yr = a[idx2];
4236                    yi = a[idx2 + 1];
4237                    a[idx1] = yr;
4238                    a[idx1 + 1] = yi;
4239                    a[idx2] = xr;
4240                    a[idx2 + 1] = xi;
4241                    j1 -= nm;
4242                    k1 -= 2 * nm;
4243                    idx1 = offa + j1;
4244                    idx2 = offa + k1;
4245                    xr = a[idx1];
4246                    xi = a[idx1 + 1];
4247                    yr = a[idx2];
4248                    yi = a[idx2 + 1];
4249                    a[idx1] = yr;
4250                    a[idx1 + 1] = yi;
4251                    a[idx2] = xr;
4252                    a[idx2 + 1] = xi;
4253                    j1 -= nm;
4254                    k1 += nm;
4255                    idx1 = offa + j1;
4256                    idx2 = offa + k1;
4257                    xr = a[idx1];
4258                    xi = a[idx1 + 1];
4259                    yr = a[idx2];
4260                    yi = a[idx2 + 1];
4261                    a[idx1] = yr;
4262                    a[idx1 + 1] = yi;
4263                    a[idx2] = xr;
4264                    a[idx2 + 1] = xi;
4265                    j1 -= nm;
4266                    k1 -= 2 * nm;
4267                    idx1 = offa + j1;
4268                    idx2 = offa + k1;
4269                    xr = a[idx1];
4270                    xi = a[idx1 + 1];
4271                    yr = a[idx2];
4272                    yi = a[idx2 + 1];
4273                    a[idx1] = yr;
4274                    a[idx1 + 1] = yi;
4275                    a[idx2] = xr;
4276                    a[idx2 + 1] = xi;
4277                }
4278                k1 = idx0 + 2 * ip[m + k];
4279                j1 = k1 + 2;
4280                k1 += nh;
4281                idx1 = offa + j1;
4282                idx2 = offa + k1;
4283                xr = a[idx1];
4284                xi = a[idx1 + 1];
4285                yr = a[idx2];
4286                yi = a[idx2 + 1];
4287                a[idx1] = yr;
4288                a[idx1 + 1] = yi;
4289                a[idx2] = xr;
4290                a[idx2 + 1] = xi;
4291                j1 += nm;
4292                k1 += 2 * nm;
4293                idx1 = offa + j1;
4294                idx2 = offa + k1;
4295                xr = a[idx1];
4296                xi = a[idx1 + 1];
4297                yr = a[idx2];
4298                yi = a[idx2 + 1];
4299                a[idx1] = yr;
4300                a[idx1 + 1] = yi;
4301                a[idx2] = xr;
4302                a[idx2 + 1] = xi;
4303                j1 += nm;
4304                k1 -= nm;
4305                idx1 = offa + j1;
4306                idx2 = offa + k1;
4307                xr = a[idx1];
4308                xi = a[idx1 + 1];
4309                yr = a[idx2];
4310                yi = a[idx2 + 1];
4311                a[idx1] = yr;
4312                a[idx1 + 1] = yi;
4313                a[idx2] = xr;
4314                a[idx2 + 1] = xi;
4315                j1 -= 2;
4316                k1 -= nh;
4317                idx1 = offa + j1;
4318                idx2 = offa + k1;
4319                xr = a[idx1];
4320                xi = a[idx1 + 1];
4321                yr = a[idx2];
4322                yi = a[idx2 + 1];
4323                a[idx1] = yr;
4324                a[idx1 + 1] = yi;
4325                a[idx2] = xr;
4326                a[idx2 + 1] = xi;
4327                j1 += nh + 2;
4328                k1 += nh + 2;
4329                idx1 = offa + j1;
4330                idx2 = offa + k1;
4331                xr = a[idx1];
4332                xi = a[idx1 + 1];
4333                yr = a[idx2];
4334                yi = a[idx2 + 1];
4335                a[idx1] = yr;
4336                a[idx1 + 1] = yi;
4337                a[idx2] = xr;
4338                a[idx2 + 1] = xi;
4339                j1 -= nh - nm;
4340                k1 += 2 * nm - 2;
4341                idx1 = offa + j1;
4342                idx2 = offa + k1;
4343                xr = a[idx1];
4344                xi = a[idx1 + 1];
4345                yr = a[idx2];
4346                yi = a[idx2 + 1];
4347                a[idx1] = yr;
4348                a[idx1 + 1] = yi;
4349                a[idx2] = xr;
4350                a[idx2 + 1] = xi;
4351            }
4352        } else {
4353            for (int k = 0; k < m; k++) {
4354                idx0 = 4 * k;
4355                for (int j = 0; j < k; j++) {
4356                    j1 = 4 * j + ip[m + k];
4357                    k1 = idx0 + ip[m + j];
4358                    idx1 = offa + j1;
4359                    idx2 = offa + k1;
4360                    xr = a[idx1];
4361                    xi = a[idx1 + 1];
4362                    yr = a[idx2];
4363                    yi = a[idx2 + 1];
4364                    a[idx1] = yr;
4365                    a[idx1 + 1] = yi;
4366                    a[idx2] = xr;
4367                    a[idx2 + 1] = xi;
4368                    j1 += nm;
4369                    k1 += nm;
4370                    idx1 = offa + j1;
4371                    idx2 = offa + k1;
4372                    xr = a[idx1];
4373                    xi = a[idx1 + 1];
4374                    yr = a[idx2];
4375                    yi = a[idx2 + 1];
4376                    a[idx1] = yr;
4377                    a[idx1 + 1] = yi;
4378                    a[idx2] = xr;
4379                    a[idx2 + 1] = xi;
4380                    j1 += nh;
4381                    k1 += 2;
4382                    idx1 = offa + j1;
4383                    idx2 = offa + k1;
4384                    xr = a[idx1];
4385                    xi = a[idx1 + 1];
4386                    yr = a[idx2];
4387                    yi = a[idx2 + 1];
4388                    a[idx1] = yr;
4389                    a[idx1 + 1] = yi;
4390                    a[idx2] = xr;
4391                    a[idx2 + 1] = xi;
4392                    j1 -= nm;
4393                    k1 -= nm;
4394                    idx1 = offa + j1;
4395                    idx2 = offa + k1;
4396                    xr = a[idx1];
4397                    xi = a[idx1 + 1];
4398                    yr = a[idx2];
4399                    yi = a[idx2 + 1];
4400                    a[idx1] = yr;
4401                    a[idx1 + 1] = yi;
4402                    a[idx2] = xr;
4403                    a[idx2 + 1] = xi;
4404                    j1 += 2;
4405                    k1 += nh;
4406                    idx1 = offa + j1;
4407                    idx2 = offa + k1;
4408                    xr = a[idx1];
4409                    xi = a[idx1 + 1];
4410                    yr = a[idx2];
4411                    yi = a[idx2 + 1];
4412                    a[idx1] = yr;
4413                    a[idx1 + 1] = yi;
4414                    a[idx2] = xr;
4415                    a[idx2 + 1] = xi;
4416                    j1 += nm;
4417                    k1 += nm;
4418                    idx1 = offa + j1;
4419                    idx2 = offa + k1;
4420                    xr = a[idx1];
4421                    xi = a[idx1 + 1];
4422                    yr = a[idx2];
4423                    yi = a[idx2 + 1];
4424                    a[idx1] = yr;
4425                    a[idx1 + 1] = yi;
4426                    a[idx2] = xr;
4427                    a[idx2 + 1] = xi;
4428                    j1 -= nh;
4429                    k1 -= 2;
4430                    idx1 = offa + j1;
4431                    idx2 = offa + k1;
4432                    xr = a[idx1];
4433                    xi = a[idx1 + 1];
4434                    yr = a[idx2];
4435                    yi = a[idx2 + 1];
4436                    a[idx1] = yr;
4437                    a[idx1 + 1] = yi;
4438                    a[idx2] = xr;
4439                    a[idx2 + 1] = xi;
4440                    j1 -= nm;
4441                    k1 -= nm;
4442                    idx1 = offa + j1;
4443                    idx2 = offa + k1;
4444                    xr = a[idx1];
4445                    xi = a[idx1 + 1];
4446                    yr = a[idx2];
4447                    yi = a[idx2 + 1];
4448                    a[idx1] = yr;
4449                    a[idx1 + 1] = yi;
4450                    a[idx2] = xr;
4451                    a[idx2 + 1] = xi;
4452                }
4453                k1 = idx0 + ip[m + k];
4454                j1 = k1 + 2;
4455                k1 += nh;
4456                idx1 = offa + j1;
4457                idx2 = offa + k1;
4458                xr = a[idx1];
4459                xi = a[idx1 + 1];
4460                yr = a[idx2];
4461                yi = a[idx2 + 1];
4462                a[idx1] = yr;
4463                a[idx1 + 1] = yi;
4464                a[idx2] = xr;
4465                a[idx2 + 1] = xi;
4466                j1 += nm;
4467                k1 += nm;
4468                idx1 = offa + j1;
4469                idx2 = offa + k1;
4470                xr = a[idx1];
4471                xi = a[idx1 + 1];
4472                yr = a[idx2];
4473                yi = a[idx2 + 1];
4474                a[idx1] = yr;
4475                a[idx1 + 1] = yi;
4476                a[idx2] = xr;
4477                a[idx2 + 1] = xi;
4478            }
4479        }
4480    }
4481
4482    private void bitrv2conj(int n, int[] ip, double[] a, int offa) {
4483        int j1, k1, l, m, nh, nm;
4484        double xr, xi, yr, yi;
4485        int idx0, idx1, idx2;
4486
4487        m = 1;
4488        for (l = n >> 2; l > 8; l >>= 2) {
4489            m <<= 1;
4490        }
4491        nh = n >> 1;
4492        nm = 4 * m;
4493        if (l == 8) {
4494            for (int k = 0; k < m; k++) {
4495                idx0 = 4 * k;
4496                for (int j = 0; j < k; j++) {
4497                    j1 = 4 * j + 2 * ip[m + k];
4498                    k1 = idx0 + 2 * ip[m + j];
4499                    idx1 = offa + j1;
4500                    idx2 = offa + k1;
4501                    xr = a[idx1];
4502                    xi = -a[idx1 + 1];
4503                    yr = a[idx2];
4504                    yi = -a[idx2 + 1];
4505                    a[idx1] = yr;
4506                    a[idx1 + 1] = yi;
4507                    a[idx2] = xr;
4508                    a[idx2 + 1] = xi;
4509                    j1 += nm;
4510                    k1 += 2 * nm;
4511                    idx1 = offa + j1;
4512                    idx2 = offa + k1;
4513                    xr = a[idx1];
4514                    xi = -a[idx1 + 1];
4515                    yr = a[idx2];
4516                    yi = -a[idx2 + 1];
4517                    a[idx1] = yr;
4518                    a[idx1 + 1] = yi;
4519                    a[idx2] = xr;
4520                    a[idx2 + 1] = xi;
4521                    j1 += nm;
4522                    k1 -= nm;
4523                    idx1 = offa + j1;
4524                    idx2 = offa + k1;
4525                    xr = a[idx1];
4526                    xi = -a[idx1 + 1];
4527                    yr = a[idx2];
4528                    yi = -a[idx2 + 1];
4529                    a[idx1] = yr;
4530                    a[idx1 + 1] = yi;
4531                    a[idx2] = xr;
4532                    a[idx2 + 1] = xi;
4533                    j1 += nm;
4534                    k1 += 2 * nm;
4535                    idx1 = offa + j1;
4536                    idx2 = offa + k1;
4537                    xr = a[idx1];
4538                    xi = -a[idx1 + 1];
4539                    yr = a[idx2];
4540                    yi = -a[idx2 + 1];
4541                    a[idx1] = yr;
4542                    a[idx1 + 1] = yi;
4543                    a[idx2] = xr;
4544                    a[idx2 + 1] = xi;
4545                    j1 += nh;
4546                    k1 += 2;
4547                    idx1 = offa + j1;
4548                    idx2 = offa + k1;
4549                    xr = a[idx1];
4550                    xi = -a[idx1 + 1];
4551                    yr = a[idx2];
4552                    yi = -a[idx2 + 1];
4553                    a[idx1] = yr;
4554                    a[idx1 + 1] = yi;
4555                    a[idx2] = xr;
4556                    a[idx2 + 1] = xi;
4557                    j1 -= nm;
4558                    k1 -= 2 * nm;
4559                    idx1 = offa + j1;
4560                    idx2 = offa + k1;
4561                    xr = a[idx1];
4562                    xi = -a[idx1 + 1];
4563                    yr = a[idx2];
4564                    yi = -a[idx2 + 1];
4565                    a[idx1] = yr;
4566                    a[idx1 + 1] = yi;
4567                    a[idx2] = xr;
4568                    a[idx2 + 1] = xi;
4569                    j1 -= nm;
4570                    k1 += nm;
4571                    idx1 = offa + j1;
4572                    idx2 = offa + k1;
4573                    xr = a[idx1];
4574                    xi = -a[idx1 + 1];
4575                    yr = a[idx2];
4576                    yi = -a[idx2 + 1];
4577                    a[idx1] = yr;
4578                    a[idx1 + 1] = yi;
4579                    a[idx2] = xr;
4580                    a[idx2 + 1] = xi;
4581                    j1 -= nm;
4582                    k1 -= 2 * nm;
4583                    idx1 = offa + j1;
4584                    idx2 = offa + k1;
4585                    xr = a[idx1];
4586                    xi = -a[idx1 + 1];
4587                    yr = a[idx2];
4588                    yi = -a[idx2 + 1];
4589                    a[idx1] = yr;
4590                    a[idx1 + 1] = yi;
4591                    a[idx2] = xr;
4592                    a[idx2 + 1] = xi;
4593                    j1 += 2;
4594                    k1 += nh;
4595                    idx1 = offa + j1;
4596                    idx2 = offa + k1;
4597                    xr = a[idx1];
4598                    xi = -a[idx1 + 1];
4599                    yr = a[idx2];
4600                    yi = -a[idx2 + 1];
4601                    a[idx1] = yr;
4602                    a[idx1 + 1] = yi;
4603                    a[idx2] = xr;
4604                    a[idx2 + 1] = xi;
4605                    j1 += nm;
4606                    k1 += 2 * nm;
4607                    idx1 = offa + j1;
4608                    idx2 = offa + k1;
4609                    xr = a[idx1];
4610                    xi = -a[idx1 + 1];
4611                    yr = a[idx2];
4612                    yi = -a[idx2 + 1];
4613                    a[idx1] = yr;
4614                    a[idx1 + 1] = yi;
4615                    a[idx2] = xr;
4616                    a[idx2 + 1] = xi;
4617                    j1 += nm;
4618                    k1 -= nm;
4619                    idx1 = offa + j1;
4620                    idx2 = offa + k1;
4621                    xr = a[idx1];
4622                    xi = -a[idx1 + 1];
4623                    yr = a[idx2];
4624                    yi = -a[idx2 + 1];
4625                    a[idx1] = yr;
4626                    a[idx1 + 1] = yi;
4627                    a[idx2] = xr;
4628                    a[idx2 + 1] = xi;
4629                    j1 += nm;
4630                    k1 += 2 * nm;
4631                    idx1 = offa + j1;
4632                    idx2 = offa + k1;
4633                    xr = a[idx1];
4634                    xi = -a[idx1 + 1];
4635                    yr = a[idx2];
4636                    yi = -a[idx2 + 1];
4637                    a[idx1] = yr;
4638                    a[idx1 + 1] = yi;
4639                    a[idx2] = xr;
4640                    a[idx2 + 1] = xi;
4641                    j1 -= nh;
4642                    k1 -= 2;
4643                    idx1 = offa + j1;
4644                    idx2 = offa + k1;
4645                    xr = a[idx1];
4646                    xi = -a[idx1 + 1];
4647                    yr = a[idx2];
4648                    yi = -a[idx2 + 1];
4649                    a[idx1] = yr;
4650                    a[idx1 + 1] = yi;
4651                    a[idx2] = xr;
4652                    a[idx2 + 1] = xi;
4653                    j1 -= nm;
4654                    k1 -= 2 * nm;
4655                    idx1 = offa + j1;
4656                    idx2 = offa + k1;
4657                    xr = a[idx1];
4658                    xi = -a[idx1 + 1];
4659                    yr = a[idx2];
4660                    yi = -a[idx2 + 1];
4661                    a[idx1] = yr;
4662                    a[idx1 + 1] = yi;
4663                    a[idx2] = xr;
4664                    a[idx2 + 1] = xi;
4665                    j1 -= nm;
4666                    k1 += nm;
4667                    idx1 = offa + j1;
4668                    idx2 = offa + k1;
4669                    xr = a[idx1];
4670                    xi = -a[idx1 + 1];
4671                    yr = a[idx2];
4672                    yi = -a[idx2 + 1];
4673                    a[idx1] = yr;
4674                    a[idx1 + 1] = yi;
4675                    a[idx2] = xr;
4676                    a[idx2 + 1] = xi;
4677                    j1 -= nm;
4678                    k1 -= 2 * nm;
4679                    idx1 = offa + j1;
4680                    idx2 = offa + k1;
4681                    xr = a[idx1];
4682                    xi = -a[idx1 + 1];
4683                    yr = a[idx2];
4684                    yi = -a[idx2 + 1];
4685                    a[idx1] = yr;
4686                    a[idx1 + 1] = yi;
4687                    a[idx2] = xr;
4688                    a[idx2 + 1] = xi;
4689                }
4690                k1 = idx0 + 2 * ip[m + k];
4691                j1 = k1 + 2;
4692                k1 += nh;
4693                idx1 = offa + j1;
4694                idx2 = offa + k1;
4695                a[idx1 - 1] = -a[idx1 - 1];
4696                xr = a[idx1];
4697                xi = -a[idx1 + 1];
4698                yr = a[idx2];
4699                yi = -a[idx2 + 1];
4700                a[idx1] = yr;
4701                a[idx1 + 1] = yi;
4702                a[idx2] = xr;
4703                a[idx2 + 1] = xi;
4704                a[idx2 + 3] = -a[idx2 + 3];
4705                j1 += nm;
4706                k1 += 2 * nm;
4707                idx1 = offa + j1;
4708                idx2 = offa + k1;
4709                xr = a[idx1];
4710                xi = -a[idx1 + 1];
4711                yr = a[idx2];
4712                yi = -a[idx2 + 1];
4713                a[idx1] = yr;
4714                a[idx1 + 1] = yi;
4715                a[idx2] = xr;
4716                a[idx2 + 1] = xi;
4717                j1 += nm;
4718                k1 -= nm;
4719                idx1 = offa + j1;
4720                idx2 = offa + k1;
4721                xr = a[idx1];
4722                xi = -a[idx1 + 1];
4723                yr = a[idx2];
4724                yi = -a[idx2 + 1];
4725                a[idx1] = yr;
4726                a[idx1 + 1] = yi;
4727                a[idx2] = xr;
4728                a[idx2 + 1] = xi;
4729                j1 -= 2;
4730                k1 -= nh;
4731                idx1 = offa + j1;
4732                idx2 = offa + k1;
4733                xr = a[idx1];
4734                xi = -a[idx1 + 1];
4735                yr = a[idx2];
4736                yi = -a[idx2 + 1];
4737                a[idx1] = yr;
4738                a[idx1 + 1] = yi;
4739                a[idx2] = xr;
4740                a[idx2 + 1] = xi;
4741                j1 += nh + 2;
4742                k1 += nh + 2;
4743                idx1 = offa + j1;
4744                idx2 = offa + k1;
4745                xr = a[idx1];
4746                xi = -a[idx1 + 1];
4747                yr = a[idx2];
4748                yi = -a[idx2 + 1];
4749                a[idx1] = yr;
4750                a[idx1 + 1] = yi;
4751                a[idx2] = xr;
4752                a[idx2 + 1] = xi;
4753                j1 -= nh - nm;
4754                k1 += 2 * nm - 2;
4755                idx1 = offa + j1;
4756                idx2 = offa + k1;
4757                a[idx1 - 1] = -a[idx1 - 1];
4758                xr = a[idx1];
4759                xi = -a[idx1 + 1];
4760                yr = a[idx2];
4761                yi = -a[idx2 + 1];
4762                a[idx1] = yr;
4763                a[idx1 + 1] = yi;
4764                a[idx2] = xr;
4765                a[idx2 + 1] = xi;
4766                a[idx2 + 3] = -a[idx2 + 3];
4767            }
4768        } else {
4769            for (int k = 0; k < m; k++) {
4770                idx0 = 4 * k;
4771                for (int j = 0; j < k; j++) {
4772                    j1 = 4 * j + ip[m + k];
4773                    k1 = idx0 + ip[m + j];
4774                    idx1 = offa + j1;
4775                    idx2 = offa + k1;
4776                    xr = a[idx1];
4777                    xi = -a[idx1 + 1];
4778                    yr = a[idx2];
4779                    yi = -a[idx2 + 1];
4780                    a[idx1] = yr;
4781                    a[idx1 + 1] = yi;
4782                    a[idx2] = xr;
4783                    a[idx2 + 1] = xi;
4784                    j1 += nm;
4785                    k1 += nm;
4786                    idx1 = offa + j1;
4787                    idx2 = offa + k1;
4788                    xr = a[idx1];
4789                    xi = -a[idx1 + 1];
4790                    yr = a[idx2];
4791                    yi = -a[idx2 + 1];
4792                    a[idx1] = yr;
4793                    a[idx1 + 1] = yi;
4794                    a[idx2] = xr;
4795                    a[idx2 + 1] = xi;
4796                    j1 += nh;
4797                    k1 += 2;
4798                    idx1 = offa + j1;
4799                    idx2 = offa + k1;
4800                    xr = a[idx1];
4801                    xi = -a[idx1 + 1];
4802                    yr = a[idx2];
4803                    yi = -a[idx2 + 1];
4804                    a[idx1] = yr;
4805                    a[idx1 + 1] = yi;
4806                    a[idx2] = xr;
4807                    a[idx2 + 1] = xi;
4808                    j1 -= nm;
4809                    k1 -= nm;
4810                    idx1 = offa + j1;
4811                    idx2 = offa + k1;
4812                    xr = a[idx1];
4813                    xi = -a[idx1 + 1];
4814                    yr = a[idx2];
4815                    yi = -a[idx2 + 1];
4816                    a[idx1] = yr;
4817                    a[idx1 + 1] = yi;
4818                    a[idx2] = xr;
4819                    a[idx2 + 1] = xi;
4820                    j1 += 2;
4821                    k1 += nh;
4822                    idx1 = offa + j1;
4823                    idx2 = offa + k1;
4824                    xr = a[idx1];
4825                    xi = -a[idx1 + 1];
4826                    yr = a[idx2];
4827                    yi = -a[idx2 + 1];
4828                    a[idx1] = yr;
4829                    a[idx1 + 1] = yi;
4830                    a[idx2] = xr;
4831                    a[idx2 + 1] = xi;
4832                    j1 += nm;
4833                    k1 += nm;
4834                    idx1 = offa + j1;
4835                    idx2 = offa + k1;
4836                    xr = a[idx1];
4837                    xi = -a[idx1 + 1];
4838                    yr = a[idx2];
4839                    yi = -a[idx2 + 1];
4840                    a[idx1] = yr;
4841                    a[idx1 + 1] = yi;
4842                    a[idx2] = xr;
4843                    a[idx2 + 1] = xi;
4844                    j1 -= nh;
4845                    k1 -= 2;
4846                    idx1 = offa + j1;
4847                    idx2 = offa + k1;
4848                    xr = a[idx1];
4849                    xi = -a[idx1 + 1];
4850                    yr = a[idx2];
4851                    yi = -a[idx2 + 1];
4852                    a[idx1] = yr;
4853                    a[idx1 + 1] = yi;
4854                    a[idx2] = xr;
4855                    a[idx2 + 1] = xi;
4856                    j1 -= nm;
4857                    k1 -= nm;
4858                    idx1 = offa + j1;
4859                    idx2 = offa + k1;
4860                    xr = a[idx1];
4861                    xi = -a[idx1 + 1];
4862                    yr = a[idx2];
4863                    yi = -a[idx2 + 1];
4864                    a[idx1] = yr;
4865                    a[idx1 + 1] = yi;
4866                    a[idx2] = xr;
4867                    a[idx2 + 1] = xi;
4868                }
4869                k1 = idx0 + ip[m + k];
4870                j1 = k1 + 2;
4871                k1 += nh;
4872                idx1 = offa + j1;
4873                idx2 = offa + k1;
4874                a[idx1 - 1] = -a[idx1 - 1];
4875                xr = a[idx1];
4876                xi = -a[idx1 + 1];
4877                yr = a[idx2];
4878                yi = -a[idx2 + 1];
4879                a[idx1] = yr;
4880                a[idx1 + 1] = yi;
4881                a[idx2] = xr;
4882                a[idx2 + 1] = xi;
4883                a[idx2 + 3] = -a[idx2 + 3];
4884                j1 += nm;
4885                k1 += nm;
4886                idx1 = offa + j1;
4887                idx2 = offa + k1;
4888                a[idx1 - 1] = -a[idx1 - 1];
4889                xr = a[idx1];
4890                xi = -a[idx1 + 1];
4891                yr = a[idx2];
4892                yi = -a[idx2 + 1];
4893                a[idx1] = yr;
4894                a[idx1 + 1] = yi;
4895                a[idx2] = xr;
4896                a[idx2 + 1] = xi;
4897                a[idx2 + 3] = -a[idx2 + 3];
4898            }
4899        }
4900    }
4901
4902    private void bitrv216(double[] a, int offa) {
4903        double x1r, x1i, x2r, x2i, x3r, x3i, x4r, x4i, x5r, x5i, x7r, x7i, x8r, x8i, x10r, x10i, x11r, x11i, x12r, x12i, x13r, x13i, x14r, x14i;
4904
4905        x1r = a[offa + 2];
4906        x1i = a[offa + 3];
4907        x2r = a[offa + 4];
4908        x2i = a[offa + 5];
4909        x3r = a[offa + 6];
4910        x3i = a[offa + 7];
4911        x4r = a[offa + 8];
4912        x4i = a[offa + 9];
4913        x5r = a[offa + 10];
4914        x5i = a[offa + 11];
4915        x7r = a[offa + 14];
4916        x7i = a[offa + 15];
4917        x8r = a[offa + 16];
4918        x8i = a[offa + 17];
4919        x10r = a[offa + 20];
4920        x10i = a[offa + 21];
4921        x11r = a[offa + 22];
4922        x11i = a[offa + 23];
4923        x12r = a[offa + 24];
4924        x12i = a[offa + 25];
4925        x13r = a[offa + 26];
4926        x13i = a[offa + 27];
4927        x14r = a[offa + 28];
4928        x14i = a[offa + 29];
4929        a[offa + 2] = x8r;
4930        a[offa + 3] = x8i;
4931        a[offa + 4] = x4r;
4932        a[offa + 5] = x4i;
4933        a[offa + 6] = x12r;
4934        a[offa + 7] = x12i;
4935        a[offa + 8] = x2r;
4936        a[offa + 9] = x2i;
4937        a[offa + 10] = x10r;
4938        a[offa + 11] = x10i;
4939        a[offa + 14] = x14r;
4940        a[offa + 15] = x14i;
4941        a[offa + 16] = x1r;
4942        a[offa + 17] = x1i;
4943        a[offa + 20] = x5r;
4944        a[offa + 21] = x5i;
4945        a[offa + 22] = x13r;
4946        a[offa + 23] = x13i;
4947        a[offa + 24] = x3r;
4948        a[offa + 25] = x3i;
4949        a[offa + 26] = x11r;
4950        a[offa + 27] = x11i;
4951        a[offa + 28] = x7r;
4952        a[offa + 29] = x7i;
4953    }
4954
4955    private void bitrv216neg(double[] a, int offa) {
4956        double x1r, x1i, x2r, x2i, x3r, x3i, x4r, x4i, x5r, x5i, x6r, x6i, x7r, x7i, x8r, x8i, x9r, x9i, x10r, x10i, x11r, x11i, x12r, x12i, x13r, x13i, x14r, x14i, x15r, x15i;
4957
4958        x1r = a[offa + 2];
4959        x1i = a[offa + 3];
4960        x2r = a[offa + 4];
4961        x2i = a[offa + 5];
4962        x3r = a[offa + 6];
4963        x3i = a[offa + 7];
4964        x4r = a[offa + 8];
4965        x4i = a[offa + 9];
4966        x5r = a[offa + 10];
4967        x5i = a[offa + 11];
4968        x6r = a[offa + 12];
4969        x6i = a[offa + 13];
4970        x7r = a[offa + 14];
4971        x7i = a[offa + 15];
4972        x8r = a[offa + 16];
4973        x8i = a[offa + 17];
4974        x9r = a[offa + 18];
4975        x9i = a[offa + 19];
4976        x10r = a[offa + 20];
4977        x10i = a[offa + 21];
4978        x11r = a[offa + 22];
4979        x11i = a[offa + 23];
4980        x12r = a[offa + 24];
4981        x12i = a[offa + 25];
4982        x13r = a[offa + 26];
4983        x13i = a[offa + 27];
4984        x14r = a[offa + 28];
4985        x14i = a[offa + 29];
4986        x15r = a[offa + 30];
4987        x15i = a[offa + 31];
4988        a[offa + 2] = x15r;
4989        a[offa + 3] = x15i;
4990        a[offa + 4] = x7r;
4991        a[offa + 5] = x7i;
4992        a[offa + 6] = x11r;
4993        a[offa + 7] = x11i;
4994        a[offa + 8] = x3r;
4995        a[offa + 9] = x3i;
4996        a[offa + 10] = x13r;
4997        a[offa + 11] = x13i;
4998        a[offa + 12] = x5r;
4999        a[offa + 13] = x5i;
5000        a[offa + 14] = x9r;
5001        a[offa + 15] = x9i;
5002        a[offa + 16] = x1r;
5003        a[offa + 17] = x1i;
5004        a[offa + 18] = x14r;
5005        a[offa + 19] = x14i;
5006        a[offa + 20] = x6r;
5007        a[offa + 21] = x6i;
5008        a[offa + 22] = x10r;
5009        a[offa + 23] = x10i;
5010        a[offa + 24] = x2r;
5011        a[offa + 25] = x2i;
5012        a[offa + 26] = x12r;
5013        a[offa + 27] = x12i;
5014        a[offa + 28] = x4r;
5015        a[offa + 29] = x4i;
5016        a[offa + 30] = x8r;
5017        a[offa + 31] = x8i;
5018    }
5019
5020    private void bitrv208(double[] a, int offa) {
5021        double x1r, x1i, x3r, x3i, x4r, x4i, x6r, x6i;
5022
5023        x1r = a[offa + 2];
5024        x1i = a[offa + 3];
5025        x3r = a[offa + 6];
5026        x3i = a[offa + 7];
5027        x4r = a[offa + 8];
5028        x4i = a[offa + 9];
5029        x6r = a[offa + 12];
5030        x6i = a[offa + 13];
5031        a[offa + 2] = x4r;
5032        a[offa + 3] = x4i;
5033        a[offa + 6] = x6r;
5034        a[offa + 7] = x6i;
5035        a[offa + 8] = x1r;
5036        a[offa + 9] = x1i;
5037        a[offa + 12] = x3r;
5038        a[offa + 13] = x3i;
5039    }
5040
5041    private void bitrv208neg(double[] a, int offa) {
5042        double x1r, x1i, x2r, x2i, x3r, x3i, x4r, x4i, x5r, x5i, x6r, x6i, x7r, x7i;
5043
5044        x1r = a[offa + 2];
5045        x1i = a[offa + 3];
5046        x2r = a[offa + 4];
5047        x2i = a[offa + 5];
5048        x3r = a[offa + 6];
5049        x3i = a[offa + 7];
5050        x4r = a[offa + 8];
5051        x4i = a[offa + 9];
5052        x5r = a[offa + 10];
5053        x5i = a[offa + 11];
5054        x6r = a[offa + 12];
5055        x6i = a[offa + 13];
5056        x7r = a[offa + 14];
5057        x7i = a[offa + 15];
5058        a[offa + 2] = x7r;
5059        a[offa + 3] = x7i;
5060        a[offa + 4] = x3r;
5061        a[offa + 5] = x3i;
5062        a[offa + 6] = x5r;
5063        a[offa + 7] = x5i;
5064        a[offa + 8] = x1r;
5065        a[offa + 9] = x1i;
5066        a[offa + 10] = x6r;
5067        a[offa + 11] = x6i;
5068        a[offa + 12] = x2r;
5069        a[offa + 13] = x2i;
5070        a[offa + 14] = x4r;
5071        a[offa + 15] = x4i;
5072    }
5073
5074    private void cftf1st(int n, double[] a, int offa, double[] w, int startw) {
5075        int j0, j1, j2, j3, k, m, mh;
5076        double wn4r, csc1, csc3, wk1r, wk1i, wk3r, wk3i, wd1r, wd1i, wd3r, wd3i;
5077        double x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i, y0r, y0i, y1r, y1i, y2r, y2i, y3r, y3i;
5078        int idx0, idx1, idx2, idx3, idx4, idx5;
5079        mh = n >> 3;
5080        m = 2 * mh;
5081        j1 = m;
5082        j2 = j1 + m;
5083        j3 = j2 + m;
5084        idx1 = offa + j1;
5085        idx2 = offa + j2;
5086        idx3 = offa + j3;
5087        x0r = a[offa] + a[idx2];
5088        x0i = a[offa + 1] + a[idx2 + 1];
5089        x1r = a[offa] - a[idx2];
5090        x1i = a[offa + 1] - a[idx2 + 1];
5091        x2r = a[idx1] + a[idx3];
5092        x2i = a[idx1 + 1] + a[idx3 + 1];
5093        x3r = a[idx1] - a[idx3];
5094        x3i = a[idx1 + 1] - a[idx3 + 1];
5095        a[offa] = x0r + x2r;
5096        a[offa + 1] = x0i + x2i;
5097        a[idx1] = x0r - x2r;
5098        a[idx1 + 1] = x0i - x2i;
5099        a[idx2] = x1r - x3i;
5100        a[idx2 + 1] = x1i + x3r;
5101        a[idx3] = x1r + x3i;
5102        a[idx3 + 1] = x1i - x3r;
5103        wn4r = w[startw + 1];
5104        csc1 = w[startw + 2];
5105        csc3 = w[startw + 3];
5106        wd1r = 1;
5107        wd1i = 0;
5108        wd3r = 1;
5109        wd3i = 0;
5110        k = 0;
5111        for (int j = 2; j < mh - 2; j += 4) {
5112            k += 4;
5113            idx4 = startw + k;
5114            wk1r = csc1 * (wd1r + w[idx4]);
5115            wk1i = csc1 * (wd1i + w[idx4 + 1]);
5116            wk3r = csc3 * (wd3r + w[idx4 + 2]);
5117            wk3i = csc3 * (wd3i + w[idx4 + 3]);
5118            wd1r = w[idx4];
5119            wd1i = w[idx4 + 1];
5120            wd3r = w[idx4 + 2];
5121            wd3i = w[idx4 + 3];
5122            j1 = j + m;
5123            j2 = j1 + m;
5124            j3 = j2 + m;
5125            idx1 = offa + j1;
5126            idx2 = offa + j2;
5127            idx3 = offa + j3;
5128            idx5 = offa + j;
5129            x0r = a[idx5] + a[idx2];
5130            x0i = a[idx5 + 1] + a[idx2 + 1];
5131            x1r = a[idx5] - a[idx2];
5132            x1i = a[idx5 + 1] - a[idx2 + 1];
5133            y0r = a[idx5 + 2] + a[idx2 + 2];
5134            y0i = a[idx5 + 3] + a[idx2 + 3];
5135            y1r = a[idx5 + 2] - a[idx2 + 2];
5136            y1i = a[idx5 + 3] - a[idx2 + 3];
5137            x2r = a[idx1] + a[idx3];
5138            x2i = a[idx1 + 1] + a[idx3 + 1];
5139            x3r = a[idx1] - a[idx3];
5140            x3i = a[idx1 + 1] - a[idx3 + 1];
5141            y2r = a[idx1 + 2] + a[idx3 + 2];
5142            y2i = a[idx1 + 3] + a[idx3 + 3];
5143            y3r = a[idx1 + 2] - a[idx3 + 2];
5144            y3i = a[idx1 + 3] - a[idx3 + 3];
5145            a[idx5] = x0r + x2r;
5146            a[idx5 + 1] = x0i + x2i;
5147            a[idx5 + 2] = y0r + y2r;
5148            a[idx5 + 3] = y0i + y2i;
5149            a[idx1] = x0r - x2r;
5150            a[idx1 + 1] = x0i - x2i;
5151            a[idx1 + 2] = y0r - y2r;
5152            a[idx1 + 3] = y0i - y2i;
5153            x0r = x1r - x3i;
5154            x0i = x1i + x3r;
5155            a[idx2] = wk1r * x0r - wk1i * x0i;
5156            a[idx2 + 1] = wk1r * x0i + wk1i * x0r;
5157            x0r = y1r - y3i;
5158            x0i = y1i + y3r;
5159            a[idx2 + 2] = wd1r * x0r - wd1i * x0i;
5160            a[idx2 + 3] = wd1r * x0i + wd1i * x0r;
5161            x0r = x1r + x3i;
5162            x0i = x1i - x3r;
5163            a[idx3] = wk3r * x0r + wk3i * x0i;
5164            a[idx3 + 1] = wk3r * x0i - wk3i * x0r;
5165            x0r = y1r + y3i;
5166            x0i = y1i - y3r;
5167            a[idx3 + 2] = wd3r * x0r + wd3i * x0i;
5168            a[idx3 + 3] = wd3r * x0i - wd3i * x0r;
5169            j0 = m - j;
5170            j1 = j0 + m;
5171            j2 = j1 + m;
5172            j3 = j2 + m;
5173            idx0 = offa + j0;
5174            idx1 = offa + j1;
5175            idx2 = offa + j2;
5176            idx3 = offa + j3;
5177            x0r = a[idx0] + a[idx2];
5178            x0i = a[idx0 + 1] + a[idx2 + 1];
5179            x1r = a[idx0] - a[idx2];
5180            x1i = a[idx0 + 1] - a[idx2 + 1];
5181            y0r = a[idx0 - 2] + a[idx2 - 2];
5182            y0i = a[idx0 - 1] + a[idx2 - 1];
5183            y1r = a[idx0 - 2] - a[idx2 - 2];
5184            y1i = a[idx0 - 1] - a[idx2 - 1];
5185            x2r = a[idx1] + a[idx3];
5186            x2i = a[idx1 + 1] + a[idx3 + 1];
5187            x3r = a[idx1] - a[idx3];
5188            x3i = a[idx1 + 1] - a[idx3 + 1];
5189            y2r = a[idx1 - 2] + a[idx3 - 2];
5190            y2i = a[idx1 - 1] + a[idx3 - 1];
5191            y3r = a[idx1 - 2] - a[idx3 - 2];
5192            y3i = a[idx1 - 1] - a[idx3 - 1];
5193            a[idx0] = x0r + x2r;
5194            a[idx0 + 1] = x0i + x2i;
5195            a[idx0 - 2] = y0r + y2r;
5196            a[idx0 - 1] = y0i + y2i;
5197            a[idx1] = x0r - x2r;
5198            a[idx1 + 1] = x0i - x2i;
5199            a[idx1 - 2] = y0r - y2r;
5200            a[idx1 - 1] = y0i - y2i;
5201            x0r = x1r - x3i;
5202            x0i = x1i + x3r;
5203            a[idx2] = wk1i * x0r - wk1r * x0i;
5204            a[idx2 + 1] = wk1i * x0i + wk1r * x0r;
5205            x0r = y1r - y3i;
5206            x0i = y1i + y3r;
5207            a[idx2 - 2] = wd1i * x0r - wd1r * x0i;
5208            a[idx2 - 1] = wd1i * x0i + wd1r * x0r;
5209            x0r = x1r + x3i;
5210            x0i = x1i - x3r;
5211            a[idx3] = wk3i * x0r + wk3r * x0i;
5212            a[idx3 + 1] = wk3i * x0i - wk3r * x0r;
5213            x0r = y1r + y3i;
5214            x0i = y1i - y3r;
5215            a[offa + j3 - 2] = wd3i * x0r + wd3r * x0i;
5216            a[offa + j3 - 1] = wd3i * x0i - wd3r * x0r;
5217        }
5218        wk1r = csc1 * (wd1r + wn4r);
5219        wk1i = csc1 * (wd1i + wn4r);
5220        wk3r = csc3 * (wd3r - wn4r);
5221        wk3i = csc3 * (wd3i - wn4r);
5222        j0 = mh;
5223        j1 = j0 + m;
5224        j2 = j1 + m;
5225        j3 = j2 + m;
5226        idx0 = offa + j0;
5227        idx1 = offa + j1;
5228        idx2 = offa + j2;
5229        idx3 = offa + j3;
5230        x0r = a[idx0 - 2] + a[idx2 - 2];
5231        x0i = a[idx0 - 1] + a[idx2 - 1];
5232        x1r = a[idx0 - 2] - a[idx2 - 2];
5233        x1i = a[idx0 - 1] - a[idx2 - 1];
5234        x2r = a[idx1 - 2] + a[idx3 - 2];
5235        x2i = a[idx1 - 1] + a[idx3 - 1];
5236        x3r = a[idx1 - 2] - a[idx3 - 2];
5237        x3i = a[idx1 - 1] - a[idx3 - 1];
5238        a[idx0 - 2] = x0r + x2r;
5239        a[idx0 - 1] = x0i + x2i;
5240        a[idx1 - 2] = x0r - x2r;
5241        a[idx1 - 1] = x0i - x2i;
5242        x0r = x1r - x3i;
5243        x0i = x1i + x3r;
5244        a[idx2 - 2] = wk1r * x0r - wk1i * x0i;
5245        a[idx2 - 1] = wk1r * x0i + wk1i * x0r;
5246        x0r = x1r + x3i;
5247        x0i = x1i - x3r;
5248        a[idx3 - 2] = wk3r * x0r + wk3i * x0i;
5249        a[idx3 - 1] = wk3r * x0i - wk3i * x0r;
5250        x0r = a[idx0] + a[idx2];
5251        x0i = a[idx0 + 1] + a[idx2 + 1];
5252        x1r = a[idx0] - a[idx2];
5253        x1i = a[idx0 + 1] - a[idx2 + 1];
5254        x2r = a[idx1] + a[idx3];
5255        x2i = a[idx1 + 1] + a[idx3 + 1];
5256        x3r = a[idx1] - a[idx3];
5257        x3i = a[idx1 + 1] - a[idx3 + 1];
5258        a[idx0] = x0r + x2r;
5259        a[idx0 + 1] = x0i + x2i;
5260        a[idx1] = x0r - x2r;
5261        a[idx1 + 1] = x0i - x2i;
5262        x0r = x1r - x3i;
5263        x0i = x1i + x3r;
5264        a[idx2] = wn4r * (x0r - x0i);
5265        a[idx2 + 1] = wn4r * (x0i + x0r);
5266        x0r = x1r + x3i;
5267        x0i = x1i - x3r;
5268        a[idx3] = -wn4r * (x0r + x0i);
5269        a[idx3 + 1] = -wn4r * (x0i - x0r);
5270        x0r = a[idx0 + 2] + a[idx2 + 2];
5271        x0i = a[idx0 + 3] + a[idx2 + 3];
5272        x1r = a[idx0 + 2] - a[idx2 + 2];
5273        x1i = a[idx0 + 3] - a[idx2 + 3];
5274        x2r = a[idx1 + 2] + a[idx3 + 2];
5275        x2i = a[idx1 + 3] + a[idx3 + 3];
5276        x3r = a[idx1 + 2] - a[idx3 + 2];
5277        x3i = a[idx1 + 3] - a[idx3 + 3];
5278        a[idx0 + 2] = x0r + x2r;
5279        a[idx0 + 3] = x0i + x2i;
5280        a[idx1 + 2] = x0r - x2r;
5281        a[idx1 + 3] = x0i - x2i;
5282        x0r = x1r - x3i;
5283        x0i = x1i + x3r;
5284        a[idx2 + 2] = wk1i * x0r - wk1r * x0i;
5285        a[idx2 + 3] = wk1i * x0i + wk1r * x0r;
5286        x0r = x1r + x3i;
5287        x0i = x1i - x3r;
5288        a[idx3 + 2] = wk3i * x0r + wk3r * x0i;
5289        a[idx3 + 3] = wk3i * x0i - wk3r * x0r;
5290    }
5291
5292    private void cftb1st(int n, double[] a, int offa, double[] w, int startw) {
5293        int j0, j1, j2, j3, k, m, mh;
5294        double wn4r, csc1, csc3, wk1r, wk1i, wk3r, wk3i, wd1r, wd1i, wd3r, wd3i;
5295        double x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i, y0r, y0i, y1r, y1i, y2r, y2i, y3r, y3i;
5296        int idx0, idx1, idx2, idx3, idx4, idx5;
5297        mh = n >> 3;
5298        m = 2 * mh;
5299        j1 = m;
5300        j2 = j1 + m;
5301        j3 = j2 + m;
5302        idx1 = offa + j1;
5303        idx2 = offa + j2;
5304        idx3 = offa + j3;
5305
5306        x0r = a[offa] + a[idx2];
5307        x0i = -a[offa + 1] - a[idx2 + 1];
5308        x1r = a[offa] - a[idx2];
5309        x1i = -a[offa + 1] + a[idx2 + 1];
5310        x2r = a[idx1] + a[idx3];
5311        x2i = a[idx1 + 1] + a[idx3 + 1];
5312        x3r = a[idx1] - a[idx3];
5313        x3i = a[idx1 + 1] - a[idx3 + 1];
5314        a[offa] = x0r + x2r;
5315        a[offa + 1] = x0i - x2i;
5316        a[idx1] = x0r - x2r;
5317        a[idx1 + 1] = x0i + x2i;
5318        a[idx2] = x1r + x3i;
5319        a[idx2 + 1] = x1i + x3r;
5320        a[idx3] = x1r - x3i;
5321        a[idx3 + 1] = x1i - x3r;
5322        wn4r = w[startw + 1];
5323        csc1 = w[startw + 2];
5324        csc3 = w[startw + 3];
5325        wd1r = 1;
5326        wd1i = 0;
5327        wd3r = 1;
5328        wd3i = 0;
5329        k = 0;
5330        for (int j = 2; j < mh - 2; j += 4) {
5331            k += 4;
5332            idx4 = startw + k;
5333            wk1r = csc1 * (wd1r + w[idx4]);
5334            wk1i = csc1 * (wd1i + w[idx4 + 1]);
5335            wk3r = csc3 * (wd3r + w[idx4 + 2]);
5336            wk3i = csc3 * (wd3i + w[idx4 + 3]);
5337            wd1r = w[idx4];
5338            wd1i = w[idx4 + 1];
5339            wd3r = w[idx4 + 2];
5340            wd3i = w[idx4 + 3];
5341            j1 = j + m;
5342            j2 = j1 + m;
5343            j3 = j2 + m;
5344            idx1 = offa + j1;
5345            idx2 = offa + j2;
5346            idx3 = offa + j3;
5347            idx5 = offa + j;
5348            x0r = a[idx5] + a[idx2];
5349            x0i = -a[idx5 + 1] - a[idx2 + 1];
5350            x1r = a[idx5] - a[offa + j2];
5351            x1i = -a[idx5 + 1] + a[idx2 + 1];
5352            y0r = a[idx5 + 2] + a[idx2 + 2];
5353            y0i = -a[idx5 + 3] - a[idx2 + 3];
5354            y1r = a[idx5 + 2] - a[idx2 + 2];
5355            y1i = -a[idx5 + 3] + a[idx2 + 3];
5356            x2r = a[idx1] + a[idx3];
5357            x2i = a[idx1 + 1] + a[idx3 + 1];
5358            x3r = a[idx1] - a[idx3];
5359            x3i = a[idx1 + 1] - a[idx3 + 1];
5360            y2r = a[idx1 + 2] + a[idx3 + 2];
5361            y2i = a[idx1 + 3] + a[idx3 + 3];
5362            y3r = a[idx1 + 2] - a[idx3 + 2];
5363            y3i = a[idx1 + 3] - a[idx3 + 3];
5364            a[idx5] = x0r + x2r;
5365            a[idx5 + 1] = x0i - x2i;
5366            a[idx5 + 2] = y0r + y2r;
5367            a[idx5 + 3] = y0i - y2i;
5368            a[idx1] = x0r - x2r;
5369            a[idx1 + 1] = x0i + x2i;
5370            a[idx1 + 2] = y0r - y2r;
5371            a[idx1 + 3] = y0i + y2i;
5372            x0r = x1r + x3i;
5373            x0i = x1i + x3r;
5374            a[idx2] = wk1r * x0r - wk1i * x0i;
5375            a[idx2 + 1] = wk1r * x0i + wk1i * x0r;
5376            x0r = y1r + y3i;
5377            x0i = y1i + y3r;
5378            a[idx2 + 2] = wd1r * x0r - wd1i * x0i;
5379            a[idx2 + 3] = wd1r * x0i + wd1i * x0r;
5380            x0r = x1r - x3i;
5381            x0i = x1i - x3r;
5382            a[idx3] = wk3r * x0r + wk3i * x0i;
5383            a[idx3 + 1] = wk3r * x0i - wk3i * x0r;
5384            x0r = y1r - y3i;
5385            x0i = y1i - y3r;
5386            a[idx3 + 2] = wd3r * x0r + wd3i * x0i;
5387            a[idx3 + 3] = wd3r * x0i - wd3i * x0r;
5388            j0 = m - j;
5389            j1 = j0 + m;
5390            j2 = j1 + m;
5391            j3 = j2 + m;
5392            idx0 = offa + j0;
5393            idx1 = offa + j1;
5394            idx2 = offa + j2;
5395            idx3 = offa + j3;
5396            x0r = a[idx0] + a[idx2];
5397            x0i = -a[idx0 + 1] - a[idx2 + 1];
5398            x1r = a[idx0] - a[idx2];
5399            x1i = -a[idx0 + 1] + a[idx2 + 1];
5400            y0r = a[idx0 - 2] + a[idx2 - 2];
5401            y0i = -a[idx0 - 1] - a[idx2 - 1];
5402            y1r = a[idx0 - 2] - a[idx2 - 2];
5403            y1i = -a[idx0 - 1] + a[idx2 - 1];
5404            x2r = a[idx1] + a[idx3];
5405            x2i = a[idx1 + 1] + a[idx3 + 1];
5406            x3r = a[idx1] - a[idx3];
5407            x3i = a[idx1 + 1] - a[idx3 + 1];
5408            y2r = a[idx1 - 2] + a[idx3 - 2];
5409            y2i = a[idx1 - 1] + a[idx3 - 1];
5410            y3r = a[idx1 - 2] - a[idx3 - 2];
5411            y3i = a[idx1 - 1] - a[idx3 - 1];
5412            a[idx0] = x0r + x2r;
5413            a[idx0 + 1] = x0i - x2i;
5414            a[idx0 - 2] = y0r + y2r;
5415            a[idx0 - 1] = y0i - y2i;
5416            a[idx1] = x0r - x2r;
5417            a[idx1 + 1] = x0i + x2i;
5418            a[idx1 - 2] = y0r - y2r;
5419            a[idx1 - 1] = y0i + y2i;
5420            x0r = x1r + x3i;
5421            x0i = x1i + x3r;
5422            a[idx2] = wk1i * x0r - wk1r * x0i;
5423            a[idx2 + 1] = wk1i * x0i + wk1r * x0r;
5424            x0r = y1r + y3i;
5425            x0i = y1i + y3r;
5426            a[idx2 - 2] = wd1i * x0r - wd1r * x0i;
5427            a[idx2 - 1] = wd1i * x0i + wd1r * x0r;
5428            x0r = x1r - x3i;
5429            x0i = x1i - x3r;
5430            a[idx3] = wk3i * x0r + wk3r * x0i;
5431            a[idx3 + 1] = wk3i * x0i - wk3r * x0r;
5432            x0r = y1r - y3i;
5433            x0i = y1i - y3r;
5434            a[idx3 - 2] = wd3i * x0r + wd3r * x0i;
5435            a[idx3 - 1] = wd3i * x0i - wd3r * x0r;
5436        }
5437        wk1r = csc1 * (wd1r + wn4r);
5438        wk1i = csc1 * (wd1i + wn4r);
5439        wk3r = csc3 * (wd3r - wn4r);
5440        wk3i = csc3 * (wd3i - wn4r);
5441        j0 = mh;
5442        j1 = j0 + m;
5443        j2 = j1 + m;
5444        j3 = j2 + m;
5445        idx0 = offa + j0;
5446        idx1 = offa + j1;
5447        idx2 = offa + j2;
5448        idx3 = offa + j3;
5449        x0r = a[idx0 - 2] + a[idx2 - 2];
5450        x0i = -a[idx0 - 1] - a[idx2 - 1];
5451        x1r = a[idx0 - 2] - a[idx2 - 2];
5452        x1i = -a[idx0 - 1] + a[idx2 - 1];
5453        x2r = a[idx1 - 2] + a[idx3 - 2];
5454        x2i = a[idx1 - 1] + a[idx3 - 1];
5455        x3r = a[idx1 - 2] - a[idx3 - 2];
5456        x3i = a[idx1 - 1] - a[idx3 - 1];
5457        a[idx0 - 2] = x0r + x2r;
5458        a[idx0 - 1] = x0i - x2i;
5459        a[idx1 - 2] = x0r - x2r;
5460        a[idx1 - 1] = x0i + x2i;
5461        x0r = x1r + x3i;
5462        x0i = x1i + x3r;
5463        a[idx2 - 2] = wk1r * x0r - wk1i * x0i;
5464        a[idx2 - 1] = wk1r * x0i + wk1i * x0r;
5465        x0r = x1r - x3i;
5466        x0i = x1i - x3r;
5467        a[idx3 - 2] = wk3r * x0r + wk3i * x0i;
5468        a[idx3 - 1] = wk3r * x0i - wk3i * x0r;
5469        x0r = a[idx0] + a[idx2];
5470        x0i = -a[idx0 + 1] - a[idx2 + 1];
5471        x1r = a[idx0] - a[idx2];
5472        x1i = -a[idx0 + 1] + a[idx2 + 1];
5473        x2r = a[idx1] + a[idx3];
5474        x2i = a[idx1 + 1] + a[idx3 + 1];
5475        x3r = a[idx1] - a[idx3];
5476        x3i = a[idx1 + 1] - a[idx3 + 1];
5477        a[idx0] = x0r + x2r;
5478        a[idx0 + 1] = x0i - x2i;
5479        a[idx1] = x0r - x2r;
5480        a[idx1 + 1] = x0i + x2i;
5481        x0r = x1r + x3i;
5482        x0i = x1i + x3r;
5483        a[idx2] = wn4r * (x0r - x0i);
5484        a[idx2 + 1] = wn4r * (x0i + x0r);
5485        x0r = x1r - x3i;
5486        x0i = x1i - x3r;
5487        a[idx3] = -wn4r * (x0r + x0i);
5488        a[idx3 + 1] = -wn4r * (x0i - x0r);
5489        x0r = a[idx0 + 2] + a[idx2 + 2];
5490        x0i = -a[idx0 + 3] - a[idx2 + 3];
5491        x1r = a[idx0 + 2] - a[idx2 + 2];
5492        x1i = -a[idx0 + 3] + a[idx2 + 3];
5493        x2r = a[idx1 + 2] + a[idx3 + 2];
5494        x2i = a[idx1 + 3] + a[idx3 + 3];
5495        x3r = a[idx1 + 2] - a[idx3 + 2];
5496        x3i = a[idx1 + 3] - a[idx3 + 3];
5497        a[idx0 + 2] = x0r + x2r;
5498        a[idx0 + 3] = x0i - x2i;
5499        a[idx1 + 2] = x0r - x2r;
5500        a[idx1 + 3] = x0i + x2i;
5501        x0r = x1r + x3i;
5502        x0i = x1i + x3r;
5503        a[idx2 + 2] = wk1i * x0r - wk1r * x0i;
5504        a[idx2 + 3] = wk1i * x0i + wk1r * x0r;
5505        x0r = x1r - x3i;
5506        x0i = x1i - x3r;
5507        a[idx3 + 2] = wk3i * x0r + wk3r * x0i;
5508        a[idx3 + 3] = wk3i * x0i - wk3r * x0r;
5509    }
5510
5511    private void cftrec4_th(final int n, final double[] a, final int offa, final int nw, final double[] w) {
5512        int i;
5513        int idiv4, m, nthreads;
5514        int idx = 0;
5515        nthreads = 2;
5516        idiv4 = 0;
5517        m = n >> 1;
5518        if (n > ConcurrencyUtils.getThreadsBeginN_1D_FFT_4Threads()) {
5519            nthreads = 4;
5520            idiv4 = 1;
5521            m >>= 1;
5522        }
5523        Future<?>[] futures = new Future[nthreads];
5524        final int mf = m;
5525        for (i = 0; i < nthreads; i++) {
5526            final int firstIdx = offa + i * m;
5527            if (i != idiv4) {
5528                futures[idx++] = ConcurrencyUtils.submit(new Runnable() {
5529                    public void run() {
5530                        int isplt, j, k, m;
5531                        int idx1 = firstIdx + mf;
5532                        m = n;
5533                        while (m > 512) {
5534                            m >>= 2;
5535                            cftmdl1(m, a, idx1 - m, w, nw - (m >> 1));
5536                        }
5537                        cftleaf(m, 1, a, idx1 - m, nw, w);
5538                        k = 0;
5539                        int idx2 = firstIdx - m;
5540                        for (j = mf - m; j > 0; j -= m) {
5541                            k++;
5542                            isplt = cfttree(m, j, k, a, firstIdx, nw, w);
5543                            cftleaf(m, isplt, a, idx2 + j, nw, w);
5544                        }
5545                    }
5546                });
5547            } else {
5548                futures[idx++] = ConcurrencyUtils.submit(new Runnable() {
5549                    public void run() {
5550                        int isplt, j, k, m;
5551                        int idx1 = firstIdx + mf;
5552                        k = 1;
5553                        m = n;
5554                        while (m > 512) {
5555                            m >>= 2;
5556                            k <<= 2;
5557                            cftmdl2(m, a, idx1 - m, w, nw - m);
5558                        }
5559                        cftleaf(m, 0, a, idx1 - m, nw, w);
5560                        k >>= 1;
5561                        int idx2 = firstIdx - m;
5562                        for (j = mf - m; j > 0; j -= m) {
5563                            k++;
5564                            isplt = cfttree(m, j, k, a, firstIdx, nw, w);
5565                            cftleaf(m, isplt, a, idx2 + j, nw, w);
5566                        }
5567                    }
5568                });
5569            }
5570        }
5571        ConcurrencyUtils.waitForCompletion(futures);
5572    }
5573
5574    private void cftrec4(int n, double[] a, int offa, int nw, double[] w) {
5575        int isplt, j, k, m;
5576
5577        m = n;
5578        int idx1 = offa + n;
5579        while (m > 512) {
5580            m >>= 2;
5581            cftmdl1(m, a, idx1 - m, w, nw - (m >> 1));
5582        }
5583        cftleaf(m, 1, a, idx1 - m, nw, w);
5584        k = 0;
5585        int idx2 = offa - m;
5586        for (j = n - m; j > 0; j -= m) {
5587            k++;
5588            isplt = cfttree(m, j, k, a, offa, nw, w);
5589            cftleaf(m, isplt, a, idx2 + j, nw, w);
5590        }
5591    }
5592
5593    private int cfttree(int n, int j, int k, double[] a, int offa, int nw, double[] w) {
5594        int i, isplt, m;
5595        int idx1 = offa - n;
5596        if ((k & 3) != 0) {
5597            isplt = k & 1;
5598            if (isplt != 0) {
5599                cftmdl1(n, a, idx1 + j, w, nw - (n >> 1));
5600            } else {
5601                cftmdl2(n, a, idx1 + j, w, nw - n);
5602            }
5603        } else {
5604            m = n;
5605            for (i = k; (i & 3) == 0; i >>= 2) {
5606                m <<= 2;
5607            }
5608            isplt = i & 1;
5609            int idx2 = offa + j;
5610            if (isplt != 0) {
5611                while (m > 128) {
5612                    cftmdl1(m, a, idx2 - m, w, nw - (m >> 1));
5613                    m >>= 2;
5614                }
5615            } else {
5616                while (m > 128) {
5617                    cftmdl2(m, a, idx2 - m, w, nw - m);
5618                    m >>= 2;
5619                }
5620            }
5621        }
5622        return isplt;
5623    }
5624
5625    private void cftleaf(int n, int isplt, double[] a, int offa, int nw, double[] w) {
5626        if (n == 512) {
5627            cftmdl1(128, a, offa, w, nw - 64);
5628            cftf161(a, offa, w, nw - 8);
5629            cftf162(a, offa + 32, w, nw - 32);
5630            cftf161(a, offa + 64, w, nw - 8);
5631            cftf161(a, offa + 96, w, nw - 8);
5632            cftmdl2(128, a, offa + 128, w, nw - 128);
5633            cftf161(a, offa + 128, w, nw - 8);
5634            cftf162(a, offa + 160, w, nw - 32);
5635            cftf161(a, offa + 192, w, nw - 8);
5636            cftf162(a, offa + 224, w, nw - 32);
5637            cftmdl1(128, a, offa + 256, w, nw - 64);
5638            cftf161(a, offa + 256, w, nw - 8);
5639            cftf162(a, offa + 288, w, nw - 32);
5640            cftf161(a, offa + 320, w, nw - 8);
5641            cftf161(a, offa + 352, w, nw - 8);
5642            if (isplt != 0) {
5643                cftmdl1(128, a, offa + 384, w, nw - 64);
5644                cftf161(a, offa + 480, w, nw - 8);
5645            } else {
5646                cftmdl2(128, a, offa + 384, w, nw - 128);
5647                cftf162(a, offa + 480, w, nw - 32);
5648            }
5649            cftf161(a, offa + 384, w, nw - 8);
5650            cftf162(a, offa + 416, w, nw - 32);
5651            cftf161(a, offa + 448, w, nw - 8);
5652        } else {
5653            cftmdl1(64, a, offa, w, nw - 32);
5654            cftf081(a, offa, w, nw - 8);
5655            cftf082(a, offa + 16, w, nw - 8);
5656            cftf081(a, offa + 32, w, nw - 8);
5657            cftf081(a, offa + 48, w, nw - 8);
5658            cftmdl2(64, a, offa + 64, w, nw - 64);
5659            cftf081(a, offa + 64, w, nw - 8);
5660            cftf082(a, offa + 80, w, nw - 8);
5661            cftf081(a, offa + 96, w, nw - 8);
5662            cftf082(a, offa + 112, w, nw - 8);
5663            cftmdl1(64, a, offa + 128, w, nw - 32);
5664            cftf081(a, offa + 128, w, nw - 8);
5665            cftf082(a, offa + 144, w, nw - 8);
5666            cftf081(a, offa + 160, w, nw - 8);
5667            cftf081(a, offa + 176, w, nw - 8);
5668            if (isplt != 0) {
5669                cftmdl1(64, a, offa + 192, w, nw - 32);
5670                cftf081(a, offa + 240, w, nw - 8);
5671            } else {
5672                cftmdl2(64, a, offa + 192, w, nw - 64);
5673                cftf082(a, offa + 240, w, nw - 8);
5674            }
5675            cftf081(a, offa + 192, w, nw - 8);
5676            cftf082(a, offa + 208, w, nw - 8);
5677            cftf081(a, offa + 224, w, nw - 8);
5678        }
5679    }
5680
5681    private void cftmdl1(int n, double[] a, int offa, double[] w, int startw) {
5682        int j0, j1, j2, j3, k, m, mh;
5683        double wn4r, wk1r, wk1i, wk3r, wk3i;
5684        double x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i;
5685        int idx0, idx1, idx2, idx3, idx4, idx5;
5686
5687        mh = n >> 3;
5688        m = 2 * mh;
5689        j1 = m;
5690        j2 = j1 + m;
5691        j3 = j2 + m;
5692        idx1 = offa + j1;
5693        idx2 = offa + j2;
5694        idx3 = offa + j3;
5695        x0r = a[offa] + a[idx2];
5696        x0i = a[offa + 1] + a[idx2 + 1];
5697        x1r = a[offa] - a[idx2];
5698        x1i = a[offa + 1] - a[idx2 + 1];
5699        x2r = a[idx1] + a[idx3];
5700        x2i = a[idx1 + 1] + a[idx3 + 1];
5701        x3r = a[idx1] - a[idx3];
5702        x3i = a[idx1 + 1] - a[idx3 + 1];
5703        a[offa] = x0r + x2r;
5704        a[offa + 1] = x0i + x2i;
5705        a[idx1] = x0r - x2r;
5706        a[idx1 + 1] = x0i - x2i;
5707        a[idx2] = x1r - x3i;
5708        a[idx2 + 1] = x1i + x3r;
5709        a[idx3] = x1r + x3i;
5710        a[idx3 + 1] = x1i - x3r;
5711        wn4r = w[startw + 1];
5712        k = 0;
5713        for (int j = 2; j < mh; j += 2) {
5714            k += 4;
5715            idx4 = startw + k;
5716            wk1r = w[idx4];
5717            wk1i = w[idx4 + 1];
5718            wk3r = w[idx4 + 2];
5719            wk3i = w[idx4 + 3];
5720            j1 = j + m;
5721            j2 = j1 + m;
5722            j3 = j2 + m;
5723            idx1 = offa + j1;
5724            idx2 = offa + j2;
5725            idx3 = offa + j3;
5726            idx5 = offa + j;
5727            x0r = a[idx5] + a[idx2];
5728            x0i = a[idx5 + 1] + a[idx2 + 1];
5729            x1r = a[idx5] - a[idx2];
5730            x1i = a[idx5 + 1] - a[idx2 + 1];
5731            x2r = a[idx1] + a[idx3];
5732            x2i = a[idx1 + 1] + a[idx3 + 1];
5733            x3r = a[idx1] - a[idx3];
5734            x3i = a[idx1 + 1] - a[idx3 + 1];
5735            a[idx5] = x0r + x2r;
5736            a[idx5 + 1] = x0i + x2i;
5737            a[idx1] = x0r - x2r;
5738            a[idx1 + 1] = x0i - x2i;
5739            x0r = x1r - x3i;
5740            x0i = x1i + x3r;
5741            a[idx2] = wk1r * x0r - wk1i * x0i;
5742            a[idx2 + 1] = wk1r * x0i + wk1i * x0r;
5743            x0r = x1r + x3i;
5744            x0i = x1i - x3r;
5745            a[idx3] = wk3r * x0r + wk3i * x0i;
5746            a[idx3 + 1] = wk3r * x0i - wk3i * x0r;
5747            j0 = m - j;
5748            j1 = j0 + m;
5749            j2 = j1 + m;
5750            j3 = j2 + m;
5751            idx0 = offa + j0;
5752            idx1 = offa + j1;
5753            idx2 = offa + j2;
5754            idx3 = offa + j3;
5755            x0r = a[idx0] + a[idx2];
5756            x0i = a[idx0 + 1] + a[idx2 + 1];
5757            x1r = a[idx0] - a[idx2];
5758            x1i = a[idx0 + 1] - a[idx2 + 1];
5759            x2r = a[idx1] + a[idx3];
5760            x2i = a[idx1 + 1] + a[idx3 + 1];
5761            x3r = a[idx1] - a[idx3];
5762            x3i = a[idx1 + 1] - a[idx3 + 1];
5763            a[idx0] = x0r + x2r;
5764            a[idx0 + 1] = x0i + x2i;
5765            a[idx1] = x0r - x2r;
5766            a[idx1 + 1] = x0i - x2i;
5767            x0r = x1r - x3i;
5768            x0i = x1i + x3r;
5769            a[idx2] = wk1i * x0r - wk1r * x0i;
5770            a[idx2 + 1] = wk1i * x0i + wk1r * x0r;
5771            x0r = x1r + x3i;
5772            x0i = x1i - x3r;
5773            a[idx3] = wk3i * x0r + wk3r * x0i;
5774            a[idx3 + 1] = wk3i * x0i - wk3r * x0r;
5775        }
5776        j0 = mh;
5777        j1 = j0 + m;
5778        j2 = j1 + m;
5779        j3 = j2 + m;
5780        idx0 = offa + j0;
5781        idx1 = offa + j1;
5782        idx2 = offa + j2;
5783        idx3 = offa + j3;
5784        x0r = a[idx0] + a[idx2];
5785        x0i = a[idx0 + 1] + a[idx2 + 1];
5786        x1r = a[idx0] - a[idx2];
5787        x1i = a[idx0 + 1] - a[idx2 + 1];
5788        x2r = a[idx1] + a[idx3];
5789        x2i = a[idx1 + 1] + a[idx3 + 1];
5790        x3r = a[idx1] - a[idx3];
5791        x3i = a[idx1 + 1] - a[idx3 + 1];
5792        a[idx0] = x0r + x2r;
5793        a[idx0 + 1] = x0i + x2i;
5794        a[idx1] = x0r - x2r;
5795        a[idx1 + 1] = x0i - x2i;
5796        x0r = x1r - x3i;
5797        x0i = x1i + x3r;
5798        a[idx2] = wn4r * (x0r - x0i);
5799        a[idx2 + 1] = wn4r * (x0i + x0r);
5800        x0r = x1r + x3i;
5801        x0i = x1i - x3r;
5802        a[idx3] = -wn4r * (x0r + x0i);
5803        a[idx3 + 1] = -wn4r * (x0i - x0r);
5804    }
5805
5806    private void cftmdl2(int n, double[] a, int offa, double[] w, int startw) {
5807        int j0, j1, j2, j3, k, kr, m, mh;
5808        double wn4r, wk1r, wk1i, wk3r, wk3i, wd1r, wd1i, wd3r, wd3i;
5809        double x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i, y0r, y0i, y2r, y2i;
5810        int idx0, idx1, idx2, idx3, idx4, idx5, idx6;
5811
5812        mh = n >> 3;
5813        m = 2 * mh;
5814        wn4r = w[startw + 1];
5815        j1 = m;
5816        j2 = j1 + m;
5817        j3 = j2 + m;
5818        idx1 = offa + j1;
5819        idx2 = offa + j2;
5820        idx3 = offa + j3;
5821        x0r = a[offa] - a[idx2 + 1];
5822        x0i = a[offa + 1] + a[idx2];
5823        x1r = a[offa] + a[idx2 + 1];
5824        x1i = a[offa + 1] - a[idx2];
5825        x2r = a[idx1] - a[idx3 + 1];
5826        x2i = a[idx1 + 1] + a[idx3];
5827        x3r = a[idx1] + a[idx3 + 1];
5828        x3i = a[idx1 + 1] - a[idx3];
5829        y0r = wn4r * (x2r - x2i);
5830        y0i = wn4r * (x2i + x2r);
5831        a[offa] = x0r + y0r;
5832        a[offa + 1] = x0i + y0i;
5833        a[idx1] = x0r - y0r;
5834        a[idx1 + 1] = x0i - y0i;
5835        y0r = wn4r * (x3r - x3i);
5836        y0i = wn4r * (x3i + x3r);
5837        a[idx2] = x1r - y0i;
5838        a[idx2 + 1] = x1i + y0r;
5839        a[idx3] = x1r + y0i;
5840        a[idx3 + 1] = x1i - y0r;
5841        k = 0;
5842        kr = 2 * m;
5843        for (int j = 2; j < mh; j += 2) {
5844            k += 4;
5845            idx4 = startw + k;
5846            wk1r = w[idx4];
5847            wk1i = w[idx4 + 1];
5848            wk3r = w[idx4 + 2];
5849            wk3i = w[idx4 + 3];
5850            kr -= 4;
5851            idx5 = startw + kr;
5852            wd1i = w[idx5];
5853            wd1r = w[idx5 + 1];
5854            wd3i = w[idx5 + 2];
5855            wd3r = w[idx5 + 3];
5856            j1 = j + m;
5857            j2 = j1 + m;
5858            j3 = j2 + m;
5859            idx1 = offa + j1;
5860            idx2 = offa + j2;
5861            idx3 = offa + j3;
5862            idx6 = offa + j;
5863            x0r = a[idx6] - a[idx2 + 1];
5864            x0i = a[idx6 + 1] + a[idx2];
5865            x1r = a[idx6] + a[idx2 + 1];
5866            x1i = a[idx6 + 1] - a[idx2];
5867            x2r = a[idx1] - a[idx3 + 1];
5868            x2i = a[idx1 + 1] + a[idx3];
5869            x3r = a[idx1] + a[idx3 + 1];
5870            x3i = a[idx1 + 1] - a[idx3];
5871            y0r = wk1r * x0r - wk1i * x0i;
5872            y0i = wk1r * x0i + wk1i * x0r;
5873            y2r = wd1r * x2r - wd1i * x2i;
5874            y2i = wd1r * x2i + wd1i * x2r;
5875            a[idx6] = y0r + y2r;
5876            a[idx6 + 1] = y0i + y2i;
5877            a[idx1] = y0r - y2r;
5878            a[idx1 + 1] = y0i - y2i;
5879            y0r = wk3r * x1r + wk3i * x1i;
5880            y0i = wk3r * x1i - wk3i * x1r;
5881            y2r = wd3r * x3r + wd3i * x3i;
5882            y2i = wd3r * x3i - wd3i * x3r;
5883            a[idx2] = y0r + y2r;
5884            a[idx2 + 1] = y0i + y2i;
5885            a[idx3] = y0r - y2r;
5886            a[idx3 + 1] = y0i - y2i;
5887            j0 = m - j;
5888            j1 = j0 + m;
5889            j2 = j1 + m;
5890            j3 = j2 + m;
5891            idx0 = offa + j0;
5892            idx1 = offa + j1;
5893            idx2 = offa + j2;
5894            idx3 = offa + j3;
5895            x0r = a[idx0] - a[idx2 + 1];
5896            x0i = a[idx0 + 1] + a[idx2];
5897            x1r = a[idx0] + a[idx2 + 1];
5898            x1i = a[idx0 + 1] - a[idx2];
5899            x2r = a[idx1] - a[idx3 + 1];
5900            x2i = a[idx1 + 1] + a[idx3];
5901            x3r = a[idx1] + a[idx3 + 1];
5902            x3i = a[idx1 + 1] - a[idx3];
5903            y0r = wd1i * x0r - wd1r * x0i;
5904            y0i = wd1i * x0i + wd1r * x0r;
5905            y2r = wk1i * x2r - wk1r * x2i;
5906            y2i = wk1i * x2i + wk1r * x2r;
5907            a[idx0] = y0r + y2r;
5908            a[idx0 + 1] = y0i + y2i;
5909            a[idx1] = y0r - y2r;
5910            a[idx1 + 1] = y0i - y2i;
5911            y0r = wd3i * x1r + wd3r * x1i;
5912            y0i = wd3i * x1i - wd3r * x1r;
5913            y2r = wk3i * x3r + wk3r * x3i;
5914            y2i = wk3i * x3i - wk3r * x3r;
5915            a[idx2] = y0r + y2r;
5916            a[idx2 + 1] = y0i + y2i;
5917            a[idx3] = y0r - y2r;
5918            a[idx3 + 1] = y0i - y2i;
5919        }
5920        wk1r = w[startw + m];
5921        wk1i = w[startw + m + 1];
5922        j0 = mh;
5923        j1 = j0 + m;
5924        j2 = j1 + m;
5925        j3 = j2 + m;
5926        idx0 = offa + j0;
5927        idx1 = offa + j1;
5928        idx2 = offa + j2;
5929        idx3 = offa + j3;
5930        x0r = a[idx0] - a[idx2 + 1];
5931        x0i = a[idx0 + 1] + a[idx2];
5932        x1r = a[idx0] + a[idx2 + 1];
5933        x1i = a[idx0 + 1] - a[idx2];
5934        x2r = a[idx1] - a[idx3 + 1];
5935        x2i = a[idx1 + 1] + a[idx3];
5936        x3r = a[idx1] + a[idx3 + 1];
5937        x3i = a[idx1 + 1] - a[idx3];
5938        y0r = wk1r * x0r - wk1i * x0i;
5939        y0i = wk1r * x0i + wk1i * x0r;
5940        y2r = wk1i * x2r - wk1r * x2i;
5941        y2i = wk1i * x2i + wk1r * x2r;
5942        a[idx0] = y0r + y2r;
5943        a[idx0 + 1] = y0i + y2i;
5944        a[idx1] = y0r - y2r;
5945        a[idx1 + 1] = y0i - y2i;
5946        y0r = wk1i * x1r - wk1r * x1i;
5947        y0i = wk1i * x1i + wk1r * x1r;
5948        y2r = wk1r * x3r - wk1i * x3i;
5949        y2i = wk1r * x3i + wk1i * x3r;
5950        a[idx2] = y0r - y2r;
5951        a[idx2 + 1] = y0i - y2i;
5952        a[idx3] = y0r + y2r;
5953        a[idx3 + 1] = y0i + y2i;
5954    }
5955
5956    private void cftfx41(int n, double[] a, int offa, int nw, double[] w) {
5957        if (n == 128) {
5958            cftf161(a, offa, w, nw - 8);
5959            cftf162(a, offa + 32, w, nw - 32);
5960            cftf161(a, offa + 64, w, nw - 8);
5961            cftf161(a, offa + 96, w, nw - 8);
5962        } else {
5963            cftf081(a, offa, w, nw - 8);
5964            cftf082(a, offa + 16, w, nw - 8);
5965            cftf081(a, offa + 32, w, nw - 8);
5966            cftf081(a, offa + 48, w, nw - 8);
5967        }
5968    }
5969
5970    private void cftf161(double[] a, int offa, double[] w, int startw) {
5971        double wn4r, wk1r, wk1i, x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i, y0r, y0i, y1r, y1i, y2r, y2i, y3r, y3i, y4r, y4i, y5r, y5i, y6r, y6i, y7r, y7i, y8r, y8i, y9r, y9i, y10r, y10i, y11r, y11i, y12r, y12i, y13r, y13i, y14r, y14i, y15r, y15i;
5972
5973        wn4r = w[startw + 1];
5974        wk1r = w[startw + 2];
5975        wk1i = w[startw + 3];
5976
5977        x0r = a[offa] + a[offa + 16];
5978        x0i = a[offa + 1] + a[offa + 17];
5979        x1r = a[offa] - a[offa + 16];
5980        x1i = a[offa + 1] - a[offa + 17];
5981        x2r = a[offa + 8] + a[offa + 24];
5982        x2i = a[offa + 9] + a[offa + 25];
5983        x3r = a[offa + 8] - a[offa + 24];
5984        x3i = a[offa + 9] - a[offa + 25];
5985        y0r = x0r + x2r;
5986        y0i = x0i + x2i;
5987        y4r = x0r - x2r;
5988        y4i = x0i - x2i;
5989        y8r = x1r - x3i;
5990        y8i = x1i + x3r;
5991        y12r = x1r + x3i;
5992        y12i = x1i - x3r;
5993        x0r = a[offa + 2] + a[offa + 18];
5994        x0i = a[offa + 3] + a[offa + 19];
5995        x1r = a[offa + 2] - a[offa + 18];
5996        x1i = a[offa + 3] - a[offa + 19];
5997        x2r = a[offa + 10] + a[offa + 26];
5998        x2i = a[offa + 11] + a[offa + 27];
5999        x3r = a[offa + 10] - a[offa + 26];
6000        x3i = a[offa + 11] - a[offa + 27];
6001        y1r = x0r + x2r;
6002        y1i = x0i + x2i;
6003        y5r = x0r - x2r;
6004        y5i = x0i - x2i;
6005        x0r = x1r - x3i;
6006        x0i = x1i + x3r;
6007        y9r = wk1r * x0r - wk1i * x0i;
6008        y9i = wk1r * x0i + wk1i * x0r;
6009        x0r = x1r + x3i;
6010        x0i = x1i - x3r;
6011        y13r = wk1i * x0r - wk1r * x0i;
6012        y13i = wk1i * x0i + wk1r * x0r;
6013        x0r = a[offa + 4] + a[offa + 20];
6014        x0i = a[offa + 5] + a[offa + 21];
6015        x1r = a[offa + 4] - a[offa + 20];
6016        x1i = a[offa + 5] - a[offa + 21];
6017        x2r = a[offa + 12] + a[offa + 28];
6018        x2i = a[offa + 13] + a[offa + 29];
6019        x3r = a[offa + 12] - a[offa + 28];
6020        x3i = a[offa + 13] - a[offa + 29];
6021        y2r = x0r + x2r;
6022        y2i = x0i + x2i;
6023        y6r = x0r - x2r;
6024        y6i = x0i - x2i;
6025        x0r = x1r - x3i;
6026        x0i = x1i + x3r;
6027        y10r = wn4r * (x0r - x0i);
6028        y10i = wn4r * (x0i + x0r);
6029        x0r = x1r + x3i;
6030        x0i = x1i - x3r;
6031        y14r = wn4r * (x0r + x0i);
6032        y14i = wn4r * (x0i - x0r);
6033        x0r = a[offa + 6] + a[offa + 22];
6034        x0i = a[offa + 7] + a[offa + 23];
6035        x1r = a[offa + 6] - a[offa + 22];
6036        x1i = a[offa + 7] - a[offa + 23];
6037        x2r = a[offa + 14] + a[offa + 30];
6038        x2i = a[offa + 15] + a[offa + 31];
6039        x3r = a[offa + 14] - a[offa + 30];
6040        x3i = a[offa + 15] - a[offa + 31];
6041        y3r = x0r + x2r;
6042        y3i = x0i + x2i;
6043        y7r = x0r - x2r;
6044        y7i = x0i - x2i;
6045        x0r = x1r - x3i;
6046        x0i = x1i + x3r;
6047        y11r = wk1i * x0r - wk1r * x0i;
6048        y11i = wk1i * x0i + wk1r * x0r;
6049        x0r = x1r + x3i;
6050        x0i = x1i - x3r;
6051        y15r = wk1r * x0r - wk1i * x0i;
6052        y15i = wk1r * x0i + wk1i * x0r;
6053        x0r = y12r - y14r;
6054        x0i = y12i - y14i;
6055        x1r = y12r + y14r;
6056        x1i = y12i + y14i;
6057        x2r = y13r - y15r;
6058        x2i = y13i - y15i;
6059        x3r = y13r + y15r;
6060        x3i = y13i + y15i;
6061        a[offa + 24] = x0r + x2r;
6062        a[offa + 25] = x0i + x2i;
6063        a[offa + 26] = x0r - x2r;
6064        a[offa + 27] = x0i - x2i;
6065        a[offa + 28] = x1r - x3i;
6066        a[offa + 29] = x1i + x3r;
6067        a[offa + 30] = x1r + x3i;
6068        a[offa + 31] = x1i - x3r;
6069        x0r = y8r + y10r;
6070        x0i = y8i + y10i;
6071        x1r = y8r - y10r;
6072        x1i = y8i - y10i;
6073        x2r = y9r + y11r;
6074        x2i = y9i + y11i;
6075        x3r = y9r - y11r;
6076        x3i = y9i - y11i;
6077        a[offa + 16] = x0r + x2r;
6078        a[offa + 17] = x0i + x2i;
6079        a[offa + 18] = x0r - x2r;
6080        a[offa + 19] = x0i - x2i;
6081        a[offa + 20] = x1r - x3i;
6082        a[offa + 21] = x1i + x3r;
6083        a[offa + 22] = x1r + x3i;
6084        a[offa + 23] = x1i - x3r;
6085        x0r = y5r - y7i;
6086        x0i = y5i + y7r;
6087        x2r = wn4r * (x0r - x0i);
6088        x2i = wn4r * (x0i + x0r);
6089        x0r = y5r + y7i;
6090        x0i = y5i - y7r;
6091        x3r = wn4r * (x0r - x0i);
6092        x3i = wn4r * (x0i + x0r);
6093        x0r = y4r - y6i;
6094        x0i = y4i + y6r;
6095        x1r = y4r + y6i;
6096        x1i = y4i - y6r;
6097        a[offa + 8] = x0r + x2r;
6098        a[offa + 9] = x0i + x2i;
6099        a[offa + 10] = x0r - x2r;
6100        a[offa + 11] = x0i - x2i;
6101        a[offa + 12] = x1r - x3i;
6102        a[offa + 13] = x1i + x3r;
6103        a[offa + 14] = x1r + x3i;
6104        a[offa + 15] = x1i - x3r;
6105        x0r = y0r + y2r;
6106        x0i = y0i + y2i;
6107        x1r = y0r - y2r;
6108        x1i = y0i - y2i;
6109        x2r = y1r + y3r;
6110        x2i = y1i + y3i;
6111        x3r = y1r - y3r;
6112        x3i = y1i - y3i;
6113        a[offa] = x0r + x2r;
6114        a[offa + 1] = x0i + x2i;
6115        a[offa + 2] = x0r - x2r;
6116        a[offa + 3] = x0i - x2i;
6117        a[offa + 4] = x1r - x3i;
6118        a[offa + 5] = x1i + x3r;
6119        a[offa + 6] = x1r + x3i;
6120        a[offa + 7] = x1i - x3r;
6121    }
6122
6123    private void cftf162(double[] a, int offa, double[] w, int startw) {
6124        double wn4r, wk1r, wk1i, wk2r, wk2i, wk3r, wk3i, x0r, x0i, x1r, x1i, x2r, x2i, y0r, y0i, y1r, y1i, y2r, y2i, y3r, y3i, y4r, y4i, y5r, y5i, y6r, y6i, y7r, y7i, y8r, y8i, y9r, y9i, y10r, y10i, y11r, y11i, y12r, y12i, y13r, y13i, y14r, y14i, y15r, y15i;
6125
6126        wn4r = w[startw + 1];
6127        wk1r = w[startw + 4];
6128        wk1i = w[startw + 5];
6129        wk3r = w[startw + 6];
6130        wk3i = -w[startw + 7];
6131        wk2r = w[startw + 8];
6132        wk2i = w[startw + 9];
6133        x1r = a[offa] - a[offa + 17];
6134        x1i = a[offa + 1] + a[offa + 16];
6135        x0r = a[offa + 8] - a[offa + 25];
6136        x0i = a[offa + 9] + a[offa + 24];
6137        x2r = wn4r * (x0r - x0i);
6138        x2i = wn4r * (x0i + x0r);
6139        y0r = x1r + x2r;
6140        y0i = x1i + x2i;
6141        y4r = x1r - x2r;
6142        y4i = x1i - x2i;
6143        x1r = a[offa] + a[offa + 17];
6144        x1i = a[offa + 1] - a[offa + 16];
6145        x0r = a[offa + 8] + a[offa + 25];
6146        x0i = a[offa + 9] - a[offa + 24];
6147        x2r = wn4r * (x0r - x0i);
6148        x2i = wn4r * (x0i + x0r);
6149        y8r = x1r - x2i;
6150        y8i = x1i + x2r;
6151        y12r = x1r + x2i;
6152        y12i = x1i - x2r;
6153        x0r = a[offa + 2] - a[offa + 19];
6154        x0i = a[offa + 3] + a[offa + 18];
6155        x1r = wk1r * x0r - wk1i * x0i;
6156        x1i = wk1r * x0i + wk1i * x0r;
6157        x0r = a[offa + 10] - a[offa + 27];
6158        x0i = a[offa + 11] + a[offa + 26];
6159        x2r = wk3i * x0r - wk3r * x0i;
6160        x2i = wk3i * x0i + wk3r * x0r;
6161        y1r = x1r + x2r;
6162        y1i = x1i + x2i;
6163        y5r = x1r - x2r;
6164        y5i = x1i - x2i;
6165        x0r = a[offa + 2] + a[offa + 19];
6166        x0i = a[offa + 3] - a[offa + 18];
6167        x1r = wk3r * x0r - wk3i * x0i;
6168        x1i = wk3r * x0i + wk3i * x0r;
6169        x0r = a[offa + 10] + a[offa + 27];
6170        x0i = a[offa + 11] - a[offa + 26];
6171        x2r = wk1r * x0r + wk1i * x0i;
6172        x2i = wk1r * x0i - wk1i * x0r;
6173        y9r = x1r - x2r;
6174        y9i = x1i - x2i;
6175        y13r = x1r + x2r;
6176        y13i = x1i + x2i;
6177        x0r = a[offa + 4] - a[offa + 21];
6178        x0i = a[offa + 5] + a[offa + 20];
6179        x1r = wk2r * x0r - wk2i * x0i;
6180        x1i = wk2r * x0i + wk2i * x0r;
6181        x0r = a[offa + 12] - a[offa + 29];
6182        x0i = a[offa + 13] + a[offa + 28];
6183        x2r = wk2i * x0r - wk2r * x0i;
6184        x2i = wk2i * x0i + wk2r * x0r;
6185        y2r = x1r + x2r;
6186        y2i = x1i + x2i;
6187        y6r = x1r - x2r;
6188        y6i = x1i - x2i;
6189        x0r = a[offa + 4] + a[offa + 21];
6190        x0i = a[offa + 5] - a[offa + 20];
6191        x1r = wk2i * x0r - wk2r * x0i;
6192        x1i = wk2i * x0i + wk2r * x0r;
6193        x0r = a[offa + 12] + a[offa + 29];
6194        x0i = a[offa + 13] - a[offa + 28];
6195        x2r = wk2r * x0r - wk2i * x0i;
6196        x2i = wk2r * x0i + wk2i * x0r;
6197        y10r = x1r - x2r;
6198        y10i = x1i - x2i;
6199        y14r = x1r + x2r;
6200        y14i = x1i + x2i;
6201        x0r = a[offa + 6] - a[offa + 23];
6202        x0i = a[offa + 7] + a[offa + 22];
6203        x1r = wk3r * x0r - wk3i * x0i;
6204        x1i = wk3r * x0i + wk3i * x0r;
6205        x0r = a[offa + 14] - a[offa + 31];
6206        x0i = a[offa + 15] + a[offa + 30];
6207        x2r = wk1i * x0r - wk1r * x0i;
6208        x2i = wk1i * x0i + wk1r * x0r;
6209        y3r = x1r + x2r;
6210        y3i = x1i + x2i;
6211        y7r = x1r - x2r;
6212        y7i = x1i - x2i;
6213        x0r = a[offa + 6] + a[offa + 23];
6214        x0i = a[offa + 7] - a[offa + 22];
6215        x1r = wk1i * x0r + wk1r * x0i;
6216        x1i = wk1i * x0i - wk1r * x0r;
6217        x0r = a[offa + 14] + a[offa + 31];
6218        x0i = a[offa + 15] - a[offa + 30];
6219        x2r = wk3i * x0r - wk3r * x0i;
6220        x2i = wk3i * x0i + wk3r * x0r;
6221        y11r = x1r + x2r;
6222        y11i = x1i + x2i;
6223        y15r = x1r - x2r;
6224        y15i = x1i - x2i;
6225        x1r = y0r + y2r;
6226        x1i = y0i + y2i;
6227        x2r = y1r + y3r;
6228        x2i = y1i + y3i;
6229        a[offa] = x1r + x2r;
6230        a[offa + 1] = x1i + x2i;
6231        a[offa + 2] = x1r - x2r;
6232        a[offa + 3] = x1i - x2i;
6233        x1r = y0r - y2r;
6234        x1i = y0i - y2i;
6235        x2r = y1r - y3r;
6236        x2i = y1i - y3i;
6237        a[offa + 4] = x1r - x2i;
6238        a[offa + 5] = x1i + x2r;
6239        a[offa + 6] = x1r + x2i;
6240        a[offa + 7] = x1i - x2r;
6241        x1r = y4r - y6i;
6242        x1i = y4i + y6r;
6243        x0r = y5r - y7i;
6244        x0i = y5i + y7r;
6245        x2r = wn4r * (x0r - x0i);
6246        x2i = wn4r * (x0i + x0r);
6247        a[offa + 8] = x1r + x2r;
6248        a[offa + 9] = x1i + x2i;
6249        a[offa + 10] = x1r - x2r;
6250        a[offa + 11] = x1i - x2i;
6251        x1r = y4r + y6i;
6252        x1i = y4i - y6r;
6253        x0r = y5r + y7i;
6254        x0i = y5i - y7r;
6255        x2r = wn4r * (x0r - x0i);
6256        x2i = wn4r * (x0i + x0r);
6257        a[offa + 12] = x1r - x2i;
6258        a[offa + 13] = x1i + x2r;
6259        a[offa + 14] = x1r + x2i;
6260        a[offa + 15] = x1i - x2r;
6261        x1r = y8r + y10r;
6262        x1i = y8i + y10i;
6263        x2r = y9r - y11r;
6264        x2i = y9i - y11i;
6265        a[offa + 16] = x1r + x2r;
6266        a[offa + 17] = x1i + x2i;
6267        a[offa + 18] = x1r - x2r;
6268        a[offa + 19] = x1i - x2i;
6269        x1r = y8r - y10r;
6270        x1i = y8i - y10i;
6271        x2r = y9r + y11r;
6272        x2i = y9i + y11i;
6273        a[offa + 20] = x1r - x2i;
6274        a[offa + 21] = x1i + x2r;
6275        a[offa + 22] = x1r + x2i;
6276        a[offa + 23] = x1i - x2r;
6277        x1r = y12r - y14i;
6278        x1i = y12i + y14r;
6279        x0r = y13r + y15i;
6280        x0i = y13i - y15r;
6281        x2r = wn4r * (x0r - x0i);
6282        x2i = wn4r * (x0i + x0r);
6283        a[offa + 24] = x1r + x2r;
6284        a[offa + 25] = x1i + x2i;
6285        a[offa + 26] = x1r - x2r;
6286        a[offa + 27] = x1i - x2i;
6287        x1r = y12r + y14i;
6288        x1i = y12i - y14r;
6289        x0r = y13r - y15i;
6290        x0i = y13i + y15r;
6291        x2r = wn4r * (x0r - x0i);
6292        x2i = wn4r * (x0i + x0r);
6293        a[offa + 28] = x1r - x2i;
6294        a[offa + 29] = x1i + x2r;
6295        a[offa + 30] = x1r + x2i;
6296        a[offa + 31] = x1i - x2r;
6297    }
6298
6299    private void cftf081(double[] a, int offa, double[] w, int startw) {
6300        double wn4r, x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i, y0r, y0i, y1r, y1i, y2r, y2i, y3r, y3i, y4r, y4i, y5r, y5i, y6r, y6i, y7r, y7i;
6301
6302        wn4r = w[startw + 1];
6303        x0r = a[offa] + a[offa + 8];
6304        x0i = a[offa + 1] + a[offa + 9];
6305        x1r = a[offa] - a[offa + 8];
6306        x1i = a[offa + 1] - a[offa + 9];
6307        x2r = a[offa + 4] + a[offa + 12];
6308        x2i = a[offa + 5] + a[offa + 13];
6309        x3r = a[offa + 4] - a[offa + 12];
6310        x3i = a[offa + 5] - a[offa + 13];
6311        y0r = x0r + x2r;
6312        y0i = x0i + x2i;
6313        y2r = x0r - x2r;
6314        y2i = x0i - x2i;
6315        y1r = x1r - x3i;
6316        y1i = x1i + x3r;
6317        y3r = x1r + x3i;
6318        y3i = x1i - x3r;
6319        x0r = a[offa + 2] + a[offa + 10];
6320        x0i = a[offa + 3] + a[offa + 11];
6321        x1r = a[offa + 2] - a[offa + 10];
6322        x1i = a[offa + 3] - a[offa + 11];
6323        x2r = a[offa + 6] + a[offa + 14];
6324        x2i = a[offa + 7] + a[offa + 15];
6325        x3r = a[offa + 6] - a[offa + 14];
6326        x3i = a[offa + 7] - a[offa + 15];
6327        y4r = x0r + x2r;
6328        y4i = x0i + x2i;
6329        y6r = x0r - x2r;
6330        y6i = x0i - x2i;
6331        x0r = x1r - x3i;
6332        x0i = x1i + x3r;
6333        x2r = x1r + x3i;
6334        x2i = x1i - x3r;
6335        y5r = wn4r * (x0r - x0i);
6336        y5i = wn4r * (x0r + x0i);
6337        y7r = wn4r * (x2r - x2i);
6338        y7i = wn4r * (x2r + x2i);
6339        a[offa + 8] = y1r + y5r;
6340        a[offa + 9] = y1i + y5i;
6341        a[offa + 10] = y1r - y5r;
6342        a[offa + 11] = y1i - y5i;
6343        a[offa + 12] = y3r - y7i;
6344        a[offa + 13] = y3i + y7r;
6345        a[offa + 14] = y3r + y7i;
6346        a[offa + 15] = y3i - y7r;
6347        a[offa] = y0r + y4r;
6348        a[offa + 1] = y0i + y4i;
6349        a[offa + 2] = y0r - y4r;
6350        a[offa + 3] = y0i - y4i;
6351        a[offa + 4] = y2r - y6i;
6352        a[offa + 5] = y2i + y6r;
6353        a[offa + 6] = y2r + y6i;
6354        a[offa + 7] = y2i - y6r;
6355    }
6356
6357    private void cftf082(double[] a, int offa, double[] w, int startw) {
6358        double wn4r, wk1r, wk1i, x0r, x0i, x1r, x1i, y0r, y0i, y1r, y1i, y2r, y2i, y3r, y3i, y4r, y4i, y5r, y5i, y6r, y6i, y7r, y7i;
6359
6360        wn4r = w[startw + 1];
6361        wk1r = w[startw + 2];
6362        wk1i = w[startw + 3];
6363        y0r = a[offa] - a[offa + 9];
6364        y0i = a[offa + 1] + a[offa + 8];
6365        y1r = a[offa] + a[offa + 9];
6366        y1i = a[offa + 1] - a[offa + 8];
6367        x0r = a[offa + 4] - a[offa + 13];
6368        x0i = a[offa + 5] + a[offa + 12];
6369        y2r = wn4r * (x0r - x0i);
6370        y2i = wn4r * (x0i + x0r);
6371        x0r = a[offa + 4] + a[offa + 13];
6372        x0i = a[offa + 5] - a[offa + 12];
6373        y3r = wn4r * (x0r - x0i);
6374        y3i = wn4r * (x0i + x0r);
6375        x0r = a[offa + 2] - a[offa + 11];
6376        x0i = a[offa + 3] + a[offa + 10];
6377        y4r = wk1r * x0r - wk1i * x0i;
6378        y4i = wk1r * x0i + wk1i * x0r;
6379        x0r = a[offa + 2] + a[offa + 11];
6380        x0i = a[offa + 3] - a[offa + 10];
6381        y5r = wk1i * x0r - wk1r * x0i;
6382        y5i = wk1i * x0i + wk1r * x0r;
6383        x0r = a[offa + 6] - a[offa + 15];
6384        x0i = a[offa + 7] + a[offa + 14];
6385        y6r = wk1i * x0r - wk1r * x0i;
6386        y6i = wk1i * x0i + wk1r * x0r;
6387        x0r = a[offa + 6] + a[offa + 15];
6388        x0i = a[offa + 7] - a[offa + 14];
6389        y7r = wk1r * x0r - wk1i * x0i;
6390        y7i = wk1r * x0i + wk1i * x0r;
6391        x0r = y0r + y2r;
6392        x0i = y0i + y2i;
6393        x1r = y4r + y6r;
6394        x1i = y4i + y6i;
6395        a[offa] = x0r + x1r;
6396        a[offa + 1] = x0i + x1i;
6397        a[offa + 2] = x0r - x1r;
6398        a[offa + 3] = x0i - x1i;
6399        x0r = y0r - y2r;
6400        x0i = y0i - y2i;
6401        x1r = y4r - y6r;
6402        x1i = y4i - y6i;
6403        a[offa + 4] = x0r - x1i;
6404        a[offa + 5] = x0i + x1r;
6405        a[offa + 6] = x0r + x1i;
6406        a[offa + 7] = x0i - x1r;
6407        x0r = y1r - y3i;
6408        x0i = y1i + y3r;
6409        x1r = y5r - y7r;
6410        x1i = y5i - y7i;
6411        a[offa + 8] = x0r + x1r;
6412        a[offa + 9] = x0i + x1i;
6413        a[offa + 10] = x0r - x1r;
6414        a[offa + 11] = x0i - x1i;
6415        x0r = y1r + y3i;
6416        x0i = y1i - y3r;
6417        x1r = y5r + y7r;
6418        x1i = y5i + y7i;
6419        a[offa + 12] = x0r - x1i;
6420        a[offa + 13] = x0i + x1r;
6421        a[offa + 14] = x0r + x1i;
6422        a[offa + 15] = x0i - x1r;
6423    }
6424
6425    private void cftf040(double[] a, int offa) {
6426        double x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i;
6427
6428        x0r = a[offa] + a[offa + 4];
6429        x0i = a[offa + 1] + a[offa + 5];
6430        x1r = a[offa] - a[offa + 4];
6431        x1i = a[offa + 1] - a[offa + 5];
6432        x2r = a[offa + 2] + a[offa + 6];
6433        x2i = a[offa + 3] + a[offa + 7];
6434        x3r = a[offa + 2] - a[offa + 6];
6435        x3i = a[offa + 3] - a[offa + 7];
6436        a[offa] = x0r + x2r;
6437        a[offa + 1] = x0i + x2i;
6438        a[offa + 2] = x1r - x3i;
6439        a[offa + 3] = x1i + x3r;
6440        a[offa + 4] = x0r - x2r;
6441        a[offa + 5] = x0i - x2i;
6442        a[offa + 6] = x1r + x3i;
6443        a[offa + 7] = x1i - x3r;
6444    }
6445
6446    private void cftb040(double[] a, int offa) {
6447        double x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i;
6448
6449        x0r = a[offa] + a[offa + 4];
6450        x0i = a[offa + 1] + a[offa + 5];
6451        x1r = a[offa] - a[offa + 4];
6452        x1i = a[offa + 1] - a[offa + 5];
6453        x2r = a[offa + 2] + a[offa + 6];
6454        x2i = a[offa + 3] + a[offa + 7];
6455        x3r = a[offa + 2] - a[offa + 6];
6456        x3i = a[offa + 3] - a[offa + 7];
6457        a[offa] = x0r + x2r;
6458        a[offa + 1] = x0i + x2i;
6459        a[offa + 2] = x1r + x3i;
6460        a[offa + 3] = x1i - x3r;
6461        a[offa + 4] = x0r - x2r;
6462        a[offa + 5] = x0i - x2i;
6463        a[offa + 6] = x1r - x3i;
6464        a[offa + 7] = x1i + x3r;
6465    }
6466
6467    private void cftx020(double[] a, int offa) {
6468        double x0r, x0i;
6469        x0r = a[offa] - a[offa + 2];
6470        x0i = -a[offa + 1] + a[offa + 3];
6471        a[offa] += a[offa + 2];
6472        a[offa + 1] += a[offa + 3];
6473        a[offa + 2] = x0r;
6474        a[offa + 3] = x0i;
6475    }
6476
6477    private void cftxb020(double[] a, int offa) {
6478        double x0r, x0i;
6479
6480        x0r = a[offa] - a[offa + 2];
6481        x0i = a[offa + 1] - a[offa + 3];
6482        a[offa] += a[offa + 2];
6483        a[offa + 1] += a[offa + 3];
6484        a[offa + 2] = x0r;
6485        a[offa + 3] = x0i;
6486    }
6487
6488    private void cftxc020(double[] a, int offa) {
6489        double x0r, x0i;
6490        x0r = a[offa] - a[offa + 2];
6491        x0i = a[offa + 1] + a[offa + 3];
6492        a[offa] += a[offa + 2];
6493        a[offa + 1] -= a[offa + 3];
6494        a[offa + 2] = x0r;
6495        a[offa + 3] = x0i;
6496    }
6497
6498    private void rftfsub(int n, double[] a, int offa, int nc, double[] c, int startc) {
6499        int k, kk, ks, m;
6500        double wkr, wki, xr, xi, yr, yi;
6501        int idx1, idx2;
6502
6503        m = n >> 1;
6504        ks = 2 * nc / m;
6505        kk = 0;
6506        for (int j = 2; j < m; j += 2) {
6507            k = n - j;
6508            kk += ks;
6509            wkr = 0.5 - c[startc + nc - kk];
6510            wki = c[startc + kk];
6511            idx1 = offa + j;
6512            idx2 = offa + k;
6513            xr = a[idx1] - a[idx2];
6514            xi = a[idx1 + 1] + a[idx2 + 1];
6515            yr = wkr * xr - wki * xi;
6516            yi = wkr * xi + wki * xr;
6517            a[idx1] -= yr;
6518            a[idx1 + 1] = yi - a[idx1 + 1];
6519            a[idx2] += yr;
6520            a[idx2 + 1] = yi - a[idx2 + 1];
6521        }
6522        a[offa + m + 1] = -a[offa + m + 1];
6523    }
6524
6525    private void rftbsub(int n, double[] a, int offa, int nc, double[] c, int startc) {
6526        int k, kk, ks, m;
6527        double wkr, wki, xr, xi, yr, yi;
6528        int idx1, idx2;
6529
6530        m = n >> 1;
6531        ks = 2 * nc / m;
6532        kk = 0;
6533        for (int j = 2; j < m; j += 2) {
6534            k = n - j;
6535            kk += ks;
6536            wkr = 0.5 - c[startc + nc - kk];
6537            wki = c[startc + kk];
6538            idx1 = offa + j;
6539            idx2 = offa + k;
6540            xr = a[idx1] - a[idx2];
6541            xi = a[idx1 + 1] + a[idx2 + 1];
6542            yr = wkr * xr - wki * xi;
6543            yi = wkr * xi + wki * xr;
6544            a[idx1] -= yr;
6545            a[idx1 + 1] -= yi;
6546            a[idx2] += yr;
6547            a[idx2 + 1] -= yi;
6548        }
6549    }
6550
6551    private void scale(final double m, final double[] a, int offa, boolean complex) {
6552        final double norm = (1.0 / m);
6553        int n2;
6554        if (complex) {
6555            n2 = 2 * n;
6556        } else {
6557            n2 = n;
6558        }
6559        int nthreads = ConcurrencyUtils.getNumberOfThreads();
6560        if ((nthreads > 1) && (n2 >= ConcurrencyUtils.getThreadsBeginN_1D_FFT_2Threads())) {
6561            final int k = n2 / nthreads;
6562            Future<?>[] futures = new Future[nthreads];
6563            for (int i = 0; i < nthreads; i++) {
6564                final int firstIdx = offa + i * k;
6565                final int lastIdx = (i == (nthreads - 1)) ? offa + n2 : firstIdx + k;
6566                futures[i] = ConcurrencyUtils.submit(new Runnable() {
6567
6568                    public void run() {
6569                        for (int i = firstIdx; i < lastIdx; i++) {
6570                            a[i] *= norm;
6571                        }
6572                    }
6573                });
6574            }
6575            ConcurrencyUtils.waitForCompletion(futures);
6576        } else {
6577            for (int i = offa; i < offa + n2; i++) {
6578                a[i] *= norm;
6579            }
6580
6581        }
6582    }
6583}