1 /* 2 * Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 package com.sun.media.sound; 26 27 /** 28 * Fast Fourier Transformer. 29 * 30 * @author Karl Helgason 31 */ 32 public final class FFT { 33 34 private final double[] w; 35 private final int fftFrameSize; 36 private final int sign; 37 private final int[] bitm_array; 38 private final int fftFrameSize2; 39 40 // Sign = -1 is FFT, 1 is IFFT (inverse FFT) 41 // Data = Interlaced double array to be transformed. 42 // The order is: real (sin), complex (cos) 43 // Framesize must be power of 2 44 public FFT(int fftFrameSize, int sign) { 45 w = computeTwiddleFactors(fftFrameSize, sign); 46 47 this.fftFrameSize = fftFrameSize; 48 this.sign = sign; 49 fftFrameSize2 = fftFrameSize << 1; 50 51 // Pre-process Bit-Reversal 52 bitm_array = new int[fftFrameSize2]; 53 for (int i = 2; i < fftFrameSize2; i += 2) { 54 int j; 55 int bitm; 56 for (bitm = 2, j = 0; bitm < fftFrameSize2; bitm <<= 1) { 57 if ((i & bitm) != 0) 58 j++; 59 j <<= 1; 60 } 61 bitm_array[i] = j; 62 } 63 64 } 65 66 public void transform(double[] data) { 67 bitreversal(data); 68 calc(fftFrameSize, data, sign, w); 69 } 70 71 private final static double[] computeTwiddleFactors(int fftFrameSize, 72 int sign) { 73 74 int imax = (int) (Math.log(fftFrameSize) / Math.log(2.)); 75 76 double[] warray = new double[(fftFrameSize - 1) * 4]; 77 int w_index = 0; 78 79 for (int i = 0, nstep = 2; i < imax; i++) { 80 int jmax = nstep; 81 nstep <<= 1; 82 83 double wr = 1.0; 84 double wi = 0.0; 85 86 double arg = Math.PI / (jmax >> 1); 87 double wfr = Math.cos(arg); 88 double wfi = sign * Math.sin(arg); 89 90 for (int j = 0; j < jmax; j += 2) { 91 warray[w_index++] = wr; 92 warray[w_index++] = wi; 93 94 double tempr = wr; 95 wr = tempr * wfr - wi * wfi; 96 wi = tempr * wfi + wi * wfr; 97 } 98 } 99 100 // PRECOMPUTATION of wwr1, wwi1 for factor 4 Decomposition (3 * complex 101 // operators and 8 +/- complex operators) 102 { 103 w_index = 0; 104 int w_index2 = warray.length >> 1; 105 for (int i = 0, nstep = 2; i < (imax - 1); i++) { 106 int jmax = nstep; 107 nstep *= 2; 108 109 int ii = w_index + jmax; 110 for (int j = 0; j < jmax; j += 2) { 111 double wr = warray[w_index++]; 112 double wi = warray[w_index++]; 113 double wr1 = warray[ii++]; 114 double wi1 = warray[ii++]; 115 warray[w_index2++] = wr * wr1 - wi * wi1; 116 warray[w_index2++] = wr * wi1 + wi * wr1; 117 } 118 } 119 120 } 121 122 return warray; 123 } 124 125 private final static void calc(int fftFrameSize, double[] data, int sign, 126 double[] w) { 127 128 final int fftFrameSize2 = fftFrameSize << 1; 129 130 int nstep = 2; 131 132 if (nstep >= fftFrameSize2) 133 return; 134 int i = nstep - 2; 135 if (sign == -1) 136 calcF4F(fftFrameSize, data, i, nstep, w); 137 else 138 calcF4I(fftFrameSize, data, i, nstep, w); 139 140 } 141 142 private final static void calcF2E(int fftFrameSize, double[] data, int i, 143 int nstep, double[] w) { 144 int jmax = nstep; 145 for (int n = 0; n < jmax; n += 2) { 146 double wr = w[i++]; 147 double wi = w[i++]; 148 int m = n + jmax; 149 double datam_r = data[m]; 150 double datam_i = data[m + 1]; 151 double datan_r = data[n]; 152 double datan_i = data[n + 1]; 153 double tempr = datam_r * wr - datam_i * wi; 154 double tempi = datam_r * wi + datam_i * wr; 155 data[m] = datan_r - tempr; 156 data[m + 1] = datan_i - tempi; 157 data[n] = datan_r + tempr; 158 data[n + 1] = datan_i + tempi; 159 } 160 return; 161 162 } 163 164 // Perform Factor-4 Decomposition with 3 * complex operators and 8 +/- 165 // complex operators 166 private final static void calcF4F(int fftFrameSize, double[] data, int i, 167 int nstep, double[] w) { 168 final int fftFrameSize2 = fftFrameSize << 1; // 2*fftFrameSize; 169 // Factor-4 Decomposition 170 171 int w_len = w.length >> 1; 172 while (nstep < fftFrameSize2) { 173 174 if (nstep << 2 == fftFrameSize2) { 175 // Goto Factor-4 Final Decomposition 176 // calcF4E(data, i, nstep, -1, w); 177 calcF4FE(fftFrameSize, data, i, nstep, w); 178 return; 179 } 180 int jmax = nstep; 181 int nnstep = nstep << 1; 182 if (nnstep == fftFrameSize2) { 183 // Factor-4 Decomposition not possible 184 calcF2E(fftFrameSize, data, i, nstep, w); 185 return; 186 } 187 nstep <<= 2; 188 int ii = i + jmax; 189 int iii = i + w_len; 190 191 { 192 i += 2; 193 ii += 2; 194 iii += 2; 195 196 for (int n = 0; n < fftFrameSize2; n += nstep) { 197 int m = n + jmax; 198 199 double datam1_r = data[m]; 200 double datam1_i = data[m + 1]; 201 double datan1_r = data[n]; 202 double datan1_i = data[n + 1]; 203 204 n += nnstep; 205 m += nnstep; 206 double datam2_r = data[m]; 207 double datam2_i = data[m + 1]; 208 double datan2_r = data[n]; 209 double datan2_i = data[n + 1]; 210 211 double tempr = datam1_r; 212 double tempi = datam1_i; 213 214 datam1_r = datan1_r - tempr; 215 datam1_i = datan1_i - tempi; 216 datan1_r = datan1_r + tempr; 217 datan1_i = datan1_i + tempi; 218 219 double n2w1r = datan2_r; 220 double n2w1i = datan2_i; 221 double m2ww1r = datam2_r; 222 double m2ww1i = datam2_i; 223 224 tempr = m2ww1r - n2w1r; 225 tempi = m2ww1i - n2w1i; 226 227 datam2_r = datam1_r + tempi; 228 datam2_i = datam1_i - tempr; 229 datam1_r = datam1_r - tempi; 230 datam1_i = datam1_i + tempr; 231 232 tempr = n2w1r + m2ww1r; 233 tempi = n2w1i + m2ww1i; 234 235 datan2_r = datan1_r - tempr; 236 datan2_i = datan1_i - tempi; 237 datan1_r = datan1_r + tempr; 238 datan1_i = datan1_i + tempi; 239 240 data[m] = datam2_r; 241 data[m + 1] = datam2_i; 242 data[n] = datan2_r; 243 data[n + 1] = datan2_i; 244 245 n -= nnstep; 246 m -= nnstep; 247 data[m] = datam1_r; 248 data[m + 1] = datam1_i; 249 data[n] = datan1_r; 250 data[n + 1] = datan1_i; 251 252 } 253 } 254 255 for (int j = 2; j < jmax; j += 2) { 256 double wr = w[i++]; 257 double wi = w[i++]; 258 double wr1 = w[ii++]; 259 double wi1 = w[ii++]; 260 double wwr1 = w[iii++]; 261 double wwi1 = w[iii++]; 262 // double wwr1 = wr * wr1 - wi * wi1; // these numbers can be 263 // precomputed!!! 264 // double wwi1 = wr * wi1 + wi * wr1; 265 266 for (int n = j; n < fftFrameSize2; n += nstep) { 267 int m = n + jmax; 268 269 double datam1_r = data[m]; 270 double datam1_i = data[m + 1]; 271 double datan1_r = data[n]; 272 double datan1_i = data[n + 1]; 273 274 n += nnstep; 275 m += nnstep; 276 double datam2_r = data[m]; 277 double datam2_i = data[m + 1]; 278 double datan2_r = data[n]; 279 double datan2_i = data[n + 1]; 280 281 double tempr = datam1_r * wr - datam1_i * wi; 282 double tempi = datam1_r * wi + datam1_i * wr; 283 284 datam1_r = datan1_r - tempr; 285 datam1_i = datan1_i - tempi; 286 datan1_r = datan1_r + tempr; 287 datan1_i = datan1_i + tempi; 288 289 double n2w1r = datan2_r * wr1 - datan2_i * wi1; 290 double n2w1i = datan2_r * wi1 + datan2_i * wr1; 291 double m2ww1r = datam2_r * wwr1 - datam2_i * wwi1; 292 double m2ww1i = datam2_r * wwi1 + datam2_i * wwr1; 293 294 tempr = m2ww1r - n2w1r; 295 tempi = m2ww1i - n2w1i; 296 297 datam2_r = datam1_r + tempi; 298 datam2_i = datam1_i - tempr; 299 datam1_r = datam1_r - tempi; 300 datam1_i = datam1_i + tempr; 301 302 tempr = n2w1r + m2ww1r; 303 tempi = n2w1i + m2ww1i; 304 305 datan2_r = datan1_r - tempr; 306 datan2_i = datan1_i - tempi; 307 datan1_r = datan1_r + tempr; 308 datan1_i = datan1_i + tempi; 309 310 data[m] = datam2_r; 311 data[m + 1] = datam2_i; 312 data[n] = datan2_r; 313 data[n + 1] = datan2_i; 314 315 n -= nnstep; 316 m -= nnstep; 317 data[m] = datam1_r; 318 data[m + 1] = datam1_i; 319 data[n] = datan1_r; 320 data[n + 1] = datan1_i; 321 } 322 } 323 324 i += jmax << 1; 325 326 } 327 328 calcF2E(fftFrameSize, data, i, nstep, w); 329 330 } 331 332 // Perform Factor-4 Decomposition with 3 * complex operators and 8 +/- 333 // complex operators 334 private final static void calcF4I(int fftFrameSize, double[] data, int i, 335 int nstep, double[] w) { 336 final int fftFrameSize2 = fftFrameSize << 1; // 2*fftFrameSize; 337 // Factor-4 Decomposition 338 339 int w_len = w.length >> 1; 340 while (nstep < fftFrameSize2) { 341 342 if (nstep << 2 == fftFrameSize2) { 343 // Goto Factor-4 Final Decomposition 344 // calcF4E(data, i, nstep, 1, w); 345 calcF4IE(fftFrameSize, data, i, nstep, w); 346 return; 347 } 348 int jmax = nstep; 349 int nnstep = nstep << 1; 350 if (nnstep == fftFrameSize2) { 351 // Factor-4 Decomposition not possible 352 calcF2E(fftFrameSize, data, i, nstep, w); 353 return; 354 } 355 nstep <<= 2; 356 int ii = i + jmax; 357 int iii = i + w_len; 358 { 359 i += 2; 360 ii += 2; 361 iii += 2; 362 363 for (int n = 0; n < fftFrameSize2; n += nstep) { 364 int m = n + jmax; 365 366 double datam1_r = data[m]; 367 double datam1_i = data[m + 1]; 368 double datan1_r = data[n]; 369 double datan1_i = data[n + 1]; 370 371 n += nnstep; 372 m += nnstep; 373 double datam2_r = data[m]; 374 double datam2_i = data[m + 1]; 375 double datan2_r = data[n]; 376 double datan2_i = data[n + 1]; 377 378 double tempr = datam1_r; 379 double tempi = datam1_i; 380 381 datam1_r = datan1_r - tempr; 382 datam1_i = datan1_i - tempi; 383 datan1_r = datan1_r + tempr; 384 datan1_i = datan1_i + tempi; 385 386 double n2w1r = datan2_r; 387 double n2w1i = datan2_i; 388 double m2ww1r = datam2_r; 389 double m2ww1i = datam2_i; 390 391 tempr = n2w1r - m2ww1r; 392 tempi = n2w1i - m2ww1i; 393 394 datam2_r = datam1_r + tempi; 395 datam2_i = datam1_i - tempr; 396 datam1_r = datam1_r - tempi; 397 datam1_i = datam1_i + tempr; 398 399 tempr = n2w1r + m2ww1r; 400 tempi = n2w1i + m2ww1i; 401 402 datan2_r = datan1_r - tempr; 403 datan2_i = datan1_i - tempi; 404 datan1_r = datan1_r + tempr; 405 datan1_i = datan1_i + tempi; 406 407 data[m] = datam2_r; 408 data[m + 1] = datam2_i; 409 data[n] = datan2_r; 410 data[n + 1] = datan2_i; 411 412 n -= nnstep; 413 m -= nnstep; 414 data[m] = datam1_r; 415 data[m + 1] = datam1_i; 416 data[n] = datan1_r; 417 data[n + 1] = datan1_i; 418 419 } 420 421 } 422 for (int j = 2; j < jmax; j += 2) { 423 double wr = w[i++]; 424 double wi = w[i++]; 425 double wr1 = w[ii++]; 426 double wi1 = w[ii++]; 427 double wwr1 = w[iii++]; 428 double wwi1 = w[iii++]; 429 // double wwr1 = wr * wr1 - wi * wi1; // these numbers can be 430 // precomputed!!! 431 // double wwi1 = wr * wi1 + wi * wr1; 432 433 for (int n = j; n < fftFrameSize2; n += nstep) { 434 int m = n + jmax; 435 436 double datam1_r = data[m]; 437 double datam1_i = data[m + 1]; 438 double datan1_r = data[n]; 439 double datan1_i = data[n + 1]; 440 441 n += nnstep; 442 m += nnstep; 443 double datam2_r = data[m]; 444 double datam2_i = data[m + 1]; 445 double datan2_r = data[n]; 446 double datan2_i = data[n + 1]; 447 448 double tempr = datam1_r * wr - datam1_i * wi; 449 double tempi = datam1_r * wi + datam1_i * wr; 450 451 datam1_r = datan1_r - tempr; 452 datam1_i = datan1_i - tempi; 453 datan1_r = datan1_r + tempr; 454 datan1_i = datan1_i + tempi; 455 456 double n2w1r = datan2_r * wr1 - datan2_i * wi1; 457 double n2w1i = datan2_r * wi1 + datan2_i * wr1; 458 double m2ww1r = datam2_r * wwr1 - datam2_i * wwi1; 459 double m2ww1i = datam2_r * wwi1 + datam2_i * wwr1; 460 461 tempr = n2w1r - m2ww1r; 462 tempi = n2w1i - m2ww1i; 463 464 datam2_r = datam1_r + tempi; 465 datam2_i = datam1_i - tempr; 466 datam1_r = datam1_r - tempi; 467 datam1_i = datam1_i + tempr; 468 469 tempr = n2w1r + m2ww1r; 470 tempi = n2w1i + m2ww1i; 471 472 datan2_r = datan1_r - tempr; 473 datan2_i = datan1_i - tempi; 474 datan1_r = datan1_r + tempr; 475 datan1_i = datan1_i + tempi; 476 477 data[m] = datam2_r; 478 data[m + 1] = datam2_i; 479 data[n] = datan2_r; 480 data[n + 1] = datan2_i; 481 482 n -= nnstep; 483 m -= nnstep; 484 data[m] = datam1_r; 485 data[m + 1] = datam1_i; 486 data[n] = datan1_r; 487 data[n + 1] = datan1_i; 488 489 } 490 } 491 492 i += jmax << 1; 493 494 } 495 496 calcF2E(fftFrameSize, data, i, nstep, w); 497 498 } 499 500 // Perform Factor-4 Decomposition with 3 * complex operators and 8 +/- 501 // complex operators 502 private final static void calcF4FE(int fftFrameSize, double[] data, int i, 503 int nstep, double[] w) { 504 final int fftFrameSize2 = fftFrameSize << 1; // 2*fftFrameSize; 505 // Factor-4 Decomposition 506 507 int w_len = w.length >> 1; 508 while (nstep < fftFrameSize2) { 509 510 int jmax = nstep; 511 int nnstep = nstep << 1; 512 if (nnstep == fftFrameSize2) { 513 // Factor-4 Decomposition not possible 514 calcF2E(fftFrameSize, data, i, nstep, w); 515 return; 516 } 517 nstep <<= 2; 518 int ii = i + jmax; 519 int iii = i + w_len; 520 for (int n = 0; n < jmax; n += 2) { 521 double wr = w[i++]; 522 double wi = w[i++]; 523 double wr1 = w[ii++]; 524 double wi1 = w[ii++]; 525 double wwr1 = w[iii++]; 526 double wwi1 = w[iii++]; 527 // double wwr1 = wr * wr1 - wi * wi1; // these numbers can be 528 // precomputed!!! 529 // double wwi1 = wr * wi1 + wi * wr1; 530 531 int m = n + jmax; 532 533 double datam1_r = data[m]; 534 double datam1_i = data[m + 1]; 535 double datan1_r = data[n]; 536 double datan1_i = data[n + 1]; 537 538 n += nnstep; 539 m += nnstep; 540 double datam2_r = data[m]; 541 double datam2_i = data[m + 1]; 542 double datan2_r = data[n]; 543 double datan2_i = data[n + 1]; 544 545 double tempr = datam1_r * wr - datam1_i * wi; 546 double tempi = datam1_r * wi + datam1_i * wr; 547 548 datam1_r = datan1_r - tempr; 549 datam1_i = datan1_i - tempi; 550 datan1_r = datan1_r + tempr; 551 datan1_i = datan1_i + tempi; 552 553 double n2w1r = datan2_r * wr1 - datan2_i * wi1; 554 double n2w1i = datan2_r * wi1 + datan2_i * wr1; 555 double m2ww1r = datam2_r * wwr1 - datam2_i * wwi1; 556 double m2ww1i = datam2_r * wwi1 + datam2_i * wwr1; 557 558 tempr = m2ww1r - n2w1r; 559 tempi = m2ww1i - n2w1i; 560 561 datam2_r = datam1_r + tempi; 562 datam2_i = datam1_i - tempr; 563 datam1_r = datam1_r - tempi; 564 datam1_i = datam1_i + tempr; 565 566 tempr = n2w1r + m2ww1r; 567 tempi = n2w1i + m2ww1i; 568 569 datan2_r = datan1_r - tempr; 570 datan2_i = datan1_i - tempi; 571 datan1_r = datan1_r + tempr; 572 datan1_i = datan1_i + tempi; 573 574 data[m] = datam2_r; 575 data[m + 1] = datam2_i; 576 data[n] = datan2_r; 577 data[n + 1] = datan2_i; 578 579 n -= nnstep; 580 m -= nnstep; 581 data[m] = datam1_r; 582 data[m + 1] = datam1_i; 583 data[n] = datan1_r; 584 data[n + 1] = datan1_i; 585 586 } 587 588 i += jmax << 1; 589 590 } 591 592 } 593 594 // Perform Factor-4 Decomposition with 3 * complex operators and 8 +/- 595 // complex operators 596 private final static void calcF4IE(int fftFrameSize, double[] data, int i, 597 int nstep, double[] w) { 598 final int fftFrameSize2 = fftFrameSize << 1; // 2*fftFrameSize; 599 // Factor-4 Decomposition 600 601 int w_len = w.length >> 1; 602 while (nstep < fftFrameSize2) { 603 604 int jmax = nstep; 605 int nnstep = nstep << 1; 606 if (nnstep == fftFrameSize2) { 607 // Factor-4 Decomposition not possible 608 calcF2E(fftFrameSize, data, i, nstep, w); 609 return; 610 } 611 nstep <<= 2; 612 int ii = i + jmax; 613 int iii = i + w_len; 614 for (int n = 0; n < jmax; n += 2) { 615 double wr = w[i++]; 616 double wi = w[i++]; 617 double wr1 = w[ii++]; 618 double wi1 = w[ii++]; 619 double wwr1 = w[iii++]; 620 double wwi1 = w[iii++]; 621 // double wwr1 = wr * wr1 - wi * wi1; // these numbers can be 622 // precomputed!!! 623 // double wwi1 = wr * wi1 + wi * wr1; 624 625 int m = n + jmax; 626 627 double datam1_r = data[m]; 628 double datam1_i = data[m + 1]; 629 double datan1_r = data[n]; 630 double datan1_i = data[n + 1]; 631 632 n += nnstep; 633 m += nnstep; 634 double datam2_r = data[m]; 635 double datam2_i = data[m + 1]; 636 double datan2_r = data[n]; 637 double datan2_i = data[n + 1]; 638 639 double tempr = datam1_r * wr - datam1_i * wi; 640 double tempi = datam1_r * wi + datam1_i * wr; 641 642 datam1_r = datan1_r - tempr; 643 datam1_i = datan1_i - tempi; 644 datan1_r = datan1_r + tempr; 645 datan1_i = datan1_i + tempi; 646 647 double n2w1r = datan2_r * wr1 - datan2_i * wi1; 648 double n2w1i = datan2_r * wi1 + datan2_i * wr1; 649 double m2ww1r = datam2_r * wwr1 - datam2_i * wwi1; 650 double m2ww1i = datam2_r * wwi1 + datam2_i * wwr1; 651 652 tempr = n2w1r - m2ww1r; 653 tempi = n2w1i - m2ww1i; 654 655 datam2_r = datam1_r + tempi; 656 datam2_i = datam1_i - tempr; 657 datam1_r = datam1_r - tempi; 658 datam1_i = datam1_i + tempr; 659 660 tempr = n2w1r + m2ww1r; 661 tempi = n2w1i + m2ww1i; 662 663 datan2_r = datan1_r - tempr; 664 datan2_i = datan1_i - tempi; 665 datan1_r = datan1_r + tempr; 666 datan1_i = datan1_i + tempi; 667 668 data[m] = datam2_r; 669 data[m + 1] = datam2_i; 670 data[n] = datan2_r; 671 data[n + 1] = datan2_i; 672 673 n -= nnstep; 674 m -= nnstep; 675 data[m] = datam1_r; 676 data[m + 1] = datam1_i; 677 data[n] = datan1_r; 678 data[n + 1] = datan1_i; 679 680 } 681 682 i += jmax << 1; 683 684 } 685 686 } 687 688 private final void bitreversal(double[] data) { 689 if (fftFrameSize < 4) 690 return; 691 692 int inverse = fftFrameSize2 - 2; 693 for (int i = 0; i < fftFrameSize; i += 4) { 694 int j = bitm_array[i]; 695 696 // Performing Bit-Reversal, even v.s. even, O(2N) 697 if (i < j) { 698 699 int n = i; 700 int m = j; 701 702 // COMPLEX: SWAP(data[n], data[m]) 703 // Real Part 704 double tempr = data[n]; 705 data[n] = data[m]; 706 data[m] = tempr; 707 // Imagery Part 708 n++; 709 m++; 710 double tempi = data[n]; 711 data[n] = data[m]; 712 data[m] = tempi; 713 714 n = inverse - i; 715 m = inverse - j; 716 717 // COMPLEX: SWAP(data[n], data[m]) 718 // Real Part 719 tempr = data[n]; 720 data[n] = data[m]; 721 data[m] = tempr; 722 // Imagery Part 723 n++; 724 m++; 725 tempi = data[n]; 726 data[n] = data[m]; 727 data[m] = tempi; 728 } 729 730 // Performing Bit-Reversal, odd v.s. even, O(N) 731 732 int m = j + fftFrameSize; // bitm_array[i+2]; 733 // COMPLEX: SWAP(data[n], data[m]) 734 // Real Part 735 int n = i + 2; 736 double tempr = data[n]; 737 data[n] = data[m]; 738 data[m] = tempr; 739 // Imagery Part 740 n++; 741 m++; 742 double tempi = data[n]; 743 data[n] = data[m]; 744 data[m] = tempi; 745 } 746 747 } 748 }