2012-04-04 1 views
5

나는 Weierstrass 변환을 사용하여 주어진 신호를 부드럽게하기 위해 파이썬 코드를 만들었는데, 이것은 기본적으로 신호로 정규화 된 가우스의 컨볼 루션 (convolution)이다. 다음과 같이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 함수에 있습니다.

이 문제가 발생하는 이유를 이해하려면 먼저 scipy에서 fftconvolve의 작동을 이해해야합니다.
fftconvolve 함수는 기본적으로 convolution 정리를 사용하여 계산 속도를 높입니다. 한마디로
는 말한다 : 우리가 직접 정리를 적용하면
회선 (INT1, INT2) = IFFT (FFT (INT1) * FFT (INT2))
우리가 원하는 결과를 얻을니까. 원하는 결과를 얻으려면 max (int1, int2) 크기의 두 배 배열에서 fft를 취해야합니다. 그러나 이로 인해 원하지 않는 경계 효과가 발생합니다. 이것은 fft 코드에서 size (int)가 size (fft를 취할 수있는 크기)보다 크면 입력을 0으로 채운 다음 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

다우의 http://math.stackexchange.com/q/127875/2206 – endolith

답변

3

대칭 필터 커널이 끝에서 생성하는 것은 데이터가 끝을 벗어난다고 가정합니다.

양 끝 너머로 0으로 가정 한 현재 결과 모양이 마음에 들지 않으면 다른 가정, 예를 들어 데이터 반영 또는 다항 회귀 연속으로 데이터를 확장 해보십시오. 확장자가 0 인 경우를 제외하고는 필터 커널의 길이의 절반 이상으로 데이터를 확장합니다.이 경우 확장자가 0이 아닌 경우 비 원형 회선에 필요한 0 패딩이 필요합니다. 그런 다음 필터링 후 추가 된 최종 확장을 제거하고 가정의 모양이 마음에 드는지보십시오. 그렇지 않다면 다른 가정을 시도하십시오. 또는 더 나은 아직 실제 데이터를 사용하면 끝을 넘어 있다면.

+0

감사합니다. 귀하의 회신은 모든 가능성을 열어줍니다. – Omkar

6

가장 좋은 방법은 mode = 'valid' 사용하는 것이 아마도 : 공정 전체 신호 : 당신이 당신의 신호를 래핑 할 수없는 한

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

을, 또는 처리되는 신호는 (더 큰 신호로부터 발췌 한 것입니다 경우에 관심 영역을 자르기) 컨볼 루션을 할 때 항상 가장자리 효과를 갖게됩니다.어떻게 대처할 것인지 선택해야합니다. mode = valid을 사용하면 그것들을 잘라내는데 아주 좋은 해결책입니다. 신호가 항상 '계단 모양'이라는 것을 알고 있으면 적절하게 처리 된 신호의 전면과 끝을 확장 할 수 있습니다.

+0

해결책 감사합니다. – Omkar

관련 문제