ワイエルシュトラス変換を使用して特定の信号を平滑化するための Python コードを作成しました。これは基本的に正規化されたガウスと信号の畳み込みです。
コードは次のとおりです。
#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')
このコードをたとえばステップ関数に対して実行すると、角が滑らかになりますが、境界では別の角が解釈されてそれも滑らかになり、結果として境界で不要な動作が発生します。以下のリンクに示されている図でこれを説明します。
境界効果
畳み込みを見つけるために直接積分する場合、この問題は発生しません。したがって、問題は Weierstrass 変換にはないため、問題は scipy の fftconvolve 関数にあります。
この問題が発生する理由を理解するには、まず scipy での fftconvolve の動作を理解する必要があります。
fftconvolve 関数は、基本的に畳み込み定理を使用して計算を高速化します。
convolution( int1
,int2)=ifft(fft(int1)*fft(int2))
この定理を直接適用すると、望ましい結果が得られません。目的の結果を得るには、配列の fft を max(int1,int2) の 2 倍のサイズにする必要があります。しかし、これは望ましくない境界効果につながります。これは、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
イプシロンを使用するため、以下に示すように、平滑化された関数に小さなジャンプがあるため、この方法には問題があります
。
この境界の問題を解決するために、上記の方法に変更を加えることはできますか?