Logo Coherent WaveBurst  
Reference Guide
Logo
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
WaveDWT.cc
Go to the documentation of this file.
1 // $Id: WaveDWT.cc,v 1.6 2002/06/27 06:30:43 klimenko Exp $
2 
3 #define WAVEDWT_CC
4 
5 #include <strstream>
6 #include <stdexcept>
7 #include "WaveDWT.hh"
8 
9 //namespace datacondAPI {
10 //namespace wat {
11 
12 ClassImp(WaveDWT<double>)
13 
14 using namespace std;
15 
16 // constructors
17 
18 template<class DataType_t>
19 WaveDWT<DataType_t>::
20 WaveDWT(int mH,int mL,int tree, enum BORDER border) :
21 Wavelet(mH, mL, tree, border), pWWS(NULL), nWWS(0), nSTS(0)
22 { }
23 
24 template<class DataType_t>
26 Wavelet(w), pWWS(NULL), nWWS(0), nSTS(0)
27 {
28  std::cout<<" I am WaveDWT Clone: "<<endl;
29 }
30 
31 template<class DataType_t>
33 Wavelet(w), pWWS(NULL), nWWS(0)
34 {
35  this->nSTS = w.nSTS;
36 }
37 
38 // destructor
39 template<class DataType_t>
41 {
42  release();
43 }
44 
45 template<class DataType_t>
47 {
48  return new WaveDWT<DataType_t>(*this);
49 }
50 
51 // - Virtual procedure for forward wavelet transform.
52 // - Real code for decompose will appear in a derivative
53 // classe, since it depends of the wavelet type.
54 // - Only ldeep steps of decomposition will be done.
55 // - By default ldeep=1, which means do one step.
56 template<class DataType_t>
57 void WaveDWT<DataType_t>::t2w(int ldeep)
58 {
59  int maxLevel = getMaxLevel();
60 
61  int levs = m_Level;
62  int levf = m_Level+ldeep;
63  if((ldeep == -1) || (levf > maxLevel)) levf = maxLevel;
64 
65  int layf;
66  for(int level=levs; level<levf; level++)
67  {
68  layf = (m_TreeType) ? 1<<level : 1;
69 
70  for(int layer=0; layer<layf; layer++)
71  forward(level,layer);
72 
73  m_Level=level+1;
74 
75  }
76 
77  m_Level = levf;
78  m_Layer = (m_TreeType) ? (1<<m_Level)-1 : m_Level;
79 
80 }
81 
82 // - Virtual procedure for inverse wavelet transform.
83 // - Real code for reconstruct will appear in a derivative
84 // classe, since it depends of the type of wavelet.
85 // - Only ldeep steps of reconstruction will be done.
86 // - By default ldeep=1, which means do one step.
87 template<class DataType_t>
88 void WaveDWT<DataType_t>::w2t(int ldeep)
89 {
90  int levs = m_Level;
91  int levf = m_Level-ldeep;
92  if((ldeep == -1) || (levf < 0)) levf = 0;
93 
94  int layf;
95  for(int level=levs-1; level>=levf; level--)
96  {
97  layf = (m_TreeType) ? 1<<level : 1;
98 
99  for(int layer=0; layer<layf; layer++)
100  inverse(level,layer);
101 
102  m_Level=level;
103 
104  }
105  m_Level=levf;
106 }
107 
108 
109 // access function
110 template<class DataType_t>
112 {
113 // convert layer index or frequency index to slice
114 // input parameter is the layer number. In general the layer number
115 // is integer, but double is used to distinguish between o and 90 phase
116 // zero layers in WDM: they are accessed as getLayer(+-0.x)
117  int level = m_Level;
118  int layer = int(fabs(index)+0.001); // convert to int
119 
120  int maxlayer = (BinaryTree()) ? (1<<level)-1 : level;
121 
122  if(layer > maxlayer){
123  layer = maxlayer;
124 
125  std::ostrstream oss;
126  oss << "WaveDWT::getSlice(): "
127  << "argument "<<index<<" is set to " << layer << endl;
128 
129  std::invalid_argument exception(oss.str());
130  oss.freeze(0);
131  throw exception;
132  }
133 
134  if(BinaryTree()){
135  layer = convertF2L(level,layer);
136  }
137  else {
138 
139  if(layer) { // detail layers
140  level -= layer-1;
141  layer = 1;
142  }
143  else{ // approximation layer
144  layer = 0;
145  }
146  }
147 
148  return getSlice(level,layer);
149 }
150 
151 // convert (level,layer) to slice
152 template<class DataType_t>
153 slice WaveDWT<DataType_t>::getSlice(const int level, const int layer)
154 {
155  if(!allocate()){
156  std::invalid_argument("WaveDWT::getSlice(): data is not allocated");
157  return slice(0,1,1);
158  }
159 
160  size_t m = nWWS>>level; // number of elements
161  size_t s = 1<<level; // slice step
162  size_t i = getOffset(level,layer); // first element
163 
164  if(i+(m-1)*s+1 > nWWS){
165  std::invalid_argument("WaveDWT::getSlice(): invalide arguments");
166  return slice(0,1,1);
167  }
168 
169  return slice(i,m,s);
170 }
171 
172 
173 // Calculate maximal level of wavelet decomposition,
174 // which depends on the length of wavelet filters.
175 template<class DataType_t>
177 {
178  if(!allocate()) return 0;
179  return Wavelet::getMaxLevel((int)nWWS);
180 }
181 
182 // allocate input data
183 template<class DataType_t>
185 allocate(size_t n, DataType_t *p)
186 {
187  bool allocate = false;
188  if(pWWS == NULL && n>0 && p != NULL){
189  allocate = true;
190  pWWS = p;
191  nWWS = n;
192  }
193  return allocate;
194 }
195 
196 // check allocation status
197 template<class DataType_t>
199 {
200  return (pWWS == NULL || nWWS == 0) ? false : true;
201 }
202 
203 // release input data
204 template<class DataType_t>
206 {
207  pWWS = NULL;
208  nWWS = 0;
209 }
210 
211 // forward does one step of forward Fast Wavelet Transform.
212 // It's implemented for FWT with even number of coefficients.
213 // Also the lenght of high and low pass filters is the same,
214 // It is used for Daubechies, Symlet and Meyer wavelets.
215 //
216 // <level> input parameter is the level to be transformed
217 // <layer> input parameter is the layer to be transformed.
218 // <pF> wavelet filter, the pF length is m_H=m_L
219 //
220 // note: borders are handled in B_CYCLE mode
221 // note: even wavelet mode is standard
222 
223 template<class DataType_t>
224 void WaveDWT<DataType_t>::forwardFWT(int level, int layer,
225  const double* pLPF,
226  const double* pHPF)
227 {
228  int VM = (m_H/2&1); // 1 if Odd Vanishing Moments
229  int nS = nWWS>>level; // number of samples in the layer
230  int kL = -(m_H/2-VM); // k left limit for left border
231  int iL = nS-m_H+1; // i left limit for regular case
232 
233 // switch to odd wavelet mode
234 // if(m_Parity && layer&1) kL -= VM ? 1 : -1;
235  if(m_Parity) kL -= VM ? 1 : -1;
236 
237  int iR = nS+kL; // i right limit for right border
238 
239 //EVM--------------odd wavelet mode-----------------------
240 //
241 // LP [a0] [h0] | h1 h2 h3 0 0 0 0 h0 | [s0]
242 // HP [d0] [h3] |-h2 h1 -h0 0 0 0 0 h3 | [s1]
243 // [a1] | 0 h0 h1 h2 h3 0 0 0 | [s2]
244 // for [d1] = | 0 h3 -h2 h1 -h0 0 0 0 | X [s3]
245 // DB2 [a2] = | 0 0 0 h0 h1 h2 h3 0 | X [s4]
246 // [d2] | 0 0 0 h3 -h2 h1 -h0 0 | [s5]
247 // [a3] | 0 0 0 0 0 h0 h1 h2 | [ h3] [s6]
248 // [d3] |-h0 0 0 0 0 h3 -h2 h1 | [-h0] [s7]
249 //
250 //EVM--------------even border handling---------------------
251 //
252 // LP [a0] [h0 h1] | h2 h3 0 0 0 0 h0 h1 | [s0]
253 // HP [d0] [h3 -h2] | h1 -h0 0 0 0 0 h3 -h2 | [s1]
254 // [a1] | h0 h1 h2 h3 0 0 0 0 | [s2]
255 // for [d1] = | h3 -h2 h1 -h0 0 0 0 0 | X [s3]
256 // DB2 [a2] = | 0 0 h0 h1 h2 h3 0 0 | X [s4]
257 // [d2] | 0 0 h3 -h2 h1 -h0 0 0 | [s5]
258 // [a3] | 0 0 0 0 h0 h1 h2 h3 | [s6]
259 // [d3] | 0 0 0 0 h3 -h2 h1 -h0 | [s7]
260 //
261 //
262 // temp array: a d a d a d ..... a d a d a d
263 // a - approximations, d - details
264 //---------------------------------------------------------
265 
266 
267 //OVM---------------odd border handling-----------------------
268 //
269 // index i: -3 -2 -1 | 0 1 2 3 4 5 6 7 8
270 // limits: iL iR
271 //
272 // index k: -3 -2 -1 | 0 1 2 3 4 5 6 7 8 9 10 11 | 12 13
273 // limits: kL kR
274 //
275 // LP h0 h1 h2 | h3 h4 h5 0 0 0 0 0 0 h0 h1 h2 |
276 // HP h5 -h4 h3 | -h2 h1 -h0 0 0 0 0 0 0 h5 -h4 h3 |
277 // h0 | h1 h2 h3 h4 h5 0 0 0 0 0 0 h0 |
278 // for h5 | -h4 h3 -h2 h1 -h0 0 0 0 0 0 0 h5 |
279 // DB3 | 0 h0 h1 h2 h3 h4 h5 0 0 0 0 0 |
280 // | 0 h5 -h4 h3 -h2 h1 -h0 0 0 0 0 0 |
281 // | 0 0 0 h0 h1 h2 h3 h4 h5 0 0 0 |
282 // | 0 0 0 h5 -h4 h3 -h2 h1 -h0 0 0 0 |
283 // | 0 0 0 0 0 h0 h1 h2 h3 h4 h5 0 |
284 // | 0 0 0 0 0 h5 -h4 h3 -h2 h1 -h0 0 |
285 // | h5 0 0 0 0 0 0 h0 h1 h2 h3 h4 | h5
286 // | -h0 0 0 0 0 0 0 h5 -h4 h3 -h2 h1 | -h0
287 //
288 //OVM---------------even border handling-----------------------
289 //
290 // index i: -2 -1 | 0 1 2 3 4 5 6 7 8 9 10
291 // limits: iL iR
292 //
293 // index k: -2 -1 | 0 1 2 3 4 5 6 7 8 9 10 11 | 12 13 14
294 // limits: kL kR
295 //
296 // LP h0 h1 | h2 h3 h4 h5 0 0 0 0 0 0 h0 h1 |
297 // HP h5 -h4 | h3 -h2 h1 -h0 0 0 0 0 0 0 h5 -h4 |
298 // | h0 h1 h2 h3 h4 h5 0 0 0 0 0 0 |
299 // for | h5 -h4 h3 -h2 h1 -h0 0 0 0 0 0 0 |
300 // DB3 | 0 0 h0 h1 h2 h3 h4 h5 0 0 0 0 |
301 // | 0 0 h5 -h4 h3 -h2 h1 -h0 0 0 0 0 |
302 // | 0 0 0 0 h0 h1 h2 h3 h4 h5 0 0 |
303 // | 0 0 0 0 h5 -h4 h3 -h2 h1 -h0 0 0 |
304 // | 0 0 0 0 0 0 h0 h1 h2 h3 h4 h5 |
305 // | 0 0 0 0 0 0 h5 -h4 h3 -h2 h1 -h0 |
306 // | h4 h5 0 0 0 0 0 0 h0 h1 h2 h3 | h4 h5
307 // | h1 -h0 0 0 0 0 0 0 h5 -h4 h3 -h2 | h1 -h0
308 //
309 // temp array: a d a d a d ..... a d a d a d
310 // a - approximations, d - details
311 //---------------------------------------------------------
312 
313  if(pLPF==NULL || pHPF==NULL) return;
314 
315  register int i,j,k;
316  register double sumA, sumD, data;
317  register const double *p = pLPF;
318  register const double *q = pHPF;
319  register DataType_t *pD;
320  register int stride = 1<<level; // stride parameter
321 
322 // pointer to the first sample in the layer
323  DataType_t *pData = pWWS+getOffset(level,layer);
324 
325  double *temp = new double[nS]; // temporary array
326 
327 // left border
328 
329  i = kL;
330 
331  while(i<0) {
332  sumA=0.; sumD=0.;
333 
334  for(j=0; j<m_H; j++) {
335  k = i+j;
336  if(k < 0) k += nS;
337  data = pData[k<<level];
338  sumA += *p++ * data;
339  sumD += *q++ * data;
340  }
341 
342  *temp++ = sumA;
343  *temp++ = sumD;
344  i += 2;
345  p -= m_H;
346  q -= m_H;
347  }
348 
349 // processing data in the middle of array
350 
351  while(i<iL) {
352  pD = pData + (i<<level) - stride;
353  sumA=0.; sumD=0.;
354 
355  for(j=0; j<m_H; j+=2) {
356  data = *(pD += stride);
357  sumA += *p++ * data;
358  sumD += *q++ * data;
359  data = *(pD += stride);
360  sumA += *p++ * data;
361  sumD += *q++ * data;
362  }
363 
364  *temp++ = sumA;
365  *temp++ = sumD;
366  i += 2;
367  p -= m_H;
368  q -= m_H;
369  }
370 
371 // right border
372 
373  while(i<iR) {
374  sumA=0.; sumD=0.;
375 
376  for(j=0; j<m_H; j++) {
377  k = i+j;
378  if(k >= nS) k -= nS;
379  data = pData[k<<level];
380  sumA += *p++ * data;
381  sumD += *q++ * data;
382  }
383 
384  *temp++ = sumA;
385  *temp++ = sumD;
386  i += 2;
387  p -= m_H;
388  q -= m_H;
389  }
390 
391 // writing data back from temporary storage
392  for(i=nS-1; i>=0; i--) {pData[i<<level] = *(--temp);}
393 
394  if(m_Heterodine){
395  for(i=1; i<nS; i+=4) {pData[i<<level] *= -1;} // heterodine detailes coefficients
396  }
397 
398  delete [] temp;
399 }
400 
401 
402 // inverse does one step of inverse Fast Wavelet Transform.
403 // It's implemented for FWT with even number of coefficients.
404 // Also the lenght of high and low pass filters is the same
405 // It is used for Daubechies and Symlet wavelets.
406 //
407 // <level> input parameter is the level to be transformed
408 // <layer> input parameter is the layer to be transformed.
409 // <pF> wavelet filter, the pF length is m_H=m_L
410 //
411 // note: borders are handled in B_CYCLE mode
412 // note: even wavelet mode is standard
413 
414 template<class DataType_t>
415 void WaveDWT<DataType_t>::inverseFWT(int level, int layer,
416  const double* pLPF,
417  const double* pHPF)
418 {
419  if(pLPF==NULL || pHPF==NULL) return;
420 
421  int VM = (m_H/2&1); // 1 if Odd Vanishing Moments
422  int nS = nWWS>>level; // number of samples in the layer
423  int kL = -(m_H/2-2+VM); // k left limit
424  int iL = nS-m_H+1; // i left limit
425 
426  // bool ODD = m_Parity && layer&1;
427  bool ODD = m_Parity;
428  if(ODD) { kL -= 2-2*VM; }
429 
430  int iR = nS+kL; // i right limit
431 
432 // iLP filter for db2: h3 -h0 h1 -h2
433 // iHP filter for db2: h2 h1 h0 h3
434 // inverse matrix is transpose of forward matrix
435 //EVM------------------odd border handling-----------------------
436 //
437 // index i: -2 -1 0 1 2 3 4 5 6
438 // limits: iL iR
439 //
440 // index k: -2 -1 0 1 2 3 4 5 6 7 8 9
441 // limits: kL
442 // iHP [s0] h3 -h0 | h1 -h2 0 0 0 0 h3 -h0 | [a0]
443 // iLP [s1] | h2 h1 h0 h3 0 0 0 0 | [d0]
444 // [s2] | h3 -h0 h1 -h2 0 0 0 0 | [a1]
445 // for [s3] = | 0 0 h2 h1 h0 h3 0 0 | X [d1]
446 // DB2 [s4] = | 0 0 h3 -h0 h1 -h2 0 0 | X [a2]
447 // [s5] | 0 0 0 0 h2 h1 h0 h3 | [d2]
448 // [s6] | 0 0 0 0 h3 -h0 h1 -h2 | [a3]
449 // [s7] | h0 h3 0 0 0 0 h2 h1 | h0 h3 [d3]
450 //
451 //EVM---------------even border handling-----------------------
452 //
453 // iLP [s0] | h2 h1 h0 h3 0 0 0 0 | [a0]
454 // iHP [s1] | h3 -h0 h1 -h2 0 0 0 0 | [d0]
455 // [s2] | 0 0 h2 h1 h0 h3 0 0 | [a1]
456 // for [s3] = | 0 0 h3 -h0 h1 -h2 0 0 | X [d1]
457 // DB2 [s4] = | 0 0 0 0 h2 h1 h0 h3 | X [a2]
458 // [s5] | 0 0 0 0 h3 -h0 h1 -h2 | [d2]
459 // [s6] | h0 h3 0 0 0 0 h2 h1 | [a3]
460 // [s7] | h1 -h2 0 0 0 0 h3 -h0 | [d3]
461 //
462 // temp array: a d a d a d ..... a d a d a d
463 // a - approximations, d - details
464 //---------------------------------------------------------
465 
466 // iLP filter for db3: h4 h1 h2 h3 h0 h5
467 // iHP filter for db3: h5 -h0 h3 -h2 h1 -h4
468 //OVM---------------odd border handling-----------------------
469 //
470 // index i: -2 -1 | 0 1 2 3 4 5 6 7 8 9 10
471 // limits: iL iR
472 //
473 // index k: -2 -1 | 0 1 2 3 4 5 6 7 8 9 10 11 | 12 13
474 // limits: kL kR
475 //
476 // HP h5 -h0 | h3 -h2 h1 -h4 0 0 0 0 0 0 h5 -h4 |
477 // LP | h4 h1 h2 h3 h0 h5 0 0 0 0 0 0 |
478 // | h5 -h0 h3 -h2 h1 -h4 0 0 0 0 0 0 |
479 // for | 0 0 h4 h1 h2 h3 h0 h5 0 0 0 0 |
480 // DB3 | 0 0 h5 -h0 h3 -h2 h1 -h4 0 0 0 0 |
481 // | 0 0 0 0 h4 h1 h2 h3 h0 h5 0 0 |
482 // | 0 0 0 0 h5 -h0 h3 -h2 h1 -h4 0 0 |
483 // | 0 0 0 0 0 0 h4 h1 h2 h3 h0 h5 |
484 // | 0 0 0 0 0 0 h5 -h0 h3 -h2 h1 -h4 |
485 // | h0 h5 0 0 0 0 0 0 h4 h1 h2 h3 | h0 h5
486 // | h1 -h4 0 0 0 0 0 0 h5 -h0 h3 -h2 | h1 -h4
487 // | h2 h3 h0 h5 0 0 0 0 0 0 h4 h1 | h2 h3 h0 h5
488 //
489 //OVM---------------even border handling-----------------------
490 //
491 // index i: -2 -1 | 0 1 2 3 4 5 6 7 8
492 // limits: iL iR
493 //
494 // index k: -2 -1 | 0 1 2 3 4 5 6 7 8 9 10 11 | 12 13 14
495 // limits: kL kR
496 //
497 // LP h4 h1 | h2 h3 h0 h5 0 0 0 0 0 0 h4 h1 |
498 // HP h5 -h0 | h3 -h2 h1 -h4 0 0 0 0 0 0 h5 -h0 |
499 // | h4 h1 h2 h3 h0 h5 0 0 0 0 0 0 |
500 // for | h5 -h0 h3 -h2 h1 -h4 0 0 0 0 0 0 |
501 // DB3 | 0 0 h4 h1 h2 h3 h0 h5 0 0 0 0 |
502 // | 0 0 h5 -h0 h3 -h2 h1 -h4 0 0 0 0 |
503 // | 0 0 0 0 h4 h1 h2 h3 h0 h5 0 0 |
504 // | 0 0 0 0 h5 -h0 h3 -h2 h1 -h4 0 0 |
505 // | 0 0 0 0 0 0 h4 h1 h2 h3 h0 h5 |
506 // | 0 0 0 0 0 0 h5 -h0 h3 -h2 h1 -h4 |
507 // | h0 h5 0 0 0 0 0 0 h4 h1 h2 h3 | h0 h5
508 // | h1 -h4 0 0 0 0 0 0 h5 -h0 h3 -h2 | h1 -h4
509 //
510 // temp array: a d a d a d ..... a d a d a d
511 // a - approximations, d - details
512 //---------------------------------------------------------
513 
514 
515  register long i,j,k;
516  register double sumA, sumD, data;
517  register const double *p = pLPF;
518  register const double *q = pHPF;
519  register DataType_t *pD;
520  register int stride = 1<<level; // stride parameter
521 
522 // pointer to the first sample in the layer
523  DataType_t *pData = pWWS+getOffset(level,layer);
524 
525  double *temp = new double[nS]; // temporary array
526 
527  if(m_Heterodine){
528  for(i=1; i<nS; i+=4) {pData[i<<level] *= -1;} // heterodine detailes coefficients
529  }
530 
531 // left border
532 
533  i = kL;
534 
535  if(ODD){ // handle ODD wavelet mode on left border
536  p = pHPF;
537  *temp = 0;
538 
539  for(j=0; j<m_H; j++) {
540  k = i+j;
541  if(k < 0) k += nS;
542  *temp += *p++ * pData[k<<level];
543  }
544  temp++;
545  i += 2;
546  p = pLPF;
547  }
548 
549  while(i<0) {
550  sumA = 0.; sumD = 0.;
551 
552  for(j=0; j<m_H; j++) {
553  k = i+j;
554  if(k < 0) k += nS;
555  data = pData[k<<level];
556  sumA += *p++ * data;
557  sumD += *q++ * data;
558  }
559 
560  *temp++ = sumA;
561  *temp++ = sumD;
562  i += 2;
563  p -= m_H;
564  q -= m_H;
565  }
566 
567 // processing data in the middle of array
568 
569  while(i<iL) {
570  pD = pData + (i<<level) - stride;
571  sumA = 0.; sumD = 0.;
572 
573  for(j=0; j<m_H; j+=2) {
574  data = *(pD += stride);
575  sumA += *p++ * data;
576  sumD += *q++ * data;
577  data = *(pD += stride);
578  sumD += *q++ * data;
579  sumA += *p++ * data;
580  }
581 
582  *temp++ = sumA;
583  *temp++ = sumD;
584  i += 2;
585  p -= m_H;
586  q -= m_H;
587  }
588 
589 // right border
590 
591  while(i<iR) {
592  sumA = 0.; sumD = 0.;
593 
594  for(j=0; j<m_H; j++) {
595  k = i+j;
596  if(k >= nS) k -= nS;
597  data = pData[k<<level];
598  sumA += *p++ * data;
599  sumD += *q++ * data;
600  }
601 
602  *temp++ = sumA;
603  *temp++ = sumD;
604  i += 2;
605  p -= m_H;
606  q -= m_H;
607  }
608 
609  if(ODD){ // handle odd wavelet mode on right border
610  q = pLPF;
611  *temp = 0.;
612 
613  for(j=0; j<m_H; j++) {
614  k = i+j;
615  if(k >= nS) k -= nS;
616  *temp += *q++ * pData[k<<level];
617  }
618  temp++;
619  }
620 
621 // writing data back from temporary storage
622  for(i=nS-1; i>=0; i--)
623  pData[i<<level] = *(--temp);
624 
625  delete [] temp;
626 }
627 
628 // predict function does one lifting prediction step
629 // <level> input parameter is the level to be transformed
630 // <layer> input parameter is the layer to be transformed.
631 // <p_H> pointer to prediction filter. It has length m_H
632 template<class DataType_t>
634  int layer,
635  const double* p_H)
636 {
637  level++; // increment level (next level now)
638 
639 //------------------predict border handling-----------------------
640 // use even samples to predict odd samples
641 // an example for m_H=8 and 20 samples
642 // i index limits nL............nM....nR-1
643 // i index : -3 -2 -1 0 1 2 3 4 5 6
644 // j index (approx): -3 -2 -1 0 1 2 3 4 5 6 7 8 9 | 10 11 12 13
645 // odd samples: 0 1 2 3 4 5 6 7 8 9
646 // L L L M M M R R R R
647 // L,R - samples affected by borders
648 // M - not affected samples
649 //---------------------------------------------------------
650 
651  int nS = nWWS>>level; // nS - number of samples in the layer
652  int nL = 1-m_H/2; // nL - left limit of predict i index
653  int nR = nS+nL; // nR - right limit of predict i index
654  int nM = nS-m_H+1; // nM - number of M samples (first aR sample)
655  int mM = nM<<level; // (number of M samples)<<level
656 
657  double data;
658  double hsum = 0.; // filter sum
659 
660  register int i,j,k;
661  register double sum = 0.;
662 
663  register const double *h; // pointer to filter coefficient
664  register const DataType_t *dataL; // pointer to left data sample
665  register const DataType_t *dataR; // pointer to right data sample
666  register const int stride = 1<<level; // stride parameter
667 
668  double *pBorder=new double[2*(m_H-nL)]; // border array
669  double *pB;
670 
671  DataType_t *dataA, *dataD;
672 
673  dataA=pWWS+getOffset(level,layer<<1); // pointer to approximation layer
674  dataD=pWWS+getOffset(level,(layer<<1)+1); // pointer to detail layer
675 
676  for(k=0; k<m_H; k++) hsum += p_H[k];
677 
678 // left border
679 
680  pB = pBorder;
681  dataL = dataA; // first (left) sample
682  for(k=0; k<(m_H-nL); k++){
683  j = k + nL;
684  pB[k] = *(dataL + abs(j<<level));
685 
686  if(j>=0) continue;
687 
688  data = *(dataL + ((j+nS)<<level));
689  switch (m_Border) {
690  case B_PAD_ZERO : pB[k] = 0.; break; // pad zero
691  case B_PAD_EDGE : pB[k] = *dataL; break; // pad by edge value
692  case B_CYCLE : pB[k] = data; break; // cycle data
693  default : break; // mirror or interpolate
694  }
695  }
696 
697  for(i=nL; i<0; i++) { // i index
698 
699  if(m_Border != B_POLYNOM){
700  sum = 0.;
701  for(k=0; k<m_H/2; k++)
702  sum += p_H[k] * (pB[k] + pB[m_H-1-k]);
703  pB++;
704  }
705  else{
706 // pB = pBorder - nL; // point to dataA
707 // sum = hsum*Nevill(i+0.5-nL, m_H+i, pB, pB+m_H); // POLYNOM1
708  pB = pBorder - nL; // point to dataA
709  sum = hsum*Nevill(i+0.5-nL, m_H+2*i, pB, pB+m_H); // POLYNOM2
710  }
711 
712  *dataD -= sum;
713  dataD += stride;
714  }
715 
716 // regular case (no borders)
717 
718  k = (m_H-1)<<level;
719 
720  for(i=0; i<mM; i+=stride) {
721  dataL = dataA+i;
722  dataR = dataL+k;
723  h = p_H;
724 
725  sum=0.;
726  do sum += *(h++) * (*dataL + *dataR);
727  while((dataL+=stride) < (dataR-=stride));
728 /*
729  sum = *(h++) * (*dataL + *dataR);
730  if ((dataL+=stride) > (dataR-=stride)) goto P0;
731  sum += *(h++) * (*dataL + *dataR);
732  if ((dataL+=stride) > (dataR-=stride)) goto P0;
733  sum += *(h++) * (*dataL + *dataR);
734  if ((dataL+=stride) > (dataR-=stride)) goto P0;
735  sum += *(h++) * (*dataL + *dataR);
736  if ((dataL+=stride) > (dataR-=stride)) goto P0;
737  sum += *(h++) * (*dataL + *dataR);
738  if ((dataL+=stride) > (dataR-=stride)) goto P0;
739  sum += *(h++) * (*dataL + *dataR);
740  if ((dataL+=stride) > (dataR-=stride)) goto P0;
741  sum += *(h++) * (*dataL + *dataR);
742  if ((dataL+=stride) > (dataR-=stride)) goto P0;
743  sum += *(h++) * (*dataL + *dataR);
744  if ((dataL+=stride) > (dataR-=stride)) goto P0;
745  sum += *(h++) * (*dataL + *dataR);
746  if ((dataL+=stride) > (dataR-=stride)) goto P0;
747  sum += *(h++) * (*dataL + *dataR);
748  if ((dataL+=stride) > (dataR-=stride)) goto P0;
749  sum += *(h++) * (*dataL + *dataR);
750  if ((dataL+=stride) > (dataR-=stride)) goto P0;
751  sum += *(h++) * (*dataL + *dataR);
752  if ((dataL+=stride) > (dataR-=stride)) goto P0;
753  sum += *(h++) * (*dataL + *dataR);
754  if ((dataL+=stride) > (dataR-=stride)) goto P0;
755  sum += *(h++) * (*dataL + *dataR);
756  if ((dataL+=stride) > (dataR-=stride)) goto P0;
757  sum += *(h++) * (*dataL + *dataR);
758 
759 P0: *dataD -= sum; */
760  *dataD -= sum;
761  dataD += stride;
762  }
763 
764 // right border
765 
766  pB = pBorder;
767  dataR = dataA + ((nS-1)<<level); // last (right) sample
768 
769  for(k=0; k<(m_H-nL+1); k++){
770  j = m_H - 1 - k;
771  pB[k] = *(dataR - abs(j<<level));
772 
773  if(j>=0) continue;
774 
775  data = *(dataR - ((j+nS)<<level));
776  switch (m_Border) {
777  case B_PAD_ZERO : pB[k] = 0.; break; // pad zero
778  case B_PAD_EDGE : pB[k] = *dataR; break; // pad by edge value
779  case B_CYCLE : pB[k] = data; break; // cycle data
780  default : break; // mirror or interpolate
781  }
782  }
783 
784  k = 0;
785  for(i=nM; i<nR; i++) {
786 
787  if(m_Border != B_POLYNOM){
788  sum = 0.; pB++;
789 
790  for(k=0; k<m_H/2; k++)
791  sum += p_H[k] * (pB[k] + pB[m_H-1-k]);
792  }
793  else{
794 // sum = hsum*Nevill(0.5-nL, nS-i, ++pB, pBorder+m_H+1);
795  k += 2;
796  sum = hsum*Nevill((m_H-k-1)/2., m_H-k, pB+k, pBorder+m_H+1);
797  if(k == m_H) sum = *(pB+k-1) * hsum;
798  }
799 
800  *dataD -= sum;
801  dataD += stride;
802  }
803 
804  delete [] pBorder;
805 }
806 
807 
808 // update function does one lifting update step
809 // <level> input parameter is the level to be transformed.
810 // <layer> input parameter is the layer to be transformed.
811 
812 template<class DataType_t>
814  int layer,
815  const double* p_L)
816 {
817  level++; // current level
818 
819 //------------------update border handling-----------------------
820 // use odd samples to update even samples
821 // an example for m_H=8 and 20 samples
822 // L L L L M M M R R R
823 // even samples : 0 1 2 3 4 5 6 7 8 9
824 // j index (detail): -4 -3 -2 -1 0 1 2 3 4 5 6 7 8 9 | 10 11 12
825 // i index : -4 -3 -2 -1 0 1 2 3 4 5
826 // i index limits nL...............nM..nR-1
827 // L,R - samples affected by borders
828 // M - not affected samples
829 //---------------------------------------------------------
830 
831  int nS = nWWS>>level; // nS - number of samples in the layer
832  int nL = -m_L/2; // nL - left limit of update i index
833  int nR = nS+nL; // nR - right limit of update i index
834  int nM = nS-m_L+1; // nM - number of M samples
835  int mM = nM<<level; // (number of M samples)<<level
836 
837  double data;
838  double hsum = 0.; // filter sum
839 
840  register int i,j,k;
841  register double sum = 0.;
842 
843  register const double *h; // pointer to filter coefficient
844  register const DataType_t *dataL; // pointer to left data sample
845  register const DataType_t *dataR; // pointer to right data sample
846  register const int stride = 1<<level; // stride parameter
847 
848  DataType_t *dataA, *dataD;
849 
850  double *pBorder=new double[2*(m_L-nL)]; // border array
851  double *pB;
852 
853  dataA=pWWS+getOffset(level,layer<<1); // pointer to approximation layer
854  dataD=pWWS+getOffset(level,(layer<<1)+1); // pointer to detail layer
855 
856  for(k=0; k<m_L; k++) hsum += p_L[k];
857 
858 // left border
859 
860  pB = pBorder;
861  dataL = dataD; // first (left) sample
862  for(k=0; k<(m_L-nL); k++){
863  j = k + nL;
864  pB[k] = *(dataL + abs(j<<level));
865 
866  if(j>=0) continue;
867 
868  data = *(dataL + ((j+nS)<<level));
869  switch (m_Border) {
870  case B_PAD_ZERO : pB[k] = 0.; break; // pad zero
871  case B_PAD_EDGE : pB[k] = *dataL; break; // pad by edge value
872  case B_CYCLE : pB[k] = data; break; // cycle data
873  default : break; // mirror or interpolate
874  }
875  }
876 
877  for(i=nL; i<0; i++) { // i index
878 
879  if(m_Border != B_POLYNOM){
880  sum = 0.;
881  for(k=0; k<m_L/2; k++)
882  sum += p_L[k] * (pB[k] + pB[m_L-1-k]);
883  pB++;
884  }
885  else{
886 // pB = pBorder - nL; // point to dataD
887 // sum = hsum*Nevill(i-0.5-nL, m_L+i, pB, pB+m_L); // POLYNOM1
888  pB = pBorder - nL; // point to dataD
889  sum = hsum*Nevill(i-0.5-nL, m_L+2*i, pB, pB+m_L); // POLYNOM2
890  }
891 
892  *dataA += sum;
893  dataA += stride;
894  }
895 
896 // regular case (no borders)
897 
898  k = (m_L-1)<<level;
899 
900  for(i=0; i<mM; i+=stride) {
901  dataL = dataD+i;
902  dataR = dataL+k;
903  h = p_L;
904 
905  sum=0.;
906  do sum += *(h++) * (*dataL + *dataR);
907  while((dataL+=stride) < (dataR-=stride));
908 /*
909  sum = *(h++) * (*dataL + *dataR);
910  if ((dataL+=stride) > (dataR-=stride)) goto U0;
911  sum += *(h++) * (*dataL + *dataR);
912  if ((dataL+=stride) > (dataR-=stride)) goto U0;
913  sum += *(h++) * (*dataL + *dataR);
914  if ((dataL+=stride) > (dataR-=stride)) goto U0;
915  sum += *(h++) * (*dataL + *dataR);
916  if ((dataL+=stride) > (dataR-=stride)) goto U0;
917  sum += *(h++) * (*dataL + *dataR);
918  if ((dataL+=stride) > (dataR-=stride)) goto U0;
919  sum += *(h++) * (*dataL + *dataR);
920  if ((dataL+=stride) > (dataR-=stride)) goto U0;
921  sum += *(h++) * (*dataL + *dataR);
922  if ((dataL+=stride) > (dataR-=stride)) goto U0;
923  sum += *(h++) * (*dataL + *dataR);
924  if ((dataL+=stride) > (dataR-=stride)) goto U0;
925  sum += *(h++) * (*dataL + *dataR);
926  if ((dataL+=stride) > (dataR-=stride)) goto U0;
927  sum += *(h++) * (*dataL + *dataR);
928  if ((dataL+=stride) > (dataR-=stride)) goto U0;
929  sum += *(h++) * (*dataL + *dataR);
930  if ((dataL+=stride) > (dataR-=stride)) goto U0;
931  sum += *(h++) * (*dataL + *dataR);
932  if ((dataL+=stride) > (dataR-=stride)) goto U0;
933  sum += *(h++) * (*dataL + *dataR);
934  if ((dataL+=stride) > (dataR-=stride)) goto U0;
935  sum += *(h++) * (*dataL + *dataR);
936  if ((dataL+=stride) > (dataR-=stride)) goto U0;
937  sum += *(h++) * (*dataL + *dataR);
938 
939 U0: *dataA += sum; */
940  *dataA += sum;
941  dataA += stride;
942  }
943 
944 // right border
945 
946  pB = pBorder;
947  dataR = dataD + ((nS-1)<<level); // last detail sample
948 
949  for(k=0; k<(m_L-nL); k++){
950  j = m_L - 1 - k;
951  pB[k] = *(dataR - abs(j<<level));
952 
953  if(j>=0) continue;
954 
955  data = *(dataR - ((j+nS)<<level));
956  switch (m_Border) {
957  case B_PAD_ZERO : pB[k] = 0.; break; // pad zero
958  case B_PAD_EDGE : pB[k] = *dataR; break; // pad by edge value
959  case B_CYCLE : pB[k] = data; break; // cycle data
960  default : break; // mirror or interpolate
961  }
962  }
963 
964  k = 0;
965  for(i=nM; i<nR; i++) {
966 
967  if(m_Border != B_POLYNOM){
968  sum = 0.; pB++;
969  for(k=0; k<m_L/2; k++)
970  sum += p_L[k] * (pB[k] + pB[m_L-1-k]);
971  }
972  else{
973 // sum = hsum*Nevill(-0.5-nL, nS-i, ++pB, pBorder+m_L+1);
974  k += 2;
975 // sum = hsum*Nevill((m_L-k-1)/2., m_L-k, pB+k, pBorder+m_L+1); // wat version
976  sum = hsum*Nevill((m_H-k-1)/2., m_H-k, pB+k, pBorder+m_H+1); // datacond version
977  }
978 
979  *dataA += sum;
980  dataA += stride;
981  }
982 
983  delete [] pBorder;
984 }
985 
986 template <class DataType_t>
987 void WaveDWT<DataType_t>::Streamer(TBuffer &R__b)
988 {
989  // Stream an object of class WaveDWT<double>.
990  UInt_t R__s, R__c;
991  if (R__b.IsReading()) {
992  Version_t R__v = R__b.ReadVersion(&R__s, &R__c); if (R__v) { }
993  Wavelet::Streamer(R__b);
994  R__b >> nWWS;
995  R__b >> nSTS;
996  pWWS=NULL;
997  R__b.CheckByteCount(R__s, R__c, WaveDWT<DataType_t>::IsA());
998  } else {
999  R__c = R__b.WriteVersion(WaveDWT<DataType_t>::IsA(), kTRUE);
1000  Wavelet::Streamer(R__b);
1001  R__b << nWWS;
1002  R__b << nSTS;
1003  R__b.SetByteCount(R__c, kTRUE);
1004  }
1005 }
1006 
1007 
1008 // instantiations
1009 
1010 #define CLASS_INSTANTIATION(class_) template class WaveDWT< class_ >;
1011 
1012 CLASS_INSTANTIATION(float)
1013 CLASS_INSTANTIATION(double)
1014 //CLASS_INSTANTIATION(std::complex<float>)
1015 //CLASS_INSTANTIATION(std::complex<double>)
1016 
1017 #undef CLASS_INSTANTIATION
1018 
1019 //} // namespace wat
1020 //} // namespace datacondAPI
TTree * tree
Definition: TimeSortTree.C:20
virtual ~WaveDWT()
Definition: WaveDWT.cc:40
WaveDWT(int mH=1, int mL=1, int tree=0, enum BORDER border=B_CYCLE)
Definition: WaveDWT.cc:20
int n
Definition: cwb_net.C:10
virtual void t2w(int=1)
Definition: WaveDWT.cc:57
BORDER
Definition: Wavelet.hh:18
STL namespace.
double Nevill(const double x0, int n, DataType_t *p, double *q)
Definition: watfun.hh:38
int m
Definition: cwb_net.C:10
virtual void inverseFWT(int, int, const double *, const double *)
Definition: WaveDWT.cc:415
int j
Definition: cwb_net.C:10
i drho i
void release()
Definition: WaveDWT.cc:205
virtual WaveDWT< DataType_t > * Clone() const
return: Wavelet* - duplicate of *this, allocated on heap
Definition: WaveDWT.cc:46
wavearray< double > w
Definition: Test1.C:27
virtual void forwardFWT(int, int, const double *, const double *)
Definition: WaveDWT.cc:224
unsigned long nSTS
Definition: WaveDWT.hh:125
wavearray< double > h
Definition: Regression_H1.C:25
i() int(T_cor *100))
int k
#define CLASS_INSTANTIATION(class_)
Definition: WaveDWT.cc:1010
bool allocate()
Definition: WaveDWT.cc:198
virtual void update(int, int, const double *)
Definition: WaveDWT.cc:813
s s
Definition: cwb_net.C:137
virtual void predict(int, int, const double *)
Definition: WaveDWT.cc:633
virtual std::slice getSlice(const double)
Definition: WaveDWT.cc:111
wavearray< int > index
double fabs(const Complex &x)
Definition: numpy.cc:37
virtual void w2t(int=1)
Definition: WaveDWT.cc:88
virtual int getMaxLevel()
Definition: WaveDWT.cc:176
virtual int getMaxLevel(int)
Definition: Wavelet.hh:116
detector ** pD