JSci.maths.wavelet.Signal 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.GlobalSettings;
import JSci.maths.*;
import JSci.maths.wavelet.*;
import JSci.maths.wavelet.splines.*;
import java.io.*;
import java.util.Arrays;
/****************************************
* 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 [email protected] 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));
}
}