我目前正在研究以下一本书:Vidi Saptari撰写的“傅立叶变换光谱仪器工程”。我的问题与下面的代码相关,基于书中的代码,附录C.下面的代码分别计算波数为[cm-1] 5000,10000和15000的3波的干涉图,并执行FFT到检索信息。未缩放的输出的幅度为1600,而不是1。
clear;
% Sampling clock signal generation
samp_period_nm = 632.8 / 4; % sampling period in nm. 632.8 is the HeNe laser's wavelength
samp_period = 1 * samp_period_nm * 10^-7; % sampling period in cm.
scan_dist = 0.1; % mirror scan distance in cm.
no_elements = floor(scan_dist/samp_period);
x_samp = 0:samp_period:samp_period*no_elements; %Vector of clock signals in cm
xn_samp = x_samp .* (1 + rand(1, length(x_samp)));
v1 = 5000;
v2 = 10000;
v3 = 15000;
arg = 4 * pi * x_samp;
y = cos(arg*v1) + cos(arg*v2) + cos(arg*v3) ;
total_data = 2^18;
no_zero_fills=[total_data - length(y)];
zero_fills=zeros(1, no_zero_fills);
%triangular apodization
n_y = length(y);
points = 1:1:n_y;
tri = 1 - 1/(n_y) * points(1:n_y);
y = y.*tri; %dot product of interferogram with triangular apodization function
y = [y zero_fills]; %zero filling
% FFT operation
fft_y = fft(y);
% fft_y = fft_y / n_y;
% fft_y = fft_y * samp_period;
fft_y(1) = [];
n_fft=length(fft_y);
spec_y = abs(fft_y(1:n_fft/2)); %spectrum generation
nyquist = 1 / (samp_period * 4);
freq = (1:n_fft/2)/(n_fft/2)*nyquist; %frequency scale generation
figure();
plot(freq, spec_y); % plot of spectrum vs wave number
xlabel('Wavenumber [cm-1]');
ylabel('Intesity [V]');
通过将fft(fft_y)的结果与dt = samp_period相乘,如建议的here,峰值为0.025。
遵循the same link's秒解,通过将fft_y除以n_y(y的长度),幅度为0.25。
显然,我做错了什么。任何帮助表示赞赏。谢谢,
答案 0 :(得分:1)
这里你唯一错的就是期望频谱中的峰值为1.根据Parseval的DFT定理,时域信号的能量等于频域信号的能量除以长度序列N.你可以在你的例子中检查:
td_energy = sum( abs(y).^2 )
fd_energy = sum( abs(fft_y).^2 )
td_energy - fd_energy / length(y) % won't be exactly zero because you deleted the zero frequency bin.
因此,频谱中的峰值不代表时域中余弦波的幅度,而是能量。此时请注意,当您填充大量零时,能量低于您的预期。
在实践中,某个频率的平均功率通常更受关注。请考虑以下代码示例
t = linspace(-4*pi, 4*pi, 2^16);
N = length(t); % DFT length
y = cos(t); % single cosine wave
y_pow = sum( abs(y).^2 ) / N; % is 0.5
fft_y = fft(y);
fft_y_pow = (sum( abs(fft_y).^2 ) / N) /N; % is 0.5
figure; plot(abs(fft_y)./N);
通过将能量乘以序列N的长度来获得功率。如果将频谱除以N,则获得每个频率的平均功率。在上面的例子中,您可以识别出一个高度为0.5的峰值,它表示幅度1的单个cos波(因此功率为0.5)。
就个人而言,我更喜欢按1/sqrt(N)
缩放MATLAB的FFT输出,并按sqrt(N)
缩放其IFFT输出。这样,时域和频域序列的能量总是相等的。
答案 1 :(得分:0)
如果你想在IFFT输入和输出中获得相同的能量,你必须乘以 IFFT输出(时间信号)乘以sqrt(N),其中N是变换的大小。
这是代码:
与FFT相同的事情(将输出除以sqrt(N)); 希望能帮助到你 菲利克斯N = 4096;
Freq = randn(N,1)+1j*randn(N,1);
Time = sqrt(N)*ifft(Freq,N);
FreqEn = sum(real(Freq).^2 + imag(Freq).^2);
TimeEn = sum(real(Time).^2 + imag(Time).^2);
TimeEn /频率