【问题标题】:What is different between the implementation of deconvolution with fft and the deconv function in MATLAB?用fft实现反卷积和MATLAB中的deconv函数有什么区别?
【发布时间】:2017-03-22 21:12:07
【问题描述】:

我陷入了这段代码中:

function [ y ] = mydeconv( c,x )
    lx=length(x);
    lc=length(c);
    %lt=lx+lc;
    c=[c zeros(1,lx)];
    x=[x zeros(1,lc)];
    y = ifft(real((fft(c)) ./(fft(x))));
end

结果是:

mydeconv([1 2 3 3 2 1],[1 1 1])
ans =
Column 1
            NaN + 0.000000000000000i
Column 2
            NaN +               NaNi
Column 3
            NaN +               NaNi
Column 4
            NaN + 0.000000000000000i
Column 5
            NaN +               NaNi
Column 6
            NaN +               NaNi
Column 7
            NaN + 0.000000000000000i
Column 8
            NaN +               NaNi
Column 9
            NaN +               NaNi

deconv 函数的结果就是:

deconv([1 2 3 3 2 1],[1 1 1])
ans =
 1     1     1     1

原则上它应该可以工作,我不明白它有什么问题。

【问题讨论】:

  • 你为什么在 FFT 之一之后取 real 值?
  • 实际上,起初我没有,但我读了一些地方,这将纠正答案,但不是,它没有给出正确的答案。

标签: matlab signal-processing


【解决方案1】:

你的代码有两个问题:

首先,您应该采用real IFFT 输出的一部分,而不是单个FFT。

其次,您应该防止出现零除零的情况,这会在您的示例中导致 NaN

你可以实现以上两个,通过修改行计算y如下:

y = real(ifft((eps+fft(c)) ./ (eps+fft(x))));

请注意,eps 是一个小的正数,以防止出现零除零的情况。有了这个,输出是:

disp(y)
% 1.0000    1.0000    1.0000    1.0000    0.0000   -0.0000    0.0000    0.0000    0.0000

【讨论】:

  • 非常感谢,你说的太精辟了。
  • 再问一个问题,如何去除小数点后多余的零?
  • 如果您确定c = conv(x, y),那么您可以简单地选择y 的第一个length(c) - length(x) + 1 元素。在一般情况下,您可以选择包含序列总能量 99% 以上的前几个元素。
  • 请注意,如果任何 FFT 值等于 -eps,您将很快遇到同样的除零问题。
  • @SleuthEye:很公平。如果这是一个问题,可以稍微修改计算以防止所有被零除:y = real(ifft((fft(c).*conj(fft(x))+eps) ./ (eps+abs(fft(x)).^2)));.
【解决方案2】:

由于填充向量x 的长度是原始向量的倍数,因此您最终会在fft(x) 的频域中得到零。当观察到此类零时,您可以通过选择不同(更长)的长度来避免这种情况:

function [ y ] = mydeconv( c,x )
  lx=length(x);
  lc=length(c);
  if (lc >= lx)
    lt = lc;
    while (1)
      xpadded = [x zeros(1,lt-length(x))];
      Xf = fft(xpadded);
      if (min(abs(Xf)) > 0)
        break;
      end
      lt = lt + 1;
    end
    cpadded = [c zeros(1,lt-length(c))];
    Cf = fft(cpadded);
    y = real(ifft(Cf ./ Xf));
    y = y(1:lc-lx+1);
  else
    y = [];
  end
end

【讨论】:

  • 如何知道这两个向量是否有反卷积?
  • 如果c 的长度至少是x 的长度,并且xc 在任何地方都不严格为0,则有一个y 由卷积定理将是conv(x,y) = c,而c = ifft(fft(xpadded) .* fft(ypadded))。那么它只是一个简单的基本代数得到相反的ypadded = ifft(fft(c) ./ fft(xpadded))同样存在。
猜你喜欢
  • 2016-08-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-08-25
  • 1970-01-01
  • 2012-12-10
  • 1970-01-01
  • 2013-10-09
相关资源
最近更新 更多