我目前正在尝试在Java中实现FFT算法,但遇到了一些麻烦!我已经对该算法的所有其他部分进行了很好的测试,并且它们似乎运行良好。
我遇到的麻烦是,在基本情况下,它返回了一个复数数组,在基本情况下填充了A[0]
。执行完基本案例后,将执行for循环,其中y0[0]
和y1[0]
被发现为 null ,尽管将它们分配给了基本案例,对此感到很困惑。这在System.out.println
行中显示
谁能告诉我我的方式的错误?
//This method implements the recursive FFT algorithm, it assumes the input length
//N is some power of two
private static Complex[] FFT(Complex[] A, int N) {
double real, imag;
Complex A0[] = new Complex[((int) Math.ceil(N/2))];
Complex A1[] = new Complex[((int) Math.ceil(N/2))];
Complex[] omega = new Complex[N];
Complex[] y = new Complex[N];
Complex[] y0 = new Complex[((int) Math.ceil(N/2))];
Complex[] y1 = new Complex[((int) Math.ceil(N/2))];
//base case
if (N == 1) {
return A;
}
else {
real = Math.cos((2*Math.PI)/N); if (real < 1E-10 && real > 0) real = 0;
imag = Math.sin((2*Math.PI)/N); if (imag < 1E-10 && imag > 0) imag = 0;
omega[N-1] = new Complex(real, imag);
omega[0] = new Complex(1, 0);
A0 = splitInput(A, 1);
A1 = splitInput(A, 0);
//recursive calls
y0 = FFT(A0, N/2);
y1 = FFT(A1, N/2);
for (int k = 0; k < ((N/2)-1); k++) {
System.out.print("k: " + k + ", y0: " + y0[k]); System.out.println(", y1: " + y1[k]);
y[k] = y0[k].plus(omega[k].times(y1[k]));
y[k+(N/2)] = y0[k].minus(omega[k].times(y1[k]));
omega[0] = omega[0].times(omega[N]);
}
return y;
}
}
这是请求的我的splitInput方法的代码
//This method takes a double array as an argument and returns every even or odd
//element according to the second int argument being 1 or 0
private static Complex[] splitInput(Complex[] input, int even) {
Complex[] newArray = new Complex[(input.length/2)];
//Return all even elements of double array, including 0
if (even == 1) {
for (int i = 0; i < (input.length/2); i++) {
newArray[i] = new Complex(input[i*2].re, 0.0);
}
return newArray;
}
//Return all odd elements of double array
else {
for (int i = 0; i < (input.length/2); i++) {
newArray[i] = new Complex (input[(i*2) + 1].re, 0.0);
}
return newArray;
}
}
编辑:我已经按照您的建议更新了代码,仍然从
y[k] = y0[k].plus(omega[k].times(y1[k]));
行中得到了空指针异常,因为在基本情况之后y0
和y1
仍然是null
:(还有其他想法吗?这是更新的算法//This method implements the recursive FFT algorithm, it assumes the input length
//N is some power of two
private static Complex[] FFT(Complex[] A, int N) {
double real, imag;
Complex[] omega = new Complex[N];
Complex[] y = new Complex[N];
Complex[] A0;
Complex[] A1;
Complex[] y0;
Complex[] y1;
//base case
if (N == 1) {
return A;
}
else {
real = Math.cos((2*Math.PI)/N); if (real < 1E-10 && real > 0) real = 0;
imag = Math.sin((2*Math.PI)/N); if (imag < 1E-10 && imag > 0) imag = 0;;
omega[N-1] = new Complex(real, imag);
omega[0] = new Complex(1, 0);
A0 = splitInput(A, 1);
A1 = splitInput(A, 0);
//recursive calls
y0 = FFT(A0, N/2);
y1 = FFT(A1, N/2);
for (int k = 0; k < ((N/2)-1); k++) {
y[k] = y0[k].plus(omega[k].times(y1[k]));
y[k+(N/2)] = y0[k].minus(omega[k].times(y1[k]));
omega[0] = omega[0].times(omega[N-1]);
}
return y;
}
}
最佳答案
跳出来的问题:
(int) Math.ceil(N/2)
您仍在进行int
划分,因此Math.ceil()
没有任何效果,并且您的拆分数组可能不适用于奇数n
omega[0]
和omega[N-1]
,当您尝试访问NullPointerException
时,我希望有一个omega[1]
,这会在N >= 6
时发生。 omega[N]
,如sarnold A0
和A1
,然后将它们分配给splitInput