Я написал код на 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')
Если я запускаю этот код, скажем, для ступенчатой функции, он сглаживает угол, но на границе он интерпретирует другой угол и также сглаживает его, что приводит к ненужному поведению на границе. . Я объясняю это с помощью рисунка, показанного в ссылке ниже.
Граничные эффекты
Эта проблема не возникает, если мы напрямую интегрируем для нахождения свертки. Следовательно, проблема не в преобразовании Вейерштрасса, а, следовательно, проблема в функции fftconvolve scipy.
Чтобы понять, почему возникает эта проблема, нам сначала нужно понять, как работает fftconvolve в scipy.
Функция fftconvolve в основном использует теорему свертки для ускорения вычислений.
Короче говоря:
свертка (int1, int2) =ifft(fft(int1)*fft(int2))
Если мы применим эту теорему напрямую, мы не получим желаемого результата. Чтобы получить желаемый результат, нам нужно взять БПФ для массива, удвоенного размера max(int1,int2). Но это приводит к нежелательным граничным эффектам.Это связано с тем, что в коде fft, если размер (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
Проблема с этим методом, из-за использования эпсилона в сглаженной функции есть небольшие скачки, как показано ниже:
скачки в гладкой функции
Могут ли быть какие-либо изменения сделано в вышеуказанном методе для решения этой краевой задачи?