Package jsci.maths.wavelet

Java library for Wavelets.

See: Description

Package jsci.maths.wavelet Description

Java library for Wavelets.


This package was designed with Alain Béliveau and Mohamed Jardak in the winter of 1998 (at the École Polytechnique de Montréal).The idea was to provide a wavelet package that could equally well handle numerical analysis and signal processing.This is made possible by an extensive use of object-oriented design.

Terminology and background

This package assumes you know wavelet theory.If not, a good start is Daubechies' book "Ten lectures on wavelets" published by SIAM.

Numbers of the form k/2^j are called dyadic numbers and form the dyadic grid.If j is the smallest (positive) integer so that x=k/2^j, we say that x is a dyadic number of depth j.The set of all dyadic numbers is a dense set of the reals.A uniformly continuous function over the dyadic numbers is therefore continuous.

In this package, a multiscale function is a function defined (iteratively) on the dyadic grid.


  1. Numbering of wavelets

    When wavelets and scaling functions are created, one must keep in mind that the dimension() parameter (often noted n0) is the number of scaling functions (numbered from 0 to n0-1 according the the C-like notation).

    In the dyadic context, with filters of type k (for example), you'll have n0-k wavelets numbered from 0 to n0-k-1.With Haar, for example, which has a filters of type 0, you'll have as many wavelets as you have scaling functions.

  2. DiscreteHilbertSpace and numerical integration

    Numerical integration of irregular functions such as wavelets is a delicate problem.The methods in the class DiscreteHilbertSpace are only some tested solutions.They are not necessarily the best choices and contributions are welcomed (as always)!

To add wavelets (subpackages)

The wavelet package was designed so that one could add wavelets at will.Simply create you own subpackage and obey a few simple rules.

  1. Use numerical integration as included in the DiscreteHilbertSpace class for testing (bi)orthonormality. (You should get the identity matrix).
  2. The lowpass filters must preserve constants away from the boundaries.That is, if you apply the filter to the array {1,1,1,1,1,...,1} then, you'll get {1,1,1,1,1,...,1} (except maybe at the boundaries). This mean that for a dyadic filter, the sum of the coefficients of the filter should be 2 (away from the boundaries).
  3. The euclidean norm of your wavelet filter should be 1 away from the boundary.
  4. Use final static constants whenever possible for performance considerations.
  5. Use the IllegalScalingException whenever it applies.
  6. You should have at least one object of type Multiresolution if you filters are dyadic.
  7. As a rule, you should handle boundaries properly.

Optimisation and performance

While this package is not designed primarily for speed, it uses fast algorithms and should be adequately fast for most purposes. It was succesfully used for signal processing and numerical analysis and real-time applications have been written from it.

Some notes:

  1. Precision parameter

    Numerous methods have a "precision parameter" or "number of iterations" (same meaning).You should use as small a value as possible for this parameter.Note that it follows a logarithmic scale (everytime you add one, your code slows down by half).A value of 3 or 5 should be sufficient.

  2. Caching results

    The method "evaluate" should be cached whenever possible because it is the costliest method in most cases.

    Exampe : You must replace

    for(int k=0;k<10000;k++) {        d[k]=f.evaluate(j)[k];}


    double[] t=f.evaluate(j);for(int k=0;k<10000;k++) {        d[k]=t[k];}

The future

Image processing is planned in the near future.Wavelets will be added periodically and performance should be gradually enhanced.In particular, the package should include more of in-place computations maybe using the lifting scheme.

Preprocessing and postprocessing is needed for wavelets other than Haar and CDF2_4 when using them in a signal processing context because of boundary effects.


There is a lot to this package, from wavelet packets to matching pursuit...All the latest ideas are included somehow in this package.But, since one has to start somehow, here are some basic examples.

  1. (Bi)orthonormality

    This code can be used to test the orthonormality of the Daubechies wavelet.Similar code would work for any wavelet.

  2. Signal processing

    This code is an example of signal processing using Daubechies wavelets.


  1. Question:How do I calculate the number of low/high-pass coefficients?

    Answer:If there are n data samples and the wavelet has filter type filterType, then
    no. low-pass coeffs = (n + filterType)/2,
    no. high-pass coeffs = (n - filterType)/2.

  2. Help! FWT doesn't work with level 2, 3 ,4.I don't understand because when I try to execute FWT Daubechies 4 of level 4 (2, 3 too) on a 1024 sample vector it throws this exception:"JSci.maths.wavelet.IllegalScalingException: Even number of values into anodd filter! Change the number of values/iterations: 515".This is the code:
    public class Sub_Band {   Daubechies4 ondelette = new Daubechies4();   public Sub_Band() {}   public void jbInit(short[] data) {      double d[] = new double[data.length];      for (int i=0; i<data.length; i++) {         d = data;      }      System.out.println(d.length);      Signal s = new Signal(d);      s.setFilter(ondelette);      int level=4;      FWTCoef sCoef = s.fwt(level); // for some level int      ArrayMath.print(sCoef.getCoefs()[0]);      ArrayMath.print(sCoef.getCoefs()[1]);   }}
    This only works with level 1.

    Solution: Sure it does, but you need proper padding (Meyer boundaries!).The JSci implementation of Daubechies 4 uses the Meyer technique to adapt the filters to the interval.Basically, many pieces of code you can find out there will simply assume you have an infinite signaland do something really fishy at the boundaries.This implementation does something proposed by Meyer which isa bit cleaner than some alternatives.The key point is that if your original signal is a polynomial, you'd want thewavelet coefficients, even near the boundary, to be small.Because the filter type in this case is 6, this means that starting withn=1024 samples, you'll get n/2+3=515 low-pass coefficients and n/2-3=509 high-passcoefficients.The problem here is that 515 is odd, so Meyer's trick doesn't apply.But if you had started with a signal of length 1026, then you'd have 516low-pass coefficients and 510 high-pass ones, and so you'd be able totransform 516 to get 175 low-pass coefficients and 169 high-passcoefficients... Try a signal of length 1030 and it should work as you want.

Further information

Visit the Wavelet Forum to discuss both JSci specific and general issues relating to wavelets.

Daniel Lemire (Daniel.Lemire@ondelette.com)


SCaVis 2.2 © jWork.ORG