JSci.maths.wavelet.MatchingPursuit Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jsci Show documentation
Show all versions of jsci Show documentation
JSci is a set of open source Java packages. The aim is to encapsulate scientific methods/principles in the most natural way possible. As such they should greatly aid the development of scientific based software.
It offers: abstract math interfaces, linear algebra (support for various matrix and vector types), statistics (including probability distributions), wavelets, newtonian mechanics, chart/graph components (AWT and Swing), MathML DOM implementation, ...
Note: some packages, like javax.comm, for the astro and instruments package aren't listed as dependencies (not available).
The newest version!
package JSci.maths.wavelet;
import JSci.maths.*;
/*************************************
* A Wavelet (and more) matching pursuit class
* Uses adaptative Morse coding for better
* performance. The MatchingPursuit is used
* to obtain a Time-Frequency representation (TF)
* through a fast algorithm.
* @author Daniel Lemire
*************************************/
public class MatchingPursuit extends BasisFunctionLibrary implements Cloneable {
private int[] Record;
private double[] Coefs;
private double[][][] TF=new double[0][][];
public void add(MultiscaleFunction fprimary, MultiscaleFunction fdual) {
super.add(fprimary, fdual);
double[][][] TFback=TF;
TF=new double[getSize()][][];
System.arraycopy(TFback,0,TF,0,TFback.length);
TF[getSize()-1]=getTF(super.Fprimary[getSize()-1]);
}
public Object clone() {
MatchingPursuit c=(MatchingPursuit) super.clone();
if(this.Record!=null) {
c.Record=ArrayMath.copy(this.Record);
}
if(this.Coefs!=null) {
c.Coefs=ArrayMath.copy(this.Coefs);
}
if(this.TF!=null) {
TF=new double[this.TF.length][][];
System.arraycopy(TF,0,c.TF,0,TF.length);
}
return(c);
}
/*****************************
* Allows one to trace back the
* matches
******************************/
private void addToRecord (int K, double d) {
if(Record==null) {
Record=new int[1];
Record[0]=K;
Coefs=new double[1];
Coefs[0]=d;
} else {
int[] back=Record;
double[] backednorm=Coefs;
Record=new int[Record.length+1];
Coefs=new double[Record.length+1];
System.arraycopy(back,0,Record,0,Record.length-1);
System.arraycopy(backednorm,0,Coefs,0,Record.length-1);
//for(int k=0;kener1*tol) {
throw new IllegalArgumentException("Fail to match dictionnary element number "+k+" got a 'de facto' tolerance of "+(ener2/ener1));
}
}
}
/************************************
* Convert the an element to a
* time-frequency representation
* using Fourier as a basis multiply
* everything by a coefficient b.
*************************************/
private double[][] getTF(int pos, double b) {
double[][] ans=ArrayMath.copy(TF[pos]);
for(int k=0;k1)||(tol<0)) {
throw new IllegalArgumentException("The percentile should be between 0 and 1: "+tol);
}
int TimesAround=0;
double ener0=DFunction.norm();
double ts=ener0*tol;
int maxTimesAround=5*getSize();
double[][] ans=new double[0][0];
while(DFunction.norm()>ts) {
TimesAround++;
if(TimesAround>maxTimesAround) {
throw new MaximumIterationsExceededException("Impossible to match to the desired precision ("+tol+") with this dictionnary of size "+getSize()+" after "+TimesAround+" iterations. You might want to expand the dictionnary.", ans);
}
if(ans.length!=0) {
ans=add(ans,match());
} else {
ans=match();
}
}
return(ans);
}
/******************************************
* Force the system to select the given
* element as the best match. It will return
* the TF representaiton. The TF representation
* may contain negative values and so,
* taking the absolute value of the
* result will often be useful.
*******************************************/
public double[][] forcedMatch(int pos) {
double coef=DiscreteHilbertSpace.integrate(DFunction,Fdual[pos]);
addToRecord(pos,coef);
DFunction=new DiscreteFunction(DiscreteHilbertSpace.add(DFunction,-coef,Fprimary[pos]));
return(getTF(pos,coef));
}
/*********************************
* Does the matching j times and
* return the TF representation.
* The TF representation
* may contain negative values and so,
* taking the absolute value of the
* result will often be useful.
* @param j number of iterations
* @exception IllegalArgumentException if j is not positive
**********************************/
public double[][] match(int j) {
if(j<=0) {
throw new IllegalArgumentException("Can't do "+j+" matching... Must be a positive number.");
}
double[][] ans=match();
for(int k=1;k