2012-04-04 101 views
5

我已經作出了Python代碼以平滑使用爾斯特拉斯變換給定的信號,它基本上是與信號的歸一化高斯的卷積。如何消除由scipy/numpy fft中的零填充引起的邊界效應?

的代碼如下:


#Importing relevant libraries 
from __future__ import division 
from scipy.signal import fftconvolve 
import numpy as np 

def smooth_func(sig, x, t= 0.002): 
    N = len(x) 
    x1 = x[-1] 
    x0 = x[0]  


# defining a new array y which is symmetric around zero, to make the gaussian symmetric. 
    y = np.linspace(-(x1-x0)/2, (x1-x0)/2, N) 
    #gaussian centered around zero. 
    gaus = np.exp(-y**(2)/t)  

#using fftconvolve to speed up the convolution; gaus.sum() is the normalization constant. 
    return fftconvolve(sig, gaus/gaus.sum(), mode='same') 

如果我在說一個階躍函數的代碼,它平滑的角落,但在邊界它解釋另一個角落和平滑那因此,在邊界給予不必要的行爲。我用下面的鏈接中顯示的圖解釋了這一點。
Boundary effects

如果我們直接整合來找到卷積,這個問題就不會出現。因此問題不在於Weierstrass變換,因此問題在於scipy的fftconvolve函數。

要理解爲什麼這個問題出現,我們首先需要了解fftconvolve的工作中SciPy的。
fftconvolve函數基本上使用卷積定理來加速計算。
簡而言之:
卷積(int1,int2)= ifft(fft(int1)* fft(int2))
如果我們直接應用這個定理,我們不會得到所需的結果。爲了得到想要的結果,我們需要將數組的fft放在max(int1,int2)大小的兩倍的數組上。但是這會導致不希望的邊界效應。這是因爲在fft代碼中,如果size(int)大於fft的大小,它會填充輸入,然後採用fft。這個零填充正是造成不希望的邊界效應的原因。

您能否提供一個方法來消除這種邊界效應?

我試圖通過一個簡單的技巧將其刪除。在平滑函數之後,我將平滑信號的值與邊界附近的原始信號進行比較,如果它們不匹配,則將該平滑函數的值替換爲該點處的輸入信號。
據如下:


i = 0 
eps=1e-3 
while abs(smooth[i]-sig[i])> eps: #compairing the signals on the left boundary 
    smooth[i] = sig[i] 
    i = i + 1 
j = -1 

while abs(smooth[j]-sig[j])> eps: # compairing on the right boundary. 
    smooth[j] = sig[j] 
    j = j - 1 

沒有此方法的一個問題,因爲使用中有平滑函數小的跳躍的ε的,如下所示:
jumps in the smooth func

上述方法能否解決這個邊界問題有什麼變化?

+0

Dupe of http://math.stackexchange.com/q/127875/2206 – endolith 2013-08-13 18:23:12

回答

3

對稱濾波器內核在兩端產生的內容取決於您假定數據超出了終點。

如果您不喜歡當前結果的外觀(它假設兩端都是零),請嘗試用另一個假設(例如數據反射或多項式迴歸連續)來擴展數據。將兩端的數據擴展至少一半濾波器內核的長度(除非擴展名爲零,而非循環卷積所需的現有零填充則可以免費使用)。然後在過濾後刪除添加的結束擴展,並查看您是否喜歡假設的外觀。如果不是,請嘗試另一個假設。或者更好的是,如果你有這樣的結果,可以使用超出結尾的實際數據

+0

謝謝,您的回覆打開了一系列的可能性。 – Omkar 2012-04-06 03:42:11

6

最好的辦法可能是使用mode = 'valid'

The output consists only of those elements that do not rely on the zero-padding.

除非你可以用你的信號,或正在處理的信號從一個更大的信號的摘錄(在這種情況下:過程全信號那麼感興趣的作物區域)在進行卷積時總是會產生邊緣效應。你必須選擇你想如何處理它們。使用mode = valid只是把它們摘下來,這是一個很好的解決方案。如果您知道信號總是「階梯狀」,則可以根據需要擴展處理信號的前端和末端。

+0

感謝您的解決方案。 – Omkar 2012-04-06 03:37:08