Estoy buscando calcular una correlación rápida usando FFT y la biblioteca kissfft, y la escala debe ser precisa. ¿Qué escalado es necesario (hacia adelante y hacia atrás) y qué valor uso para escalar mis datos?escala de kissfft
Respuesta
Los 3 factores de escala FFT más comunes son:
1,0 FFT directa, 1,0/N FFT inversa
1,0/N FFT directa, FFT 1,0 inversa
1.0/sqrt (N) en ambas direcciones, FFT & IFFT
Dada la posible ambigüedad en la documentación, y para cualquier escalado que el usuario espere sea "correcto" para sus propósitos, lo mejor es alimentar una onda sinusoidal pura de amplitud conocida (1.0 flotación o 255 enteros) y exactamente periódica en la longitud de FFT a la FFT (y/o IFFT) en cuestión, y ver si la escala coincide con uno de los anteriores, es tal vez diferente de uno de los anteriores por 2X o sqrt (2), o la escala deseada es algo completamente diferente.
p. Ej. Escriba una prueba unitaria para kissfft en su entorno para sus tipos de datos.
Esto es lo que terminé haciendo, pero esperaba que alguien supiera que me ahorraría el problema. Este es un buen consejo en general. –
No creerá cuán confusa es la literatura de FFT si no sabe que existen estas representaciones diferentes :) –
multiplicar cada respuesta de frecuencia por 1/sqrt (N), para una escala global de 1/N
en pseudocódigo:
ifft(fft(x)*conj(fft(y))/N) == circular_correlation(x,y)
Al menos esto es cierto para kisfft con punto flotante tipos.
La salida del siguiente código C++ ejemplo debe ser algo como
la correlación circular de [1, 3i, 0 0 ....] consigo mismo = (10,0), (1.19796e- 10,3), (- 4.91499e-08,1.11519e-15), (1.77301e-08, -1.19588e-08) ...
#include <complex>
#include <iostream>
#include "kiss_fft.h"
using namespace std;
int main()
{
const int nfft=256;
kiss_fft_cfg fwd = kiss_fft_alloc(nfft,0,NULL,NULL);
kiss_fft_cfg inv = kiss_fft_alloc(nfft,1,NULL,NULL);
std::complex<float> x[nfft];
std::complex<float> fx[nfft];
memset(x,0,sizeof(x));
x[0] = 1;
x[1] = std::complex<float>(0,3);
kiss_fft(fwd,(kiss_fft_cpx*)x,(kiss_fft_cpx*)fx);
for (int k=0;k<nfft;++k) {
fx[k] = fx[k] * conj(fx[k]);
fx[k] *= 1./nfft;
}
kiss_fft(inv,(kiss_fft_cpx*)fx,(kiss_fft_cpx*)x);
cout << "the circular correlation of [1, 3i, 0 0 ....] with itself = ";
cout
<< x[0] << ","
<< x[1] << ","
<< x[2] << ","
<< x[3] << " ... " << endl;
kiss_fft_free(fwd);
kiss_fft_free(inv);
return 0;
}
El código que estoy usando es: 'ifft (fft (x) * conj (fft (y)))/N == corr' Con kissfft v1_2_9 –
Sí. Lamento dirigirlo al principio. He actualizado la descripción para que coincida con lo que mi código realmente estaba haciendo. –
- 1. Escala Drupal
- 2. escala de animación CSS3
- 3. Escala de aljaba Matplotlib
- 4. UISegmentedControl escala de imagen
- 5. Escala lógica de prueba
- 6. libgdx: escala de partículas
- 7. Java2D: problemas de escala
- 8. Función de escala de color
- 9. escala de imagen de Java
- 10. Nodo: escala socket.io/nowjs - escala en diferentes instancias
- 11. Sprites de escala en SDL
- 12. Drawable => escala de grises
- 13. Forma escalonada de escala reducida
- 14. Escala de valores en PHP
- 15. opencv VideoCapture.set escala de grises?
- 16. Escala automática de texto Tamaño
- 17. transformar escala después de rotar
- 18. Aprendizaje a gran escala
- 19. Linear X escala logarítmica
- 20. Animación UIVIew - Escala + Traslación
- 21. Pseudoinverso a gran escala
- 22. UIImageView escala/interpolación
- 23. Escala WebView en Cocoa
- 24. AS3 - Escala BitmapData
- 25. NSImage no escala
- 26. Detección de escala de zoom de iPad
- 27. ¿Modos de escala de video HTML5?
- 28. TabHost/TabWidget - Imagen de fondo de escala?
- 29. Encuentra escala de valores de CGAffineTransform
- 30. Imagen de fondo de escala en LinearLayout
Sí que debería haber sido más específico. Esperaba que alguien me ahorrara el problema de descubrir el escalado yo mismo (específico de kissfft), sin embargo lo hice yo mismo y puedo decirte que tuve que ** escalar el inverso por 1/N **. Por supuesto, la escala se omite inicialmente para fines de eficiencia, pero es importante cuando se calculan las correlaciones. No importa tanto para la autocorrelación, ya que el resultado es proporcional, pero lo que sí importa es cuando se calcula algo como el ASDF que tiene dos términos precisos para agregar al final. –
Información más detallada, probada en kiss_fftr (implementación para FFT reales): el fttr directo escala las amplitudes por 'nfft/2', mientras que el fftr inverso escala las amplitudes por' 2' independientemente de nfft. Para obtener las amplitudes originales, tiene que escalar por '2/nfft' y' 1/2' respectivamente. (Esto explica por qué tiene que escalar por '1/nfft' al hacer las FFT directas e inversas en serie.) – tmandry