J'ai un problème étrange que je ne peux pas résoudre. J'ai fait cela comme un exemple simple qui démontre le problème. J'ai une onde sinusoïdale définie entre [0, 2 * pi]. Je prends la transformée de Fourier en utilisant FFTW. Ensuite, j'ai une boucle for où je prends à plusieurs reprises la transformée de Fourier inverse. Dans chaque itération, je prends la moyenne de ma solution et j'imprime les résultats. Je m'attends à ce que la moyenne reste la même à chaque itération car il n'y a pas de changement de solution, y. Cependant, quand je prends N = 256 et d'autres valeurs paires de N, je note que la moyenne croît comme s'il y avait des erreurs numériques. Cependant, si je choisis, disons, N = 255 ou N = 257, ce n'est pas le cas et j'obtiens ce qui est attendu (avg = 0.0 pour chaque itération).Erreurs avec des appels FFTW répétés
code:
#include <stdio.h>
#include <stdlib.h>
#include <fftw3.h>
#include <math.h>
int main(void)
{
int N = 256;
double dx = 2.0 * M_PI/(double)N, dt = 1.0e-3;
double *x, *y;
x = (double *) malloc (sizeof (double) * N);
y = (double *) malloc (sizeof (double) * N);
// initial conditions
for (int i = 0; i < N; i++) {
x[i] = (double)i * dx;
y[i] = sin(x[i]);
}
fftw_complex yhat[N/2 + 1];
fftw_plan fftwplan, fftwplan2;
// forward plan
fftwplan = fftw_plan_dft_r2c_1d(N, y, yhat, FFTW_ESTIMATE);
fftw_execute(fftwplan);
// set N/2th mode to zero if N is even
if (N % 2 < 1.0e-13) {
yhat[N/2][0] = 0.0;
yhat[N/2][1] = 0.0;
}
// backward plan
fftwplan2 = fftw_plan_dft_c2r_1d(N, yhat, y, FFTW_ESTIMATE);
for (int i = 0; i < 50; i++) {
// yhat to y
fftw_execute(fftwplan2);
// rescale
for (int j = 0; j < N; j++) {
y[j] = y[j]/(double)N;
}
double avg = 0.0;
for (int j = 0; j < N; j++) {
avg += y[j];
}
printf("%.15f\n", avg/N);
}
fftw_destroy_plan(fftwplan);
fftw_destroy_plan(fftwplan2);
void fftw_cleanup(void);
free(x);
free(y);
return 0;
}
sortie N = 256:
0.000000000000000
0.000000000000000
0.000000000000000
-0.000000000000000
0.000000000000000
0.000000000000022
-0.000000000000007
-0.000000000000039
0.000000000000161
-0.000000000000314
0.000000000000369
0.000000000004775
-0.000000000007390
-0.000000000079126
-0.000000000009457
-0.000000000462023
0.000000000900855
-0.000000000196451
0.000000000931323
-0.000000009895302
0.000000039348379
0.000000133179128
0.000000260770321
-0.000003233551979
0.000008285045624
-0.000016331672668
0.000067450106144
-0.000166893005371
0.001059055328369
-0.002521514892578
0.005493164062500
-0.029907226562500
0.093383789062500
-0.339111328125000
1.208251953125000
-3.937500000000000
13.654296875000000
-43.812500000000000
161.109375000000000
-479.250000000000000
1785.500000000000000
-5369.000000000000000
19376.000000000000000
-66372.000000000000000
221104.000000000000000
-753792.000000000000000
2387712.000000000000000
-8603776.000000000000000
29706240.000000000000000
-96833536.000000000000000
Toutes les idées?
Eh bien, dans le code actuel les résultats sont supposés changer (chaque itération modifie yhat) mais je rencontre le même problème où la solution pour N même croît alors que N impair donne le bon résultat. Ici, je voulais rendre l'exemple aussi simple que possible. Cependant, je suppose que le fait que vous changez le vrai problème à chaque itération signifie que je ne peux pas utiliser une seule sauvegarde. – symmetric
Si vous souhaitez conserver les données d'entrée inchangées, utilisez l'indicateur 'FFTW_PRESERVE_INPUT'. Per http://www.fftw.org/doc/Planner-Flags.html –
J'ai modifié le plan 'c2r' pour qu'il contienne' FFTW_ESTIMATE | FFTW_PRESERVE_INPUT' et il semble avoir fait l'affaire ici et dans mon vrai problème. Merci! – symmetric