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