我正在使用Apache Commons库的FFT基本示例。我有两个班:
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();
}
}
和另一个
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;
}
}
我在createSquare()
方法中引入了一个函数(方波)。
我按顺序执行以下操作:
我执行FFT。
你能解释一下transform.transform(array, TransformType)
返回的数组是如何组成的吗?
为什么没有正确绘制傅立叶级数?
反向序列是正确的方波,其频率与初始波相同,但在y轴上没有正确缩放。怎么了?这是输出:
答案 0 :(得分:2)
在将傅立叶级数的复数形式转换为实数形式时,必须以不同方式处理常数项。或者在有问题的代码的情况下,你必须将非常数系数校正2倍。这样你得到的结果是0.5 +- 0.5
,而不是目前的0.5 +- 0.25
。< / p>
您正在使用逆变换,其中结果系数可以解释为
f(x) approx sum(m = -N/2+1, N/2-1) c[k]*exp(-i*m*k*x)
对于索引m>=1
,您组合了两个复杂的共轭术语对,得到的实数项是c[k]=a+ib
,
(a+i*b)*exp(-i*m*k*x) + (a-i*b)*exp(+i*m*k*x)
= 2*a*cos(m*k*x) + 2*b*sin(m*k*x)
你的傅里叶级数计算应该如此
value = coeff[0].getReal();
for (int m=1; m<coeff.length/2; m++) {
value += 2*coeff[m].getReal()*Math.cos(x*k*m)
+ 2*coeff[m].getImaginary()*Math.sin(x*k*m);
}