Eu sou novo no princípio de calcular a frequência instantânea e fiz muitas perguntas. Você encontra todos eles em uma lista de marcadores no final deste texto. O texto pode ser um pouco longo, desculpe-me por isso, mas eu realmente tentei resolver esse problema sozinho.
Então, eu estou interessado na frequência instantânea de um sinal com valor real . O cálculo é feito com a ajuda de um sinal analítico , onde é a transformação de Hilbert de .
Para calcular as frequências instantâneas a partir do sinal analítico , segui o artigo:
O cálculo da frequência instantânea e da largura de banda instantânea por Arthur E. Barns, de 1992. Neste artigo, ele introduz vários métodos para calcular a frequência instantânea. Eu escrevo, todas as fórmulas que ele propôs (e eu usei) em um momento.
Para "aprender", brinquei com um sinal muito simples e dois um pouco mais complexo, no MATLAB, e queria obter suas frequências instantâneas.
Fs = 1000; % sampling-rate = 1kHz
t = 0:1/Fs:10-1/Fs; % 10s 'Timevector'
chirp_signal = chirp(t,0,1,2); % 10s long chirp-signal, signal 1
added_sinusoid = chirp_signal + sin(2*pi*t*10); % chirp + sin(10Hz), signal 2
modulated_sinusoid = chirp_signal .* sin(2*pi*t*10); % chirp * sin(10Hz), signal 3
As plotagens no domínio do tempo desses três sinais têm a seguinte aparência:
As plotagens de todas as frequências instantâneas que obtive após a aplicação de todos os métodos do artigo são as seguintes:
Frequências instantâneas de sinal de chirp puro: Frequências instantâneas de sinal de chirp com sinusóide adicional: Frequências instantâneas de sinal de chirp modulado: Observe que nas três imagens os eixos y dos gráficos 3 e 4 são ampliados, de modo que as amplitudes daquelas sinais são muito pequenos!
A primeira possibilidade de passar do sinal analítico para a frequência instantânea é:
onde é a fase instantânea. Eu acho que esse é o método mais comum usado hoje, pelo menos na página do MATLAB é calculado dessa maneira. O código tem a seguinte aparência:
function [instantaneous_frequency] = f2(analytic_signal,Fs)
factor = Fs/(2*pi);
instantaneous_frequency = factor * diff(unwrap(angle(analytic_signal)));
% Insert leading 0 in return-vector to maintain size
instantaneous_frequency = [0 instantaneous_frequency];
end
No artigo, Barns sugere agora (ou melhor, as ditas compilações) outras quatro maneiras de calcular frequências instantâneas a partir do sinal analítico. Ele também menciona a fórmula superior, mas é a opinião de que ela é impraticável devido a ambiguidades na fase. Eu acho que ele não conhecia o unwrap()
método ou, para ser mais preciso, a matemática por trás dele. (Eu mesmo aprendi sobre esse método ainda hoje, quando observamos outros códigos-fonte em frequências instantâneas)
Em seu artigo, a fórmula possui a etiqueta Número (2), portanto, dei a f (t) o índice 2. Todos os outros índices correspondem da mesma maneira que seus números no artigo.
Por causa das ambiguidades em fase, ele sugere:
function [instantaneous_frequency] = f3(analytic_signal,Fs,T)
x = real(analytic_signal);
y = imag(analytic_signal);
diff_x = diff(x);
diff_y = diff(y);
factor = Fs/(2*pi);
a = x(2:end).*diff_y;
b = y(2:end).*diff_x;
c = x(2:end).^2;
d = y(2:end).^2;
instantaneous_frequency = factor * ((a-b)./(c+d));
% Insert leading 0 in return-vector to maintain size
instantaneous_frequency = [0 instantaneous_frequency];
end
Em seguida, Barner fornece mais três fórmulas denominadas "aproximações instantâneas de frequência":
function[instantaneous_frequency] = f9(analytic_signal, Fs, T)
x = real(analytic_signal);
y = imag(analytic_signal);
factor = Fs/(2*pi*T);
a = x(1:end-T).*y(1+T:end);
b = x(1+T:end).*y(1:end-T);
c = x(1:end-T).*x(1+T:end);
d = y(1:end-T).*y(1+T:end);
instantaneous_frequency = factor.*atan((a-b)./(c+d));
% Append 0 to return-vector to maintain size
instantaneous_frequency = [instantaneous_frequency zeros(1,T)];
end
function [instantaneous_frequency] = f11(analytic_signal, Fs, T)
x = real(analytic_signal);
y = imag(analytic_signal);
factor = Fs/(4*pi*T);
a = x(1:end-2*T).*y(1+2*T:end);
b = x(1+2*T:end).*y(1:end-2*T);
c = x(1:end-2*T).*x(1+2*T:end);
d = y(1:end-2*T).*y(1+2*T:end);
instantaneous_frequency = factor.*atan((a-b)./(c+d));
% Append and insert 0s to maintain size
instantaneous_frequency = [zeros(1,T) instantaneous_frequency zeros(1,T)];
end
function [instantaneous_frequency] = formula14(analytic_signal, Fs, T);
x = real(analytic_signal);
y = imag(analytic_signal);
factor = 2*Fs/(pi*T);
a = x(1:end-T).*y(1+T:end);
b = x(1+T:end).*y(1:end-T);
c = (x(1:end-T)+x(1+T:end)).^2;
d = (y(1:end-T)+y(1+T:end)).^2;
instantaneous_frequency = factor * ((a-b)./(c+d));
% Append and insert 0s to maintain size
instantaneous_frequency = [instantaneous_frequency zeros(1,T)];
end
Nas três aproximações, as fórmulas T foram definidas como Fs (T = Fs = 1000 = 1s), conforme sugerido no artigo.
Agora minhas perguntas são:
- As fórmulas f2 e f3 retornam o mesmo resultado para o sinal de chirp puro. Eu acho que isso é bom, pois eles calculam o mesmo. Os três métodos de aproximação não retornam o mesmo, nem mesmo algo próximo! Por que é esse o caso? (Espero que não seja apenas um bug de programação ...)
- Embora eles retornem o mesmo, especialmente no final do enredo, eles começam a se mexer bastante . Qual a explicação para isso? Primeiro pensei em algo como serrilhado, mas minha frequência de amostragem é bastante alta, comparada à frequência dos sinais, então acho que isso pode ser excluído.
Pelo menos f2 e f3 parecem funcionar apropriadamente em um sinal de chirp puro, mas todos os métodos, incluindo f2 e f3, parecem falhar horrivelmente, quando se trata de mais de uma frequência no sinal. Na realidade, ter mais de uma frequência em um sinal é sempre o caso. Então, como obter a (mais ou menos) freqüência instantânea correta?
- Na verdade, eu nem sei o que esperar, quando mais de uma frequência está presente no sinal. O cálculo retorna um número para um determinado ponto no tempo, então o que deve fazer quando, como aqui, mais frequências estão presentes? Retornar a média de todas as frequências ou algo assim?
E minha pergunta provavelmente mais importante é: como isso é tratado em um software real e elaborado? Digamos que eu queira saber a frequência instantânea do sinal modulado em 1,75 s, e escolhi o método f2, pois posso ter "sorte" e obter um número próximo de 6 [Hz], que provavelmente é a resposta correta, ou eu pego meus resultados poucas amostras ao lado e, de repente, recebo algum resultado com fio, até alto, porque, infelizmente, escolhi um valor no pico. Como isso pode ser tratado? Ao processá-lo com um filtro médio ou melhor ainda com mediana? Eu acho que até isso pode ficar realmente difícil, especialmente em regiões onde muitos picos estão próximos um do outro.
E uma última pergunta, não tão importante, por que a maioria dos trabalhos que encontro sobre frequências instantâneas são da área da geografia, especialmente no cálculo de eventos sismográficos como terremotos. O artigo de Barne também toma isso como exemplo. A frequência instantânea não é interessante em muitas áreas?
Até agora, sou muito grato por cada resposta, especialmente quando alguém me dá dicas de como implementá-lo em um projeto de software real ;)
Atenciosamente, Patrick