Como mudar o espectro de frequências?

7

Vamos dizer que temos um espectro que varia de -X MHz a + X MHz. Eu precisaria corrigir o erro de frequência no espectro deslocando o componente zero para o meio (0 Hz).

Se a saída (o espectro de frequências) for calculada via FFT, até onde eu sei, posso mover o espectro ajustando os 'fatores de variação' (ou coeficientes, para dados complexos e ondas senoidais e cosseno).

No caso de um tamanho 1024 FFT (índices de compartimento de 0 a 1023), o componente de 0 Hz deve existir no número de compartimento 511. No entanto, devido a um possível erro de frequência, o componente de 0 hz pode realmente estar no compartimento 510, por exemplo.

Não consigo encontrar muita informação sobre isso. Qualquer ajuda apreciada.

EDIT: Erro na pergunta.

user1166780
fonte
2
0 Hz está no compartimento 0, não? A meio da FFT é as altas frequências
endolith
11
Isso dependeria inteiramente do algoritmo usado. No entanto, uma maneira simples de pensar sobre isso é apenas para traçar as ondas: Wolfram Alpha
user1166780
Como eu acho que funciona é o seguinte: Dependendo de onde o coeficiente de frequência mais alto é usado, seria a posição do componente de frequência mais alta. No entanto, não posso explicar as regras sobre o motivo pelo qual alguns algoritmos podem ter suas saídas em posições diferentes, etc. (além de reorganizá-las no final).
precisa saber é o seguinte
O link alfa da Wolfram deve ter o seguinte: cos ((2 * pi / 512) * x * 500) + i * sin ((2 * pi / 512) * x * 500), não parece funcionar assim. Mude 500 para 1 e veja a diferença. Se você digitar 0 e 0, a frequência é obviamente 0. Mas, se os organizarmos no final (caso nossos dados sejam de -algo a + algo), podemos ter nosso componente de 0 Hz no meio.
precisa saber é o seguinte

Respostas:

8

Se a mudança de frequência desejada for um múltiplo do espaçamento da bandeja, como no seu exemplo, você poderá facilmente efetuar a mudança que deseja, girando as saídas FFT pelo número de posições necessárias. No caso mais comum em que o deslocamento de frequência não é um múltiplo inteiro do espaçamento entre compartimentos, você pode multiplicar o sinal por uma função exponencial complexa antes de executar a FFT.

Portanto, se você determinar que o componente de frequência central de que você fala está realmente localizado na frequência foffset Hz em seus dados, e os dados são amostrados na taxa fs Hz, em seguida, para mudar o espectro de modo que o componente de interesse esteja na frequência zero na saída da FFT, você faria:

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

Yshifted[k]=FFT[xshifted[n]]
Jason R
fonte
11
Obrigado por isso, mas onde você encontrou essas informações?
precisa saber é o seguinte
Bem, deixa pra lá, 'mudança de frequência de multiplicação exponencial complexa' ou similar é a palavra-chave que eu estava procurando. Obrigado novamente.
usar o seguinte comando
11
Essa é uma propriedade básica da transformação discreta de Fourier , da qual a FFT é apenas uma implementação eficiente. As outras transformações da família Fourier têm propriedades análogas próprias, mas existem diferenças sutis em cada uma.
Jason R
Estou confuso. Estou tentando usar isso para (circular) mudar um sinal de domínio em tempo real usando FFT. As trocas de amostras inteiras funcionam bem, mas quando tento trocar pela metade de uma amostra, o resultado se torna imaginário e não se parece em nada com o original (o original é simétrico, o resultado é simétrico ímpar). O mesmo para comprimentos ímpares ou pares.
Endolith 8/08
@ endolith: Não sei ao certo o que você está tentando fazer lá. A resposta que dei acima foi para aplicar facilmente uma mudança de frequência a um sinal. Você está tentando aplicar um atraso fracionário?
Jason R
-2

bem, a maneira mais simples é que, se você usou o fourier para encontrar o espectro, e precisa conhecer sua frequência pela quantidade de deslocamento, pode fazer uma coisa ..

1) descubra a resposta de impulso desses espectros

2) envolva-o com um ruído

3) veja o sinal que você obtaine4) tome sua FFT apenas para ter certeza, se combinar com a anterior

4) e veja os espectros calculando a média para diferentes partes ... para isso eu posso fornecer um algoritmo no software mathematica, que é

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]
  ]

Neste código, eu tenho um argumento para tomar pmsesignal, assim você pode usar seu próprio sinal em vez dele ..

não tenho certeza, quão bem eu expliquei isso, mas isso funcionou no meu caso ..

Felicidades!

marechal
fonte