正弦波频率拟合

时间:2010-01-21 20:46:58

标签: math matlab fft octave data-fitting

此问题基于previous similar question.

我有以下等式和经过调整的(一些随机数据):0.44 * sin(N * 2 * PI / 30)

我正在尝试使用FFT从生成的数据中获取频率。然而,频率最终接近但不等于频率(这使得波比预期的要大一些)

FFT的最大频率为7hz,但预期频率为(30 / 2PI)4.77hz。

我已经包含了FFT和绘图值的图表。

alt text

我使用的代码是:

[sampleFFTValues sFreq] = positiveFFT(sampledata, 1);
sampleFFTValues = abs(sampleFFTValues);
[v sFFTV]= max(sampleFFTValues)

正FFT可以是found here。基本上它将FFT图中心并切断负信号。

我的问题是如何才能让FFT更准确,而不必仅针对频率采用最小二乘法?

7 个答案:

答案 0 :(得分:5)

正如其他人所说,你错误地解释了信号的频率。让我举一个例子来澄清一些事情:

Fs = 200;                        %# sampling rate
t = 0:1/Fs:1-1/Fs;               %# time vector of 1 second 
f = 6;                           %# frequency of signal
x = 0.44*sin(2*pi*f*t);          %# sine wave

N = length(x);                   %# length of signal
nfft = N;                        %# n-point DFT, by default nfft=length(x)
                                 %# (Note: it is faster if nfft is a power of 2)
X = abs(fft(x,nfft)).^2 / nfft;  %# square of the magnitude of FFT

cutOff = ceil((nfft+1)/2);       %# nyquist frequency
X = X(1:cutOff);                 %# FFT is symmetric, take first half
X(2:end -1) = 2 * X(2:end -1);   %# compensate for the energy of the other half
fr = (0:cutOff-1)*Fs/nfft;       %# frequency vector

subplot(211), plot(t, x)
title('Signal (Time Domain)')
xlabel('Time (sec)'), ylabel('Amplitude')

subplot(212), stem(fr, X)
title('Power Spectrum (Frequency Domain)')
xlabel('Frequency (Hz)'), ylabel('Power')

time_frequency_domain

现在您可以看到FFT中的峰值对应于6Hz信号的原始频率

[v idx] = max(X);
fr(idx)
ans = 
      6

我们甚至可以检查Parseval's theorem是否成立:

( sum(x.^2) - sum(X) )/nfft < 1e-6

选项2

或者,我们可以使用信号处理工具箱功能:

%# estimate the power spectral density (PSD) using the periodogram
h = spectrum.periodogram;
hopts = psdopts(h);
set(hopts, 'Fs',Fs, 'NFFT',nfft, 'SpectrumType','onesided')

hpsd = psd(h, x, hopts);
figure, plot(hpsd)

Pxx = hpsd.Data;
fr = hpsd.Frequencies;
[v idx]= max(Pxx)
fr(idx)

avgpower(hpsd)

periodogram

请注意,此函数使用对数刻度:plot(fr,10*log10(Pxx))而不是plot(fr,Pxx)

答案 1 :(得分:4)

我认为FFT不适用于(准)周期信号的精细分辨率频率测量 - 见下文。

每个离散FFT都在非整数bin频率上进行扩频(即在与特定FFT的一个频率步长不完全对应的任何频率上);这些“中间”频率将被涂抹/展开在最近的整数箱周围。这种扩展的形状(“扩展函数”)取决于用于FFT的窗口函数。这种扩散功能 - 简化和概括事物 - 要么非常狭窄,要么非常非常粗糙(非常高的峰值/非常低的谷值),或者更宽但是更不规则。从理论上讲,你可以对正弦波进行非常精细的频率扫描并为每个正弦波计算FFT,然后你可以通过保存所有FFT的输出和导致输出的频率来“校准”函数的形状和行为,然后通过将待测信号的FFT输出与先前保存的结果进行比较,找到“最接近”的结果,找到更精确的频率。

很多努力。

但如果您只需要测量单个信号的频率,请不要这样做。

而是尝试测量波长。这可以像测量零交叉之间的距离一样简单(可能是多个周期以获得更高的精度 - 如果你有那么多,则测量1000个周期),并将采样率除以该值来得到频率。更简单,更快速,更精确。

示例:48000 Hz采样率,4.77 Hz信号通过最粗略的方法测量一个周期的长度,得到~0.0005 Hz分辨率。 (如果你采用 n 周期,频率分辨率也会乘以 n 。)

答案 2 :(得分:1)

假设N是以秒为单位的时间,您的频率为1 / 30Hz(y=A * sin( 2* PI * f * t)

频率分辨率=采样率/ FFT点

采样率由奈奎斯特标准确定,采样率(样本/秒)必须至少是要分析的最大频率的两倍,例如, 48kHz用于分析高达24kHz。 (对于“现实生活”数据,最好有一点缓冲区。)

因此,您可能需要增加FFT的大小。

答案 3 :(得分:1)

您正在寻找的是频率估算方法,有很多种方法。 FFT是几种估计方法的一个组成部分。如您的示例所示,仅使用峰值幅度区为您提供最差的分辨率(但对任何其他精确周期性正弦曲线的最大噪声抗扰度)。在低噪音情况下,您可以进行插值。对数幅度的抛物线插值是一种常见的估计器,但FFT结果的同步插值对于矩形窗口可能更好。零填充和执行更长的FFT基本上等同于插值。

对于零噪声中的精确正弦曲线,忘记FFT,只需求解3个未知数的等式,这可能只需要3个或4个非混叠采样点,算法可以做here和{ {3}}

我在here上列出了一些其他频率估算方法。

答案 4 :(得分:0)

如果您正在使用函数生成,而不是使用样本,则可以生成大量点并运行BIG fft,因此频率块非常小,可实现高精度。但它无法解决基本问题。

答案 5 :(得分:0)

首先,对您的问题进行更正:(30 / 2PI)不是频率。无论您使用何种采样率,信号频率均为1/30 *。 其次,你能告诉我采样数据的长度是多少吗?当FFT返回值向量时,第i个值将对应于f_i = i / N,其中N是向量的长度,而i是in [0,N-1] 对于某个整数i,您希望i / N完全等于1/30。换句话说,N应该等于30 * i,即N应该是30的倍数。现在,你使用的矢量长度是30的倍数吗?如果没有尝试制作它,应该解决这个问题。

答案 6 :(得分:-1)