package jsci.maths.wavelet;

import jsci.maths.*;

/*********************************************
* This class is meant to be used for
* Fast Wavelet Transform, Matching Pursuit
* and related signal processing algorithm.
* The basic idea is to automatically build
* and compress a library of "basis functions".
* Using Morse Coding this class delivers
* very fast code without sacrificing
* anything. The only fee is the one you pay
* to build the object, and it is a one time
* fee.
*
* Note : this class should be rewritten to
* use the java.util collections starting with
* jdk1.2.
*
* This class is not meant to be used directly
* but rather, you should build on it.
*
* It supports only 1D data.
**********************************************/
public class BasisFunctionLibrary implements Cloneable {
  //threshold for morse coding
  private double MorseThreshold=0.5;
	protected DiscreteFunction[] Fprimary;
	protected DiscreteFunction[] Fdual;
	protected DiscreteFunction DFunction;

  public Object clone() {
    try {
      BasisFunctionLibrary c=(BasisFunctionLibrary) super.clone();
      c.MorseThreshold=this.MorseThreshold;
      c.DFunction=(DiscreteFunction) this.DFunction.clone();
      c.Fprimary=cloneArrayDiscreteFunction(this.Fprimary);
      c.Fdual=cloneArrayDiscreteFunction(this.Fdual);
      return(c);
    } catch (CloneNotSupportedException cnse) {
      throw new InternalError();
    }
  }

  public void setMorseThreshold(double p) {
    if((p<0)||(p>1)) {
      throw new IllegalArgumentException("The threshold must be between 0 and 1 :"+p);
    }
    MorseThreshold=p;
  }

  public double getMorseThreshold() {
    return(MorseThreshold);
  }


	public void includeFourier () {
		for(int k=0;k<=Math.floor(DFunction.dimension()/2d);k++) {
			add(new Cosine(DFunction.dimension(),k));
		}

		for(int k=1;k20) {
        throw new IllegalScalingException("Could not match the added object with internal data object in 20 iterations.");
      }
    }
    if(f.dimension(j)!=DFunction.dimension()) {
        throw new IllegalScalingException("Could not match the added object with internal data object.");
    }
    double[] eval=ArrayMath.scalarMultiply(1/Math.sqrt((double)Cascades.PowerOf2(j)),f.evaluate(j));
    int nonzero=0;
    for(int k=0;k(MorseThreshold*(double) eval.length))
      return(new DiscreteFunction(eval));
    else {
      return(new SparseDiscreteFunction(eval));

    }
  }

	/**********************************************
	* Add a clone of the given MultiscaleFunctions
	* to the internal arrays of MultiscaleFunctions.
	***********************************************/
	public void add(MultiscaleFunction fprimary, MultiscaleFunction fdual) {
		if((fprimary==null)||(fdual==null)) {
			throw new NullPointerException("You cannot add a null object to the internal arrays.");
		}
		if(Fprimary!=null) {
			DiscreteFunction[] backup=Fprimary;
			Fprimary=new DiscreteFunction[backup.length+1];
      System.arraycopy(backup,0,Fprimary,0,backup.length);
			Fprimary[backup.length]=toDiscreteFunction((MultiscaleFunction) fprimary.clone());
		} else {
			Fprimary=new DiscreteFunction[1];
			Fprimary[0]=toDiscreteFunction((MultiscaleFunction) fprimary.clone());
		}
		if(Fdual!=null) {
			DiscreteFunction[] backup=Fdual;
			Fdual=new DiscreteFunction[backup.length+1];
      System.arraycopy(backup,0,Fdual,0,backup.length);
			Fdual[backup.length]=toDiscreteFunction((MultiscaleFunction) fdual.clone());
		} else {
			Fdual=new DiscreteFunction[1];
			Fdual[0]=toDiscreteFunction((MultiscaleFunction) fdual.clone());
		}
	}

	/********************************************
	* Add the MultiscaleFunction to both the primary
	* and dual internal arrays.
	*********************************************/
	public void add(MultiscaleFunction f) {
		add(f,f);
	}

	/********************************************
	* Add the array of MultiscaleFunction to both
  * the primary and dual internal arrays.
	*********************************************/
	public void add(MultiscaleFunction[] f) {
    for(int k=0;kroughly be
  * filled with ones.
	**************************************/
	public double[] checkBiorthogonality() {
		double[] ans=new double[getSize()];
		for(int k=0;k 

Ads help maintain this website.