package jsci.maths.wavelet;
import java.io.*;
import java.util.Arrays;
import jsci.GlobalSettings;
import jsci.maths.*;
import jsci.maths.wavelet.*;
import jsci.maths.wavelet.splines.*;
/****************************************
* This class use the linear spline as a general model for a signal.
* While this is a reasonnable design choice, this can certainly be overwritten
* if necessary.
* Basic operations on signal are supported.
* @author Daniel Lemire
*****************************************/
public class Signal extends LinearSpline implements NumericalConstants, Cloneable {
private Filter filterdual;
final static double normalisation=1.0/SQRT2;
private double[] param;
/********************************************
* Return a copy of this object
*********************************************/
public Object clone() {
Signal s=(Signal) super.clone();
if(filterdual!=null)
s.filterdual=filterdual;
//the previous line is unsafe?
if(param!=null) {
s.param=new double[param.length];
System.arraycopy(s.param,0,param,0,param.length);
}
return(s);
}
/************************************
* This method generates a copy of the
* current object with a different data
* content.
**************************************/
private Signal copy(double[] v) {
if(filterdual!=null) {
if(param!=null) {
double[] p=new double[param.length];
System.arraycopy(param,0,p,0,p.length);
return(new Signal(filterdual,v,p));
} else {
return(new Signal(filterdual,v));
}
} else {
return(new Signal(v));
}
}
/******************************
*******************************/
public Signal () {
}
/***********************************
************************************/
public Signal (double[] v) {
super(v);
}
/******************************
*******************************/
public Signal (Filter f,double[] v, double[] p) {
super(v);
filterdual=f;
System.arraycopy(p,0,param,0,param.length);
}
/********************************
*********************************/
public Signal(Filter f) {
filterdual=f;
}
/*********************************
**********************************/
public Signal (Filter f,double[] v) {
super(v);
filterdual=f;
}
/********************************************
* Get the sampled values of the sample as
* an array.
*********************************************/
public double[] getValues() {
return(this.interpolate(0));
}
/*********************************
* set the signal associated Filter
**********************************/
public void setFilter(Filter f) {
filterdual=f;
}
/***********************************
* Set the parameter of the Filter (if
* it applies).
************************************/
public void setParameters(double[] p) {
for(int k=0;k20) {
throw new IllegalArgumentException("Too many iterations.");
}
if (J<0) {
throw new IllegalArgumentException("Cannot have a negative number of iterations.");
}
double[] data=this.interpolate(0);
double[][] fwt=new double[J+1][];
for(int j=1;j<=J;j++) {
fwt[j]=highpassProject(data);
data=lowpassProject(data);
}
fwt[0]=data;
FWTCoef t=new FWTCoef(fwt);
return(t);
}
/********************************
* The Fast Wavelet Transform
* with Wavelet packets
* @param J number of iterations
* @param cout cost function
*********************************/
public FWTPacketCoef fwtPacket(int J, MappingND cout) {
if (J>20) {
throw new IllegalArgumentException("Too many iterations.");
}
if (J<0) {
throw new IllegalArgumentException("Cannot have a negative number of iterations.");
}
double[] data=this.interpolate(0);
double[][] fwt=new double[J+1][];
double[] choix1,choix2;
boolean[] choixStandard=new boolean[J];
for(int j=0;jl)||(l<0)) {
throw new IllegalArgumentException("This Kronecker doesn't exist.");
}
double[] v=new double[l];
v[i]=a;
return(v);
}
/***************************
* Compute the L2 norm of the
* signal
****************************/
public double norm() {
double[] data=this.interpolate(0);
return(ArrayMath.norm(data));
}
/***********************************
* @author Don Cross
* @author Daniel Lemire
************************************/
public Complex[] fft() {
double[] data=this.interpolate(0);
return(fft(data));
}
/**
* Performs the Fourier transform.
* Convenience method for {@link jsci.maths.FourierMath#transform(double[]) FourierMath.transform}.
*/
public static Complex[] fft(double[] data) {
return FourierMath.transform(data);
}
/**
* Performs the Fourier transform.
* Convenience method for {@link jsci.maths.FourierMath#transform(Complex[]) FourierMath.transform}.
*/
public static Complex[] fft(Complex[] data) {
return FourierMath.transform(data);
}
/*********************************
* Return the absolute value of
* the FFT
**********************************/
public double[] absFFT() {
Complex[] fft=fft();
double[] answer=new double[fft.length];
for(int i=0;idata.length-2) {
if (data.length<4) {
throw new IllegalArgumentException ("Your signal is too short to be denoised : "+data.length+" < 4");
}
throw new IllegalArgumentException ("Since you signal has dimension "+data.length+", the parameter must be at most : "+(data.length-2));
}
Complex[] ff=Signal.fft(data);
ff[k+1]=Complex.ZERO;
ff[data.length-1-k]=Complex.ZERO;
Complex[] tf=Signal.fftInverse(ff);
for(int l=0;lGlobalSettings.ZERO_TOL) {
throw new IllegalArgumentException("Complex values detected during synthesis. Please get in touch with Daniel Lemire at Daniel.Lemire@Tintin.net to report this error.");
}
}
super.setValues(data);
}
/**********************************************
* Return the entropy of the signal
***********************************************/
public double entropy () {
return(EngineerMath.entropy(this.evaluate(0)));
}
/*****************************************
* Apply the given array as a convolution
* Filter and return a new Signal.
* As one often want to compare the result
* to the original signal, this method is
* "safe", that is, it won't change the current
* object.
* @param f an array containing the coefficients
* of the convolution Filter
******************************************/
public Signal filter (double[] f) {
double[] data=interpolate(0);
if(data.length-(f.length-1)<=0) {
throw new IllegalArgumentException("Your signal is too short for this Filter : "+data.length+", "+f.length);
}
double[] ans=new double[data.length-(f.length-1)];
for(int k=0;k1)) {
throw new IllegalArgumentException("The parameter p must be between 0 and 1: "+p);
}
double[] values=this.interpolate(0);
double range=ArrayMath.max(values)-ArrayMath.min(values);
double threshold=range*p;
double[] med=(this.medianFilter(n)).interpolate(0);
for(int k=n;kthreshold) {
values[k]=med[k-n];
}
}
return(copy(values));
}
}
Ads help maintain this website.