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<=k<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<=k<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<=k<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<=k<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<=k<n/2 264 * a[2*k+1] = Im[k], 0<k<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<=k<(n+1)/2 272 * a[2*k+1] = Im[k], 0<k<(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<=k<n/2 296 * a[offa+2*k+1] = Im[k], 0<k<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<=k<(n+1)/2 304 * a[offa+2*k+1] = Im[k], 0<k<(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<=k<n/2 456 * a[2*k+1] = Im[k], 0<k<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<=k<(n+1)/2 464 * a[2*k+1] = Im[k], 0<k<(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<=k<n/2 491 * a[offa+2*k+1] = Im[k], 0<k<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<=k<(n+1)/2 499 * a[offa+2*k+1] = Im[k], 0<k<(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}