Je suis actuellement en train de mettre en œuvre l'algorithme FFT en Java et j'ai un peu de mal avec ça! J'ai testé toutes les autres parties de l'algorithme et elles semblent fonctionner correctement.
Le problème que je rencontre est que dans le cas de base, un tableau de nombres complexes est retourné, dans le cas de base A[0]
est renseigné. Après l'exécution des cas de base, la boucle for est exécutée où y0[0]
et y1[0]
sont trouvés pour être null, malgré leur attribution dans les cas de base, assez déconcerté par cela. Cela est visible dans la ligne System.out.println
Quelqu'un peut-il me dire où se trouvent mes erreurs?
//Cette méthode implémente l'algorithme FFT récursif, elle suppose que la longueur d'entrée
//N est une puissance de deux
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))];
//cas de base
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);
//appels récursifs
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;
}
}
Voici le code de ma méthode splitInput comme demandé
//Cette méthode prend un tableau de nombres complexes en argument et retourne chaque élément pair ou impair
//selon le deuxième argument int étant 1 ou 0
private static Complex[] splitInput(Complex[] input, int even) {
Complex[] newArray = new Complex[(input.length/2)];
//Renvoie tous les éléments pairs du tableau double, y compris 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;
}
//Renvoie tous les éléments impairs du tableau double
else {
for (int i = 0; i < (input.length/2); i++) {
newArray[i] = new Complex (input[(i*2) + 1].re, 0.0);
}
return newArray;
}
}
MODIFICATION: J'ai mis à jour mon code selon vos suggestions, je reçois toujours une exception de pointeur nul à la ligne y[k] = y0[k].plus(omega[k].times(y1[k]));
alors que y0
et y1
sont toujours null
après le cas de base :( des idées supplémentaires? Voici l'algorithme mis à jour
//Cette méthode implémente l'algorithme FFT récursif, elle suppose que la longueur d'entrée
//N est une puissance de deux
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;
//cas de base
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);
//appels récursifs
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;
}
}