Tôi đã tạo một mã python để làm mịn một tín hiệu đã cho bằng cách sử dụng phép biến đổi Weierstrass, về cơ bản là sự hòa tan của một gaussian chuẩn hóa với một tín hiệu.Làm thế nào để loại bỏ các hiệu ứng ranh giới phát sinh do không đệm trong fip scipy/numpy?
Mã này là như sau:
#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')
Nếu tôi chạy mã này để nói một chức năng bước, nó làm trơn nhẵn góc, nhưng ở ranh giới nó diễn giải góc khác và làm trơn nhẵn mà quá, kết quả là cho hành vi không cần thiết ở ranh giới. Tôi giải thích điều này với một con số được hiển thị trong liên kết dưới đây.
Boundary effects
Vấn đề này không phát sinh nếu chúng tôi tích hợp trực tiếp để tìm sự liên kết. Do đó vấn đề không có trong biến đổi Weierstrass, và do đó vấn đề nằm trong hàm fftconvolve của scipy.
Để hiểu lý do tại sao vấn đề này phát sinh, trước tiên chúng ta cần phải hiểu được hoạt động của fftconvolve trong scipy.
Hàm fftconvolve về cơ bản sử dụng định lý convolution để tăng tốc độ tính toán.
Nói ngắn gọn:
convolution (int1, int2) = ifft (fft (int1) * fft (int2))
Nếu chúng tôi trực tiếp áp dụng định lý này, chúng tôi không nhận được kết quả mong muốn. Để có được kết quả mong muốn, chúng ta cần lấy fft trên một mảng gấp đôi kích thước của max (int1, int2). Nhưng điều này dẫn đến các hiệu ứng ranh giới không mong muốn. Điều này là bởi vì trong mã fft, nếu kích thước (int) lớn hơn kích thước (trên đó để có fft) nó không đệm đầu vào và sau đó mất fft. Điều này đệm không chính xác là những gì chịu trách nhiệm cho các hiệu ứng ranh giới không mong muốn.
Bạn có thể đề xuất cách xóa hiệu ứng biên này không?
Tôi đã cố gắng xóa nó bằng một mẹo đơn giản. Sau khi làm mịn hàm tôi đang tính giá trị của tín hiệu được làm phẳng với tín hiệu gốc gần ranh giới và nếu chúng không khớp, tôi thay thế giá trị của func được làm phẳng bằng tín hiệu đầu vào tại điểm đó.
Nó được như sau:
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
Có một vấn đề với phương pháp này, vì sử dụng một epsilon có bước nhảy nhỏ trong chức năng làm phẳng, như hình dưới đây:
jumps in the smooth func
Có thể có bất kỳ thay đổi nào được thực hiện trong phương pháp trên để giải quyết vấn đề biên này không?
Ngắt của http://math.stackexchange.com/q/127875/2206 – endolith