I'm working with a basic example of FFT with Apache Commons library. I have two classes:
public class Fourier {
private static XYSeries data;
private static XYSeriesCollection collection;
Fourier(){
collection =new XYSeriesCollection();
createSquare();
createFourier();
showGraph();
}
private static void createSquare(){
data=new XYSeries("Dati");
for(double i=-8;i<8;i+=1d/128){
data.add(i,((i<-4||(i<4&&i>0)?1:0)));
//data.add(i,(i<0?i+1:-i+1));
}
collection.addSeries(data);
}
private static void createFourier(){
double[] arrayFourier= new double[data.getItemCount()];
for(int i=0;i<data.getItemCount();i++){
arrayFourier[i]=data.getDataItem(i).getYValue();
}
FastFourierTransformer transformer=new FastFourierTransformer(DftNormalization.STANDARD);
Complex[] coeff=transformer.transform(arrayFourier, TransformType.INVERSE);
double norm = 0;
for(Complex Z: coeff){
System.out.println(Z.abs()+"\t"+Z.toString());
norm+=(Z.abs())*(Z.abs());
}
System.out.println(norm);
XYSeries fourier=new XYSeries("Fourier");
FourierSeries series=new FourierSeries(coeff,8);
for(double i=data.getMinX();i<data.getMaxX();i+=0.05){
fourier.add(i,series.getSeries(i));
}
collection.addSeries(fourier);
}
private static void showGraph(){
JFreeChart chart = ChartFactory.createXYLineChart("Fourier", "x", "f(x)", collection, PlotOrientation.VERTICAL, true, false, false);
ChartFrame window=new ChartFrame("Fourier", chart, false);
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.pack();
window.setVisible(true);
}
public static void main(String[] args) {
Thread t=new Thread(new Runnable() {
@Override
public void run() {
new Fourier();
try {
Thread.sleep(60000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.exit(0);
}
});
t.start();
}
}
and another one
public class FourierSeries {
Complex[] coeff;
double T;
public FourierSeries(Complex[] coeff, double T) {
this.coeff=coeff;
this.T=T;
}
public double getSeries(double x){
double k=Math.PI/T;
double value=0; //primo coefficiente
int i=0;
/*for(Complex iter:coeff){
if (i!=0&&i<coeff.length/2.) {
if (i % 2 == 0) {
value += iter.abs() * Math.cos(k * i * x);
System.out.println(iter.abs()+"cos"+i);
} else {
value += iter.abs() * Math.sin(k * i * x); //npari (i dispari) modulo*cos()
System.out.println(iter.abs()+"sin"+i);
}
}
i++;
}*/
for (Complex iter : coeff) {
if(i<coeff.length/2.)
value+=iter.getReal()*Math.cos(x*k*i)+iter.getImaginary()*Math.sin(x*k*i);
i++;
}
return value;
}
}
I introduce in my createSquare()
method a function (square wave).
In order I do the following actions:
I perform the FFT.
Can you explain me how the array returned by transform.transform(array, TransformType)
is composed?
Why the Fourier series is not correctly drawn?
The inverse series is correctly a square wave with same frequency as initial wave, but not correctly scaled on y-axsis. What is wrong? This is the output: