He creado un código python para suavizar una señal dada usando la transformada Weierstrass, que es básicamente la convolución de un gaussiano normalizado con una señal.¿Cómo eliminar los efectos límite que surgen debido al relleno cero en fft scipy/numpy?
El código es el siguiente:
#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')
Si ejecuta este código para decir una función escalonada, se alisa la esquina, pero en el límite interpreta otra esquina y suaviza que también, como resultado, dando un comportamiento innecesario en el límite. Explico esto con una figura que se muestra en el siguiente enlace.
Boundary effects
Este problema no aparece si lo integramos directamente para encontrar la convolución. Por lo tanto, el problema no está en la transformación de Weierstrass, y de ahí que el problema esté en la función fftconvolucionar de scipy.
Para entender por qué surge este problema, primero debemos entender el funcionamiento de fftconvolve in scipy.
La función fftconvolve básicamente utiliza el teorema de convolución para acelerar el cálculo.
En resumen dice:
convolución (INT1, INT2) = IFFT (FFT (INT1) * FFT (INT2))
Si aplicamos directamente este teorema que no te dan el resultado deseado. Para obtener el resultado deseado, necesitamos tomar fft en una matriz del doble del tamaño de max (int1, int2). Pero esto conduce a los efectos de frontera no deseados. Esto se debe a que en el código fft, si el tamaño (int) es mayor que el tamaño (sobre el cual tomar fft) cero rellena la entrada y luego toma el fft. Este relleno cero es exactamente lo que es responsable de los efectos de frontera no deseados.
¿Puede sugerir una forma de eliminar estos efectos límite?
He intentado eliminarlo por un simple truco. Después de suavizar la función, estoy comparando el valor de la señal suavizada con la señal original cerca de los límites y, si no coinciden, reemplace el valor del func suavizado con la señal de entrada en ese punto.
Es como sigue:
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
Hay un problema con este método, debido al uso de un epsilon hay pequeños saltos en la función smoothened, como se muestra a continuación:
jumps in the smooth func
¿Se pueden realizar cambios en el método anterior para resolver este problema de límite?
Dupe of http://math.stackexchange.com/q/127875/2206 – endolith