/*
* copyright: Anthony Bagnall
*
* */
package weka.filters.timeseries;
import java.io.FileReader;
import weka.core.Attribute;
import weka.core.DenseInstance;
import weka.core.FastVector;
import weka.core.Instance;
import weka.core.Instances;
import weka.filters.SimpleBatchFilter;
public class PowerSpectrum extends FFT {
boolean log=false;
FFT fftFilter;
public void takeLogs(boolean x){log=x;}
public PowerSpectrum(){
fftFilter=new FFT();
fftFilter.useDFT();
}
@Override
protected Instances determineOutputFormat(Instances inputFormat)
throws Exception {
//Set up instances size and format.
int length=(fftFilter.findLength(inputFormat));
length/=2;
FastVector atts=new FastVector();
String name;
for(int i=0;i<length;i++){
name = "PowerSpectrum_"+i;
atts.addElement(new Attribute(name));
}
if(inputFormat.classIndex()>=0){ //Classification set, set class
//Get the class values as a fast vector
Attribute target =inputFormat.attribute(inputFormat.classIndex());
FastVector vals=new FastVector(target.numValues());
for(int i=0;i<target.numValues();i++)
vals.addElement(target.value(i));
atts.addElement(new Attribute(inputFormat.attribute(inputFormat.classIndex()).name(),vals));
}
Instances result = new Instances("PowerSpectrum"+inputFormat.relationName(),atts,inputFormat.numInstances());
if(inputFormat.classIndex()>=0)
result.setClassIndex(result.numAttributes()-1);
return result;
}
@Override
public Instances process(Instances instances) throws Exception {
//Get the FFT
//For each data, first extract the relevant data
Instances output=determineOutputFormat(instances);
Instances fft=fftFilter.process(instances);
int length=fft.numAttributes();
if(instances.classIndex()>=0)
length--;
length/=2;
if(log)
{
double l1;
for(int i=0;i<fft.numInstances();i++){
Instance f=fft.instance(i);
Instance inst=new DenseInstance(length+1);
for(int j=0;j<length;j++){
l1=f.value(j*2)*f.value(j*2)+f.value(j*2+1)*f.value(j*2+1);
inst.setValue(j,Math.log(l1));
}
//Set class value.
//Set class value.
if(output.classIndex()>=0)
inst.setValue(length, output.instance(i).classValue());
output.add(inst);
}
}
else{
for(int i=0;i<fft.numInstances();i++){
Instance f=fft.instance(i);
Instance inst=new DenseInstance(length+1);
for(int j=0;j<length;j++){
inst.setValue(j, f.value(j*2)*f.value(j*2)+f.value(j*2+1)*f.value(j*2+1));
}
//Set class value.
//Set class value.
if(output.classIndex()>=0)
inst.setValue(length, fft.instance(i).classValue());
output.add(inst);
}
}
return output;
}
public static void waferTest(){
/* Instances a=WekaMethods.loadData("C:\\Research\\Data\\Time Series Data\\Time Series Classification\\wafer\\wafer_TRAIN");
Instances b=WekaMethods.loadData("C:\\Research\\Data\\Time Series Data\\Time Series Classification\\wafer\\wafer_TEST");
PowerSpectrum ps=new PowerSpectrum();
try{
Instances c=ps.process(a);
Instances d=ps.process(b);
OutFile of = new OutFile("C:\\Research\\Data\\Time Series Data\\Time Series Classification\\wafer\\wafer_TRAIN_PS.arff");
OutFile of2 = new OutFile("C:\\Research\\Data\\Time Series Data\\Time Series Classification\\wafer\\wafer_TEST_PS.arff");
of.writeString(c.toString());
of2.writeString(d.toString());
}catch(Exception e){
System.out.println(" Exception ="+e);
}
*/ }
/* Transform by the built in filter*/
public static double[] powerSpectrum(double[] d){
//Check power of 2
if(((d.length)&(d.length-1))!=0) //Not a power of 2
return null;
FFT.Complex[] c=new FFT.Complex[d.length];
for(int j=0;j<d.length;j++){
c[j]=new FFT.Complex(d[j],0.0);
}
FFT f=new FFT();
f.fft(c,c.length);
double[] ps=new double[c.length];
for(int i=0;i<c.length;i++)
ps[i]=c[i].getReal()*c[i].getReal()+c[i].getImag()*c[i].getImag();
return ps;
}
public static Instances loadData(String fullPath)
{
Instances d=null;
FileReader r;
int nosAtts;
try{
r= new FileReader(fullPath+".arff");
d = new Instances(r);
d.setClassIndex(d.numAttributes()-1);
}
catch(Exception e)
{
System.out.println("Unable to load data on path "+fullPath+" Exception thrown ="+e);
e.printStackTrace();
System.exit(0);
}
return d;
}
public static void matlabComparison(){
//MATLAB Output generated by
// Power of 2: use FFT
//Create set of instances with 16 attributes, with values
// Case 1: All Zeros
// Case 2: 1,2,...16
// Case 3: -8,-7, -6,...,0,1,...7
//Case 4: 0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1
/* PowerSpectrum ps=new PowerSpectrum();
Instances test1=ClassifierTools.loadData("C:\\Users\\ajb\\Dropbox\\TSC Problems\\TestData\\FFT_test1");
Instances test2=ClassifierTools.loadData("C:\\Users\\ajb\\Dropbox\\TSC Problems\\TestData\\FFT_test2");
Instances t2;
try{
t2=ps.process(test1);
System.out.println(" TEST 1 PS ="+t2);
t2=ps.process(test2);
System.out.println(" TEST 2 PS ="+t2);
}catch(Exception e){
System.out.println(" Errrrrrr = "+e);
e.printStackTrace();
System.exit(0);
}
*/
// Not a power of 2: use padding
// Not a power of 2: use truncate
// Not a power of 2: use DFT
}
public static void main(String[] args){
matlabComparison();
System.exit(0);
PowerSpectrum ps = new PowerSpectrum();
System.out.println(" "+ps.getInputFormat());
Instances in=loadData("C:\\Research\\Data\\Time Series Classification\\Beef\\Beef_Train");
try{
Instances out =ps.process(in);
System.out.println(" "+out.numAttributes()+" "+out.numInstances());
Instance ins=out.instance(0);
double[] vals=ins.toDoubleArray();
System.out.println(" Class index ="+out.classIndex());
System.out.println(" Num atts ="+out.numAttributes());
System.out.println(" "+ins.value(out.classIndex()));
// for(double d:vals)
// System.out.println(" PS "+d);
}
catch(Exception e){
System.out.println(" Error ="+e);
e.printStackTrace();
}
}
}