क्या एक एकल आवृत्ति के लिए चरण की गणना करने के लिए एक एल्गोरिथ्म है?


17

आप एक समारोह है, तो f(t)=Asin(ωt+ϕ) , और संदर्भ पाप लहर sin(ωx) क्या गणना करने के लिए एक तेजी से एल्गोरिथ्म होगा ϕ ?

मैं Goertzel एल्गोरिथ्म को देख रहा था , लेकिन यह चरण से निपटने के लिए प्रतीत नहीं होता है?

जवाबों:


5

विशिष्ट आवृत्ति पर DFT का उपयोग करें। फिर वास्तविक / कल्पना भागों से आयाम और चरण की गणना करें। यह आपको नमूनाकरण समय की शुरुआत के लिए संदर्भित चरण देता है।

एक 'सामान्य' एफएफटी (या सभी एन हार्मोनिक्स के लिए गणना किए गए एक डीएफटी) में, आप आमतौर पर f = k * (sample_rate) / N के साथ आवृत्ति की गणना करते हैं, जहां k एक पूर्णांक है। यद्यपि यह पवित्र प्रतीत हो सकता है (विशेष रूप से पूरी तरह से चर्च के सदस्य के रूप में), आप वास्तव में कश्मीर के गैर-पूर्णांक मूल्यों का उपयोग कर सकते हैं जब एक एकल डीएफटी कर रहे हों।

उदाहरण के लिए, मान लें कि आपने 27 हर्ट्ज की साइन वेव का एन = 256 पॉइंट जनरेट (या प्राप्त) किया है। (मान लीजिए, नमूना_रेट = 200)। 256 अंक एफएफटी (या एन बिंदु डीएफटी) के लिए आपकी 'सामान्य' आवृत्तियां इसके अनुरूप होंगी: f = k * (sample_rate) / N = k * (200) / 256, जहां k एक पूर्णांक है। लेकिन 34.56 का एक गैर-पूर्णांक 'के' ऊपर सूचीबद्ध मापदंडों का उपयोग करके 27 हर्ट्ज की आवृत्ति के अनुरूप होगा। यह एक डीएफटी 'बिन' बनाने जैसा है जो बिल्कुल ब्याज की आवृत्ति (27 हर्ट्ज) पर केंद्रित है। कुछ C ++ कोड (DevC ++ कंपाइलर) इस प्रकार दिख सकते हैं:

#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <cmath>
using namespace std;

// arguments in main needed for Dev-C++ I/O
int main (int nNumberofArgs, char* pszArgs[ ] ) {
const long N = 256 ;
double sample_rate = 200., amp, phase, t, C, S, twopi = 6.2831853071795865; 
double  r[N] = {0.}, i[N] = {0.}, R = 0., I = 0. ;
long n ;

// k need not be integer
double k = 34.56;

// generate real points
for (n = 0; n < N; n++) {
    t =  n/sample_rate;
    r[n] = 10.*cos(twopi*27.*t - twopi/4.);
}  // end for

// compute one DFT
for (n = 0; n < N; n++) {
    C = cos(twopi*n*k/N); S = sin(twopi*n*k/N);
    R = R + r[n]*C + i[n]*S;
    I = I + i[n]*C - r[n]*S;
} // end for

cout<<"\n\ndft results for N = " << N << "\n";
cout<<"\nindex k     real          imaginary       amplitude         phase\n";

amp = 2*sqrt( (R/N)*(R/N) + (I/N)*(I/N) ) ;
phase = atan2( I, R ) ;
// printed R and I are scaled
printf("%4.2f\t%11.8f\t%11.8f\t%11.8f\t%11.8f\n",k,R/N,I/N,amp,phase);

cout << "\n\n";
system ("PAUSE");
return 0;
} // end main

//**** end program

(पुनश्च: मुझे आशा है कि ऊपर दिए गए स्टैकओवरफ्लो में अच्छी तरह से अनुवाद किया गया है - इसमें से कुछ चारों ओर लपेट सकता है)

उपरोक्त का परिणाम, -टॉप्टी / 4 का एक चरण है, जैसा कि उत्पन्न वास्तविक बिंदुओं में दिखाया गया है (और पॉस / नकारात्मक आवृत्ति को प्रतिबिंबित करने के लिए amp को दोगुना किया गया है)।

ध्यान देने योग्य कुछ बातें - मैं परीक्षण तरंग उत्पन्न करने और परिणामों की व्याख्या करने के लिए कोसाइन का उपयोग करता हूं - आपको इस बारे में सावधान रहना होगा - चरण समय = 0 के लिए संदर्भित किया जाता है, जो कि आपने नमूना शुरू किया है (यानी: जब आपने r [0 एकत्र किया] ), और कोसाइन सही व्याख्या है।

उपरोक्त कोड न तो सुरुचिपूर्ण है और न ही कुशल है (उदाहरण के लिए: पाप / कॉस मान, आदि के लिए एक लुक-अप तालिकाओं का उपयोग करें)।

जैसे ही आप बड़े एन का उपयोग करते हैं, आपके परिणाम अधिक सटीक होंगे, और इस तथ्य के कारण थोड़ी सी त्रुटि है कि नमूना दर और एन ऊपर एक दूसरे के गुणक नहीं हैं।

बेशक, यदि आप अपना नमूना दर, N, या f बदलना चाहते हैं, तो आपको कोड और k का मान बदलना होगा। आप निरंतर आवृत्ति लाइन पर कहीं भी एक डीएफटी बिन को डुबो सकते हैं - बस यह सुनिश्चित करें कि आप कश्मीर के मूल्य का उपयोग कर रहे हैं जो ब्याज की आवृत्ति से मेल खाती है।


K को पूर्ण रूप से पास बनाने के लिए N को समायोजित करके इस दृष्टिकोण को बेहतर बनाया जा सकता है। मैंने एक अलग उत्तर पोस्ट किया जो इस एल्गोरिथ्म की सटीकता को दर्शाता है।
मोजुबा

10

समस्या को (ग़ैर-रेखीय) न्यूनतम-वर्ग समस्या के रूप में तैयार किया जा सकता है:

F(ϕ)=12i=1n[Asin(ωi+ϕ)fi(ω)]2

F(ϕ)ϕ

व्युत्पन्न बहुत सरल है:

F(ϕ)=i=1nAcos(ωi+ϕ)[Asin(ωi+ϕ)fi(ω)]

F(ϕ)

स्पष्ट रूप से, उपरोक्त उद्देश्य फ़ंक्शन में समय-समय पर कई मिनिमा हैं, इसलिए अन्य पेनिमा में भेदभाव करने के लिए कुछ जुर्माना शब्द जोड़ा जा सकता है (उदाहरण के लिए, मॉडल समीकरण में जोड़ना )। लेकिन मुझे लगता है कि अनुकूलन बस निकटतम मिनीमा में परिवर्तित हो जाएगा और आप परिणाम को घटाकर अपडेट कर सकते हैं । 2 π कश्मीर , कश्मीर एनϕ22πk,kN


मुझे नहीं लगता कि आपको आवधिकता नहीं के कारण दंडित करने की आवश्यकता है? आप बस जो कुछ भी चरण अंतरिक्ष में minima ले सकते हैं यह एक modulu और , नहीं करता है? 2π
स्पेसी

@ मोहम्मद हां, लेकिन कुछ अनुकूलन तकनीक कई शुरुआती बिंदुओं का उपयोग कर सकती हैं जिन्हें समान मूल्य में परिवर्तित करना चाहिए या एकल वैश्विक न्यूनतम के साथ उत्तल कार्य करना चाहिए जो कि द्विघात के साथ अच्छी तरह से अनुमानित किया जा सकता है। दूसरा लाभ यह है कि हम किसी भी शुरुआती बिंदु लिए एक ही परिणाम के साथ समाप्त होते हैं । ϕ0
लिबोर

दिलचस्प। क्या मैं आपको इस संबंधित प्रश्न पर एक दरार लेने के लिए आमंत्रित कर सकता हूं ? :-)
अंतरिक्ष

@ मोहम्मद ओके, मैंने वहां थोड़ा योगदान दिया है :)
Libor

फ़ंक्शन फाई (w) कहाँ जाता है? Fi (w) एक स्थिरांक नहीं है इसलिए जब आप एक गैर स्थिरांक का व्युत्पन्न लेते हैं तो यह शून्य कैसे हो जाता है?
सैमफिशर83

5

Goertzel एल्गोरिथ्म के कई अलग-अलग सूत्रीकरण हैं। वे जो 2 राज्य चर (ऑर्थोगोनल या पास), या एक जटिल राज्य चर प्रदान करते हैं, जैसा कि संभव है कि आउटपुट का उपयोग अक्सर गोएर्टज़ल विंडो में कुछ बिंदु के संदर्भ में चरण की गणना या अनुमान लगाने के लिए किया जा सकता है, जैसे कि मध्य। अकेले एक स्केलर आउटपुट प्रदान करने वाले आमतौर पर नहीं कर सकते हैं।

आपको यह भी जानना होगा कि आपकी गोटेज़ेल विंडो आपके टाइम एक्सिस के संबंध में कहाँ है।

यदि आपका संकेत आपकी गोएर्टज़ेल विंडो में बिल्कुल पूर्णांक आवधिक नहीं है, तो विंडो के बीच में एक संदर्भ बिंदु के चारों ओर का चरण अनुमान अधिक सटीक हो सकता है फिर शुरुआत या अंत में चरण का संदर्भ दे सकता है।

यदि आप अपने सिग्नल की आवृत्ति जानते हैं तो एक पूर्ण FFT ओवरकिल है। साथ ही एफएफ़टी लंबाई में एक गोर्टज़ेल को आवधिक नहीं आवधिक रूप से ट्यून किया जा सकता है, जबकि गैर-आवधिक-इन-विंडो आवृत्तियों के लिए एक एफएफटी को अतिरिक्त प्रक्षेप या शून्य पैडिंग की आवश्यकता होगी।

कॉम्प्लेक्स गोएर्टज़ेल डीएफटी के 1 बिन के बराबर है जो कोसाइन और साइन आधार वैक्टर या एफएफटी ट्वीडल कारकों के लिए पुनरावृत्ति का उपयोग करता है।


ठीक उसी सटीकता की खिड़की के भीतर कहीं भी चरण का अनुमान नहीं लगाया गया है, क्योंकि आप खिड़की भीतर नमूने के स्तर पर चरण के अनुमान की गणना करने के लिए खिड़की के आरंभ में (चरण को जोड़ देंगे। खिड़की की शुरुआत हो रही है)? k k = ωkkk=0
ओली निमितालो

नहीं, क्योंकि विंडो के अंत में एक अलग चरण में wk परिणाम जोड़ने से शुरुआत में एक गैर-पूर्णांक-आवधिक-आवक-एपर्चर साइनसॉइड के लिए होता है। लेकिन 1-बिन डीएफटी उसी बिंदु पर एक एकल परिपत्र चरण की गणना करता है। इस प्रकार 3 मान सभी अलग-अलग होंगे। लेकिन केंद्र का चरण हमेशा विषम / समान कार्य के अनुपात से संबंधित होता है, भले ही f0 कोई भी हो।
hotpaw2

कोशिश कर रहा है, लेकिन मुझे वह नहीं मिला।
ओली निमितालो

एक कोसाइन (शून्य का चरण k = 0 पर) का उपयोग करें, आवृत्ति को थोड़ा मोड़ें (एक छोटे अपरिमेय संख्या के द्वारा, लेकिन k = 0 पर चरण को बदले बिना)। चरण बदल गया है एक DFT रिपोर्ट! वास्तव में k = N / 2 पर केंद्रित एक कोसाइन के साथ ही प्रयास करें। किसी भी df के लिए k = N / 2 पर कोई परिवर्तन नहीं। पाप या किसी मिश्रण के लिए भी। चरण संदर्भ बिंदु को केंद्रित करने से f0 में परिवर्तन के साथ मापा चरण में कम परिवर्तन दिखाई देते हैं। उदाहरण के लिए फ़्रीक्वेंसी त्रुटि चरण माप त्रुटियों को बढ़ाने में योगदान नहीं करती है।
hotpaw2

1
हां, विंडो के केंद्र में चरण अनुमान त्रुटि कम होने से यह समझ में आता है कि क्या साइनसॉइड और गोएर्टज़ेल फ़िल्टर विभिन्न आवृत्तियों पर हैं। उस स्थिति में, खिड़की के अंत में चरण का अनुमान कहता है कि एक निरंतर द्वारा पक्षपाती है जो केंद्र और खिड़की के अंत के बीच की दूरी और साइनसॉइड और गोएर्टज़ेल फिल्टर आवृत्तियों के बीच का अंतर है। इस पूर्वाग्रह को घटाना केंद्र के अनुमान के अनुसार एक ही आकार की त्रुटि देता है, लेकिन इसके लिए साइनसॉइड की आवृत्ति जानने की आवश्यकता होती है।
ओली निमितालो

4

यदि आपके सिग्नल शोर-मुक्त हैं, तो आप दोनों में शून्य क्रॉसिंग की पहचान कर सकते हैं और आवृत्ति और सापेक्ष चरण निर्धारित कर सकते हैं।


3

यह इस बात पर निर्भर करता है कि "तेज़" की आपकी परिभाषा क्या है, आप अपना अनुमान कितना सही चाहते हैं, चाहे आप अपने नमूने के सापेक्ष या चरण चाहते हैं , और आपके फ़ंक्शन और संदर्भ साइन लहर पर कितना शोर है।ϕ

ऐसा करने का एक तरीका सिर्फ का एफएफटी लेना है और सिर्फ बिन टू टू को देखना है । ωf(t)ω हालांकि, इस पर निर्भर करेगा बिन केंद्र आवृत्ति के पास जा रहा है।ω

इसलिए:

  • "उपवास" से आपका क्या तात्पर्य है?
  • अनुमान की कितनी सही जरूरत है?
  • क्या आप नमूने के प्रारंभ के लिए (संदर्भ के सापेक्ष चरण) या चरण चाहते हैं? फर्क पड़ता है क्या?ϕ
  • प्रत्येक सिग्नल पर शोर स्तर क्या है?

पुनश्च: मैं मान रहा हूँ कि आप , के बजाय ।f(t)=Asin(ωt+ϕ)f(t)=Asin(ωx+ϕ)


2

प्रारंभ बिंदु:
1) अपने सिग्नल और संदर्भ पाप तरंग को गुणा करें: = Ainsin (ωt + ⋅) ϕsin (ωt) = 0.5⋅A⋅ (cos (ϕ) - cos (2⋅ω + + ϕ)) ) 2) पीरियड पर इंटीग्रल पाते हैं : 3) आप गणना कर सकते हैं :
F(t)
T=π/ω
I(ϕ)=0TF(t)dt =0.5Acos(ϕ)T
ϕ
cos(ϕ)=I(t)/(0.5AT)

इस बारे में सोचें:
ए को कैसे मापें? में
कैसे निर्धारित करें अंतराल? ("संदर्भ कॉस वेव" के बारे में सोचें )ϕ0..(2π)

असतत संकेत के लिए अभिन्न को योग में बदलें और ध्यान से टी चुनें!


1

आप यह भी कर सकते हैं (संख्यात्मक अंकन में):

np.arctan( (signal*cos).sum() / (signal*sin).sum() ))

जहां सिग्नल आपके चरण-स्थानांतरित सिग्नल है, कॉस और पाप संदर्भ सिग्नल हैं, और आप दो उत्पादों पर योग के माध्यम से एक निश्चित समय पर एक अभिन्न का एक अनुमान उत्पन्न करते हैं।


0

यह एक फ्रेंक्शनल बिन इंडेक्स के साथ एकल आवृत्ति डीएफटी का उपयोग करने के @ केविन मैकगी के सुझाव पर एक सुधार है। केविन के एल्गोरिथ्म में बहुत अच्छे परिणाम नहीं मिलते हैं: जबकि आधे डिब्बे और पूरे डिब्बे में यह बहुत सटीक है, यह भी लगभग पूर्णता और आधा तक है, यह बहुत अच्छा है, लेकिन अन्यथा त्रुटि 5% के भीतर हो सकती है, जो संभवतः अधिकांश कार्यों के लिए स्वीकार्य नहीं है। ।

मैं समायोजन करके केविन एल्गोरिथ्म में सुधार के लिए सुझाव , एफ टी खिड़की की लंबाई यानी ताकि संभव के रूप में एक पूरे के करीब के रूप में हो जाता है। यह FFT के विपरीत काम करता है, DFT को शक्ति 2 होने की आवश्यकता नहीं है ।NkN

नीचे दिया गया कोड स्विफ्ट में है, लेकिन सहज रूप से स्पष्ट होना चाहिए:

let f = 27.0 // frequency of the sinusoid we are going to generate
let S = 200.0 // sampling rate
let Nmax = 512 // max DFT window length
let twopi = 2 * Double.pi

// First, calculate k for Nmax, and then round it
var k = round(f * Double(Nmax) / S)

// The magic part: recalculate N to make k as close to whole as possible
// We also need to recalculate k once again due to rounding of N. This is important.
let N = Int(k * S / f)
k = f * Double(N) / S

// Generate the sinusoid
var r: [Double] = []
for i in 0..<N {
    let t = Double(i) / S
    r.append(sin(twopi * f * t))
}

// Compute single-frequency DFT
var R = 0.0, I = 0.0
let twopikn = twopi * k / Double(N)
for i in 0..<N {
    let x = Double(i) * twopikn
    R += r[i] * cos(x)
    I += r[i] * sin(x)
}
R /= Double(N)
I /= Double(N)

let amp = 2 * sqrt(R * R + I * I)
let phase = atan2(I, R) / twopi

print(String(format: "k = %.2f    R = %.8f    I = %.8f    A = %.8f    φ/2π = %.8f", k, R, I, amp, phase))

एफएफटी कुशलता से डीएफटी की गणना करने का एक तरीका है। आधुनिक पुस्तकालयों के साथ, दो प्रतिबंधों की शक्ति अब नहीं है। यदि आपको केवल एक या दो बिन मूल्यों की आवश्यकता है, तो उन्हें सीधे गणना करना बेहतर है जैसे आपने किया था। एकल शुद्ध टोन (वास्तविक या जटिल) के लिए, आवृत्ति, चरण और आयाम की गणना करने के लिए केवल दो बिन मूल्यों की आवश्यकता होती है। Dsprelated.com/showarticle/1284.php देखें । गणित काफी परिष्कृत है, लेकिन उन लेखों के लिंक हैं जहां व्युत्पत्तियों की व्याख्या की गई है। रैखिक बीजगणित एक सच्ची समझ के लिए एक शर्त है।
सेड्रॉन डॉग
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.