1

祝大家有美好的一天!

我试图解决通过观察其卷积与一些已知的脉冲响应来获得原始信号的基本问题。

但是我得到的结果在某种程度上是完全错误的,可能我在这里混合了不同的错误步骤。我已经在这里和developpez等其他网站上查看了类似的主题,但未能找出原因。我将不胜感激任何帮助。

假设我的真实信号f [.] 只是时间 1 的脉冲,而脉冲响应g [.] 是高斯的。我通过 计算它们的卷积h [.] conv(),然后,基本上,想要找到ifft( fft[h]./fft[g] ),期望这是f [.]。

第一个问题是conv()创建一个包含n+m-1 个元素的数组,其中n,m是参数数组的长度。所以,要执行,fft[h]./fft[g]我需要用 g 的长度来做。这是我可能会做错的第一个可疑地方(请参阅代码)。正确的方法是什么?

第二个问题是我得到的东西与最初的真实信号非常不同。

第三个问题是我无法理解如何处理信号偏移。在 matlab 中,我必须使用正时间信号进行操作,但是,例如,高斯脉冲响应具有时间负和正时间元素,因此,要在这里使用它,我需要将它“向前”移动(窥视将向右移动),而不是我需要“取消移动”结果?

谢谢!

这是我的废话:)

close all;

TrueSignal = zeros( 101, 1 ); % impulse in t = 1.
TrueSignal( 1 ) = 1;
ImpulseResp = normpdf(-1:0.02:1)/normpdf( 0 ); % 101 elements array

figure;
subplot( 2,2,1 );
title('True signal')
plot( TrueSignal );
subplot( 2,2,2 );
title('Impulse response')
plot( ImpulseResp );

Conv = conv( TrueSignal, ImpulseResp ); % produces 201 elements array.
subplot( 2,2,3 );
title('Convolution')
plot( Conv );

% Wrong? I need a 201 elements array to represent the impulse response.
ImpulseResp_sparse = normpdf( -1:0.01:1 )/normpdf( 0 );
FIR = fft( ImpulseResp_sparse )/201;

Inverse = ifft( fft( Conv )./FIR ); % UPD Added fft() according to one of comments, bad mistake, but still not preventing.

subplot( 2,2,4 );
title('What is that???')
plot( abs( Inverse ) ); % It's weird! With no abs(), result is even more weird! 
4

2 回答 2

2

直接使用fftfor 卷积将导致循环卷积,而您想要(以及做什么conv)是线性卷积。因此,要实现这样的方案fft,您必须将信号零填充到长度m+n-1

这是一个示例,显示convfft基于线性卷积的输出之间的等价性:

x=rand(4,1);y=rand(3,1); %sample data
out1=conv(x,y);          %output from conv()
X=fft(x,6);Y=fft(y,6);   %zero pad and compute fft
out2=ifft(X.*Y);         %output from fft based lin. conv.

您可以检查它们是否相同(在 FP 精度范围内)out1out2

以这种方式重新表述你的问题,你应该很高兴。我不知道你在问什么 re: shifts,但你可能想看看fftshiftand ifftshift

于 2013-03-11T23:04:04.967 回答
2
  1. 您可能希望使用filter(g, 1, f)而不是conv(g, f)避免结果长度的问题。或剪切生成的数组。
  2. 看起来你忘了做一个 fft:Inverse = ifft( fft(Conv)./FIR );

这对我有用:

   close all;

   TrueSignal = zeros( 101, 1 ); % impulse in t = 1.
   TrueSignal( 1 ) = 1;
   ImpulseResp = normpdf(-1:0.02:1)/normpdf( 0 ); % 101 elements array

   figure;
   subplot( 2,2,1 );
   title('True signal')
   plot( TrueSignal );
   subplot( 2,2,2 );
   title('Impulse response')
   plot( ImpulseResp );

   Conv = filter( TrueSignal, 1, ImpulseResp ); 
   subplot( 2,2,3 );
   title('Convolution')
   plot( Conv );

   fftConv = fft(Conv);

   FIR = fft( ImpulseResp );

   Inverse = ifft( fftConv./FIR );

   subplot( 2,2,4 );
   plot( abs( Inverse ) );
  1. 如前所述,FFT 假设信号是周期性的。如果要分析非周期信号,则需要使用“加窗 FFT”算法来提高质量。它几乎是一样的,但是你要把你的输入乘以一个特殊的窗口函数(例如Blackman)。添加填充也有效,但它是计算量最大的方式。
于 2013-03-11T22:49:00.100 回答