2012-04-04 13 views
5

Ho creato un codice Python per smussare un determinato segnale usando la trasformata di Weierstrass, che è sostanzialmente la convoluzione di un gaussiano normalizzato con un segnale.Come rimuovere gli effetti di confine derivanti da padding zero in fy scipy/numpy?

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 corro questo codice per dire una funzione passo, leviga l'angolo, ma al confine interpreta un altro angolo e leviga che anche, come risultato, dare un comportamento inutile al confine. Spiego questo con una figura mostrata nel link sottostante.
Boundary effects

Questo problema non si verifica 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 si dice:
convoluzione (INT1, INT2) = IFFT (FFT (INT1) * FFT (INT2))
Se applichiamo direttamente questo teorema noi non ottiene 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 limite?

Ho provato a rimuoverlo con un semplice trucco. Dopo aver levigato la funzione, sto confrontando 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'utilizzo di un epsilon ci sono piccoli salti nella funzione lisciato, come illustrato di seguito:
jumps in the smooth func

È possibile apportare modifiche al metodo sopra descritto per risolvere questo problema di limite?

+0

Duple di http://math.stackexchange.com/q/127875/2206 – endolith

risposta

3

Ciò che un kernel di filtro simmetrico produce alle estremità dipende da cosa si assume che i dati siano oltre la fine.

Se non ti piace l'aspetto del risultato corrente, che presuppone zeri oltre le due estremità, prova ad estendere i dati con un'altra ipotesi, ad esempio un riflesso dei dati o la continuazione della regressione polinomiale. Estendi i dati su entrambe le estremità di almeno la metà della lunghezza del kernel del filtro (eccetto se la tua estensione è zero, che viene gratuitamente con lo zero pad esistente esistente per la convoluzione non circolare). Quindi rimuovi le estensioni aggiunte dopo il filtro e verifica se ti piace l'aspetto della tua ipotesi. Altrimenti, prova un'altra ipotesi. O meglio ancora, usa i dati reali oltre le estremità se ne hai.

+0

Grazie, la tua risposta ti offre tutta una serie di possibilità. – Omkar

6

migliore approccio è probabilmente quello di utilizzare mode = 'valid':

The output consists only of those elements that do not rely on the zero-padding.

A meno che non si può avvolgere il segnale, o il segnale in fase di elaborazione è un estratto da un segnale più grande (in questo caso: processo segnale completo quindi ritagliare la regione di interesse) si avranno sempre effetti di margine durante la convoluzione.Devi scegliere come vuoi affrontarli. L'utilizzo di mode = valid li ritaglia semplicemente, che è una soluzione piuttosto buona. Se si sa che il segnale è sempre "graduale", si potrebbe quindi estendere la parte anteriore e la fine del segnale elaborato come appropriato.

+0

Grazie per aver risolto la vostra soluzione. – Omkar