2017-03-13 48 views
1

我被困在此代碼:用fft實現去卷積和MATLAB中的去卷積函數有什麼不同?

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 

原則上應工作,我不明白它有什麼問題。

+0

你爲什麼要在一個FFT之後得到'真實'值? – mpaskov

+0

實際上,起初我沒有,但我讀了一些在那裏,這將糾正答案,但不ddin't,它沒有給出正確的答案,但沒有真正的,但。 – MAh2014

回答

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 
+0

是的,那是我一直在尋找的。謝謝。 – MAh2014

+0

我怎麼知道這兩個矢量是否有解卷積? – MAh2014

+0

假設'c'的長度至少是'x'的長度,並且'x'或'c'在任何地方都不是嚴格的0,那麼就有一個'y',通過卷積定理可以得到'conv x,y)= c',而'c = ifft(fft(xpadded)。* fft(ypadded))''。然後,它只是一個基本的代數,以得到相反的'ypadded = ifft(fft(c)./fft(xpadded))'同樣存在。 – SleuthEye

2

有兩個問題在您的代碼:您可以通過選擇當觀察到這種零的不同(長)長度避免這種

首先,你應該採取的IFFT輸出的real一部分,而不是個別的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 
+0

非常感謝,那真是太好了。 – MAh2014

+0

只有一個問題,我怎樣才能刪除小數點後的多餘的零? – MAh2014

+0

如果你確定知道'c = conv(x,y)',那麼你可以簡單地選擇'y'的第一個'length(c) - length(x)+ 1'元素。在一般情況下,您可以選擇包含序列總能量99%以上的前幾個元素。 – aksadv