Verfasst am: 27.06.2011, 11:30
Titel: Gleitender Mittelwert mit aktuellem Messwert als Initialisie
Hallo,
auf von mir aufgenommene Messdaten möchte ich eine gleitende Mittelwertbildung anwenden.
Nach der Suche im Forum bin ich vermehrt auf den filter-Befehl von Matlab gestoßen.
Mit meinem mathematischen Hintergrund durchschaue ich leider nicht wirklich die in der Hilfe von filter angegebene
Übertragungsfunktion und das Verständnis über den Nutzen der Koeffizienten B und A ist noch nicht besonders groß.
Mit der für einen gleitenden Mittelwert vorgeschlagenen Anwendung
Das Problem, das ich in dieser Art der Benutzung des Filter-Befehls sehe, ist die Tatsache, dass ich über eine Zeit von
x-Samples (hier 5, entsprechend der Window-Size) zunächst die vorangegangenen Werte durch "Nullen" auffülle, bis sich das
Fenster komplett mit tatsächliche vorhandenen Messwerten gefüllt hat.
Somit gibt sich beim Ausplotten ein sprunghafter Anstieg über die Dauer der windowsize von Null über langsam immer mehr
ansteigende Werte bis hin zum aktuellen Mittelwert. Der gleitende Mittelwert erreicht also je nach Länge des Fensters erst
allmählich seinen "tatsächlichen" Wert.
Da ich den Mittelwert aber ungefähr abschätzen kann, möchte ich die gleitende Mittelwertbildung quasi mit dem zum aktuellen
Initialisierung des Filters mit erstem Messwert...
Code:
% Daten
data = [1:0.2:4]';
% gleitender Mittelwert über ... Messwerte
windowSize = 5;
% Koeffizienten im Zähler der Übertragungsfunktion % = Nullstellen des FIR Filters
b = ones(1,windowSize)/windowSize;
% Koeffizienten im Nenner der Übertragungsfunktion % = Polstellen des FIR Filters -> FIR hat keine Pole, daher a = 1
a = 1;
% Initialisierungsvektor muss folgende Länge habe:
nb = max(length(a),length(b))-1;
% Filter mit erstem Messwert von Data initialisieren:
init(1:nb) = data(1);
y2 = filter(b,a,data,init);
Hey,
danke für die schnelle Hilfe.
Komme ich den irgendwie um die Benutzung des filter-Befehls herum,
in dem ich die gleitende Mittelwertbildung händisch mit einer for-Schleife erstelle?
Ich verstehe nämlich immer noch nicht ganz den zusammenhang von B und A mit dem Mittelwert.
_________________
D.h. Deine b's sind [1/5, 1/5, 1/5, 1/5, 1/5] und der a-Teil fällt weg, da nur a(1) von Null verschieden ist. Damit bekommst Du also für jedes Element die Summe der 5 zurückliegenden geteilt durch 5 - also den gleitenden Mittelwert. Allerdings ist der um die Window-Länge "nach hinten geschmiert". Diesen Delay kann man aber leicht entfernen: Füge vorne einfach 4 Werte mit dem ersten Wert an, und entferne sie nach der Anwendung von FILTER wieder.
Aber eine (eher 3) FOR-Schleife ist auch kein Hexenwerk:
Code:
x = rand(1, 1000);
n = length(x);
y = zeros(1, n); % Pre-allocate! for i = 1:5
y(i) = sum(x(1:i)) / i;
end
Das geht zwar auch effizienter z.B. indem man immer nur einen neuen Wert addiert und einen alten Wert subtrahiert. Aber wenn man es effizient möchte, ist FILTER sowieso besser.
Bitte teste das noch mit z.B. ONES(1,100) und 1:100. Ich kann es gerade nicht in Matlab laufen lassen.
Gruß, Jan
MichaNoReg
Gast
Beiträge: ---
Anmeldedatum: ---
Wohnort: ---
Version: ---
Verfasst am: 06.03.2012, 16:25
Titel: Radbereiche bei Moving Average
Hallo,
die Suche nach gleitender Mittelwertbildung hat einige Treffer hier im Forum, sodass ich keinen neuen Thread aufmachen wollte. Häufig wird
Was mich etwas verwundert ist die Größe des so ermittelten Vektors. Dieser hat die selbe Dimension wie die Eingangsdaten. Müsste bei einer gleitenden Mittelwertbildung nicht auch weniger Daten entstehen bzw. was passiert an den Randbereichen?
Code:
>> WindowSize = 3;
>> x = [3333];
>> filter(ones(1,WindowSize)/WindowSize,1,x)
Das nennt man auch das Einschwingverhalten eines Filters (hier ein FIR Mittelwertfilter). Das Filter ist defaultmäßig mit Nullen gefüllt und es wird immer seriell verarbeitet, d.h. ein Wert wird am Eingang ins Filter geladen, der letzte Wert liegt dann am Ausgang an. Ebenso ergibt sich dieses Verhalten am Ende des Signals, wenn wieder Nullen nachgeschoben werden.
Du kannst das Filter aber auch anders initialsieren...
Code:
filter(ones(1,windowsize)/windowsize, 1, X,zi) % wobei zi ein Vektor der Länge windowsize - 1 sein muss.
Du kannst Beiträge in dieses Forum schreiben. Du kannst auf Beiträge in diesem Forum antworten. Du kannst deine Beiträge in diesem Forum nicht bearbeiten. Du kannst deine Beiträge in diesem Forum nicht löschen. Du kannst an Umfragen in diesem Forum nicht mitmachen. Du kannst Dateien in diesem Forum posten Du kannst Dateien in diesem Forum herunterladen
MATLAB, Simulink, Stateflow, Handle Graphics, Real-Time Workshop, SimBiology, SimHydraulics, SimEvents, and xPC TargetBox are registered trademarks and The MathWorks, the L-shaped membrane logo, and Embedded MATLAB are trademarks of The MathWorks, Inc.