/* FernUniversität in Hagen, Lehrgebiet Mensch-Computer-Interaktion License: Creative Commons Attribution-Noncommercial-Share Alike 4.0 International, see README file that comes with this work Author: J. Kerdels The use of this code for military and/or intelligence purposes is disapproved of. This file contains the definitions of a discrete wavelet transform (class DWT) and three classes of wavelets (Daubechies, Symlets, Coiflets) that can be used with this transform. general usage example: UInt_t signalsize = 1024; Double_t *signal = new Double_t[signalsize]; // ... fill your signal Daubechies *db = new Daubechies(4); // use Daubechies-wavelets of order 4 DWT::Transform(signal,signalsize,kFALSE,db); // transform the signal in place // ... use the transformed signal, e.g., filter it DWT::Transform(signal,signalsize,kTRUE,db); // perform an inverse transform to // get the signal back // cleanup later delete db; delete[] signal; */ #include #include #include #include "Wavelet.h" void DWT::Transform(Double_t *data, UInt_t *dimensions, Bool_t inverse, Wavelet *wavelet) { // *data : data to transform // *dimensions : null-terminated array of dimension sizes, each dimension // must have a size equal to a power of 2 // inverse : if kTRUE performs inverse transform // *wavelet : wavelet filter coefficients to use if ((data == 0) || (dimensions == 0) || (wavelet == 0) || (dimensions[0] == 0)) return; // get total number of data elements UInt_t dIdx = 0; UInt_t maxDim = 0; UInt_t dataSize = 1; while (dimensions[dIdx] != 0) { UInt_t curDim = dimensions[dIdx++]; dataSize *= curDim; if (curDim > maxDim) maxDim = curDim; } // get sufficiently large buffer Double_t *buffer = new Double_t[maxDim]; // check if dataSize is power of 2 if ((dataSize & (dataSize - 1)) != 0) { std::printf("all dimensions have to be powers of 2\n"); return; } UInt_t prevStep = 1; UInt_t curStep; dIdx = 0; while (dimensions[dIdx] != 0) { //std::printf("processing dimension %d\n",dIdx); // get current size of dimension UInt_t curDim = dimensions[dIdx++]; // clear buffer std::memset(buffer,0,curDim * sizeof(Double_t)); // calc current step curStep = curDim * prevStep; if (curDim > 4) { for (UInt_t dataIdx = 0; dataIdx < dataSize; dataIdx += curStep) { for (UInt_t offIdx = 0; offIdx < prevStep; ++offIdx) { UInt_t sampleIdx; UInt_t localIdx; // fill buffer for (sampleIdx = dataIdx + offIdx, localIdx = 0; localIdx < curDim; ++localIdx, sampleIdx += prevStep) { buffer[localIdx] = data[sampleIdx]; } // perform 1D transform on buffer if (inverse == kFALSE) { for (localIdx = curDim; localIdx >= 4; localIdx /= 2) wavelet->Filter(buffer,localIdx,inverse); } else { for (localIdx = 4; localIdx <= curDim; localIdx *= 2) { //std::printf("calling wavelet filter with localIdx %d\n",localIdx); wavelet->Filter(buffer,localIdx,inverse); } } // copy buffer back for (sampleIdx = dataIdx + offIdx, localIdx = 0; localIdx < curDim; ++localIdx, sampleIdx += prevStep) { data[sampleIdx] = buffer[localIdx]; } } // end for offIdx } // end for dataIdx } // end if curDim // update prevStep prevStep = curStep; } delete[] buffer; } void DWT::Transform(Double_t *data, UInt_t xCnt, Bool_t inverse, Wavelet *wavelet) { // *data : 1D-data to transform // xCnt : size of data // inverse : if kTRUE performs inverse transform // *wavelet : wavelet filter coefficients to use UInt_t dimensions[2] = {xCnt, 0}; Transform(data,dimensions,inverse,wavelet); } void DWT::Transform(Double_t *data, UInt_t xCnt, UInt_t yCnt, Bool_t inverse, Wavelet *wavelet) { // *data : 2D-data to transform // xCnt : size of data in x-direction // yCnt : size of data in y-direction // inverse : if kTRUE performs inverse transform // *wavelet : wavelet filter coefficients to use UInt_t dimensions[3] = {xCnt, yCnt, 0}; Transform(data,dimensions,inverse,wavelet); } void DWT::Transform(Double_t *data, UInt_t xCnt, UInt_t yCnt, UInt_t zCnt, Bool_t inverse, Wavelet *wavelet) { // *data : 2D-data to transform // xCnt : size of data in x-direction // yCnt : size of data in y-direction // zCnt : size of data in z-direction // inverse : if kTRUE performs inverse transform // *wavelet : wavelet filter coefficients to use UInt_t dimensions[4] = {xCnt, yCnt, zCnt, 0}; Transform(data,dimensions,inverse,wavelet); } //--------------------------------------------------------------------------- Wavelet::Wavelet() : fNrOfFilterCoefficients(0), fSmoothCoefficients(0), fDetailCoefficients(0), fBufferSize(0), fBuffer(0) {} Wavelet::~Wavelet() { FreeCoefficients(); FreeBuffer(); } void Wavelet::Filter(Double_t *data, UInt_t size, Bool_t inverse) { if ((data == 0) || (size < 4)) return; if (size > fBufferSize) { FreeBuffer(); fBufferSize = size; fBuffer = new Double_t[fBufferSize]; } std::memset(fBuffer,0,sizeof(Double_t) * fBufferSize); UInt_t offsetComp = fNrOfFilterCoefficients * size; // this constant is zero modulo size and always bigger // then fCenteringOffset. It is used to wrap around // negative indices UInt_t moduloMask = size - 1; // this works as size has to be a power of 2 UInt_t sizeD2 = size / 2; UInt_t dataIdx, bufferIdx, filterIdx; if (inverse == kFALSE) { // use filter UInt_t odIdx, odmIdx; for (dataIdx = 0, bufferIdx = 0; dataIdx < size; dataIdx += 2, ++bufferIdx) { // apply centering offset to data index odIdx = dataIdx + offsetComp + fCenteringOffset; for (filterIdx = 0; filterIdx < fNrOfFilterCoefficients; ++filterIdx) { // add filter index to the offset data index and wrap around odmIdx = (odIdx + filterIdx) & moduloMask; // get "smooth" part fBuffer[bufferIdx] += fSmoothCoefficients[filterIdx] * data[odmIdx]; // get "detail" part fBuffer[bufferIdx + sizeD2] += fDetailCoefficients[filterIdx] * data[odmIdx]; } } } else { // use transpose filter UInt_t obIdx, obmIdx; Double_t smoothValue, detailValue; for (dataIdx = 0, bufferIdx = 0; bufferIdx < size; ++dataIdx, bufferIdx += 2) { smoothValue = data[dataIdx]; detailValue = data[dataIdx + sizeD2]; // apply centering offset to buffer index obIdx = bufferIdx + offsetComp + fCenteringOffset; for (filterIdx = 0; filterIdx < fNrOfFilterCoefficients; ++filterIdx) { // add filter index to the offset data index and wrap around obmIdx = (obIdx + filterIdx) & moduloMask; // add contribution of smooth value fBuffer[obmIdx] += fSmoothCoefficients[filterIdx] * smoothValue; // add contribution of detail value fBuffer[obmIdx] += fSmoothCoefficients[filterIdx] * detailValue; } } } // copy buffer to data std::memcpy(data,fBuffer,sizeof(Double_t) * size); } void Wavelet::SetFilterCoefficients(const Double_t *filterCoefficients, UInt_t count) { FreeCoefficients(); if ((filterCoefficients == 0) || (count == 0)) return; fNrOfFilterCoefficients = count; fCenteringOffset = -((Int_t)count / 2) + 2; fSmoothCoefficients = new Double_t[fNrOfFilterCoefficients]; fDetailCoefficients = new Double_t[fNrOfFilterCoefficients]; //std::printf("copying %d coefficients\n",fNrOfFilterCoefficients); Double_t s = -1.0; for (UInt_t i = 0; i < fNrOfFilterCoefficients; ++i) { fSmoothCoefficients[i] = filterCoefficients[i]; fDetailCoefficients[fNrOfFilterCoefficients-1-i] = s * filterCoefficients[i]; s = -s; } } void Wavelet::FreeCoefficients() { if (fSmoothCoefficients != 0) { delete[] fSmoothCoefficients; fSmoothCoefficients = 0; } if (fDetailCoefficients != 0) { delete[] fDetailCoefficients; fDetailCoefficients = 0; } fNrOfFilterCoefficients = 0; } void Wavelet::FreeBuffer() { if (fBuffer != 0) { delete[] fBuffer; fBuffer = 0; } fBufferSize = 0; } Daubechies::Daubechies(UInt_t order) : Wavelet() { switch (order) { case 1 : { SetFilterCoefficients( D1 + 1, (UInt_t)( D1[0])); } break; case 2 : { SetFilterCoefficients( D2 + 1, (UInt_t)( D2[0])); } break; case 3 : { SetFilterCoefficients( D3 + 1, (UInt_t)( D3[0])); } break; case 4 : { SetFilterCoefficients( D4 + 1, (UInt_t)( D4[0])); } break; case 5 : { SetFilterCoefficients( D5 + 1, (UInt_t)( D5[0])); } break; case 6 : { SetFilterCoefficients( D6 + 1, (UInt_t)( D6[0])); } break; case 7 : { SetFilterCoefficients( D7 + 1, (UInt_t)( D7[0])); } break; case 8 : { SetFilterCoefficients( D8 + 1, (UInt_t)( D8[0])); } break; case 9 : { SetFilterCoefficients( D9 + 1, (UInt_t)( D9[0])); } break; case 10 : { SetFilterCoefficients(D10 + 1, (UInt_t)(D10[0])); } break; case 11 : { SetFilterCoefficients(D11 + 1, (UInt_t)(D11[0])); } break; case 12 : { SetFilterCoefficients(D12 + 1, (UInt_t)(D12[0])); } break; case 13 : { SetFilterCoefficients(D13 + 1, (UInt_t)(D13[0])); } break; case 14 : { SetFilterCoefficients(D14 + 1, (UInt_t)(D14[0])); } break; case 15 : { SetFilterCoefficients(D15 + 1, (UInt_t)(D15[0])); } break; case 16 : { SetFilterCoefficients(D16 + 1, (UInt_t)(D16[0])); } break; case 17 : { SetFilterCoefficients(D17 + 1, (UInt_t)(D17[0])); } break; case 18 : { SetFilterCoefficients(D18 + 1, (UInt_t)(D18[0])); } break; case 19 : { SetFilterCoefficients(D19 + 1, (UInt_t)(D19[0])); } break; case 20 : { SetFilterCoefficients(D20 + 1, (UInt_t)(D20[0])); } break; default : { std::printf("No coefficient set available for order %d\n",order); } } } const Double_t Daubechies::D1[] = { 2, 0.70710678118654757, 0.70710678118654757 }; const Double_t Daubechies::D2[] = { 4, 0.48296291314469025, 0.83651630373746899, 0.22414386804185735, -0.12940952255092145 }; const Double_t Daubechies::D3[] = { 6, 0.33267055295095688, 0.80689150931333875, 0.45987750211933132, -0.13501102001039084, -0.085441273882241486, 0.035226291882100656 }; const Double_t Daubechies::D4[] = { 8, 0.23037781330885523, 0.71484657055254153, 0.63088076792959036, -0.027983769416983849, -0.18703481171888114, 0.030841381835986965, 0.032883011666982945, -0.010597401784997278 }; const Double_t Daubechies::D5[] = { 10, 0.16010239797412501, 0.60382926979747287, 0.72430852843857441, 0.13842814590110342, -0.24229488706619015, -0.03224486958502952, 0.077571493840065148, -0.0062414902130117052, -0.012580751999015526, 0.0033357252850015492 }; const Double_t Daubechies::D6[] = { 12, 0.11154074335008017, 0.49462389039838539, 0.75113390802157753, 0.3152503517092432, -0.22626469396516913, -0.12976686756709563, 0.097501605587079362, 0.027522865530016288, -0.031582039318031156, 0.0005538422009938016, 0.0047772575110106514, -0.0010773010849955799 }; const Double_t Daubechies::D7[] = { 14, 0.077852054085062364, 0.39653931948230575, 0.72913209084655506, 0.4697822874053586, -0.14390600392910627, -0.22403618499416572, 0.071309219267050042, 0.080612609151065898, -0.038029936935034633, -0.01657454163101562, 0.012550998556013784, 0.00042957797300470274, -0.0018016407039998328, 0.00035371380000103988 }; const Double_t Daubechies::D8[] = { 16, 0.054415842243081609, 0.31287159091446592, 0.67563073629801285, 0.58535468365486909, -0.015829105256023893, -0.28401554296242809, 0.00047248457399797254, 0.12874742662018601, -0.017369301002022108, -0.044088253931064719, 0.013981027917015516, 0.0087460940470156547, -0.0048703529930106603, -0.00039174037299597711, 0.00067544940599855677, -0.00011747678400228192 }; const Double_t Daubechies::D9[] = { 18, 0.038077947363167282, 0.24383467463766728, 0.6048231236767786, 0.65728807803663891, 0.13319738582208895, -0.29327378327258685, -0.096840783220879037, 0.14854074933476008, 0.030725681478322865, -0.067632829059523988, 0.00025094711499193845, 0.022361662123515244, -0.004723204757894831, -0.0042815036819047227, 0.0018476468829611268, 0.00023038576399541288, -0.00025196318899817888, 3.9347319995026124e-05 }; const Double_t Daubechies::D10[] = { 20, 0.026670057900950818, 0.18817680007762133, 0.52720118893091983, 0.68845903945259213, 0.28117234366042648, -0.24984642432648865, -0.19594627437659665, 0.12736934033574265, 0.093057364603806592, -0.071394147165860775, -0.029457536821945671, 0.033212674058933238, 0.0036065535669883944, -0.010733175482979604, 0.0013953517469940798, 0.0019924052949908499, -0.00068585669500468248, -0.0001164668549943862, 9.3588670001089845e-05, -1.3264203002354869e-05 }; const Double_t Daubechies::D11[] = { 22, 0.018694297761470441, 0.14406702115061959, 0.44989976435603013, 0.68568677491617847, 0.41196436894789695, -0.16227524502747828, -0.27423084681792875, 0.066043588196690886, 0.14981201246638268, -0.04647995511667613, -0.066438785695020222, 0.031335090219045313, 0.020840904360180039, -0.015364820906201324, -0.0033408588730145018, 0.0049284176560587777, -0.00030859285881515924, -0.00089302325066623663, 0.00024915252355281426, 5.4439074699366381e-05, -3.4634984186983789e-05, 4.4942742772363519e-06 }; const Double_t Daubechies::D12[] = { 24, 0.013112257957229239, 0.10956627282118277, 0.37735513521420411, 0.65719872257929113, 0.51588647842780067, -0.044763885653777619, -0.31617845375277914, -0.023779257256064865, 0.18247860592758275, 0.0053595696743599965, -0.09643212009649671, 0.010849130255828966, 0.041546277495087637, -0.01221864906974642, -0.012840825198299882, 0.0067114990087955486, 0.0022486072409952287, -0.0021795036186277044, 6.5451282125215034e-06, 0.00038865306282092672, -8.8504109208203182e-05, -2.4241545757030318e-05, 1.2776952219379579e-05, -1.5290717580684923e-06 }; const Double_t Daubechies::D13[] = { 26, 0.0092021335389622788, 0.082861243872901946, 0.31199632216043488, 0.61105585115878114, 0.58888957043121193, 0.086985726179645007, -0.31497290771138414, -0.12457673075080665, 0.17947607942935084, 0.072948933656788742, -0.10580761818792761, -0.026488406475345658, 0.056139477100276156, 0.0023799722540522269, -0.023831420710327809, 0.0039239414487955773, 0.0072555894016171187, -0.002761911234656831, -0.0013156739118922766, 0.00093232613086724904, 4.9251525126285676e-05, -0.00016512898855650571, 3.0678537579324358e-05, 1.0441930571407941e-05, -4.7004164793608082e-06, 5.2200350984547998e-07 }; const Double_t Daubechies::D14[] = { 28, 0.0064611534600864905, 0.062364758849384874, 0.25485026779256437, 0.55430561794077093, 0.63118784910471981, 0.21867068775886594, -0.27168855227867705, -0.21803352999321651, 0.13839521386479153, 0.13998901658445695, -0.086748411568110598, -0.071548955503983505, 0.05523712625925082, 0.026981408307947971, -0.030185351540353976, -0.0056150495303375755, 0.012789493266340071, -0.00074621898926387534, -0.003849638868019787, 0.001061691085606874, 0.00070802115423540481, -0.00038683194731287514, -4.1777245770370672e-05, 6.875504252695734e-05, -1.0337209184568496e-05, -4.3897049017804176e-06, 1.7249946753674012e-06, -1.7871399683109222e-07 }; const Double_t Daubechies::D15[] = { 30, 0.0045385373615773762, 0.046743394892750617, 0.20602386398692688, 0.49263177170797529, 0.64581314035721027, 0.33900253545462167, -0.19320413960907623, -0.28888259656686216, 0.065282952848765688, 0.19014671400708816, -0.039666176555733602, -0.11112093603713753, 0.033877143923563204, 0.054780550584559995, -0.025767007328366939, -0.020810050169636805, 0.015083918027862582, 0.0051010003604228726, -0.0064877345603061454, -0.00024175649075894543, 0.0019433239803823459, -0.00037348235413726472, -0.00035956524436229364, 0.00015589648992055726, 2.579269915531323e-05, -2.8133296266037558e-05, 3.3629871817363823e-06, 1.8112704079399406e-06, -6.3168823258794506e-07, 6.1333599133037138e-08 }; const Double_t Daubechies::D16[] = { 32, 0.0031892209253436892, 0.034907714323629047, 0.1650642834886438, 0.43031272284545874, 0.63735633208298326, 0.44029025688580486, -0.089751089402363524, -0.32706331052747578, -0.02791820813292813, 0.21119069394696974, 0.027340263752899923, -0.13238830556335474, -0.0062397227521562536, 0.075924236044457791, -0.0075889743686425939, -0.036888397691556774, 0.010297659641009963, 0.013993768859843242, -0.0069900145633907508, -0.0036442796214883506, 0.00312802338120381, 0.00040789698084934395, -0.00094102174935854332, 0.00011424152003843815, 0.00017478724522506327, -6.103596621404321e-05, -1.394566898819319e-05, 1.133660866126152e-05, -1.0435713423102517e-06, -7.3636567854418147e-07, 2.3087840868545578e-07, -2.1093396300980412e-08 }; const Double_t Daubechies::D17[] = { 34, 0.0022418070010387899, 0.025985393703623173, 0.13121490330791097, 0.37035072415288578, 0.61099661568502728, 0.5183157640572823, 0.027314970403312946, -0.32832074836418546, -0.12659975221599248, 0.19731058956508457, 0.10113548917744287, -0.12681569177849797, -0.057091419631858077, 0.081105986654080822, 0.022312336178011833, -0.046922438389378908, -0.0032709555358783646, 0.022733676583919053, -0.0030429899813869555, -0.0086029215203478147, 0.0029679966915180638, 0.0023012052421511474, -0.001436845304805, -0.00032813251941022427, 0.00043946542776894542, -2.5610109566546042e-05, -8.2048032024582121e-05, 2.3186813798761639e-05, 6.9906009850812941e-06, -4.5059424772259631e-06, 3.0165496099963414e-07, 2.9577009333187617e-07, -8.4239484460081536e-08, 7.2674929685663697e-09 }; const Double_t Daubechies::D18[] = { 36, 0.0015763102184365595, 0.019288531724094969, 0.10358846582214751, 0.31467894133619284, 0.57182680776508177, 0.57180165488712198, 0.14722311196952223, -0.29365404073579809, -0.21648093400458224, 0.14953397556500755, 0.16708131276294505, -0.092331884150304119, -0.10675224665906288, 0.064887216212358198, 0.057051247739058272, -0.04452614190225633, -0.023733210395336858, 0.026670705926689853, 0.0062621679544386608, -0.013051480946517112, 0.00011863003387493042, 0.0049433436054565939, -0.0011187326669886426, -0.0013405962983313922, 0.00062846568296447147, 0.0002135815619103188, -0.00019864855231101547, -1.5359171230213409e-07, 3.7412378807308472e-05, -8.5206025374234635e-06, -3.3326344788769603e-06, 1.7687129836228861e-06, -7.691632689865049e-08, -1.1760987670250871e-07, 3.0688358630370302e-08, -2.5079344549419292e-09 }; const Double_t Daubechies::D19[] = { 38, 0.0011086697631864314, 0.01428109845082521, 0.08127811326580564, 0.26438843174202237, 0.52443637746688621, 0.60170454913009164, 0.26089495265212009, -0.22809139421653665, -0.28583863175723145, 0.074652269708066474, 0.21234974330662043, -0.033518541903202262, -0.14278569504021468, 0.027584350624887129, 0.086906755555450702, -0.026501236250778635, -0.045674226277784918, 0.021623767409452484, 0.019375549889114482, -0.013988388678695632, -0.0058669222811121953, 0.0070407473670804953, 0.00076895435922424884, -0.0026875518007344408, 0.00034180865344939543, 0.0007358025205041731, -0.00026067613568119951, -0.00012460079173506306, 8.7112704672504432e-05, 5.1059504870906939e-06, -1.6640176297224622e-05, 3.0109643163099385e-06, 1.5319314766978769e-06, -6.8627556577981102e-07, 1.4470882988040879e-08, 4.6369377758023682e-08, -1.1164020670405678e-08, 8.6668488390344833e-10 }; const Double_t Daubechies::D20[] = { 40, 0.00077995361366591117, 0.010549394624937735, 0.063423780459005291, 0.21994211355113222, 0.47269618531033147, 0.61049323893785579, 0.36150229873889705, -0.13921208801128787, -0.32678680043353758, -0.016727088308801888, 0.22829105082013823, 0.039850246458519104, -0.15545875070604531, -0.024716827337521424, 0.10229171917513397, 0.0056322468576854544, -0.061722899624668884, 0.0058746818113949465, 0.032294299530119162, -0.0087893249245557647, -0.013810526137727442, 0.0067216273018096935, 0.0044205423867663502, -0.003581494259744107, -0.00083156217287724745, 0.0013925596193045254, -5.3497598443404532e-05, -0.0003851047486990061, 0.00010153288973669777, 6.7742808283730477e-05, -3.7105861833906152e-05, -4.3761438621821972e-06, 7.2412482876637907e-06, -1.0119940100181473e-06, -6.847079596993149e-07, 2.633924226266962e-07, 2.0143220235374613e-10, -1.8148432482976221e-08, 4.05612705554717e-09, -2.9988364896157532e-10 }; Symlets::Symlets(UInt_t order) : Wavelet() { switch (order) { case 2 : { SetFilterCoefficients( S2 + 1, (UInt_t)( S2[0])); } break; case 3 : { SetFilterCoefficients( S3 + 1, (UInt_t)( S3[0])); } break; case 4 : { SetFilterCoefficients( S4 + 1, (UInt_t)( S4[0])); } break; case 5 : { SetFilterCoefficients( S5 + 1, (UInt_t)( S5[0])); } break; case 6 : { SetFilterCoefficients( S6 + 1, (UInt_t)( S6[0])); } break; case 7 : { SetFilterCoefficients( S7 + 1, (UInt_t)( S7[0])); } break; case 8 : { SetFilterCoefficients( S8 + 1, (UInt_t)( S8[0])); } break; case 9 : { SetFilterCoefficients( S9 + 1, (UInt_t)( S9[0])); } break; case 10 : { SetFilterCoefficients(S10 + 1, (UInt_t)(S10[0])); } break; case 11 : { SetFilterCoefficients(S11 + 1, (UInt_t)(S11[0])); } break; case 12 : { SetFilterCoefficients(S12 + 1, (UInt_t)(S12[0])); } break; case 13 : { SetFilterCoefficients(S13 + 1, (UInt_t)(S13[0])); } break; case 14 : { SetFilterCoefficients(S14 + 1, (UInt_t)(S14[0])); } break; case 15 : { SetFilterCoefficients(S15 + 1, (UInt_t)(S15[0])); } break; case 16 : { SetFilterCoefficients(S16 + 1, (UInt_t)(S16[0])); } break; case 17 : { SetFilterCoefficients(S17 + 1, (UInt_t)(S17[0])); } break; case 18 : { SetFilterCoefficients(S18 + 1, (UInt_t)(S18[0])); } break; case 19 : { SetFilterCoefficients(S19 + 1, (UInt_t)(S19[0])); } break; case 20 : { SetFilterCoefficients(S20 + 1, (UInt_t)(S20[0])); } break; default : { std::printf("No coefficient set available for order %d\n",order); } } } const Double_t Symlets::S2[] = { 4, 0.48296291314469025, 0.83651630373746899, 0.22414386804185735, -0.12940952255092145 }; const Double_t Symlets::S3[] = { 6, 0.33267055295095688, 0.80689150931333875, 0.45987750211933132, -0.13501102001039084, -0.085441273882241486, 0.035226291882100656 }; const Double_t Symlets::S4[] = { 8, 0.032223100604042702, -0.012603967262037833, -0.099219543576847216, 0.29785779560527736, 0.80373875180591614, 0.49761866763201545, -0.02963552764599851, -0.075765714789273325 }; const Double_t Symlets::S5[] = { 10, 0.019538882735286728, -0.021101834024758855, -0.17532808990845047, 0.016602105764522319, 0.63397896345821192, 0.72340769040242059, 0.1993975339773936, -0.039134249302383094, 0.029519490925774643, 0.027333068345077982 }; const Double_t Symlets::S6[] = { 12, -0.007800708325034148, 0.0017677118642428036, 0.044724901770665779, -0.021060292512300564, -0.072637522786462516, 0.3379294217276218, 0.787641141030194, 0.49105594192674662, -0.048311742585632998, -0.11799011114819057, 0.0034907120842174702, 0.015404109327027373 }; const Double_t Symlets::S7[] = { 14, 0.010268176708511255, 0.0040102448715336634, -0.10780823770381774, -0.14004724044296152, 0.28862963175151463, 0.76776431700316405, 0.5361019170917628, 0.017441255086855827, -0.049552834937127255, 0.067892693501372697, 0.03051551316596357, -0.01263630340325193, -0.0010473848886829163, 0.0026818145682578781 }; const Double_t Symlets::S8[] = { 16, 0.0018899503327594609, -0.0003029205147213668, -0.014952258337048231, 0.0038087520138906151, 0.049137179673607506, -0.027219029917056003, -0.051945838107709037, 0.3644418948353314, 0.77718575170052351, 0.48135965125837221, -0.061273359067658524, -0.14329423835080971, 0.0076074873249176054, 0.031695087811492981, -0.00054213233179114812, -0.0033824159510061256 }; const Double_t Symlets::S9[] = { 18, 0.0010694900329086053, -0.00047315449868008311, -0.010264064027633142, 0.0088592674934004842, 0.06207778930288603, -0.018233770779395985, -0.19155083129728512, 0.035272488035271894, 0.61733844914093583, 0.717897082764412, 0.238760914607303, -0.054568958430834071, 0.00058346274612580684, 0.03022487885827568, -0.01152821020767923, -0.013271967781817119, 0.00061978088898558676, 0.0014009155259146807 }; const Double_t Symlets::S10[] = { 20, -0.00045932942100465878, 5.7036083618494284e-05, 0.0045931735853118284, -0.00080435893201654491, -0.02035493981231129, 0.0057649120335819086, 0.049994972077376687, -0.0319900568824278, -0.035536740473817552, 0.38382676106708546, 0.7695100370211071, 0.47169066693843925, -0.070880535783243853, -0.15949427888491757, 0.011609893903711381, 0.045927239231092203, -0.0014653825813050513, -0.0086412992770224222, 9.5632670722894754e-05, 0.00077015980911449011 }; const Double_t Symlets::S11[] = { 22, 0.00048926361026192387, 0.00011053509764272153, -0.0063896036664548919, -0.0020034719001093887, 0.043000190681552281, 0.035266759564466552, -0.14460234370531561, -0.2046547944958006, 0.23768990904924897, 0.73034354908839572, 0.57202297801008706, 0.097198394458909473, -0.022832651022562687, 0.069976799610734136, 0.0370374159788594, -0.024080841595864003, -0.0098579348287897942, 0.0065124956747714497, 0.00058835273539699145, -0.0017343662672978692, -3.8795655736158566e-05, 0.00017172195069934854 }; const Double_t Symlets::S12[] = { 24, -0.00017906658697508691, -1.8158078862617515e-05, 0.0023502976141834648, 0.00030764779631059454, -0.014589836449234145, -0.0026043910313322326, 0.057804179445505657, 0.01530174062247884, -0.17037069723886492, -0.07833262231634322, 0.46274103121927235, 0.76347909778365719, 0.39888597239022, -0.022162306170337816, -0.035848830736954392, 0.049179318299660837, 0.0075537806116804775, -0.024220722675013445, -0.0014089092443297553, 0.007414965517654251, 0.00018021409008538188, -0.0013497557555715387, -1.1353928041541452e-05, 0.00011196719424656033 }; const Double_t Symlets::S13[] = { 26, 7.0429866906944016e-05, 3.6905373423196241e-05, -0.0007213643851362283, 0.00041326119884196064, 0.0056748537601224395, -0.0014924472742598532, -0.020749686325515677, 0.017618296880653084, 0.092926030899137119, 0.0088197576704205465, -0.14049009311363403, 0.11023022302137217, 0.64456438390118564, 0.69573915056149638, 0.19770481877117801, -0.12436246075153011, -0.059750627717943698, 0.013862497435849205, -0.017211642726299048, -0.02021676813338983, 0.0052963597387250252, 0.0075262253899680996, -0.00017094285853022211, -0.0011360634389281183, -3.5738623648689009e-05, 6.8203252630753188e-05 }; const Double_t Symlets::S14[] = { 28, 4.4618977991475265e-05, 1.9329016965523917e-05, -0.00060576018246643346, -7.3214213567023991e-05, 0.0045326774719456481, 0.0010131419871842082, -0.019439314263626713, -0.0023650488367403851, 0.069827616361807551, 0.025898587531046669, -0.15999741114652205, -0.058111823317717831, 0.47533576263420663, 0.75997624196109093, 0.39320152196208885, -0.035318112114979733, -0.057634498351326995, 0.037433088362853452, 0.0042805204990193782, -0.029196217764038187, -0.0027537747912240711, 0.010037693717672269, 0.00036647657366011829, -0.002579441725933078, -6.2865424814776362e-05, 0.00039843567297594335, 1.1210865808890361e-05, -2.5879090265397886e-05 }; const Double_t Symlets::S15[] = { 30, 2.8660708525318081e-05, 2.1717890150778919e-05, -0.00040216853760293483, -0.00010815440168545525, 0.003481028737064895, 0.0015261382781819983, -0.017171252781638731, -0.0087447888864779517, 0.067969829044879179, 0.068393310060480245, -0.13405629845625389, -0.1966263587662373, 0.2439627054321663, 0.72184302963618119, 0.57864041521503451, 0.11153369514261872, -0.04108266663538248, 0.040735479696810677, 0.021937642719753955, -0.038876716876833493, -0.019405011430934468, 0.010079977087905669, 0.003423450736351241, -0.0035901654473726417, -0.00026731644647180568, 0.0010705672194623959, 5.5122547855586653e-05, -0.00016066186637495343, -7.3596667989194696e-06, 9.7124197379633478e-06 }; const Double_t Symlets::S16[] = { 32, -1.0797982104319795e-05, -5.3964831793152419e-06, 0.00016545679579108483, 3.656592483348223e-05, -0.0013387206066921965, -0.00022211647621176323, 0.0069377611308027096, 0.001359844742484172, -0.024952758046290123, -0.0035102750683740089, 0.078037852903419913, 0.03072113906330156, -0.15959219218520598, -0.054040601387606135, 0.47534280601152273, 0.75652498787569711, 0.39712293362064416, -0.034574228416972504, -0.066983049070217779, 0.032333091610663785, 0.0048692744049046071, -0.031051202843553064, -0.0031265171722710075, 0.012666731659857348, 0.00071821197883178923, -0.0038809122526038786, -0.0001084456223089688, 0.00085235471080470952, 2.8078582128442894e-05, -0.00010943147929529757, -3.1135564076219692e-06, 6.2300067012207606e-06 }; const Double_t Symlets::S17[] = { 34, 3.7912531943321266e-06, -2.4527163425832999e-06, -7.6071244056051285e-05, 2.5207933140828779e-05, 0.0007198270642148971, 5.8400428694052584e-05, -0.0039323252797979023, -0.0019054076898526659, 0.012396988366648726, 0.0099529825235095976, -0.01803889724191924, -0.0072616347509287674, 0.016158808725919346, -0.086070874720733381, -0.15507600534974825, 0.18053958458111286, 0.68148899534492502, 0.65071662920454565, 0.14239835041467819, -0.11856693261143636, 0.0172711782105185, 0.10475461484223211, 0.017903952214341119, -0.033291383492359328, -0.0048192128031761478, 0.010482366933031529, 0.0008567700701915741, -0.0027416759756816018, -0.00013864230268045499, 0.0004759963802638669, -1.3506383399901165e-05, -6.2937025975541919e-05, 2.7801266938414138e-06, 4.297343327345983e-06 }; const Double_t Symlets::S18[] = { 36, -1.5131530692371587e-06, 7.8472980558317646e-07, 2.9557437620930811e-05, -9.858816030140058e-06, -0.00026583011024241041, 4.7416145183736671e-05, 0.0014280863270832796, -0.00018877623940755607, -0.0052397896830266083, 0.0010877847895956929, 0.015012356344250213, -0.0032607442000749834, -0.031712684731814537, 0.0062779445543116943, 0.028529597039037808, -0.073799207290607169, -0.032480573290138676, 0.40148386057061813, 0.75362914010179283, 0.47396905989393956, -0.052029158983952786, -0.15993814866932407, 0.033995667103947358, 0.084219929970386548, -0.0050770851607570529, -0.030325091089369604, 0.0016429863972782159, 0.0095021643909623654, -0.00041152110923597756, -0.0023138718145060992, 7.0212734590362685e-05, 0.00039616840638254753, -1.4020992577726755e-05, -4.5246757874949856e-05, 1.354915761832114e-06, 2.6126125564836423e-06 }; const Double_t Symlets::S19[] = { 38, 1.7509367995348687e-06, 2.0623170632395688e-06, -2.8151138661550245e-05, -1.6821387029373716e-05, 0.00027621877685734072, 0.00012930767650701415, -0.0017049602611649971, -0.00061792232779831076, 0.0082622369555282547, 0.0043193518748949689, -0.027709896931311252, -0.016908234861345205, 0.084072676279245043, 0.093630843415897141, -0.11624173010739675, -0.17659686625203097, 0.25826616923728363, 0.71955552571639425, 0.57814494533860505, 0.10902582508127781, -0.067525058040294086, 0.0089545911730436242, 0.0070155738571741596, -0.046635983534938946, -0.022651993378245951, 0.015797439295674631, 0.0079684383206133063, -0.005122205002583014, -0.0011607032572062486, 0.0021214250281823303, 0.00015915804768084938, -0.00063576451500433403, -4.6120396002105868e-05, 0.0001155392333357879, 8.8733121737292863e-06, -1.1880518269823984e-05, -6.4636513033459633e-07, 5.4877327682158382e-07 }; const Double_t Symlets::S20[] = { 40, -6.3291290447763946e-07, -3.2567026420174407e-07, 1.22872527779612e-05, 4.5254222091516362e-06, -0.00011739133516291466, -2.6615550335516086e-05, 0.00074761085978205719, 0.00012544091723067259, -0.0034716478028440734, -0.0006111263857992088, 0.012157040948785737, 0.0019385970672402002, -0.035373336756604236, -0.0068437019650692274, 0.088919668028199561, 0.036250951653933078, -0.16057829841525254, -0.051088342921067398, 0.47199147510148703, 0.75116272842273002, 0.40583144434845059, -0.029819368880333728, -0.078994344928398158, 0.025579349509413946, 0.0081232283560096815, -0.031629437144957966, -0.0033138573836233591, 0.017004049023390339, 0.0014230873594621453, -0.0066065857990888609, -0.0003052628317957281, 0.0020889947081901982, 7.2159911880740349e-05, -0.00049473109156726548, -1.928412300645204e-05, 7.992967835772481e-05, 3.0256660627369661e-06, -7.919361411976999e-06, -1.9015675890554106e-07, 3.695537474835221e-07 }; Coiflets::Coiflets(UInt_t order) : Wavelet() { switch (order) { case 1 : { SetFilterCoefficients( C1 + 1, (UInt_t)( C1[0])); } break; case 2 : { SetFilterCoefficients( C2 + 1, (UInt_t)( C2[0])); } break; case 3 : { SetFilterCoefficients( C3 + 1, (UInt_t)( C3[0])); } break; case 4 : { SetFilterCoefficients( C4 + 1, (UInt_t)( C4[0])); } break; case 5 : { SetFilterCoefficients( C5 + 1, (UInt_t)( C5[0])); } break; default : { std::printf("No coefficient set available for order %d\n",order); } } } const Double_t Coiflets::C1[] = { 6, -0.072732619512853897, 0.33789766245780922, 0.85257202021225542, 0.38486484686420286, -0.072732619512853897, -0.01565572813546454 }; const Double_t Coiflets::C2[] = { 12, 0.016387336463522112, -0.041464936781759151, -0.067372554721963018, 0.38611006682116222, 0.81272363544554227, 0.41700518442169254, -0.076488599078306393, -0.059434418646456898, 0.023680171946334084, 0.0056114348193944995, -0.0018232088707029932, -0.00072054944536451221 }; const Double_t Coiflets::C3[] = { 18, -0.0037935128644910141, 0.0077825964273254182, 0.023452696141836267, -0.0657719112818555, -0.061123390002672869, 0.4051769024096169, 0.79377722262562056, 0.42848347637761874, -0.071799821619312018, -0.082301927106885983, 0.034555027573061628, 0.015880544863615904, -0.0090079761366615805, -0.0025745176887502236, 0.0011175187708906016, 0.00046621696011288631, -7.0983303138141252e-05, -3.4599772836212559e-05 }; const Double_t Coiflets::C4[] = { 24, 0.00089231366858231456, -0.0016294920126017326, -0.0073461663276420935, 0.016068943964776348, 0.026682300156053072, -0.081266699680878754, -0.056077313316754807, 0.41530840703043026, 0.78223893092049901, 0.4343860564914685, -0.066627474263425038, -0.096220442033987982, 0.039334427123337491, 0.025082261844864097, -0.015211731527946259, -0.0056582866866107199, 0.0037514361572784571, 0.0012665619292989445, -0.00058902075624433831, -0.00025997455248771324, 6.2339034461007128e-05, 3.1229875865345646e-05, -3.2596802368833675e-06, -1.7849850030882614e-06 }; const Double_t Coiflets::C5[] = { 30, -0.00021208083980379827, 0.00035858968789573785, 0.0021782363581090178, -0.004159358781386048, -0.010131117519849788, 0.023408156785839195, 0.02816802897093635, -0.091920010559696244, -0.052043163176243773, 0.42156620669085149, 0.77428960365295618, 0.43799162617183712, -0.062035963962903569, -0.10557420870333893, 0.041289208750181702, 0.032683574267111833, -0.019761778942572639, -0.0091642311624818458, 0.0067641854480530832, 0.0024333732126576722, -0.0016628637020130838, -0.00063813134304511142, 0.00030225958181306315, 0.00014054114970203437, -4.1340432272512511e-05, -2.1315026809955787e-05, 3.7346551751414047e-06, 2.0637618513646814e-06, -1.6744288576823017e-07, -9.517657273819165e-08 };