00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034 #include "TSpectrumTransform.h"
00035 #include "TMath.h"
00036
00037 ClassImp(TSpectrumTransform)
00038
00039
00040 TSpectrumTransform::TSpectrumTransform()
00041 {
00042
00043 fSize=0;
00044 fTransformType=kTransformCos;
00045 fDegree=0;
00046 fDirection=kTransformForward;
00047 fXmin=0;
00048 fXmax=0;
00049 fFilterCoeff=0;
00050 fEnhanceCoeff=0.5;
00051 }
00052
00053
00054 TSpectrumTransform::TSpectrumTransform(Int_t size):TNamed("SpectrumTransform", "Miroslav Morhac transformer")
00055 {
00056
00057
00058 Int_t j,n;
00059 if (size <= 0){
00060 Error ("TSpectrumTransform","Invalid length, must be > than 0");
00061 return;
00062 }
00063 j = 0;
00064 n = 1;
00065 for (; n < size;) {
00066 j += 1;
00067 n = n * 2;
00068 }
00069 if (n != size){
00070 Error ("TSpectrumTransform","Invalid length, must be power of 2");
00071 return;
00072 }
00073 fSize=size;
00074 fTransformType=kTransformCos;
00075 fDegree=0;
00076 fDirection=kTransformForward;
00077 fXmin=size/4;
00078 fXmax=size-1;
00079 fFilterCoeff=0;
00080 fEnhanceCoeff=0.5;
00081 }
00082
00083
00084
00085 TSpectrumTransform::~TSpectrumTransform()
00086 {
00087
00088 }
00089
00090
00091 void TSpectrumTransform::Haar(float *working_space, int num, int direction)
00092 {
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103 int i, ii, li, l2, l3, j, jj, jj1, lj, iter, m, jmin, jmax;
00104 double a, b, c, wlk;
00105 float val;
00106 for (i = 0; i < num; i++)
00107 working_space[i + num] = 0;
00108 i = num;
00109 iter = 0;
00110 for (; i > 1;) {
00111 iter += 1;
00112 i = i / 2;
00113 }
00114 if (direction == kTransformForward) {
00115 for (m = 1; m <= iter; m++) {
00116 li = iter + 1 - m;
00117 l2 = (int) TMath::Power(2, li - 1);
00118 for (i = 0; i < (2 * l2); i++) {
00119 working_space[num + i] = working_space[i];
00120 }
00121 for (j = 0; j < l2; j++) {
00122 l3 = l2 + j;
00123 jj = 2 * j;
00124 val = working_space[jj + num] + working_space[jj + 1 + num];
00125 working_space[j] = val;
00126 val = working_space[jj + num] - working_space[jj + 1 + num];
00127 working_space[l3] = val;
00128 }
00129 }
00130 }
00131 val = working_space[0];
00132 val = val / TMath::Sqrt(TMath::Power(2, iter));
00133 working_space[0] = val;
00134 val = working_space[1];
00135 val = val / TMath::Sqrt(TMath::Power(2, iter));
00136 working_space[1] = val;
00137 for (ii = 2; ii <= iter; ii++) {
00138 i = ii - 1;
00139 wlk = 1 / TMath::Sqrt(TMath::Power(2, iter - i));
00140 jmin = (int) TMath::Power(2, i);
00141 jmax = (int) TMath::Power(2, ii) - 1;
00142 for (j = jmin; j <= jmax; j++) {
00143 val = working_space[j];
00144 a = val;
00145 a = a * wlk;
00146 val = a;
00147 working_space[j] = val;
00148 }
00149 }
00150 if (direction == kTransformInverse) {
00151 for (m = 1; m <= iter; m++) {
00152 a = 2;
00153 b = m - 1;
00154 c = TMath::Power(a, b);
00155 li = (int) c;
00156 for (i = 0; i < (2 * li); i++) {
00157 working_space[i + num] = working_space[i];
00158 }
00159 for (j = 0; j < li; j++) {
00160 lj = li + j;
00161 jj = 2 * (j + 1) - 1;
00162 jj1 = jj - 1;
00163 val = working_space[j + num] - working_space[lj + num];
00164 working_space[jj] = val;
00165 val = working_space[j + num] + working_space[lj + num];
00166 working_space[jj1] = val;
00167 }
00168 }
00169 }
00170 return;
00171 }
00172
00173
00174 void TSpectrumTransform::Walsh(float *working_space, int num)
00175 {
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185 int i, m, nump = 1, mnum, mnum2, mp, ib, mp2, mnum21, iba, iter;
00186 double a;
00187 float val1, val2;
00188 for (i = 0; i < num; i++)
00189 working_space[i + num] = 0;
00190 i = num;
00191 iter = 0;
00192 for (; i > 1;) {
00193 iter += 1;
00194 i = i / 2;
00195 }
00196 for (m = 1; m <= iter; m++) {
00197 if (m == 1)
00198 nump = 1;
00199
00200 else
00201 nump = nump * 2;
00202 mnum = num / nump;
00203 mnum2 = mnum / 2;
00204 for (mp = 0; mp < nump; mp++) {
00205 ib = mp * mnum;
00206 for (mp2 = 0; mp2 < mnum2; mp2++) {
00207 mnum21 = mnum2 + mp2 + ib;
00208 iba = ib + mp2;
00209 val1 = working_space[iba];
00210 val2 = working_space[mnum21];
00211 working_space[iba + num] = val1 + val2;
00212 working_space[mnum21 + num] = val1 - val2;
00213 }
00214 }
00215 for (i = 0; i < num; i++) {
00216 working_space[i] = working_space[i + num];
00217 }
00218 }
00219 a = num;
00220 a = TMath::Sqrt(a);
00221 val2 = a;
00222 for (i = 0; i < num; i++) {
00223 val1 = working_space[i];
00224 val1 = val1 / val2;
00225 working_space[i] = val1;
00226 }
00227 return;
00228 }
00229
00230
00231 void TSpectrumTransform::BitReverse(float *working_space, int num)
00232 {
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242 int ipower[26];
00243 int i, ib, il, ibd, ip, ifac, i1;
00244 for (i = 0; i < num; i++) {
00245 working_space[i + num] = working_space[i];
00246 }
00247 for (i = 1; i <= num; i++) {
00248 ib = i - 1;
00249 il = 1;
00250 lab9:ibd = ib / 2;
00251 ipower[il - 1] = 1;
00252 if (ib == (ibd * 2))
00253 ipower[il - 1] = 0;
00254 if (ibd == 0)
00255 goto lab10;
00256 ib = ibd;
00257 il = il + 1;
00258 goto lab9;
00259 lab10:ip = 1;
00260 ifac = num;
00261 for (i1 = 1; i1 <= il; i1++) {
00262 ifac = ifac / 2;
00263 ip = ip + ifac * ipower[i1 - 1];
00264 }
00265 working_space[ip - 1] = working_space[i - 1 + num];
00266 }
00267 return;
00268 }
00269
00270
00271 void TSpectrumTransform::Fourier(float *working_space, int num, int hartley,
00272 int direction, int zt_clear)
00273 {
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285 int nxp2, nxp, i, j, k, m, iter, mxp, j1, j2, n1, n2, it;
00286 double a, b, c, d, sign, wpwr, arg, wr, wi, tr, ti, pi =
00287 3.14159265358979323846;
00288 float val1, val2, val3, val4;
00289 if (direction == kTransformForward && zt_clear == 0) {
00290 for (i = 0; i < num; i++)
00291 working_space[i + num] = 0;
00292 }
00293 i = num;
00294 iter = 0;
00295 for (; i > 1;) {
00296 iter += 1;
00297 i = i / 2;
00298 }
00299 sign = -1;
00300 if (direction == kTransformInverse)
00301 sign = 1;
00302 nxp2 = num;
00303 for (it = 1; it <= iter; it++) {
00304 nxp = nxp2;
00305 nxp2 = nxp / 2;
00306 a = nxp2;
00307 wpwr = pi / a;
00308 for (m = 1; m <= nxp2; m++) {
00309 a = m - 1;
00310 arg = a * wpwr;
00311 wr = TMath::Cos(arg);
00312 wi = sign * TMath::Sin(arg);
00313 for (mxp = nxp; mxp <= num; mxp += nxp) {
00314 j1 = mxp - nxp + m;
00315 j2 = j1 + nxp2;
00316 val1 = working_space[j1 - 1];
00317 val2 = working_space[j2 - 1];
00318 val3 = working_space[j1 - 1 + num];
00319 val4 = working_space[j2 - 1 + num];
00320 a = val1;
00321 b = val2;
00322 c = val3;
00323 d = val4;
00324 tr = a - b;
00325 ti = c - d;
00326 a = a + b;
00327 val1 = a;
00328 working_space[j1 - 1] = val1;
00329 c = c + d;
00330 val1 = c;
00331 working_space[j1 - 1 + num] = val1;
00332 a = tr * wr - ti * wi;
00333 val1 = a;
00334 working_space[j2 - 1] = val1;
00335 a = ti * wr + tr * wi;
00336 val1 = a;
00337 working_space[j2 - 1 + num] = val1;
00338 }
00339 }
00340 }
00341 n2 = num / 2;
00342 n1 = num - 1;
00343 j = 1;
00344 for (i = 1; i <= n1; i++) {
00345 if (i >= j)
00346 goto lab55;
00347 val1 = working_space[j - 1];
00348 val2 = working_space[j - 1 + num];
00349 val3 = working_space[i - 1];
00350 working_space[j - 1] = val3;
00351 working_space[j - 1 + num] = working_space[i - 1 + num];
00352 working_space[i - 1] = val1;
00353 working_space[i - 1 + num] = val2;
00354 lab55: k = n2;
00355 lab60: if (k >= j) goto lab65;
00356 j = j - k;
00357 k = k / 2;
00358 goto lab60;
00359 lab65: j = j + k;
00360 }
00361 a = num;
00362 a = TMath::Sqrt(a);
00363 for (i = 0; i < num; i++) {
00364 if (hartley == 0) {
00365 val1 = working_space[i];
00366 b = val1;
00367 b = b / a;
00368 val1 = b;
00369 working_space[i] = val1;
00370 b = working_space[i + num];
00371 b = b / a;
00372 working_space[i + num] = b;
00373 }
00374
00375 else {
00376 b = working_space[i];
00377 c = working_space[i + num];
00378 b = (b + c) / a;
00379 working_space[i] = b;
00380 working_space[i + num] = 0;
00381 }
00382 }
00383 if (hartley == 1 && direction == kTransformInverse) {
00384 for (i = 1; i < num; i++)
00385 working_space[num - i + num] = working_space[i];
00386 working_space[0 + num] = working_space[0];
00387 for (i = 0; i < num; i++) {
00388 working_space[i] = working_space[i + num];
00389 working_space[i + num] = 0;
00390 }
00391 }
00392 return;
00393 }
00394
00395
00396 void TSpectrumTransform::BitReverseHaar(float *working_space, int shift, int num,
00397 int start)
00398 {
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410 int ipower[26];
00411 int i, ib, il, ibd, ip, ifac, i1;
00412 for (i = 0; i < num; i++) {
00413 working_space[i + shift + start] = working_space[i + start];
00414 working_space[i + shift + start + 2 * shift] =
00415 working_space[i + start + 2 * shift];
00416 }
00417 for (i = 1; i <= num; i++) {
00418 ib = i - 1;
00419 il = 1;
00420 lab9: ibd = ib / 2;
00421 ipower[il - 1] = 1;
00422 if (ib == (ibd * 2))
00423 ipower[il - 1] = 0;
00424 if (ibd == 0)
00425 goto lab10;
00426 ib = ibd;
00427 il = il + 1;
00428 goto lab9;
00429 lab10: ip = 1;
00430 ifac = num;
00431 for (i1 = 1; i1 <= il; i1++) {
00432 ifac = ifac / 2;
00433 ip = ip + ifac * ipower[i1 - 1];
00434 }
00435 working_space[ip - 1 + start] =
00436 working_space[i - 1 + shift + start];
00437 working_space[ip - 1 + start + 2 * shift] =
00438 working_space[i - 1 + shift + start + 2 * shift];
00439 }
00440 return;
00441 }
00442
00443
00444 int TSpectrumTransform::GeneralExe(float *working_space, int zt_clear, int num,
00445 int degree, int type)
00446 {
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459 int i, j, k, m, nump, mnum, mnum2, mp, ib, mp2, mnum21, iba, iter,
00460 mp2step, mppom, ring;
00461 double a, b, c, d, wpwr, arg, wr, wi, tr, ti, pi =
00462 3.14159265358979323846;
00463 float val1, val2, val3, val4, a0oldr = 0, b0oldr = 0, a0r, b0r;
00464 if (zt_clear == 0) {
00465 for (i = 0; i < num; i++)
00466 working_space[i + 2 * num] = 0;
00467 }
00468 i = num;
00469 iter = 0;
00470 for (; i > 1;) {
00471 iter += 1;
00472 i = i / 2;
00473 }
00474 a = num;
00475 wpwr = 2.0 * pi / a;
00476 nump = num;
00477 mp2step = 1;
00478 ring = num;
00479 for (i = 0; i < iter - degree; i++)
00480 ring = ring / 2;
00481 for (m = 1; m <= iter; m++) {
00482 nump = nump / 2;
00483 mnum = num / nump;
00484 mnum2 = mnum / 2;
00485 if (m > degree
00486 && (type == kTransformFourierHaar
00487 || type == kTransformWalshHaar
00488 || type == kTransformCosHaar
00489 || type == kTransformSinHaar))
00490 mp2step *= 2;
00491 if (ring > 1)
00492 ring = ring / 2;
00493 for (mp = 0; mp < nump; mp++) {
00494 if (type != kTransformWalshHaar) {
00495 mppom = mp;
00496 mppom = mppom % ring;
00497 a = 0;
00498 j = 1;
00499 k = num / 4;
00500 for (i = 0; i < (iter - 1); i++) {
00501 if ((mppom & j) != 0)
00502 a = a + k;
00503 j = j * 2;
00504 k = k / 2;
00505 }
00506 arg = a * wpwr;
00507 wr = TMath::Cos(arg);
00508 wi = TMath::Sin(arg);
00509 }
00510
00511 else {
00512 wr = 1;
00513 wi = 0;
00514 }
00515 ib = mp * mnum;
00516 for (mp2 = 0; mp2 < mnum2; mp2++) {
00517 mnum21 = mnum2 + mp2 + ib;
00518 iba = ib + mp2;
00519 if (mp2 % mp2step == 0) {
00520 a0r = a0oldr;
00521 b0r = b0oldr;
00522 a0r = 1 / TMath::Sqrt(2.0);
00523 b0r = 1 / TMath::Sqrt(2.0);
00524 }
00525
00526 else {
00527 a0r = 1;
00528 b0r = 0;
00529 }
00530 val1 = working_space[iba];
00531 val2 = working_space[mnum21];
00532 val3 = working_space[iba + 2 * num];
00533 val4 = working_space[mnum21 + 2 * num];
00534 a = val1;
00535 b = val2;
00536 c = val3;
00537 d = val4;
00538 tr = a * a0r + b * b0r;
00539 val1 = tr;
00540 working_space[num + iba] = val1;
00541 ti = c * a0r + d * b0r;
00542 val1 = ti;
00543 working_space[num + iba + 2 * num] = val1;
00544 tr =
00545 a * b0r * wr - c * b0r * wi - b * a0r * wr + d * a0r * wi;
00546 val1 = tr;
00547 working_space[num + mnum21] = val1;
00548 ti =
00549 c * b0r * wr + a * b0r * wi - d * a0r * wr - b * a0r * wi;
00550 val1 = ti;
00551 working_space[num + mnum21 + 2 * num] = val1;
00552 }
00553 }
00554 for (i = 0; i < num; i++) {
00555 val1 = working_space[num + i];
00556 working_space[i] = val1;
00557 val1 = working_space[num + i + 2 * num];
00558 working_space[i + 2 * num] = val1;
00559 }
00560 }
00561 return (0);
00562 }
00563
00564
00565 int TSpectrumTransform::GeneralInv(float *working_space, int num, int degree,
00566 int type)
00567 {
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579 int i, j, k, m, nump =
00580 1, mnum, mnum2, mp, ib, mp2, mnum21, iba, iter, mp2step, mppom,
00581 ring;
00582 double a, b, c, d, wpwr, arg, wr, wi, tr, ti, pi =
00583 3.14159265358979323846;
00584 float val1, val2, val3, val4, a0oldr = 0, b0oldr = 0, a0r, b0r;
00585 i = num;
00586 iter = 0;
00587 for (; i > 1;) {
00588 iter += 1;
00589 i = i / 2;
00590 }
00591 a = num;
00592 wpwr = 2.0 * pi / a;
00593 mp2step = 1;
00594 if (type == kTransformFourierHaar || type == kTransformWalshHaar
00595 || type == kTransformCosHaar || type == kTransformSinHaar) {
00596 for (i = 0; i < iter - degree; i++)
00597 mp2step *= 2;
00598 }
00599 ring = 1;
00600 for (m = 1; m <= iter; m++) {
00601 if (m == 1)
00602 nump = 1;
00603
00604 else
00605 nump = nump * 2;
00606 mnum = num / nump;
00607 mnum2 = mnum / 2;
00608 if (m > iter - degree + 1)
00609 ring *= 2;
00610 for (mp = nump - 1; mp >= 0; mp--) {
00611 if (type != kTransformWalshHaar) {
00612 mppom = mp;
00613 mppom = mppom % ring;
00614 a = 0;
00615 j = 1;
00616 k = num / 4;
00617 for (i = 0; i < (iter - 1); i++) {
00618 if ((mppom & j) != 0)
00619 a = a + k;
00620 j = j * 2;
00621 k = k / 2;
00622 }
00623 arg = a * wpwr;
00624 wr = TMath::Cos(arg);
00625 wi = TMath::Sin(arg);
00626 }
00627
00628 else {
00629 wr = 1;
00630 wi = 0;
00631 }
00632 ib = mp * mnum;
00633 for (mp2 = 0; mp2 < mnum2; mp2++) {
00634 mnum21 = mnum2 + mp2 + ib;
00635 iba = ib + mp2;
00636 if (mp2 % mp2step == 0) {
00637 a0r = a0oldr;
00638 b0r = b0oldr;
00639 a0r = 1 / TMath::Sqrt(2.0);
00640 b0r = 1 / TMath::Sqrt(2.0);
00641 }
00642
00643 else {
00644 a0r = 1;
00645 b0r = 0;
00646 }
00647 val1 = working_space[iba];
00648 val2 = working_space[mnum21];
00649 val3 = working_space[iba + 2 * num];
00650 val4 = working_space[mnum21 + 2 * num];
00651 a = val1;
00652 b = val2;
00653 c = val3;
00654 d = val4;
00655 tr = a * a0r + b * wr * b0r + d * wi * b0r;
00656 val1 = tr;
00657 working_space[num + iba] = val1;
00658 ti = c * a0r + d * wr * b0r - b * wi * b0r;
00659 val1 = ti;
00660 working_space[num + iba + 2 * num] = val1;
00661 tr = a * b0r - b * wr * a0r - d * wi * a0r;
00662 val1 = tr;
00663 working_space[num + mnum21] = val1;
00664 ti = c * b0r - d * wr * a0r + b * wi * a0r;
00665 val1 = ti;
00666 working_space[num + mnum21 + 2 * num] = val1;
00667 }
00668 }
00669 if (m <= iter - degree
00670 && (type == kTransformFourierHaar
00671 || type == kTransformWalshHaar
00672 || type == kTransformCosHaar
00673 || type == kTransformSinHaar))
00674 mp2step /= 2;
00675 for (i = 0; i < num; i++) {
00676 val1 = working_space[num + i];
00677 working_space[i] = val1;
00678 val1 = working_space[num + i + 2 * num];
00679 working_space[i + 2 * num] = val1;
00680 }
00681 }
00682 return (0);
00683 }
00684
00685
00686
00687
00688
00689
00690 void TSpectrumTransform::Transform(const float *source, float *destVector)
00691 {
00692
00693
00694
00695
00696
00697
00698
00699
00700
00701
00702
00703
00704
00705
00706
00707
00708
00709
00710
00711
00712
00713
00714
00715
00716
00717
00718
00719
00720
00721
00722
00723
00724
00725
00726
00727
00728
00729
00730
00731
00732
00733
00734
00735
00736
00737
00738
00739
00740
00741
00742
00743
00744
00745
00746
00747
00748
00749
00750
00751
00752
00753
00754
00755
00756
00757
00758
00759
00760
00761
00762
00763
00764
00765
00766
00767
00768
00769
00770
00771
00772
00773
00774
00775
00776
00777
00778
00779
00780
00781
00782
00783
00784
00785
00786
00787
00788
00789
00790
00791
00792
00793
00794
00795
00796
00797
00798
00799
00800
00801
00802
00803
00804
00805
00806
00807
00808
00809
00810
00811
00812
00813
00814
00815
00816
00817
00818
00819
00820
00821
00822
00823
00824
00825
00826
00827
00828
00829
00830
00831
00832
00833
00834
00835
00836
00837
00838
00839
00840
00841
00842
00843
00844
00845
00846
00847
00848
00849
00850
00851
00852
00853
00854
00855
00856
00857
00858
00859
00860
00861
00862
00863
00864
00865
00866
00867
00868
00869
00870
00871
00872
00873
00874
00875
00876
00877
00878
00879
00880
00881
00882
00883
00884
00885
00886
00887
00888
00889
00890
00891
00892
00893
00894
00895
00896
00897
00898
00899
00900
00901
00902
00903
00904
00905
00906
00907
00908
00909
00910
00911
00912
00913
00914
00915
00916
00917
00918
00919
00920
00921
00922
00923
00924
00925
00926
00927
00928
00929
00930
00931
00932
00933
00934
00935
00936
00937
00938
00939
00940
00941
00942
00943
00944
00945
00946
00947
00948
00949
00950
00951
00952
00953
00954
00955
00956
00957 int i, j=0, k = 1, m, l;
00958 float val;
00959 double a, b, pi = 3.14159265358979323846;
00960 float *working_space = 0;
00961 if (fTransformType >= kTransformFourierWalsh && fTransformType <= kTransformSinHaar) {
00962 if (fTransformType >= kTransformCosWalsh)
00963 fDegree += 1;
00964 k = (int) TMath::Power(2, fDegree);
00965 j = fSize / k;
00966 }
00967 switch (fTransformType) {
00968 case kTransformHaar:
00969 case kTransformWalsh:
00970 working_space = new float[2 * fSize];
00971 break;
00972 case kTransformCos:
00973 case kTransformSin:
00974 case kTransformFourier:
00975 case kTransformHartley:
00976 case kTransformFourierWalsh:
00977 case kTransformFourierHaar:
00978 case kTransformWalshHaar:
00979 working_space = new float[4 * fSize];
00980 break;
00981 case kTransformCosWalsh:
00982 case kTransformCosHaar:
00983 case kTransformSinWalsh:
00984 case kTransformSinHaar:
00985 working_space = new float[8 * fSize];
00986 break;
00987 }
00988 if (fDirection == kTransformForward) {
00989 switch (fTransformType) {
00990 case kTransformHaar:
00991 for (i = 0; i < fSize; i++) {
00992 working_space[i] = source[i];
00993 }
00994 Haar(working_space, fSize, fDirection);
00995 for (i = 0; i < fSize; i++) {
00996 destVector[i] = working_space[i];
00997 }
00998 break;
00999 case kTransformWalsh:
01000 for (i = 0; i < fSize; i++) {
01001 working_space[i] = source[i];
01002 }
01003 Walsh(working_space, fSize);
01004 BitReverse(working_space, fSize);
01005 for (i = 0; i < fSize; i++) {
01006 destVector[i] = working_space[i];
01007 }
01008 break;
01009 case kTransformCos:
01010 fSize = 2 * fSize;
01011 for (i = 1; i <= (fSize / 2); i++) {
01012 val = source[i - 1];
01013 working_space[i - 1] = val;
01014 working_space[fSize - i] = val;
01015 }
01016 Fourier(working_space, fSize, 0, kTransformForward, 0);
01017 for (i = 0; i < fSize / 2; i++) {
01018 a = pi * (double) i / (double) fSize;
01019 a = TMath::Cos(a);
01020 b = working_space[i];
01021 a = b / a;
01022 working_space[i] = a;
01023 working_space[i + fSize] = 0;
01024 } working_space[0] = working_space[0] / TMath::Sqrt(2.0);
01025 for (i = 0; i < fSize / 2; i++) {
01026 destVector[i] = working_space[i];
01027 }
01028 break;
01029 case kTransformSin:
01030 fSize = 2 * fSize;
01031 for (i = 1; i <= (fSize / 2); i++) {
01032 val = source[i - 1];
01033 working_space[i - 1] = val;
01034 working_space[fSize - i] = -val;
01035 }
01036 Fourier(working_space, fSize, 0, kTransformForward, 0);
01037 for (i = 0; i < fSize / 2; i++) {
01038 a = pi * (double) i / (double) fSize;
01039 a = TMath::Sin(a);
01040 b = working_space[i];
01041 if (a != 0)
01042 a = b / a;
01043 working_space[i - 1] = a;
01044 working_space[i + fSize] = 0;
01045 }
01046 working_space[fSize / 2 - 1] =
01047 working_space[fSize / 2] / TMath::Sqrt(2.0);
01048 for (i = 0; i < fSize / 2; i++) {
01049 destVector[i] = working_space[i];
01050 }
01051 break;
01052 case kTransformFourier:
01053 for (i = 0; i < fSize; i++) {
01054 working_space[i] = source[i];
01055 }
01056 Fourier(working_space, fSize, 0, kTransformForward, 0);
01057 for (i = 0; i < 2 * fSize; i++) {
01058 destVector[i] = working_space[i];
01059 }
01060 break;
01061 case kTransformHartley:
01062 for (i = 0; i < fSize; i++) {
01063 working_space[i] = source[i];
01064 }
01065 Fourier(working_space, fSize, 1, kTransformForward, 0);
01066 for (i = 0; i < fSize; i++) {
01067 destVector[i] = working_space[i];
01068 }
01069 break;
01070 case kTransformFourierWalsh:
01071 case kTransformFourierHaar:
01072 case kTransformWalshHaar:
01073 case kTransformCosWalsh:
01074 case kTransformCosHaar:
01075 case kTransformSinWalsh:
01076 case kTransformSinHaar:
01077 for (i = 0; i < fSize; i++) {
01078 val = source[i];
01079 if (fTransformType == kTransformCosWalsh
01080 || fTransformType == kTransformCosHaar) {
01081 j = (int) TMath::Power(2, fDegree) / 2;
01082 k = i / j;
01083 k = 2 * k * j;
01084 working_space[k + i % j] = val;
01085 working_space[k + 2 * j - 1 - i % j] = val;
01086 }
01087
01088 else if (fTransformType == kTransformSinWalsh
01089 || fTransformType == kTransformSinHaar) {
01090 j = (int) TMath::Power(2, fDegree) / 2;
01091 k = i / j;
01092 k = 2 * k * j;
01093 working_space[k + i % j] = val;
01094 working_space[k + 2 * j - 1 - i % j] = -val;
01095 }
01096
01097 else
01098 working_space[i] = val;
01099 }
01100 if (fTransformType == kTransformFourierWalsh
01101 || fTransformType == kTransformFourierHaar
01102 || fTransformType == kTransformWalshHaar) {
01103 for (i = 0; i < j; i++)
01104 BitReverseHaar(working_space, fSize, k, i * k);
01105 GeneralExe(working_space, 0, fSize, fDegree, fTransformType);
01106 }
01107
01108 else if (fTransformType == kTransformCosWalsh
01109 || fTransformType == kTransformCosHaar) {
01110 m = (int) TMath::Power(2, fDegree);
01111 l = 2 * fSize / m;
01112 for (i = 0; i < l; i++)
01113 BitReverseHaar(working_space, 2 * fSize, m, i * m);
01114 GeneralExe(working_space, 0, 2 * fSize, fDegree, fTransformType);
01115 for (i = 0; i < fSize; i++) {
01116 k = i / j;
01117 k = 2 * k * j;
01118 a = pi * (double) (i % j) / (double) (2 * j);
01119 a = TMath::Cos(a);
01120 b = working_space[k + i % j];
01121 if (i % j == 0)
01122 a = b / TMath::Sqrt(2.0);
01123
01124 else
01125 a = b / a;
01126 working_space[i] = a;
01127 working_space[i + 2 * fSize] = 0;
01128 }
01129 }
01130
01131 else if (fTransformType == kTransformSinWalsh
01132 || fTransformType == kTransformSinHaar) {
01133 m = (int) TMath::Power(2, fDegree);
01134 l = 2 * fSize / m;
01135 for (i = 0; i < l; i++)
01136 BitReverseHaar(working_space, 2 * fSize, m, i * m);
01137 GeneralExe(working_space, 0, 2 * fSize, fDegree, fTransformType);
01138 for (i = 0; i < fSize; i++) {
01139 k = i / j;
01140 k = 2 * k * j;
01141 a = pi * (double) (i % j) / (double) (2 * j);
01142 a = TMath::Cos(a);
01143 b = working_space[j + k + i % j];
01144 if (i % j == 0)
01145 a = b / TMath::Sqrt(2.0);
01146
01147 else
01148 a = b / a;
01149 working_space[j + k / 2 - i % j - 1] = a;
01150 working_space[i + 2 * fSize] = 0;
01151 }
01152 }
01153 if (fTransformType > kTransformWalshHaar)
01154 k = (int) TMath::Power(2, fDegree - 1);
01155
01156 else
01157 k = (int) TMath::Power(2, fDegree);
01158 j = fSize / k;
01159 for (i = 0, l = 0; i < fSize; i++, l = (l + k) % fSize) {
01160 working_space[fSize + i] = working_space[l + i / j];
01161 working_space[fSize + i + 2 * fSize] =
01162 working_space[l + i / j + 2 * fSize];
01163 }
01164 for (i = 0; i < fSize; i++) {
01165 working_space[i] = working_space[fSize + i];
01166 working_space[i + 2 * fSize] =
01167 working_space[fSize + i + 2 * fSize];
01168 }
01169 for (i = 0; i < fSize; i++) {
01170 destVector[i] = working_space[i];
01171 }
01172 if (fTransformType == kTransformFourierWalsh
01173 || fTransformType == kTransformFourierHaar) {
01174 for (i = 0; i < fSize; i++) {
01175 destVector[fSize + i] = working_space[i + 2 * fSize];
01176 }
01177 }
01178 break;
01179 }
01180 }
01181
01182 else if (fDirection == kTransformInverse) {
01183 switch (fTransformType) {
01184 case kTransformHaar:
01185 for (i = 0; i < fSize; i++) {
01186 working_space[i] = source[i];
01187 }
01188 Haar(working_space, fSize, fDirection);
01189 for (i = 0; i < fSize; i++) {
01190 destVector[i] = working_space[i];
01191 }
01192 break;
01193 case kTransformWalsh:
01194 for (i = 0; i < fSize; i++) {
01195 working_space[i] = source[i];
01196 }
01197 BitReverse(working_space, fSize);
01198 Walsh(working_space, fSize);
01199 for (i = 0; i < fSize; i++) {
01200 destVector[i] = working_space[i];
01201 }
01202 break;
01203 case kTransformCos:
01204 for (i = 0; i < fSize; i++) {
01205 working_space[i] = source[i];
01206 }
01207 fSize = 2 * fSize;
01208 working_space[0] = working_space[0] * TMath::Sqrt(2.0);
01209 for (i = 0; i < fSize / 2; i++) {
01210 a = pi * (double) i / (double) fSize;
01211 b = TMath::Sin(a);
01212 a = TMath::Cos(a);
01213 working_space[i + fSize] = (double) working_space[i] * b;
01214 working_space[i] = (double) working_space[i] * a;
01215 } for (i = 2; i <= (fSize / 2); i++) {
01216 working_space[fSize - i + 1] = working_space[i - 1];
01217 working_space[fSize - i + 1 + fSize] =
01218 -working_space[i - 1 + fSize];
01219 }
01220 working_space[fSize / 2] = 0;
01221 working_space[fSize / 2 + fSize] = 0;
01222 Fourier(working_space, fSize, 0, kTransformInverse, 1);
01223 for (i = 0; i < fSize / 2; i++) {
01224 destVector[i] = working_space[i];
01225 }
01226 break;
01227 case kTransformSin:
01228 for (i = 0; i < fSize; i++) {
01229 working_space[i] = source[i];
01230 }
01231 fSize = 2 * fSize;
01232 working_space[fSize / 2] =
01233 working_space[fSize / 2 - 1] * TMath::Sqrt(2.0);
01234 for (i = fSize / 2 - 1; i > 0; i--) {
01235 a = pi * (double) i / (double) fSize;
01236 working_space[i + fSize] =
01237 -(double) working_space[i - 1] * TMath::Cos(a);
01238 working_space[i] =
01239 (double) working_space[i - 1] * TMath::Sin(a);
01240 } for (i = 2; i <= (fSize / 2); i++) {
01241 working_space[fSize - i + 1] = working_space[i - 1];
01242 working_space[fSize - i + 1 + fSize] =
01243 -working_space[i - 1 + fSize];
01244 }
01245 working_space[0] = 0;
01246 working_space[fSize] = 0;
01247 working_space[fSize / 2 + fSize] = 0;
01248 Fourier(working_space, fSize, 0, kTransformInverse, 0);
01249 for (i = 0; i < fSize / 2; i++) {
01250 destVector[i] = working_space[i];
01251 }
01252 break;
01253 case kTransformFourier:
01254 for (i = 0; i < 2 * fSize; i++) {
01255 working_space[i] = source[i];
01256 }
01257 Fourier(working_space, fSize, 0, kTransformInverse, 0);
01258 for (i = 0; i < fSize; i++) {
01259 destVector[i] = working_space[i];
01260 }
01261 break;
01262 case kTransformHartley:
01263 for (i = 0; i < fSize; i++) {
01264 working_space[i] = source[i];
01265 }
01266 Fourier(working_space, fSize, 1, kTransformInverse, 0);
01267 for (i = 0; i < fSize; i++) {
01268 destVector[i] = working_space[i];
01269 }
01270 break;
01271 case kTransformFourierWalsh:
01272 case kTransformFourierHaar:
01273 case kTransformWalshHaar:
01274 case kTransformCosWalsh:
01275 case kTransformCosHaar:
01276 case kTransformSinWalsh:
01277 case kTransformSinHaar:
01278 for (i = 0; i < fSize; i++) {
01279 working_space[i] = source[i];
01280 }
01281 if (fTransformType == kTransformFourierWalsh
01282 || fTransformType == kTransformFourierHaar) {
01283 for (i = 0; i < fSize; i++) {
01284 working_space[i + 2 * fSize] = source[fSize + i];
01285 }
01286 }
01287 if (fTransformType > kTransformWalshHaar)
01288 k = (int) TMath::Power(2, fDegree - 1);
01289
01290 else
01291 k = (int) TMath::Power(2, fDegree);
01292 j = fSize / k;
01293 for (i = 0, l = 0; i < fSize; i++, l = (l + k) % fSize) {
01294 working_space[fSize + l + i / j] = working_space[i];
01295 working_space[fSize + l + i / j + 2 * fSize] =
01296 working_space[i + 2 * fSize];
01297 }
01298 for (i = 0; i < fSize; i++) {
01299 working_space[i] = working_space[fSize + i];
01300 working_space[i + 2 * fSize] =
01301 working_space[fSize + i + 2 * fSize];
01302 }
01303 if (fTransformType == kTransformFourierWalsh
01304 || fTransformType == kTransformFourierHaar
01305 || fTransformType == kTransformWalshHaar) {
01306 GeneralInv(working_space, fSize, fDegree, fTransformType);
01307 for (i = 0; i < j; i++)
01308 BitReverseHaar(working_space, fSize, k, i * k);
01309 }
01310
01311 else if (fTransformType == kTransformCosWalsh
01312 || fTransformType == kTransformCosHaar) {
01313 j = (int) TMath::Power(2, fDegree) / 2;
01314 m = (int) TMath::Power(2, fDegree);
01315 l = 2 * fSize / m;
01316 for (i = 0; i < fSize; i++) {
01317 k = i / j;
01318 k = 2 * k * j;
01319 a = pi * (double) (i % j) / (double) (2 * j);
01320 if (i % j == 0) {
01321 working_space[2 * fSize + k + i % j] =
01322 working_space[i] * TMath::Sqrt(2.0);
01323 working_space[4 * fSize + 2 * fSize + k + i % j] = 0;
01324 }
01325
01326 else {
01327 b = TMath::Sin(a);
01328 a = TMath::Cos(a);
01329 working_space[4 * fSize + 2 * fSize + k + i % j] =
01330 -(double) working_space[i] * b;
01331 working_space[2 * fSize + k + i % j] =
01332 (double) working_space[i] * a;
01333 } } for (i = 0; i < fSize; i++) {
01334 k = i / j;
01335 k = 2 * k * j;
01336 if (i % j == 0) {
01337 working_space[2 * fSize + k + j] = 0;
01338 working_space[4 * fSize + 2 * fSize + k + j] = 0;
01339 }
01340
01341 else {
01342 working_space[2 * fSize + k + 2 * j - i % j] =
01343 working_space[2 * fSize + k + i % j];
01344 working_space[4 * fSize + 2 * fSize + k + 2 * j - i % j] =
01345 -working_space[4 * fSize + 2 * fSize + k + i % j];
01346 }
01347 }
01348 for (i = 0; i < 2 * fSize; i++) {
01349 working_space[i] = working_space[2 * fSize + i];
01350 working_space[4 * fSize + i] =
01351 working_space[4 * fSize + 2 * fSize + i];
01352 }
01353 GeneralInv(working_space, 2 * fSize, fDegree, fTransformType);
01354 m = (int) TMath::Power(2, fDegree);
01355 l = 2 * fSize / m;
01356 for (i = 0; i < l; i++)
01357 BitReverseHaar(working_space, 2 * fSize, m, i * m);
01358 }
01359
01360 else if (fTransformType == kTransformSinWalsh
01361 || fTransformType == kTransformSinHaar) {
01362 j = (int) TMath::Power(2, fDegree) / 2;
01363 m = (int) TMath::Power(2, fDegree);
01364 l = 2 * fSize / m;
01365 for (i = 0; i < fSize; i++) {
01366 k = i / j;
01367 k = 2 * k * j;
01368 a = pi * (double) (i % j) / (double) (2 * j);
01369 if (i % j == 0) {
01370 working_space[2 * fSize + k + j + i % j] =
01371 working_space[j + k / 2 - i % j -
01372 1] * TMath::Sqrt(2.0);
01373 working_space[4 * fSize + 2 * fSize + k + j + i % j] = 0;
01374 }
01375
01376 else {
01377 b = TMath::Sin(a);
01378 a = TMath::Cos(a);
01379 working_space[4 * fSize + 2 * fSize + k + j + i % j] =
01380 -(double) working_space[j + k / 2 - i % j - 1] * b;
01381 working_space[2 * fSize + k + j + i % j] =
01382 (double) working_space[j + k / 2 - i % j - 1] * a;
01383 } } for (i = 0; i < fSize; i++) {
01384 k = i / j;
01385 k = 2 * k * j;
01386 if (i % j == 0) {
01387 working_space[2 * fSize + k] = 0;
01388 working_space[4 * fSize + 2 * fSize + k] = 0;
01389 }
01390
01391 else {
01392 working_space[2 * fSize + k + i % j] =
01393 working_space[2 * fSize + k + 2 * j - i % j];
01394 working_space[4 * fSize + 2 * fSize + k + i % j] =
01395 -working_space[4 * fSize + 2 * fSize + k + 2 * j -
01396 i % j];
01397 }
01398 }
01399 for (i = 0; i < 2 * fSize; i++) {
01400 working_space[i] = working_space[2 * fSize + i];
01401 working_space[4 * fSize + i] =
01402 working_space[4 * fSize + 2 * fSize + i];
01403 }
01404 GeneralInv(working_space, 2 * fSize, fDegree, fTransformType);
01405 for (i = 0; i < l; i++)
01406 BitReverseHaar(working_space, 2 * fSize, m, i * m);
01407 }
01408 for (i = 0; i < fSize; i++) {
01409 if (fTransformType >= kTransformCosWalsh) {
01410 k = i / j;
01411 k = 2 * k * j;
01412 val = working_space[k + i % j];
01413 }
01414
01415 else
01416 val = working_space[i];
01417 destVector[i] = val;
01418 }
01419 break;
01420 }
01421 }
01422 delete[]working_space;
01423 return;
01424 }
01425
01426
01427
01428
01429 void TSpectrumTransform::FilterZonal(const float *source, float *destVector)
01430 {
01431
01432
01433
01434
01435
01436
01437
01438
01439
01440
01441
01442
01443
01444
01445
01446
01447
01448
01449
01450
01451
01452
01453
01454
01455
01456
01457
01458
01459
01460
01461
01462
01463
01464
01465
01466
01467
01468
01469
01470
01471
01472
01473
01474
01475
01476
01477
01478
01479
01480
01481
01482
01483
01484
01485
01486
01487
01488
01489
01490
01491
01492
01493
01494
01495
01496
01497
01498
01499
01500
01501
01502
01503
01504
01505
01506
01507
01508
01509
01510
01511
01512
01513
01514
01515
01516
01517
01518
01519
01520
01521
01522
01523
01524
01525
01526
01527
01528
01529
01530
01531
01532
01533
01534
01535
01536
01537
01538
01539
01540
01541
01542
01543
01544
01545
01546
01547
01548
01549
01550
01551
01552
01553
01554
01555
01556
01557
01558
01559
01560
01561
01562
01563
01564
01565
01566
01567
01568
01569
01570
01571
01572
01573
01574
01575
01576
01577
01578
01579
01580
01581
01582
01583
01584
01585 int i, j=0, k = 1, m, l;
01586 float val;
01587 float *working_space = 0;
01588 double a, b, pi = 3.14159265358979323846, old_area, new_area;
01589 if (fTransformType >= kTransformFourierWalsh && fTransformType <= kTransformSinHaar) {
01590 if (fTransformType >= kTransformCosWalsh)
01591 fDegree += 1;
01592 k = (int) TMath::Power(2, fDegree);
01593 j = fSize / k;
01594 }
01595 switch (fTransformType) {
01596 case kTransformHaar:
01597 case kTransformWalsh:
01598 working_space = new float[2 * fSize];
01599 break;
01600 case kTransformCos:
01601 case kTransformSin:
01602 case kTransformFourier:
01603 case kTransformHartley:
01604 case kTransformFourierWalsh:
01605 case kTransformFourierHaar:
01606 case kTransformWalshHaar:
01607 working_space = new float[4 * fSize];
01608 break;
01609 case kTransformCosWalsh:
01610 case kTransformCosHaar:
01611 case kTransformSinWalsh:
01612 case kTransformSinHaar:
01613 working_space = new float[8 * fSize];
01614 break;
01615 }
01616 switch (fTransformType) {
01617 case kTransformHaar:
01618 for (i = 0; i < fSize; i++) {
01619 working_space[i] = source[i];
01620 }
01621 Haar(working_space, fSize, kTransformForward);
01622 break;
01623 case kTransformWalsh:
01624 for (i = 0; i < fSize; i++) {
01625 working_space[i] = source[i];
01626 }
01627 Walsh(working_space, fSize);
01628 BitReverse(working_space, fSize);
01629 break;
01630 case kTransformCos:
01631 fSize = 2 * fSize;
01632 for (i = 1; i <= (fSize / 2); i++) {
01633 val = source[i - 1];
01634 working_space[i - 1] = val;
01635 working_space[fSize - i] = val;
01636 }
01637 Fourier(working_space, fSize, 0, kTransformForward, 0);
01638 for (i = 0; i < fSize / 2; i++) {
01639 a = pi * (double) i / (double) fSize;
01640 a = TMath::Cos(a);
01641 b = working_space[i];
01642 a = b / a;
01643 working_space[i] = a;
01644 working_space[i + fSize] = 0;
01645 } working_space[0] = working_space[0] / TMath::Sqrt(2.0);
01646 fSize = fSize / 2;
01647 break;
01648 case kTransformSin:
01649 fSize = 2 * fSize;
01650 for (i = 1; i <= (fSize / 2); i++) {
01651 val = source[i - 1];
01652 working_space[i - 1] = val;
01653 working_space[fSize - i] = -val;
01654 }
01655 Fourier(working_space, fSize, 0, kTransformForward, 0);
01656 for (i = 0; i < fSize / 2; i++) {
01657 a = pi * (double) i / (double) fSize;
01658 a = TMath::Sin(a);
01659 b = working_space[i];
01660 if (a != 0)
01661 a = b / a;
01662 working_space[i - 1] = a;
01663 working_space[i + fSize] = 0;
01664 }
01665 working_space[fSize / 2 - 1] =
01666 working_space[fSize / 2] / TMath::Sqrt(2.0);
01667 fSize = fSize / 2;
01668 break;
01669 case kTransformFourier:
01670 for (i = 0; i < fSize; i++) {
01671 working_space[i] = source[i];
01672 }
01673 Fourier(working_space, fSize, 0, kTransformForward, 0);
01674 break;
01675 case kTransformHartley:
01676 for (i = 0; i < fSize; i++) {
01677 working_space[i] = source[i];
01678 }
01679 Fourier(working_space, fSize, 1, kTransformForward, 0);
01680 break;
01681 case kTransformFourierWalsh:
01682 case kTransformFourierHaar:
01683 case kTransformWalshHaar:
01684 case kTransformCosWalsh:
01685 case kTransformCosHaar:
01686 case kTransformSinWalsh:
01687 case kTransformSinHaar:
01688 for (i = 0; i < fSize; i++) {
01689 val = source[i];
01690 if (fTransformType == kTransformCosWalsh || fTransformType == kTransformCosHaar) {
01691 j = (int) TMath::Power(2, fDegree) / 2;
01692 k = i / j;
01693 k = 2 * k * j;
01694 working_space[k + i % j] = val;
01695 working_space[k + 2 * j - 1 - i % j] = val;
01696 }
01697
01698 else if (fTransformType == kTransformSinWalsh
01699 || fTransformType == kTransformSinHaar) {
01700 j = (int) TMath::Power(2, fDegree) / 2;
01701 k = i / j;
01702 k = 2 * k * j;
01703 working_space[k + i % j] = val;
01704 working_space[k + 2 * j - 1 - i % j] = -val;
01705 }
01706
01707 else
01708 working_space[i] = val;
01709 }
01710 if (fTransformType == kTransformFourierWalsh
01711 || fTransformType == kTransformFourierHaar
01712 || fTransformType == kTransformWalshHaar) {
01713 for (i = 0; i < j; i++)
01714 BitReverseHaar(working_space, fSize, k, i * k);
01715 GeneralExe(working_space, 0, fSize, fDegree, fTransformType);
01716 }
01717
01718 else if (fTransformType == kTransformCosWalsh || fTransformType == kTransformCosHaar) {
01719 m = (int) TMath::Power(2, fDegree);
01720 l = 2 * fSize / m;
01721 for (i = 0; i < l; i++)
01722 BitReverseHaar(working_space, 2 * fSize, m, i * m);
01723 GeneralExe(working_space, 0, 2 * fSize, fDegree, fTransformType);
01724 for (i = 0; i < fSize; i++) {
01725 k = i / j;
01726 k = 2 * k * j;
01727 a = pi * (double) (i % j) / (double) (2 * j);
01728 a = TMath::Cos(a);
01729 b = working_space[k + i % j];
01730 if (i % j == 0)
01731 a = b / TMath::Sqrt(2.0);
01732
01733 else
01734 a = b / a;
01735 working_space[i] = a;
01736 working_space[i + 2 * fSize] = 0;
01737 }
01738 }
01739
01740 else if (fTransformType == kTransformSinWalsh || fTransformType == kTransformSinHaar) {
01741 m = (int) TMath::Power(2, fDegree);
01742 l = 2 * fSize / m;
01743 for (i = 0; i < l; i++)
01744 BitReverseHaar(working_space, 2 * fSize, m, i * m);
01745 GeneralExe(working_space, 0, 2 * fSize, fDegree, fTransformType);
01746 for (i = 0; i < fSize; i++) {
01747 k = i / j;
01748 k = 2 * k * j;
01749 a = pi * (double) (i % j) / (double) (2 * j);
01750 a = TMath::Cos(a);
01751 b = working_space[j + k + i % j];
01752 if (i % j == 0)
01753 a = b / TMath::Sqrt(2.0);
01754
01755 else
01756 a = b / a;
01757 working_space[j + k / 2 - i % j - 1] = a;
01758 working_space[i + 2 * fSize] = 0;
01759 }
01760 }
01761 if (fTransformType > kTransformWalshHaar)
01762 k = (int) TMath::Power(2, fDegree - 1);
01763
01764 else
01765 k = (int) TMath::Power(2, fDegree);
01766 j = fSize / k;
01767 for (i = 0, l = 0; i < fSize; i++, l = (l + k) % fSize) {
01768 working_space[fSize + i] = working_space[l + i / j];
01769 working_space[fSize + i + 2 * fSize] =
01770 working_space[l + i / j + 2 * fSize];
01771 }
01772 for (i = 0; i < fSize; i++) {
01773 working_space[i] = working_space[fSize + i];
01774 working_space[i + 2 * fSize] = working_space[fSize + i + 2 * fSize];
01775 }
01776 break;
01777 }
01778 if (!working_space) return;
01779 for (i = 0, old_area = 0; i < fSize; i++) {
01780 old_area += working_space[i];
01781 }
01782 for (i = 0, new_area = 0; i < fSize; i++) {
01783 if (i >= fXmin && i <= fXmax)
01784 working_space[i] = fFilterCoeff;
01785 new_area += working_space[i];
01786 }
01787 if (new_area != 0) {
01788 a = old_area / new_area;
01789 for (i = 0; i < fSize; i++) {
01790 working_space[i] *= a;
01791 }
01792 }
01793 if (fTransformType == kTransformFourier) {
01794 for (i = 0, old_area = 0; i < fSize; i++) {
01795 old_area += working_space[i + fSize];
01796 }
01797 for (i = 0, new_area = 0; i < fSize; i++) {
01798 if (i >= fXmin && i <= fXmax)
01799 working_space[i + fSize] = fFilterCoeff;
01800 new_area += working_space[i + fSize];
01801 }
01802 if (new_area != 0) {
01803 a = old_area / new_area;
01804 for (i = 0; i < fSize; i++) {
01805 working_space[i + fSize] *= a;
01806 }
01807 }
01808 }
01809
01810 else if (fTransformType == kTransformFourierWalsh
01811 || fTransformType == kTransformFourierHaar) {
01812 for (i = 0, old_area = 0; i < fSize; i++) {
01813 old_area += working_space[i + 2 * fSize];
01814 }
01815 for (i = 0, new_area = 0; i < fSize; i++) {
01816 if (i >= fXmin && i <= fXmax)
01817 working_space[i + 2 * fSize] = fFilterCoeff;
01818 new_area += working_space[i + 2 * fSize];
01819 }
01820 if (new_area != 0) {
01821 a = old_area / new_area;
01822 for (i = 0; i < fSize; i++) {
01823 working_space[i + 2 * fSize] *= a;
01824 }
01825 }
01826 }
01827 switch (fTransformType) {
01828 case kTransformHaar:
01829 Haar(working_space, fSize, kTransformInverse);
01830 for (i = 0; i < fSize; i++) {
01831 destVector[i] = working_space[i];
01832 }
01833 break;
01834 case kTransformWalsh:
01835 BitReverse(working_space, fSize);
01836 Walsh(working_space, fSize);
01837 for (i = 0; i < fSize; i++) {
01838 destVector[i] = working_space[i];
01839 }
01840 break;
01841 case kTransformCos:
01842 fSize = 2 * fSize;
01843 working_space[0] = working_space[0] * TMath::Sqrt(2.0);
01844 for (i = 0; i < fSize / 2; i++) {
01845 a = pi * (double) i / (double) fSize;
01846 b = TMath::Sin(a);
01847 a = TMath::Cos(a);
01848 working_space[i + fSize] = (double) working_space[i] * b;
01849 working_space[i] = (double) working_space[i] * a;
01850 } for (i = 2; i <= (fSize / 2); i++) {
01851 working_space[fSize - i + 1] = working_space[i - 1];
01852 working_space[fSize - i + 1 + fSize] =
01853 -working_space[i - 1 + fSize];
01854 }
01855 working_space[fSize / 2] = 0;
01856 working_space[fSize / 2 + fSize] = 0;
01857 Fourier(working_space, fSize, 0, kTransformInverse, 1);
01858 for (i = 0; i < fSize / 2; i++) {
01859 destVector[i] = working_space[i];
01860 }
01861 break;
01862 case kTransformSin:
01863 fSize = 2 * fSize;
01864 working_space[fSize / 2] =
01865 working_space[fSize / 2 - 1] * TMath::Sqrt(2.0);
01866 for (i = fSize / 2 - 1; i > 0; i--) {
01867 a = pi * (double) i / (double) fSize;
01868 working_space[i + fSize] =
01869 -(double) working_space[i - 1] * TMath::Cos(a);
01870 working_space[i] = (double) working_space[i - 1] * TMath::Sin(a);
01871 } for (i = 2; i <= (fSize / 2); i++) {
01872 working_space[fSize - i + 1] = working_space[i - 1];
01873 working_space[fSize - i + 1 + fSize] =
01874 -working_space[i - 1 + fSize];
01875 }
01876 working_space[0] = 0;
01877 working_space[fSize] = 0;
01878 working_space[fSize / 2 + fSize] = 0;
01879 Fourier(working_space, fSize, 0, kTransformInverse, 0);
01880 for (i = 0; i < fSize / 2; i++) {
01881 destVector[i] = working_space[i];
01882 }
01883 break;
01884 case kTransformFourier:
01885 Fourier(working_space, fSize, 0, kTransformInverse, 0);
01886 for (i = 0; i < fSize; i++) {
01887 destVector[i] = working_space[i];
01888 }
01889 break;
01890 case kTransformHartley:
01891 Fourier(working_space, fSize, 1, kTransformInverse, 0);
01892 for (i = 0; i < fSize; i++) {
01893 destVector[i] = working_space[i];
01894 }
01895 break;
01896 case kTransformFourierWalsh:
01897 case kTransformFourierHaar:
01898 case kTransformWalshHaar:
01899 case kTransformCosWalsh:
01900 case kTransformCosHaar:
01901 case kTransformSinWalsh:
01902 case kTransformSinHaar:
01903 if (fTransformType > kTransformWalshHaar)
01904 k = (int) TMath::Power(2, fDegree - 1);
01905
01906 else
01907 k = (int) TMath::Power(2, fDegree);
01908 j = fSize / k;
01909 for (i = 0, l = 0; i < fSize; i++, l = (l + k) % fSize) {
01910 working_space[fSize + l + i / j] = working_space[i];
01911 working_space[fSize + l + i / j + 2 * fSize] =
01912 working_space[i + 2 * fSize];
01913 }
01914 for (i = 0; i < fSize; i++) {
01915 working_space[i] = working_space[fSize + i];
01916 working_space[i + 2 * fSize] = working_space[fSize + i + 2 * fSize];
01917 }
01918 if (fTransformType == kTransformFourierWalsh
01919 || fTransformType == kTransformFourierHaar
01920 || fTransformType == kTransformWalshHaar) {
01921 GeneralInv(working_space, fSize, fDegree, fTransformType);
01922 for (i = 0; i < j; i++)
01923 BitReverseHaar(working_space, fSize, k, i * k);
01924 }
01925
01926 else if (fTransformType == kTransformCosWalsh || fTransformType == kTransformCosHaar) {
01927 j = (int) TMath::Power(2, fDegree) / 2;
01928 m = (int) TMath::Power(2, fDegree);
01929 l = 2 * fSize / m;
01930 for (i = 0; i < fSize; i++) {
01931 k = i / j;
01932 k = 2 * k * j;
01933 a = pi * (double) (i % j) / (double) (2 * j);
01934 if (i % j == 0) {
01935 working_space[2 * fSize + k + i % j] =
01936 working_space[i] * TMath::Sqrt(2.0);
01937 working_space[4 * fSize + 2 * fSize + k + i % j] = 0;
01938 }
01939
01940 else {
01941 b = TMath::Sin(a);
01942 a = TMath::Cos(a);
01943 working_space[4 * fSize + 2 * fSize + k + i % j] =
01944 -(double) working_space[i] * b;
01945 working_space[2 * fSize + k + i % j] =
01946 (double) working_space[i] * a;
01947 } } for (i = 0; i < fSize; i++) {
01948 k = i / j;
01949 k = 2 * k * j;
01950 if (i % j == 0) {
01951 working_space[2 * fSize + k + j] = 0;
01952 working_space[4 * fSize + 2 * fSize + k + j] = 0;
01953 }
01954
01955 else {
01956 working_space[2 * fSize + k + 2 * j - i % j] =
01957 working_space[2 * fSize + k + i % j];
01958 working_space[4 * fSize + 2 * fSize + k + 2 * j - i % j] =
01959 -working_space[4 * fSize + 2 * fSize + k + i % j];
01960 }
01961 }
01962 for (i = 0; i < 2 * fSize; i++) {
01963 working_space[i] = working_space[2 * fSize + i];
01964 working_space[4 * fSize + i] =
01965 working_space[4 * fSize + 2 * fSize + i];
01966 }
01967 GeneralInv(working_space, 2 * fSize, fDegree, fTransformType);
01968 m = (int) TMath::Power(2, fDegree);
01969 l = 2 * fSize / m;
01970 for (i = 0; i < l; i++)
01971 BitReverseHaar(working_space, 2 * fSize, m, i * m);
01972 }
01973
01974 else if (fTransformType == kTransformSinWalsh || fTransformType == kTransformSinHaar) {
01975 j = (int) TMath::Power(2, fDegree) / 2;
01976 m = (int) TMath::Power(2, fDegree);
01977 l = 2 * fSize / m;
01978 for (i = 0; i < fSize; i++) {
01979 k = i / j;
01980 k = 2 * k * j;
01981 a = pi * (double) (i % j) / (double) (2 * j);
01982 if (i % j == 0) {
01983 working_space[2 * fSize + k + j + i % j] =
01984 working_space[j + k / 2 - i % j - 1] * TMath::Sqrt(2.0);
01985 working_space[4 * fSize + 2 * fSize + k + j + i % j] = 0;
01986 }
01987
01988 else {
01989 b = TMath::Sin(a);
01990 a = TMath::Cos(a);
01991 working_space[4 * fSize + 2 * fSize + k + j + i % j] =
01992 -(double) working_space[j + k / 2 - i % j - 1] * b;
01993 working_space[2 * fSize + k + j + i % j] =
01994 (double) working_space[j + k / 2 - i % j - 1] * a;
01995 } } for (i = 0; i < fSize; i++) {
01996 k = i / j;
01997 k = 2 * k * j;
01998 if (i % j == 0) {
01999 working_space[2 * fSize + k] = 0;
02000 working_space[4 * fSize + 2 * fSize + k] = 0;
02001 }
02002
02003 else {
02004 working_space[2 * fSize + k + i % j] =
02005 working_space[2 * fSize + k + 2 * j - i % j];
02006 working_space[4 * fSize + 2 * fSize + k + i % j] =
02007 -working_space[4 * fSize + 2 * fSize + k + 2 * j - i % j];
02008 }
02009 }
02010 for (i = 0; i < 2 * fSize; i++) {
02011 working_space[i] = working_space[2 * fSize + i];
02012 working_space[4 * fSize + i] =
02013 working_space[4 * fSize + 2 * fSize + i];
02014 }
02015 GeneralInv(working_space, 2 * fSize, fDegree, fTransformType);
02016 for (i = 0; i < l; i++)
02017 BitReverseHaar(working_space, 2 * fSize, m, i * m);
02018 }
02019 for (i = 0; i < fSize; i++) {
02020 if (fTransformType >= kTransformCosWalsh) {
02021 k = i / j;
02022 k = 2 * k * j;
02023 val = working_space[k + i % j];
02024 }
02025
02026 else
02027 val = working_space[i];
02028 destVector[i] = val;
02029 }
02030 break;
02031 }
02032 delete[]working_space;
02033 return;
02034 }
02035
02036
02037
02038 void TSpectrumTransform::Enhance(const float *source, float *destVector)
02039 {
02040
02041
02042
02043
02044
02045
02046
02047
02048
02049
02050
02051
02052
02053
02054
02055
02056
02057
02058
02059
02060
02061
02062
02063
02064
02065
02066
02067
02068
02069
02070
02071
02072
02073
02074
02075
02076
02077
02078
02079
02080
02081
02082
02083
02084
02085
02086
02087
02088
02089
02090
02091
02092
02093
02094
02095
02096
02097
02098
02099
02100
02101
02102
02103
02104
02105
02106
02107
02108
02109
02110
02111
02112
02113
02114
02115
02116
02117
02118
02119
02120
02121
02122
02123
02124
02125
02126
02127
02128
02129
02130
02131
02132
02133
02134
02135
02136
02137
02138
02139
02140
02141
02142
02143
02144
02145
02146
02147
02148
02149
02150
02151
02152
02153
02154
02155
02156
02157
02158
02159
02160
02161
02162
02163
02164
02165
02166
02167
02168
02169
02170
02171
02172
02173
02174
02175
02176
02177
02178
02179
02180
02181
02182
02183
02184
02185
02186
02187
02188
02189
02190
02191
02192 int i, j=0, k = 1, m, l;
02193 float val;
02194 float *working_space = 0;
02195 double a, b, pi = 3.14159265358979323846, old_area, new_area;
02196 if (fTransformType >= kTransformFourierWalsh && fTransformType <= kTransformSinHaar) {
02197 if (fTransformType >= kTransformCosWalsh)
02198 fDegree += 1;
02199 k = (int) TMath::Power(2, fDegree);
02200 j = fSize / k;
02201 }
02202 switch (fTransformType) {
02203 case kTransformHaar:
02204 case kTransformWalsh:
02205 working_space = new float[2 * fSize];
02206 break;
02207 case kTransformCos:
02208 case kTransformSin:
02209 case kTransformFourier:
02210 case kTransformHartley:
02211 case kTransformFourierWalsh:
02212 case kTransformFourierHaar:
02213 case kTransformWalshHaar:
02214 working_space = new float[4 * fSize];
02215 break;
02216 case kTransformCosWalsh:
02217 case kTransformCosHaar:
02218 case kTransformSinWalsh:
02219 case kTransformSinHaar:
02220 working_space = new float[8 * fSize];
02221 break;
02222 }
02223 switch (fTransformType) {
02224 case kTransformHaar:
02225 for (i = 0; i < fSize; i++) {
02226 working_space[i] = source[i];
02227 }
02228 Haar(working_space, fSize, kTransformForward);
02229 break;
02230 case kTransformWalsh:
02231 for (i = 0; i < fSize; i++) {
02232 working_space[i] = source[i];
02233 }
02234 Walsh(working_space, fSize);
02235 BitReverse(working_space, fSize);
02236 break;
02237 case kTransformCos:
02238 fSize = 2 * fSize;
02239 for (i = 1; i <= (fSize / 2); i++) {
02240 val = source[i - 1];
02241 working_space[i - 1] = val;
02242 working_space[fSize - i] = val;
02243 }
02244 Fourier(working_space, fSize, 0, kTransformForward, 0);
02245 for (i = 0; i < fSize / 2; i++) {
02246 a = pi * (double) i / (double) fSize;
02247 a = TMath::Cos(a);
02248 b = working_space[i];
02249 a = b / a;
02250 working_space[i] = a;
02251 working_space[i + fSize] = 0;
02252 } working_space[0] = working_space[0] / TMath::Sqrt(2.0);
02253 fSize = fSize / 2;
02254 break;
02255 case kTransformSin:
02256 fSize = 2 * fSize;
02257 for (i = 1; i <= (fSize / 2); i++) {
02258 val = source[i - 1];
02259 working_space[i - 1] = val;
02260 working_space[fSize - i] = -val;
02261 }
02262 Fourier(working_space, fSize, 0, kTransformForward, 0);
02263 for (i = 0; i < fSize / 2; i++) {
02264 a = pi * (double) i / (double) fSize;
02265 a = TMath::Sin(a);
02266 b = working_space[i];
02267 if (a != 0)
02268 a = b / a;
02269 working_space[i - 1] = a;
02270 working_space[i + fSize] = 0;
02271 }
02272 working_space[fSize / 2 - 1] =
02273 working_space[fSize / 2] / TMath::Sqrt(2.0);
02274 fSize = fSize / 2;
02275 break;
02276 case kTransformFourier:
02277 for (i = 0; i < fSize; i++) {
02278 working_space[i] = source[i];
02279 }
02280 Fourier(working_space, fSize, 0, kTransformForward, 0);
02281 break;
02282 case kTransformHartley:
02283 for (i = 0; i < fSize; i++) {
02284 working_space[i] = source[i];
02285 }
02286 Fourier(working_space, fSize, 1, kTransformForward, 0);
02287 break;
02288 case kTransformFourierWalsh:
02289 case kTransformFourierHaar:
02290 case kTransformWalshHaar:
02291 case kTransformCosWalsh:
02292 case kTransformCosHaar:
02293 case kTransformSinWalsh:
02294 case kTransformSinHaar:
02295 for (i = 0; i < fSize; i++) {
02296 val = source[i];
02297 if (fTransformType == kTransformCosWalsh || fTransformType == kTransformCosHaar) {
02298 j = (int) TMath::Power(2, fDegree) / 2;
02299 k = i / j;
02300 k = 2 * k * j;
02301 working_space[k + i % j] = val;
02302 working_space[k + 2 * j - 1 - i % j] = val;
02303 }
02304
02305 else if (fTransformType == kTransformSinWalsh
02306 || fTransformType == kTransformSinHaar) {
02307 j = (int) TMath::Power(2, fDegree) / 2;
02308 k = i / j;
02309 k = 2 * k * j;
02310 working_space[k + i % j] = val;
02311 working_space[k + 2 * j - 1 - i % j] = -val;
02312 }
02313
02314 else
02315 working_space[i] = val;
02316 }
02317 if (fTransformType == kTransformFourierWalsh
02318 || fTransformType == kTransformFourierHaar
02319 || fTransformType == kTransformWalshHaar) {
02320 for (i = 0; i < j; i++)
02321 BitReverseHaar(working_space, fSize, k, i * k);
02322 GeneralExe(working_space, 0, fSize, fDegree, fTransformType);
02323 }
02324
02325 else if (fTransformType == kTransformCosWalsh || fTransformType == kTransformCosHaar) {
02326 m = (int) TMath::Power(2, fDegree);
02327 l = 2 * fSize / m;
02328 for (i = 0; i < l; i++)
02329 BitReverseHaar(working_space, 2 * fSize, m, i * m);
02330 GeneralExe(working_space, 0, 2 * fSize, fDegree, fTransformType);
02331 for (i = 0; i < fSize; i++) {
02332 k = i / j;
02333 k = 2 * k * j;
02334 a = pi * (double) (i % j) / (double) (2 * j);
02335 a = TMath::Cos(a);
02336 b = working_space[k + i % j];
02337 if (i % j == 0)
02338 a = b / TMath::Sqrt(2.0);
02339
02340 else
02341 a = b / a;
02342 working_space[i] = a;
02343 working_space[i + 2 * fSize] = 0;
02344 }
02345 }
02346
02347 else if (fTransformType == kTransformSinWalsh || fTransformType == kTransformSinHaar) {
02348 m = (int) TMath::Power(2, fDegree);
02349 l = 2 * fSize / m;
02350 for (i = 0; i < l; i++)
02351 BitReverseHaar(working_space, 2 * fSize, m, i * m);
02352 GeneralExe(working_space, 0, 2 * fSize, fDegree, fTransformType);
02353 for (i = 0; i < fSize; i++) {
02354 k = i / j;
02355 k = 2 * k * j;
02356 a = pi * (double) (i % j) / (double) (2 * j);
02357 a = TMath::Cos(a);
02358 b = working_space[j + k + i % j];
02359 if (i % j == 0)
02360 a = b / TMath::Sqrt(2.0);
02361
02362 else
02363 a = b / a;
02364 working_space[j + k / 2 - i % j - 1] = a;
02365 working_space[i + 2 * fSize] = 0;
02366 }
02367 }
02368 if (fTransformType > kTransformWalshHaar)
02369 k = (int) TMath::Power(2, fDegree - 1);
02370
02371 else
02372 k = (int) TMath::Power(2, fDegree);
02373 j = fSize / k;
02374 for (i = 0, l = 0; i < fSize; i++, l = (l + k) % fSize) {
02375 working_space[fSize + i] = working_space[l + i / j];
02376 working_space[fSize + i + 2 * fSize] =
02377 working_space[l + i / j + 2 * fSize];
02378 }
02379 for (i = 0; i < fSize; i++) {
02380 working_space[i] = working_space[fSize + i];
02381 working_space[i + 2 * fSize] = working_space[fSize + i + 2 * fSize];
02382 }
02383 break;
02384 }
02385 if (!working_space) return;
02386 for (i = 0, old_area = 0; i < fSize; i++) {
02387 old_area += working_space[i];
02388 }
02389 for (i = 0, new_area = 0; i < fSize; i++) {
02390 if (i >= fXmin && i <= fXmax)
02391 working_space[i] *= fEnhanceCoeff;
02392 new_area += working_space[i];
02393 }
02394 if (new_area != 0) {
02395 a = old_area / new_area;
02396 for (i = 0; i < fSize; i++) {
02397 working_space[i] *= a;
02398 }
02399 }
02400 if (fTransformType == kTransformFourier) {
02401 for (i = 0, old_area = 0; i < fSize; i++) {
02402 old_area += working_space[i + fSize];
02403 }
02404 for (i = 0, new_area = 0; i < fSize; i++) {
02405 if (i >= fXmin && i <= fXmax)
02406 working_space[i + fSize] *= fEnhanceCoeff;
02407 new_area += working_space[i + fSize];
02408 }
02409 if (new_area != 0) {
02410 a = old_area / new_area;
02411 for (i = 0; i < fSize; i++) {
02412 working_space[i + fSize] *= a;
02413 }
02414 }
02415 }
02416
02417 else if (fTransformType == kTransformFourierWalsh
02418 || fTransformType == kTransformFourierHaar) {
02419 for (i = 0, old_area = 0; i < fSize; i++) {
02420 old_area += working_space[i + 2 * fSize];
02421 }
02422 for (i = 0, new_area = 0; i < fSize; i++) {
02423 if (i >= fXmin && i <= fXmax)
02424 working_space[i + 2 * fSize] *= fEnhanceCoeff;
02425 new_area += working_space[i + 2 * fSize];
02426 }
02427 if (new_area != 0) {
02428 a = old_area / new_area;
02429 for (i = 0; i < fSize; i++) {
02430 working_space[i + 2 * fSize] *= a;
02431 }
02432 }
02433 }
02434 switch (fTransformType) {
02435 case kTransformHaar:
02436 Haar(working_space, fSize, kTransformInverse);
02437 for (i = 0; i < fSize; i++) {
02438 destVector[i] = working_space[i];
02439 }
02440 break;
02441 case kTransformWalsh:
02442 BitReverse(working_space, fSize);
02443 Walsh(working_space, fSize);
02444 for (i = 0; i < fSize; i++) {
02445 destVector[i] = working_space[i];
02446 }
02447 break;
02448 case kTransformCos:
02449 fSize = 2 * fSize;
02450 working_space[0] = working_space[0] * TMath::Sqrt(2.0);
02451 for (i = 0; i < fSize / 2; i++) {
02452 a = pi * (double) i / (double) fSize;
02453 b = TMath::Sin(a);
02454 a = TMath::Cos(a);
02455 working_space[i + fSize] = (double) working_space[i] * b;
02456 working_space[i] = (double) working_space[i] * a;
02457 } for (i = 2; i <= (fSize / 2); i++) {
02458 working_space[fSize - i + 1] = working_space[i - 1];
02459 working_space[fSize - i + 1 + fSize] =
02460 -working_space[i - 1 + fSize];
02461 }
02462 working_space[fSize / 2] = 0;
02463 working_space[fSize / 2 + fSize] = 0;
02464 Fourier(working_space, fSize, 0, kTransformInverse, 1);
02465 for (i = 0; i < fSize / 2; i++) {
02466 destVector[i] = working_space[i];
02467 }
02468 break;
02469 case kTransformSin:
02470 fSize = 2 * fSize;
02471 working_space[fSize / 2] =
02472 working_space[fSize / 2 - 1] * TMath::Sqrt(2.0);
02473 for (i = fSize / 2 - 1; i > 0; i--) {
02474 a = pi * (double) i / (double) fSize;
02475 working_space[i + fSize] =
02476 -(double) working_space[i - 1] * TMath::Cos(a);
02477 working_space[i] = (double) working_space[i - 1] * TMath::Sin(a);
02478 } for (i = 2; i <= (fSize / 2); i++) {
02479 working_space[fSize - i + 1] = working_space[i - 1];
02480 working_space[fSize - i + 1 + fSize] =
02481 -working_space[i - 1 + fSize];
02482 }
02483 working_space[0] = 0;
02484 working_space[fSize] = 0;
02485 working_space[fSize / 2 + fSize] = 0;
02486 Fourier(working_space, fSize, 0, kTransformInverse, 0);
02487 for (i = 0; i < fSize / 2; i++) {
02488 destVector[i] = working_space[i];
02489 }
02490 break;
02491 case kTransformFourier:
02492 Fourier(working_space, fSize, 0, kTransformInverse, 0);
02493 for (i = 0; i < fSize; i++) {
02494 destVector[i] = working_space[i];
02495 }
02496 break;
02497 case kTransformHartley:
02498 Fourier(working_space, fSize, 1, kTransformInverse, 0);
02499 for (i = 0; i < fSize; i++) {
02500 destVector[i] = working_space[i];
02501 }
02502 break;
02503 case kTransformFourierWalsh:
02504 case kTransformFourierHaar:
02505 case kTransformWalshHaar:
02506 case kTransformCosWalsh:
02507 case kTransformCosHaar:
02508 case kTransformSinWalsh:
02509 case kTransformSinHaar:
02510 if (fTransformType > kTransformWalshHaar)
02511 k = (int) TMath::Power(2, fDegree - 1);
02512
02513 else
02514 k = (int) TMath::Power(2, fDegree);
02515 j = fSize / k;
02516 for (i = 0, l = 0; i < fSize; i++, l = (l + k) % fSize) {
02517 working_space[fSize + l + i / j] = working_space[i];
02518 working_space[fSize + l + i / j + 2 * fSize] =
02519 working_space[i + 2 * fSize];
02520 }
02521 for (i = 0; i < fSize; i++) {
02522 working_space[i] = working_space[fSize + i];
02523 working_space[i + 2 * fSize] = working_space[fSize + i + 2 * fSize];
02524 }
02525 if (fTransformType == kTransformFourierWalsh
02526 || fTransformType == kTransformFourierHaar
02527 || fTransformType == kTransformWalshHaar) {
02528 GeneralInv(working_space, fSize, fDegree, fTransformType);
02529 for (i = 0; i < j; i++)
02530 BitReverseHaar(working_space, fSize, k, i * k);
02531 }
02532
02533 else if (fTransformType == kTransformCosWalsh || fTransformType == kTransformCosHaar) {
02534 j = (int) TMath::Power(2, fDegree) / 2;
02535 m = (int) TMath::Power(2, fDegree);
02536 l = 2 * fSize / m;
02537 for (i = 0; i < fSize; i++) {
02538 k = i / j;
02539 k = 2 * k * j;
02540 a = pi * (double) (i % j) / (double) (2 * j);
02541 if (i % j == 0) {
02542 working_space[2 * fSize + k + i % j] =
02543 working_space[i] * TMath::Sqrt(2.0);
02544 working_space[4 * fSize + 2 * fSize + k + i % j] = 0;
02545 }
02546
02547 else {
02548 b = TMath::Sin(a);
02549 a = TMath::Cos(a);
02550 working_space[4 * fSize + 2 * fSize + k + i % j] =
02551 -(double) working_space[i] * b;
02552 working_space[2 * fSize + k + i % j] =
02553 (double) working_space[i] * a;
02554 } } for (i = 0; i < fSize; i++) {
02555 k = i / j;
02556 k = 2 * k * j;
02557 if (i % j == 0) {
02558 working_space[2 * fSize + k + j] = 0;
02559 working_space[4 * fSize + 2 * fSize + k + j] = 0;
02560 }
02561
02562 else {
02563 working_space[2 * fSize + k + 2 * j - i % j] =
02564 working_space[2 * fSize + k + i % j];
02565 working_space[4 * fSize + 2 * fSize + k + 2 * j - i % j] =
02566 -working_space[4 * fSize + 2 * fSize + k + i % j];
02567 }
02568 }
02569 for (i = 0; i < 2 * fSize; i++) {
02570 working_space[i] = working_space[2 * fSize + i];
02571 working_space[4 * fSize + i] =
02572 working_space[4 * fSize + 2 * fSize + i];
02573 }
02574 GeneralInv(working_space, 2 * fSize, fDegree, fTransformType);
02575 m = (int) TMath::Power(2, fDegree);
02576 l = 2 * fSize / m;
02577 for (i = 0; i < l; i++)
02578 BitReverseHaar(working_space, 2 * fSize, m, i * m);
02579 }
02580
02581 else if (fTransformType == kTransformSinWalsh || fTransformType == kTransformSinHaar) {
02582 j = (int) TMath::Power(2, fDegree) / 2;
02583 m = (int) TMath::Power(2, fDegree);
02584 l = 2 * fSize / m;
02585 for (i = 0; i < fSize; i++) {
02586 k = i / j;
02587 k = 2 * k * j;
02588 a = pi * (double) (i % j) / (double) (2 * j);
02589 if (i % j == 0) {
02590 working_space[2 * fSize + k + j + i % j] =
02591 working_space[j + k / 2 - i % j - 1] * TMath::Sqrt(2.0);
02592 working_space[4 * fSize + 2 * fSize + k + j + i % j] = 0;
02593 }
02594
02595 else {
02596 b = TMath::Sin(a);
02597 a = TMath::Cos(a);
02598 working_space[4 * fSize + 2 * fSize + k + j + i % j] =
02599 -(double) working_space[j + k / 2 - i % j - 1] * b;
02600 working_space[2 * fSize + k + j + i % j] =
02601 (double) working_space[j + k / 2 - i % j - 1] * a;
02602 } } for (i = 0; i < fSize; i++) {
02603 k = i / j;
02604 k = 2 * k * j;
02605 if (i % j == 0) {
02606 working_space[2 * fSize + k] = 0;
02607 working_space[4 * fSize + 2 * fSize + k] = 0;
02608 }
02609
02610 else {
02611 working_space[2 * fSize + k + i % j] =
02612 working_space[2 * fSize + k + 2 * j - i % j];
02613 working_space[4 * fSize + 2 * fSize + k + i % j] =
02614 -working_space[4 * fSize + 2 * fSize + k + 2 * j - i % j];
02615 }
02616 }
02617 for (i = 0; i < 2 * fSize; i++) {
02618 working_space[i] = working_space[2 * fSize + i];
02619 working_space[4 * fSize + i] =
02620 working_space[4 * fSize + 2 * fSize + i];
02621 }
02622 GeneralInv(working_space, 2 * fSize, fDegree, fTransformType);
02623 for (i = 0; i < l; i++)
02624 BitReverseHaar(working_space, 2 * fSize, m, i * m);
02625 }
02626 for (i = 0; i < fSize; i++) {
02627 if (fTransformType >= kTransformCosWalsh) {
02628 k = i / j;
02629 k = 2 * k * j;
02630 val = working_space[k + i % j];
02631 }
02632
02633 else
02634 val = working_space[i];
02635 destVector[i] = val;
02636 }
02637 break;
02638 }
02639 delete[]working_space;
02640 return;
02641 }
02642
02643
02644 void TSpectrumTransform::SetTransformType(Int_t transType, Int_t degree)
02645 {
02646
02647
02648
02649
02650
02651
02652
02653 Int_t j, n;
02654 j = 0;
02655 n = 1;
02656 for (; n < fSize;) {
02657 j += 1;
02658 n = n * 2;
02659 }
02660 if (transType < kTransformHaar || transType > kTransformSinHaar){
02661 Error ("TSpectrumTransform","Invalid type of transform");
02662 return;
02663 }
02664 if (transType >= kTransformFourierWalsh && transType <= kTransformSinHaar) {
02665 if (degree > j || degree < 1){
02666 Error ("TSpectrumTransform","Invalid degree of mixed transform");
02667 return;
02668 }
02669 }
02670 fTransformType=transType;
02671 fDegree=degree;
02672 }
02673
02674
02675
02676 void TSpectrumTransform::SetRegion(Int_t xmin, Int_t xmax)
02677 {
02678
02679
02680
02681
02682
02683
02684 if(xmin<0 || xmax < xmin || xmax >= fSize){
02685 Error("TSpectrumTransform", "Wrong range");
02686 return;
02687 }
02688 fXmin = xmin;
02689 fXmax = xmax;
02690 }
02691
02692
02693 void TSpectrumTransform::SetDirection(Int_t direction)
02694 {
02695
02696
02697
02698
02699
02700
02701 if(direction != kTransformForward && direction != kTransformInverse){
02702 Error("TSpectrumTransform", "Wrong direction");
02703 return;
02704 }
02705 fDirection = direction;
02706 }
02707
02708
02709 void TSpectrumTransform::SetFilterCoeff(Float_t filterCoeff)
02710 {
02711
02712
02713
02714
02715
02716
02717 fFilterCoeff = filterCoeff;
02718 }
02719
02720
02721 void TSpectrumTransform::SetEnhanceCoeff(Float_t enhanceCoeff)
02722 {
02723
02724
02725
02726
02727
02728
02729 fEnhanceCoeff = enhanceCoeff;
02730 }