Ho creato un codice Python per smussare un determinato segnale usando la trasformata di Weierstrass, che è fondamentalmente la convoluzione di un gaussiano normalizzato con un segnale.
Il codice è il seguente:
#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')
Se eseguo questo codice per dire una funzione di passaggio, smussa l'angolo, ma al confine interpreta un altro angolo e lo uniforma, dando come risultato un comportamento non necessario al confine. Spiego questo con una figura mostrata in questa immagine
Questo problema non si presenta se ci integriamo direttamente per trovare la convoluzione. Quindi il problema non è nella trasformata di Weierstrass, e quindi il problema è nella funzione fftconvolve di scipy.
Per capire perché questo problema si presenta, dobbiamo prima capire il funzionamento di fftconvolve in scipy.
La funzione fftconvolve utilizza fondamentalmente il teorema della convoluzione per accelerare il calcolo.
In breve dice:
convolution(int1,int2)=ifft(fft(int1)*fft(int2))
Se applichiamo direttamente questo teorema non otteniamo il risultato desiderato. Per ottenere il risultato desiderato, dobbiamo prendere il fft su un array che raddoppia la dimensione di max (int1, int2). Ma questo porta agli effetti di confine indesiderati. Questo perché nel codice fft, se size (int) è maggiore della dimensione (oltre la quale prendere fft), esso azzera l'input e quindi prende il fft. Questo padding zero è esattamente ciò che è responsabile degli effetti di confine indesiderati.
Puoi suggerire un modo per rimuovere questi effetti di contorno?
Ho provato a rimuoverlo con un semplice trucco. Dopo aver levigato la funzione, ho confrontato il valore del segnale levigato con il segnale originale vicino ai limiti e se non corrispondono, sostituisco il valore della funzione levigata con il segnale di ingresso in quel punto.
È come segue:
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'è un problema con questo metodo, a causa dell'uso di un epsilon ci sono piccoli salti in la funzione smussata .
Potrebbero esserci delle modifiche nel metodo sopra riportato per risolvere questo problema di limite?