#include <daub.h>
Inheritance diagram for Daubechies::
Public Methods  
void  forwardStep (T &a, const int n) 
Forward Daubechies D4 transform step. More...  
void  forwardStepRev (T &a, const int n) 
Forward Daubechies D4 transform step, where the locations for the high and low pass filters are reversed. More...  
void  inverseStep (T &a, const int n) 
Inverse Daubechies D4 transform. More...  
Daubechies ()  
Initialize the filter constants used in the Daubechies D4 transform. More...  
void  forwardTrans (T &ts, int N) 
Forward Daubechies D4 transform. More...  
void  inverseTrans (T &coef, int N) 
Inverse Daubechies D4 transform. More...  
Protected Methods  
void  predict (T &vec, int N, transDirection direction) 
Predict step, to be defined by the subclass. More...  
virtual void  update (T &vec, int N, transDirection direction) 
Update step, to be defined by the subclass. More...  
Private Attributes  
double  h0 
forward transform scaling coefficients. More...  
double  h1 
forward transform scaling coefficients. More...  
double  h2 
forward transform scaling coefficients. More...  
double  h3 
forward transform scaling coefficients. More...  
double  g0 
forward transform wave coefficients. More...  
double  g1 
forward transform wave coefficients. More...  
double  g2 
forward transform wave coefficients. More...  
double  g3 
forward transform wave coefficients. More...  
double  Ih0 
double  Ih1 
double  Ih2 
double  Ih3 
double  Ig0 
double  Ig1 
double  Ig2 
double  Ig3 
I have to confess up front that the comment here does not even come close to describing wavelet algorithms and the Daubechies D4 algorithm in particular. I don't think that it can be described in anything less than a journal article or perhaps a book. I even have to apologize for the notation I use to describe the algorithm, which is barely adequate. But explaining the correct notation would take a fair amount of space as well. This comment really represents some notes that I wrote up as I implemented the code. If you are unfamiliar with wavelets I suggest that you look at the bearcave.com web pages and at the wavelet literature. I have yet to see a really good reference on wavelets for the software developer. The best book I can recommend is Ripples in Mathematics by Jensen and CourHarbo.
All wavelet algorithms have two components, a wavelet function and a scaling function. These are sometime also referred to as high pass and low pass filters respectively.
The wavelet function is passed two or more samples and calculates a wavelet coefficient. In the case of the Haar wavelet this is
coef_{i} = odd_{i}  even_{i} or coef_{i} = 0.5 * (odd_{i}  even_{i})
depending on the version of the Haar algorithm used.
The scaling function produces a smoother version of the original data. In the case of the Haar wavelet algorithm this is an average of two adjacent elements.
The Daubechies D4 wavelet algorithm also has a wavelet and a scaling function. The coefficients for the scaling function are denoted as h_{i} and the wavelet coefficients are g_{i}.
Mathematicians like to talk about wavelets in terms of a wavelet algorithm applied to an infinite data set. In this case one step of the forward transform can be expressed as the infinite matrix of wavelet coefficients represented below multiplied by the infinite signal vector.
a_{i} = ...h0,h1,h2,h3, 0, 0, 0, 0, 0, 0, 0, ... s_{i} c_{i} = ...g0,g1,g2,g3, 0, 0, 0, 0, 0, 0, 0, ... s_{i+1} a_{i+1} = ...0, 0, h0,h1,h2,h3, 0, 0, 0, 0, 0, ... s_{i+2} c_{i+1} = ...0, 0, g0,g1,g2,g3, 0, 0, 0, 0, 0, ... s_{i+3} a_{i+2} = ...0, 0, 0, 0, h0,h1,h2,h3, 0, 0, 0, ... s_{i+4} c_{i+2} = ...0, 0, 0, 0, g0,g1,g2,g3, 0, 0, 0, ... s_{i+5} a_{i+3} = ...0, 0, 0, 0, 0, 0, h0,h1,h2,h3, 0, ... s_{i+6} c_{i+3} = ...0, 0, 0, 0, 0, 0, g0,g1,g2,g3, 0, ... s_{i+7}
The dot product (inner product) of the infinite vector and a row of the matrix produces either a smoother version of the signal (a_{i}) or a wavelet coefficient (c_{i}).
In an ordered wavelet transform, the smoothed (a_{i}) are stored in the first half of an n element array region. The wavelet coefficients (c_{i}) are stored in the second half the n element region. The algorithm is recursive. The smoothed values become the input to the next step.
The transpose of the forward transform matrix above is used to calculate an inverse transform step. Here the dot product is formed from the result of the forward transform and an inverse transform matrix row.
s_{i} = ...h2,g2,h0,g0, 0, 0, 0, 0, 0, 0, 0, ... a_{i} s_{i+1} = ...h3,g3,h1,g1, 0, 0, 0, 0, 0, 0, 0, ... c_{i} s_{i+2} = ...0, 0, h2,g2,h0,g0, 0, 0, 0, 0, 0, ... a_{i+1} s_{i+3} = ...0, 0, h3,g3,h1,g1, 0, 0, 0, 0, 0, ... c_{i+1} s_{i+4} = ...0, 0, 0, 0, h2,g2,h0,g0, 0, 0, 0, ... a_{i+2} s_{i+5} = ...0, 0, 0, 0, h3,g3,h1,g1, 0, 0, 0, ... c_{i+2} s_{i+6} = ...0, 0, 0, 0, 0, 0, h2,g2,h0,g0, 0, ... a_{i+3} s_{i+7} = ...0, 0, 0, 0, 0, 0, h3,g3,h1,g1, 0, ... c_{i+3}
Using a standard dot product is grossly inefficient since most of the operands are zero. In practice the wavelet coefficient values are moved along the signal vector and a four element dot product is calculated. Expressed in terms of arrays, for the forward transform this would be:
a_{i} = s[i]*h0 + s[i+1]*h1 + s[i+2]*h2 + s[i+3]*h3 c_{i} = s[i]*g0 + s[i+1]*g1 + s[i+2]*g2 + s[i+3]*g3
This works fine if we have an infinite data set, since we don't have to worry about shifting the coefficients "off the end" of the signal.
I sometimes joke that I left my infinite data set in my other bear suit. The only problem with the algorithm described so far is that we don't have an infinite signal. The signal is finite. In fact not only must the signal be finite, but it must have a power of two number of elements.
If i=N1, the i+2 and i+3 elements will be beyond the end of the array. There are a number of methods for handling the wavelet edge problem. This version of the algorithm acts like the data is periodic, where the data at the start of the signal wraps around to the end.
This algorithm uses a temporary array. A Lifting Scheme version of the Daubechies D4 algorithm does not require a temporary. The matrix discussion above is based on material from Ripples in Mathematics, by Jensen and CourHarbo. Any error are mine.
Author: Ian Kaplan
Use: You may use this software for any purpose as long as I cannot be held liable for the result. Please credit me with authorship if use use this source code.
This comment is formatted for the doxygen documentation generator
Definition at line 132 of file daub.h.

Initialize the filter constants used in the Daubechies D4 transform.
Definition at line 243 of file daub.h. 00244 { 00245 const double sqrt_3 = sqrt( 3 ); 00246 const double denom = 4 * sqrt( 2 ); 00247 00248 // 00249 // forward transform scaling (smoothing) coefficients 00250 // 00251 h0 = (1 + sqrt_3)/denom; 00252 h1 = (3 + sqrt_3)/denom; 00253 h2 = (3  sqrt_3)/denom; 00254 h3 = (1  sqrt_3)/denom; 00255 // 00256 // forward transform wavelet coefficients (a.k.a. high 00257 // pass filter coefficients) 00258 // 00259 g0 = h3; 00260 g1 = h2; 00261 g2 = h1; 00262 g3 = h0; 00263 00264 Ih0 = h2; 00265 Ih1 = g2; // h1 00266 Ih2 = h0; 00267 Ih3 = g0; // h3 00268 00269 Ig0 = h3; 00270 Ig1 = g3; // h0 00271 Ig2 = h1; 00272 Ig3 = g1; // h2 00273 } 

Forward Daubechies D4 transform step.
Reimplemented from liftbase. Definition at line 160 of file daub.h. 00161 { 00162 if (n >= 4) { 00163 int i, j; 00164 const int half = n >> 1; 00165 00166 double* tmp = new double[n]; 00167 00168 for (i = 0, j = 0; j < n3; j += 2, i++) { 00169 tmp[i] = a[j]*h0 + a[j+1]*h1 + a[j+2]*h2 + a[j+3]*h3; 00170 tmp[i+half] = a[j]*g0 + a[j+1]*g1 + a[j+2]*g2 + a[j+3]*g3; 00171 } 00172 00173 tmp[i] = a[n2]*h0 + a[n1]*h1 + a[0]*h2 + a[1]*h3; 00174 tmp[i+half] = a[n2]*g0 + a[n1]*g1 + a[0]*g2 + a[1]*g3; 00175 00176 for (i = 0; i < n; i++) { 00177 a[i] = tmp[i]; 00178 } 00179 delete [] tmp; 00180 } 00181 } 

Forward Daubechies D4 transform step, where the locations for the high and low pass filters are reversed.
Reimplemented from liftbase. Definition at line 188 of file daub.h. 00189 { 00190 if (n >= 4) { 00191 int i, j; 00192 const int half = n >> 1; 00193 00194 double* tmp = new double[n]; 00195 00196 for (i = 0, j = 0; j < n3; j += 2, i++) { 00197 tmp[i+half] = a[j]*h0 + a[j+1]*h1 + a[j+2]*h2 + a[j+3]*h3; 00198 tmp[i] = a[j]*g0 + a[j+1]*g1 + a[j+2]*g2 + a[j+3]*g3; 00199 } 00200 00201 tmp[i+half] = a[n2]*h0 + a[n1]*h1 + a[0]*h2 + a[1]*h3; 00202 tmp[i] = a[n2]*g0 + a[n1]*g1 + a[0]*g2 + a[1]*g3; 00203 00204 for (i = 0; i < n; i++) { 00205 a[i] = tmp[i]; 00206 } 00207 delete [] tmp; 00208 } 00209 } 

Forward Daubechies D4 transform.
Reimplemented from liftbase. Definition at line 278 of file daub.h. 00279 { 00280 int n; 00281 for (n = N; n >= 4; n >>= 1) { 00282 forwardStep( ts, n ); 00283 } 00284 } // forwardTrans 

Inverse Daubechies D4 transform.
Reimplemented from liftbase. Definition at line 214 of file daub.h. 00215 { 00216 if (n >= 4) { 00217 int i, j; 00218 const int half = n >> 1; 00219 const int halfPls1 = half + 1; 00220 00221 double* tmp = new double[n]; 00222 00223 // last smooth val last coef. first smooth first coef 00224 tmp[0] = a[half1]*Ih0 + a[n1]*Ih1 + a[0]*Ih2 + a[half]*Ih3; 00225 tmp[1] = a[half1]*Ig0 + a[n1]*Ig1 + a[0]*Ig2 + a[half]*Ig3; 00226 for (i = 0, j = 2; i < half1; i++) { 00227 // smooth val coef. val smooth val coef. val 00228 tmp[j++] = a[i]*Ih0 + a[i+half]*Ih1 + a[i+1]*Ih2 + a[i+halfPls1]*Ih3; 00229 tmp[j++] = a[i]*Ig0 + a[i+half]*Ig1 + a[i+1]*Ig2 + a[i+halfPls1]*Ig3; 00230 } 00231 for (i = 0; i < n; i++) { 00232 a[i] = tmp[i]; 00233 } 00234 delete [] tmp; 00235 } 00236 } // inverseStep 

Inverse Daubechies D4 transform.
Reimplemented from liftbase. Definition at line 290 of file daub.h. 00291 { 00292 int n; 00293 for (n = 4; n <= N; n <<= 1) { 00294 inverseStep( coef, n ); 00295 } 00296 } // inverseTrans 

Predict step, to be defined by the subclass.
Reimplemented from liftbase. Definition at line 135 of file daub.h. 00136 { 00137 assert( false ); 00138 } // predict 

Update step, to be defined by the subclass.
Reimplemented from liftbase. Definition at line 140 of file daub.h. 00141 { 00142 assert( false ); 00143 } // update 

















forward transform wave coefficients.


forward transform wave coefficients.


forward transform wave coefficients.


forward transform wave coefficients.


forward transform scaling coefficients.


forward transform scaling coefficients.


forward transform scaling coefficients.


forward transform scaling coefficients.
