Class DaubechiesWavelet


  • public class DaubechiesWavelet
    extends java.lang.Object

    Daubechies D4 wavelet transform (D4 denotes four coefficients)

    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 Cour-Harbo.

    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

    coefi = oddi - eveni
    or
    coefi = 0.5 * (oddi - eveni)

    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 hi and the wavelet coefficients are gi.

    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.

    ai = ...h0,h1,h2,h3, 0, 0, 0, 0, 0, 0, 0, ... si
    ci = ...g0,g1,g2,g3, 0, 0, 0, 0, 0, 0, 0, ... si+1
    ai+1 = ...0, 0, h0,h1,h2,h3, 0, 0, 0, 0, 0, ... si+2
    ci+1 = ...0, 0, g0,g1,g2,g3, 0, 0, 0, 0, 0, ... si+3
    ai+2 = ...0, 0, 0, 0, h0,h1,h2,h3, 0, 0, 0, ... si+4
    ci+2 = ...0, 0, 0, 0, g0,g1,g2,g3, 0, 0, 0, ... si+5
    ai+3 = ...0, 0, 0, 0, 0, 0, h0,h1,h2,h3, 0, ... si+6
    ci+3 = ...0, 0, 0, 0, 0, 0, g0,g1,g2,g3, 0, ... si+7

    The dot product (inner product) of the infinite vector and a row of the matrix produces either a smoother version of the signal (ai) or a wavelet coefficient (ci).

    In an ordered wavelet transform, the smoothed (ai) are stored in the first half of an n element array region. The wavelet coefficients (ci) 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.

    si = ...h2,g2,h0,g0, 0, 0, 0, 0, 0, 0, 0, ... ai
    si+1 = ...h3,g3,h1,g1, 0, 0, 0, 0, 0, 0, 0, ... ci
    si+2 = ...0, 0, h2,g2,h0,g0, 0, 0, 0, 0, 0, ... ai+1
    si+3 = ...0, 0, h3,g3,h1,g1, 0, 0, 0, 0, 0, ... ci+1
    si+4 = ...0, 0, 0, 0, h2,g2,h0,g0, 0, 0, 0, ... ai+2
    si+5 = ...0, 0, 0, 0, h3,g3,h1,g1, 0, 0, 0, ... ci+2
    si+6 = ...0, 0, 0, 0, 0, 0, h2,g2,h0,g0, 0, ... ai+3
    si+7 = ...0, 0, 0, 0, 0, 0, h3,g3,h1,g1, 0, ... ci+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:

    ai = s[i]*h0 + s[i+1]*h1 + s[i+2]*h2 + s[i+3]*h3
    ci = 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=N-1, 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 Cour-Harbo. 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.

    • Field Summary

      Fields 
      Modifier and Type Field Description
      protected double denom  
      protected double g0  
      protected double g1  
      protected double g2  
      protected double g3  
      protected double h0  
      protected double h1  
      protected double h2  
      protected double h3  
      protected double Ig0  
      protected double Ig1  
      protected double Ig2  
      protected double Ig3  
      protected double Ih0  
      protected double Ih1  
      protected double Ih2  
      protected double Ih3  
      protected double sqrt_3  
    • Method Summary

      All Methods Instance Methods Concrete Methods 
      Modifier and Type Method Description
      void daubTrans​(double[] s)
      Forward Daubechies D4 transform
      void invDaubTrans​(double[] coef)
      Inverse Daubechies D4 transform
      protected void invTransform​(double[] a, int n)  
      protected void transform​(double[] a, int n)
      Forward wavelet transform.
      • Methods inherited from class java.lang.Object

        clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
    • Field Detail

      • sqrt_3

        protected final double sqrt_3
      • denom

        protected final double denom
      • h0

        protected final double h0
      • h1

        protected final double h1
      • h2

        protected final double h2
      • h3

        protected final double h3
      • g0

        protected final double g0
      • g1

        protected final double g1
      • g2

        protected final double g2
      • g3

        protected final double g3
      • Ih0

        protected final double Ih0
      • Ih1

        protected final double Ih1
      • Ih2

        protected final double Ih2
      • Ih3

        protected final double Ih3
      • Ig0

        protected final double Ig0
      • Ig1

        protected final double Ig1
      • Ig2

        protected final double Ig2
      • Ig3

        protected final double Ig3
    • Constructor Detail

      • DaubechiesWavelet

        public DaubechiesWavelet()
    • Method Detail

      • daubTrans

        public void daubTrans​(double[] s)
        Forward Daubechies D4 transform
        Parameters:
        s - input vector (result replaces original)
      • invDaubTrans

        public void invDaubTrans​(double[] coef)
        Inverse Daubechies D4 transform
        Parameters:
        coef - input vector (result replaces original)
      • invTransform

        protected void invTransform​(double[] a,
                                    int n)
      • transform

        protected void transform​(double[] a,
                                 int n)

        Forward wavelet transform.

        Note that at the end of the computation the calculation wraps around to the beginning of the signal.

        Parameters:
        a - input vector
        n - size of input vector