gpt4 book ai didi

java - 递归FFT java算法返回空值?

转载 作者:塔克拉玛干 更新时间:2023-11-02 18:59:40 25 4
gpt4 key购买 nike

我目前正尝试在 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])); 因为 y0y1 在基本情况之后仍然是 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;
}
}

最佳答案

一些想法:

每当我看到像 Math.ceil(N/2) 一样频繁重复的东西时,我认为它有理由拥有自己的命名变量。 (我知道命名变量并不总是那么容易,但我发现它对易读性至关重要。)

Complex A0[] = new Complex[((int) Math.ceil(N/2))];
Complex A1[] = new Complex[((int) Math.ceil(N/2))];

请注意,当 N==1 时,计算结果为 new Complex[0]。我不确定这是做什么的,但我想我会在内存分配之前进行 N == 1 基本情况检查。

Complex[] y0 = new Complex[((int) Math.ceil(N/2))];
Complex[] y1 = new Complex[((int) Math.ceil(N/2))];
/* ... */
y0 = FFT(A0, N/2);
y1 = FFT(A1, N/2);

我相信您可以跳过这些数组的 new Complex[...] 分配,因为您实际上从未在其中存储任何内容。

Complex[] omega = new Complex[N];
/* ... */
omega[0] = omega[0].times(omega[N]);

我很惊讶这还没有爆炸 -- omega[N] 应该引发一个 IndexOutOfBounds 异常。

关于java - 递归FFT java算法返回空值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8621790/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com