¿Cómo cambiar el espectro de frecuencia?

7

Digamos que tenemos un espectro que va desde -X MHz a + X MHz. Necesitaría corregir el error de frecuencia en el espectro cambiando el componente cero al medio (0 Hz).

Si la salida (el espectro de frecuencia) se calcula a través de FFT, hasta donde yo sé, puedo mover el espectro ajustando los 'factores de twiddle' (o coeficientes, para ondas de seno y coseno de datos complejos).

En el caso de un tamaño de 1024 FFT (índices de bin de 0 a 1023), el componente de 0 Hz debe existir en el número de bin 511. Sin embargo, debido a un posible error de frecuencia, el componente de 0 hz puede estar en el bin 510, por ejemplo.

Parece que no puedo encontrar mucha información sobre esto. Cualquier ayuda apreciada.

EDITAR: Error en la pregunta.

usuario1166780
fuente
2
0 Hz está en el contenedor 0, ¿no? El centro de la FFT son las frecuencias altas
endolito del
1
Esto dependería por completo del algoritmo utilizado. Sin embargo, una manera simple de pensarlo es simplemente trazar las olas: wolfram alpha
user1166780
Lo que creo que funciona es que: dependiendo de dónde se use el coeficiente de frecuencia más alto, sería la posición del componente de frecuencia más alto. Sin embargo, no puedo explicar las reglas de por qué algunos algoritmos pueden tener sus salidas en diferentes posiciones, etc. (aparte de reorganizarlos al final).
user1166780
Wolfram alpha link debería tener esto: cos ((2 * pi / 512) * x * 500) + i * sin ((2 * pi / 512) * x * 500), no parece funcionar aunque. Cambie 500 a 1 y vea la diferencia. Si ingresa 0 y 0, la frecuencia es por supuesto 0. Pero si los reorganizamos al final (en caso de que nuestros datos sean de -algo a + algo) podemos tener nuestro componente de 0 Hz en el medio.
user1166780

Respuestas:

8

Si el cambio de frecuencia que desea es un múltiplo del espacio del compartimiento, como en su ejemplo, entonces puede efectuar fácilmente el cambio que desee simplemente girando las salidas FFT por la cantidad de contenedores que necesita. En el caso más común de que el desplazamiento de frecuencia no es un múltiplo entero del espaciado de bin, entonces puede multiplicar la señal por una función exponencial compleja antes de realizar la FFT.

Entonces, si determina que el componente de frecuencia central del que habla está realmente ubicado en la frecuencia Hz en sus datos, y los datos se muestrean a una tasa Hz, entonces para cambiar el espectro de modo que el componente de interés sea a frecuencia cero en la salida FFT, haría:foffsetfs

xshifted[n]=x[n]ej2πfoffsetnfs,  n=0,1,,N1

Yshifted[k]=FFT[xshifted[n]]
Jason R
fuente
1
Gracias por esto, pero ¿dónde encontraste esta información?
user1166780
Bueno, no importa, 'cambio de frecuencia de multiplicación exponencial compleja' o similar es la palabra clave que estaba buscando. Gracias de nuevo.
user1166780
1
Esta es una propiedad básica de la transformada discreta de Fourier , de la cual la FFT es solo una implementación eficiente. Las otras transformaciones en la familia Fourier tienen propiedades análogas propias, pero hay diferencias sutiles en cada una.
Jason R
Estoy confundido. Estoy tratando de usar esto para (circular) cambiar una señal de dominio en tiempo real usando FFT. Los cambios de muestra enteros funcionan bien, pero cuando trato de cambiar la mitad de una muestra, el resultado se vuelve imaginario y no se parece en nada al original (el original es simétrico, el resultado es impar-simétrico). Lo mismo para longitudes pares o impares.
endolito
@endolith: No estoy seguro de lo que estás tratando de hacer allí. La respuesta que di arriba fue para aplicar fácilmente un cambio de frecuencia a una señal. ¿Estás tratando de aplicar un retraso fraccional?
Jason R
-2

bueno, la forma más simple es que, si ha utilizado el fourier para encontrar los espectros, y necesita saber su frecuencia por cuánto se desplaza, puede hacer una cosa ...

1) averiguar la respuesta al impulso de ese espectro

2) convolucionarlo con un ruido

3) vea la señal que obtiene 4) tome su FFT solo para asegurarse, si coincide con la anterior

4) y ver los espectros promediando en diferentes partes ... para esto puedo dar un algoritmo ua en el software matemático, que es

reflect[a_] := Module[{n = Length[a]},
  RotateRight[a, Floor[n/2]]
  ]

freqAxis[len_] := Module[{},
   If[OddQ[len],
    Range[1, len] - (Ceiling[len/2.]),
    Range[1, len] - (1 + Ceiling[len/2.])
    ]
   ];

colors = {Black, Red, Blue, Brown , ColorData["Legacy", "DarkGreen"], 
   ColorData["Legacy", "Goldenrod"], ColorData["Legacy", "DeepPink"], 
   Cyan, Orange, Purple, ColorData["Legacy", "DeepSkyBlue"], Magenta};

specPlot[pieces_, pieceLen_, color_] := 
 Module[{data, spec, fAxis, pos},
  fAxis = freqAxis[pieceLen];
  data = Partition[Take[mysignal, pieces*pieceLen], pieceLen];
  spec = Total[Abs[Fourier[data]]^2]/pieces;
  spec = reflect[spec];
  Print["valley=", Nearest[spec, 1.0][[1]], " atPos=", 
   pos = Position[spec, Nearest[spec, 1.0][[1]]][[1, 1]], " atFpos=", 
   Position[fAxis, 0][[1, 1]], " atF=", fAxis[[pos]], " firstMax=", 
   Max[Take[spec, Round[pieceLen/2]]], " atF=", 
   fAxis[[Position[spec, Max[Take[spec, Round[pieceLen/2]]]][[1, 
     1]]]], " lastMax=", Max[Take[spec, -Round[pieceLen/2]]], " atF=",
    fAxis[[Position[spec, Max[Take[spec, -Round[pieceLen/2]]]][[1, 
     1]]]]];
  ListLinePlot[Transpose[{fAxis, spec}], PlotStyle -> colors[[color]],
    PlotLabel -> "N = " <> ToString[pieces], PlotRange -> All]
  ]

en este código, tengo un argumento para tomar pmsesignal, por lo que puede usar su propia señal en lugar de ella ...

No estoy seguro, qué bien lo expliqué, pero esto había funcionado en mi caso ...

¡Salud!

mariscal
fuente