2012-04-04 4 views
5

Ich habe einen Python-Code gemacht, um ein gegebenes Signal mit der Weierstrass-Transformation zu glätten, was im Grunde genommen die Faltung eines normalisierten Gaußschen Signals mit einem Signal ist.Wie entfernen Sie die Grenzeffekte, die durch Nullauffüllen in scipy/numpy fft entstehen?

Der Code ist wie folgt:


#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') 

Wenn ich diesen Code für etwa eine Stufenfunktion ausführen, es die Ecke glättet, aber an der Grenze interpretiert es eine andere Ecke und glättet, dass Dies führt zu unnötigem Verhalten an der Grenze. Ich erkläre dies mit einer Abbildung, die im folgenden Link gezeigt wird.
Boundary effects

Dieses Problem tritt nicht auf, wenn wir direkt integrieren, um Faltung zu finden. Daher liegt das Problem nicht in der Weierstraß-Transformation, und daher liegt das Problem in der fftconvolve-Funktion von scipy.

Um zu verstehen, warum dieses Problem auftritt, müssen wir zuerst die Funktionsweise von fftconvolve in scipy verstehen.
Die fftconvolve-Funktion verwendet im Grunde das Faltungstheorem, um die Berechnung zu beschleunigen.
Kurz gesagt heißt es:
Faltung (INT1, INT2) = IFFT (fft (INT1) * fft (INT2))
Wenn wir diesen Satz direkt wenden wir das gewünschte Ergebnis nicht. Um das gewünschte Ergebnis zu erhalten, müssen wir das fft auf ein Array doppelter Größe von max (int1, int2) nehmen. Dies führt jedoch zu den unerwünschten Grenzeffekten. Dies liegt daran, dass in dem FFT-Code, wenn die Größe (int) größer ist als die Größe (über die fft zu nehmen ist), diese die Eingabe auffüllt und dann das fft übernimmt. Diese Nullfüllung ist genau das, was für die unerwünschten Grenzeffekte verantwortlich ist.

Können Sie einen Weg vorschlagen, diese Grenzeffekte zu entfernen?

Ich habe versucht, es durch einen einfachen Trick zu entfernen. Nach dem Glätten der Funktion vergleiche ich den Wert des geglätteten Signals mit dem ursprünglichen Signal in der Nähe der Grenzen, und wenn sie nicht übereinstimmen, ersetze den Wert der geglätteten Funktion mit dem Eingangssignal an diesem Punkt.
Es ist wie folgt:


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 

Es gibt ein Problem bei dieser Methode ist, wegen eines Epsilon gibt es kleine Sprünge in der geglätteten Funktion, wie unten dargestellt:
jumps in the smooth func

Kann es irgendwelche Änderungen in der obigen Methode geben, um dieses Grenzproblem zu lösen?

+0

Dupe von http://math.stackexchange.com/q/127875/2206 – endolith

Antwort

3

Was ein symmetrischer Filterkern an den Enden erzeugt, hängt davon ab, was Sie davon ausgehen, dass die Daten jenseits der Enden liegen.

Wenn Sie das Aussehen des aktuellen Ergebnisses, das Nullen jenseits beider Enden voraussetzt, nicht mögen, versuchen Sie, die Daten mit einer anderen Annahme zu erweitern, sagen wir eine Reflektion der Daten oder eine polynome Regressionsfortsetzung. Erweitern Sie die Daten an beiden Enden um mindestens die Hälfte der Länge des Filterkerns (es sei denn, Ihre Erweiterung ist Nullen, die kostenlos mit der vorhandenen Zero-Padding für nicht-kreisförmige Faltung verfügbar sind). Entferne dann die zusätzlichen End-Extensions nach dem Filtern und schau, ob dir das Aussehen deiner Annahme gefällt. Wenn nicht, versuchen Sie eine andere Annahme. Oder noch besser, verwenden Sie tatsächliche Daten über die Enden hinaus, wenn Sie solche haben.

+0

Danke, Ihre Antwort eröffnet eine ganze Reihe von Möglichkeiten. – Omkar

6

bester Ansatz ist wahrscheinlich mode = 'valid' zu verwenden:

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

Sofern Sie Ihr Signal wickeln können, oder das Signal verarbeitet wird, ist ein Auszug aus einem größeren Signal (in diesem Fall: Prozess-Voll-Signal Wenn Sie dann die gewünschte Region bearbeiten, werden Sie immer Kanteneffekte haben, wenn Sie Faltung durchführen.Sie müssen wählen, wie Sie mit ihnen umgehen wollen. Verwenden Sie mode = valid nur schneidet sie ab, was eine ziemlich gute Lösung ist. Wenn Sie wissen, dass das Signal immer "step-like" ist, können Sie das vordere und das Ende des bearbeiteten Signals entsprechend erweitern.

+0

Danke Ihre Lösung funktioniert. – Omkar

Verwandte Themen