Anlık frekansı hesaplama ilkesinde yeniyim ve üzerinde birçok soru ortaya çıktı. Hepsini bu metnin sonunda bir madde işareti listesinde bulabilirsiniz. Metin biraz uzun olabilir, bunun için beni affedin, ama gerçekten bu sorun üzerinde kendi başıma çalışmaya çalıştım.
Bu yüzden anlık frekansla ilgileniyorum değerli bir sinyalin . Hesaplama bir analitik sinyal yardımı ile yapılır, nerede nin Hilbert dönüşümüdür .
Analitik sinyal den anlık frekansları hesaplamak için kağıdı takip ettim:
1992'den Arthur E. Barns tarafından anlık frekans ve anlık bant genişliğinin hesaplanması. Bu makalede, anlık frekansı hesaplamak için birçok yöntem sunmaktadır. Bir anda önerdiği (ve kullandığım) tüm formülleri yazıyorum.
"Öğrenmek" için, MATLAB'da çok basit ve iki biraz daha karmaşık sinyalle oynadım ve anlık frekanslarını elde etmek istedim.
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
Bu üç sinyalin zaman alanındaki grafikler aşağıdaki gibidir:
Kağıttan tüm yöntemleri uyguladıktan sonra aldığım tüm anlık frekansların grafikleri şunlardır:
Saf cıvıltı sinyalinin anlık frekansları: Sinüsoid eklenmiş cıvıltı sinyalinin ani frekansları: Modüle edilmiş cıvıltı sinyalinin ani frekansları: Lütfen her üç görüntüde de 3 ve 4 no'lu y-ekseninin yakınlaştırıldığını unutmayın. sinyaller çok küçük!
Analitik sinyalden anlık frekansa ulaşmanın ilk olasılığı:
burada anlık fazdır. Bence günümüzde kullanılan en yaygın yöntem budur, en azından MATLAB'ın web sayfasında bu şekilde hesaplanıyor. Kod aşağıdaki gibidir:
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
Makalede, Ahırlar şimdi analitik sinyalden anlık frekansları hesaplamanın dört yolunu önermektedir (veya daha doğrusu adı geçen derlemeleri). Üst formülden de bahsediyor, ancak fazdaki belirsizlikler nedeniyle bunun pratik olmadığı görüşündedir. Sanırım, unwrap()
yöntemi bilmiyordu ya da arkasındaki matematiği daha kesin olarak tanımıyordu . (Ben, kendim bu yöntemi hemen anladım, anlık frekanslardaki diğer bazı kaynak kodlarına bakarken)
Makalesinde, formülün (2) numaralı etiketi vardır, bu nedenle, f (t) 2 dizinini verdim. Diğer tüm indeksler, kağıttaki sayılarına aynı şekilde karşılık gelir.
Aşamadaki belirsizlikler nedeniyle, şunu önerir:
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
Sonra Barner "anlık frekans yaklaşımı" adını verdiği üç formül daha verir:
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
3 yaklaşımın hepsinde Formüller T, kağıtta önerildiği gibi Fs (T = Fs = 1000 = 1s) olarak ayarlandı.
Şimdi sorum şu:
- Formül f2 ve f3, saf cıvıltı sinyali için aynı sonucu verir. Bence bu aynı şekilde hesapladıkları için iyi. Üç yaklaşım yöntemi aynı şeyi döndürmez, ona yakın bir şey bile değil! Neden böyle? (Umarım sadece bir programlama hatası değildir ...)
- Her ne kadar aynı dönseler de, özellikle arsa sonunda çok fazla kıpırdatmaya başlarlar . Bunun açıklaması nedir? İlk önce takma ad gibi bir şey düşündüm, ancak örnekleme frekansım, sinyallerin frekansına kıyasla oldukça yüksek, bu yüzden dışlanabilir.
En azından f2 ve f3, saf bir cıvıltı sinyali üzerinde uygun çalışıyor gibi görünüyor, ancak sinyalde birden fazla frekans söz konusu olduğunda, f2 ve f3 dahil olmak üzere tüm yöntemler korkunç başarısız görünüyor. Gerçekte bir sinyalde birden fazla frekans olması her zaman böyledir. Peki kişi (daha fazla veya daha az) doğru anlık frekansı nasıl alabilir?
- Aslında sinyalde birden fazla frekans olduğunda ne olacağını bile bilmiyorum. Hesaplama, belirli bir nokta için bir sayı döndürür, bu nedenle, burada olduğu gibi, daha fazla frekans mevcut olduğunda ne yapmalıdır? Tüm frekansların veya bunun gibi bir şeyin ortalamasını döndürür müsünüz?
Ve muhtemelen en önemli sorum şu, bu gerçek ve özenli bir yazılımda nasıl ele alınır? Diyelim ki 1.75 s'de modüle edilmiş sinyalin anlık frekansını bilmek istiyorum ve f2 yöntemini seçtim, 'şanslı' olabileceğimden ve büyük olasılıkla doğru cevap olan 6 [Hz] 'e yakın bir sayı elde ettiğimden veya sonuçlarımı yanında birkaç örnek al ve aniden biraz kablolu, yüksek bir yol alıyorum, çünkü ne yazık ki başakta bir değer seçtim. Bu nasıl ele alınabilir? Ortalama veya daha iyi bir medyan filtre ile postprocessing? Bence bu, özellikle çok sayıda sivri yan yana olan bölgelerde gerçekten zor olabilir.
Ve son, çok önemli olmayan bir soru, anlık frekanslar hakkında bulduğum çoğu makalenin, özellikle deprem gibi sismografik olayların hesaplanmasında coğrafya alanından olması neden. Barne'nin makalesi de bunu örnek alıyor. Anlık frekans birçok alanda ilginç değil mi?
Şimdiye kadar, her cevap için çok minnettarım, özellikle birisi bana gerçek bir yazılım projesinde nasıl uygulanacağı konusunda ipuçları verdiğinde ;)
Saygılarımla, Patrick