在fft中实现deconvolution和在MATLAB中使用deconv函数有什么不同?

时间:2017-03-13 18:46:59

标签: matlab signal-processing

我已经陷入了这段代码:

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

原则上它应该有用,我无法理解它有什么问题。

2 个答案:

答案 0 :(得分: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

答案 1 :(得分:2)

您的代码中存在两个问题:

首先,您应该采用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