Orden de frecuencias MATLAB FFT

9

Este wikibook indica que la salida de MATLAB FFTcorresponde con los números de onda ordenados como:

k={0,1,...,n2,n2+1,n2+2,...,1}

Sin embargo, en los códigos de ejemplo en la misma página, los números de onda se codifican como

k = [0:n/2-1 0 -n/2+1:-1];

que es lo mismo que el primero, pero con el onda n / 2 (el "número de onda máximo") reemplazado por 0 . Parece extraño que incluirían 0 dos veces.n/200

Parece que el orden correcto es necesario para tomar derivados a través de transformadas de Fourier, como se describe en el wikibook. ¿Cuál de estos es correcto? ¿MATLAB documenta esto en alguna parte?

Duda
fuente
3
mira en la función fftshift. Tomará la salida de fft y la reordenará desde [-n / 2 + 1: n / 2-1], lo que debería ayudar con su confusión.
Godric Seer
¿No es algo que puedes probar rápidamente por ti mismo? Averiguar en qué orden la salida de FFT es fácil de determinar con un par de experimentos.
Federico Poloni

Respuestas:

4

Quiero ampliar mi comentario y reelaborar el ejemplo al que hace referencia de una manera que debería ser más comprensible que el original y explicar por qué fftdevuelve los coeficientes de la manera en que lo hace.

Como referencia, la parte fft del ejemplo es:

Nx = size(x,2);
k = 2*pi/(b-a)*[0:Nx/2-1 0 -Nx/2+1:-1];
dFdx = ifft(1i*k.*fft(f));
d2Fdx2 = ifft(-k.^2.*fft(f));

Agregué otra sección de código directamente debajo de ella:

Nx = size(x,2);
k = 2*pi/(b-a)*(-Nx/2:Nx/2-1);
dFdxp = ifft(ifftshift(1i*k.*fftshift(fft(f))));
d2Fdx2p = ifft(ifftshift(-k.^2.*fftshift(fft(f))));

y envolvió los dos trozos de código en un momento tic; tocde rought. En un formato más legible, el segundo método usa:

ckf = fftshift(fft(f));
ckdf = 1i*k.*ckf;
df = ifft(ifftshift(ckdf));

La primera diferencia es que el segundo ejemplo tiene un aspecto mucho más intuitivo k. Esta es la principal ventaja del segundo ejemplo, ya que k está ahora en la forma en que pensamos sobre ellos. En la segunda y tercera línea tuve que agregar fftshiftalrededor de la llamada a fft, luego una llamada a ifftshiftdirectamente dentro de la llamada a ifft. Estas llamadas de función adicionales reordenan los coeficientes de lo que se requiere para que la computadora trabaje con ellos a la forma en que los humanos generalmente piensan en ellos.

El problema con el segundo ejemplo es que, si bien kes más intuitivo para nosotros, deja las matrices internas para resolver e invertir fften formas que no son tan ventajosas. Entonces, o tenemos que cambiar el orden con llamadas a fftswitchy ifftswitcho tiene que estar codificado en las fftfunciones. Esto es menos propenso a errores de los usuarios (suponiendo que no estén familiarizados con el funcionamiento de fft, como muchas personas lo están), pero usted paga un precio en tiempo de ejecución.

Como dije antes, agregué llamadas de tiempo alrededor de los dos bloques para comparar y corrí por múltiples N. Los resultados de tiempo fueron:

N =     1000,  Ex1 = 0.000222 s,   Ex2 = 0.007072 s
N =    10000,  Ex1 = 0.001576 s,   Ex2 = 0.003506 s
N =   100000,  Ex1 = 0.023857 s,   Ex2 = 0.034051 s
N =  1000000,  Ex1 = 0.213816 s,   Ex2 = 0.406250 s
N = 10000000,  Ex1 = 4.555143 s,   Ex2 = 7.102348 s

Como puede ver, el acto de cambiar los valores de un lado a otro ralentiza el proceso considerablemente, especialmente a bajo N (donde es 30 veces más lento). Esto es solo un ejemplo, y su computadora puede mostrar tendencias ligeramente diferentes dependiendo de cosas como la velocidad de la memoria, los núcleos / velocidad del procesador, etc. pero es ilustrativo del punto. La razón por la fftsalida confusa es porque le está ahorrando una fracción no trivial de su tiempo de computación.

Vidente de Godric
fuente
3
Esto todavía no responde la pregunta original: ¿por qué funciona en absoluto incluir cero dos veces? ¿Y por qué la documentación sugiere que el cero solo debe incluirse una vez?
David Ketcheson
2

Su pregunta sobre el 'reemplazo' del número de onda es bastante complicada. En general, la modificación del número de onda de este tipo no está destinada a salvar los fracasos, como algunos han sugerido aquí, sino que está diseñada para respetar las peculiaridades analíticas de, por ejemplo, ciertos operadores diferenciales. Estoy muy sorprendido de que no haya podido encontrar una discusión relacionada en los Métodos espectrales de Trefethen. Para continuar, supondré que está preocupado por la diferenciación espectral basada en FFT y que está realizando transformaciones en un dominio de cardinalidad uniforme.

La regla general, para derivadas impares, es establecer

k = [0:n/2-1 0 -n/2+1:-1];

y para derivados pares, establecer

k = [0:n/2 -n/2+1:-1];

Si se trata de un relleno, el tratamiento de la frecuencia de Nyquist es igualmente tedioso. Hay un excelente reportaje que prueba y los comentarios sobre estos temas aquí !

Stuart Hilton
fuente
0

NN/2xRN/2N/2N/2

mu7z
fuente