package jsci.maths.wavelet;

import jsci.maths.*;
import jsci.maths.wavelet.*;

/****************************************************
* This class is used to encapsulate wavelet
* packets coefficients.
* @author Daniel Lemire
*****************************************/
public final class FWTPacketCoef extends Object implements NumericalConstants, Cloneable {
	protected double[][] coefs;
	protected boolean[] StandardChoice;
	final static double normalisation=1.0/SQRT2;

	public FWTPacketCoef () {
	}

	/**********************************************
	***********************************************/
	public FWTPacketCoef (double[][] v, boolean[] b) {
		coefs=v;
		StandardChoice=b;
		if(b.length!=v.length-1) {
			throw new IllegalArgumentException("boolean[].length must be exactly double[][].length -1: boolean[].length="+b.length+" and double[][].length="+v.length);
		}
	}
  /********************************************
  * Return a copy of this object
  *********************************************/
	public Object clone() {
    try {
      FWTPacketCoef fwtp=(FWTPacketCoef) super.clone();
      if(coefs!=null)
        fwtp.coefs=ArrayMath.copy(coefs);
      if(StandardChoice!=null) {
        fwtp.StandardChoice = new boolean [StandardChoice.length];
        System.arraycopy(StandardChoice,0,fwtp.StandardChoice,0,StandardChoice.length);
      }
      return(fwtp);
    } catch (CloneNotSupportedException cnse) {
      throw new InternalError();
    }
	}

	/*************************************************
	**************************************************/
	public int getJ () {
		return(coefs.length);
	}



	/*************************************************
	**************************************************/
	public int dimension(int i) {
		if ((i<0)||(i>=coefs.length)) {
			throw new IllegalArgumentException("This scale doesn't exist : "+i+", "+coefs.length);
		}
		return(coefs[i].length);
	}

	/*******************************************************
	********************************************************/
	public double[][] getCoefs() {
		return(coefs);
	}

	/***************************
  * Compute the L2 norm of the
  * coefficients
	****************************/
	public double[] norm() {
		double[] ans=new double[coefs.length];
		for(int j=0;j=coefs.length)) {
			throw new IllegalArgumentException("The integer parameter "+i+" should be between 0 and "+(coefs.length-1));
		}
		double ans=ArrayMath.norm(coefs[i]);
		return(ans);
	}


	/************************************
  * Compute the sum of the squares of
  * the coefficients
	*************************************/
	private double[] sumSquares() {
		double[] ans=new double[coefs.length];
		for(int j=0;j=coefs.length)) {
			throw new IllegalArgumentException("The integer parameter "+i+" must be between 0 et "+(coefs.length-1));
		}
		double ans=ArrayMath.sumSquares(coefs[i]);
		return(ans);
	}

	/************************************
	*************************************/
	public double mass(int i) {
		if((i<0)||(i>=coefs.length)) {
			throw new IllegalArgumentException("The integer parameter "+i+" should be between 0 and "+(coefs.length-1));
		}
		double ans=ArrayMath.mass(coefs[i]);
		return(ans);
	}

	/************************************
	*************************************/
	private double[] variance() {
		double[] ans=new double[coefs.length];
		for(int j=0;j=coefs.length)) {
			throw new IllegalArgumentException("The integer parameter "+i+" should be between 0 and "+(coefs.length-1));
		}
		double ans=ArrayMath.variance(coefs[i]);
		return(ans);
	}


	public double sumEnergies() {
		if(coefs.length<=1) {
			throw new IllegalArgumentException("No wavelet coefficients!");
		}
		double[] energies=sumSquares();
		double ans=0.0;
		for(int k=0;k=coefs.length)) {
			throw new IllegalArgumentException("The integer parameter "+i+" should be between 0 and "+(coefs.length-1));
		}
		if(sumEnergies()==0) {
			if(coefs.length!=0) {
				return(1/coefs.length);
			} else {
				throw new IllegalArgumentException("No energy!");
			}
		}
		return(sumSquares(i)/sumEnergies());
	}



	public double varianceRatio(int i) {
		if(coefs.length<=1) {
			throw new IllegalArgumentException("No wavelet coefficients!");
		}
		if((i<0)||(i>=coefs.length)) {
			throw new IllegalArgumentException("The integer parament "+i+" should be between 0 and "+(coefs.length-1));
		}
		if(sumVariance()==0) {
			if(coefs.length!=0) {
				return(1/coefs.length);
			} else {
				throw new IllegalArgumentException("No variance!");
			}
		}
		return(variance(i)/sumVariance());
	}

        /**
        * Compute the Shannon entropy.
        */
	public double icf() {
		if(coefs.length<=1) {
			throw new IllegalArgumentException("No wavelet coefficients!");
		}
		double[] pe=new double[coefs.length-1];
		for(int j=0;j=coefs.length)) {
			throw new IllegalArgumentException("The integer parameter "+i+" should be between 0 and "+(coefs.length-1));
		}
		coefs[i]=v;
	}

	public void synthesize(Filter filtreprimaire, double[] param) {
		if(coefs.length<=1) {
			throw new IllegalArgumentException("No synthesis left to do: "+coefs.length);
		}
		double[] V0,W0;
		if(StandardChoice[StandardChoice.length-1]) {
			V0=filtreprimaire.lowpass(coefs[coefs.length-1],param);
			// Lowpass filters must be renormalized.
			V0=ArrayMath.scalarMultiply(normalisation,V0);
			W0=filtreprimaire.highpass(coefs[coefs.length-2],param);
		} else {
			V0=filtreprimaire.lowpass(coefs[coefs.length-2],param);
			// Lowpass filters must be renormalized.
			V0=ArrayMath.scalarMultiply(normalisation,V0);
			W0=filtreprimaire.highpass(coefs[coefs.length-1],param);
		}
		if(V0.length!=W0.length) {
			throw new IllegalArgumentException("Synthesis is impossible : bad data/multiresolution? "+coefs[0].length+", "+coefs[coefs.length-1].length+", "+V0.length+", "+W0.length);
		}
		V0=ArrayMath.add(V0,W0);
		double[][] c=new double[coefs.length-1][];
		for(int j=0;jcoefs.length-1)) {
			throw new IllegalArgumentException("The integer parameter "+jmax+" must be between 0 and "+(coefs.length-1));
		}
		for(int j=0;jcoefs.length-1)) {
			throw new IllegalArgumentException("The integer parameter "+jmax+" must be between 0 and "+(coefs.length-1));
		}
		for(int j=0;j=seuil) {
				ans[k]=0.0;
			}
		}
		return(ans);
	}

	/*********************************************
        * Compresses by zero-ing any value below a given percentile cut-off.
        * @param p percentile cut-off, must be between 0 and 1.
	**********************************************/
	public void compress(double p) {
		for(int k=0;k=seuil) {
				ans[k]=0.0;
			}
		}
		return(ans);
	}

	/*********************************************
        * Compresses by zero-ing any value below a given cut-off.
        * @param p cut-off.
	**********************************************/
	public void compressHard(double p) {
		for(int k=0;k 

Ads help maintain this website.