WICHTIG: Der Betrieb von goMatlab.de wird privat finanziert fortgesetzt. - Mehr Infos...

Mein MATLAB Forum - goMatlab.de

Mein MATLAB Forum

 
Gast > Registrieren       Autologin?   

Partner:




Forum
      Option
[Erweitert]
  • Diese Seite per Mail weiterempfehlen
     


Gehe zu:  
Neues Thema eröffnen Neue Antwort erstellen

Gleitender Mittelwert mit aktuellem Messwert als Initialisie

 

teutopixx
Forum-Fortgeschrittener

Forum-Fortgeschrittener


Beiträge: 77
Anmeldedatum: 09.03.11
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 27.06.2011, 11:30     Titel: Gleitender Mittelwert mit aktuellem Messwert als Initialisie
  Antworten mit Zitat      
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

Code:

filter(ones(1,windowsize)/windowsize, 1, X)
 


ergibt sich nach meinem Verständis für die Koeffizienten ständig der Wert B = 1/windowsize und A = 1.

Angenommen wir haben eine windowsize von 5, und einen Datensatz von [1;0.2;4] (wie in dem Beispiel bei der Hilfe):

Damit macht der Befehl also nichts anderes als zum aktuellen Zeitpunkt T den aktuellen Wert (hier 1) sowie die vier

vorangegangenen Werte mit B zu multiplizieren.

Also
Code:

Mittelwert 1 = 1/5 * 0 + 1/5 * 0 + 1/5 * 0 + 1/5 * 0 + 1/5 * 1
 

und
Code:

Mittelwert 2 = 1/5 * 0 + 1/5 * 0 + 1/5 * 0 + 1/5 * 1 ( = Mittelwert 1) + 1/5 * 1,2
 

usw.

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

Zeitpunkt (Startzeitpunkt) existierenden Messwert initialisieren.

Würde in dem Beispiel heißen, dass folgende Formel greifen würde (aktueller Wert zum Startzeitpunkt der Mittelwertbildung = 1):
Code:

1/5 * 1 + 1/5 * 1 + 1/5 * 1 + 1/5 * 1 + 1/5 * 1 = Mittelwert 1 = 1
 


Code:

1/5 * 1 + 1/5 * 1 + 1/5 * 1 + 1/5 * 1 + 1/5 * 1,2 = Mittelwert 1 = 1,04
 


usw. bis das Fenster sich komplett mit aktuellen Werten aus den realen Messdaten füllen lässt.

Ich glaube, dass ich um eine Verwendung der for-Schleife nicht drumrum komme.
An der Umsetzung scheitere ich leider.

Hat jemand eine Idee, die zur Lösung des Problems weiterhelfen könnte?
_________________

----
teutoPIXX
Private Nachricht senden Benutzer-Profile anzeigen


DSP
Forum-Meister

Forum-Meister



Beiträge: 2.117
Anmeldedatum: 28.02.11
Wohnort: ---
Version: R2014b
     Beitrag Verfasst am: 27.06.2011, 12:59     Titel:
  Antworten mit Zitat      
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;

y1 = filter(b,a,data);

% 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);

T=0:1:length(data)-1;
figure(1)
plot(T,y1,'b.-')
hold on
plot(T,y2,'r.-');
grid on
hold off
 
Private Nachricht senden Benutzer-Profile anzeigen
 
teutopixx
Themenstarter

Forum-Fortgeschrittener

Forum-Fortgeschrittener


Beiträge: 77
Anmeldedatum: 09.03.11
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 27.06.2011, 13:16     Titel:
  Antworten mit Zitat      
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.
_________________

----
teutoPIXX
Private Nachricht senden Benutzer-Profile anzeigen
 
Jan S
Moderator

Moderator


Beiträge: 11.057
Anmeldedatum: 08.07.10
Wohnort: Heidelberg
Version: 2009a, 2016b
     Beitrag Verfasst am: 27.06.2011, 16:37     Titel:
  Antworten mit Zitat      
Hallo teutopixx,

FILTER ist wahrscheinlich viel einfacher, als Du denkst. In "doc filter" findest Du diese Beschreibung:

Code:
y(n) = b(1)*x(n) + b(2)*x(n-1) + ... b(nb+1)*x(n-nb) + ...
   -a(2) ...etc   % Der etc Teil is uninteressant!

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

for i = 6:n-5
  y(i) = sum(x(i:i+5)) / 5;
end

for i = 5:-1:1
  y(n + 1 - i) = sum(x(n + 1 - i:n)) / 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
Private Nachricht senden Benutzer-Profile anzeigen
 
MichaNoReg

Gast


Beiträge: ---
Anmeldedatum: ---
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 06.03.2012, 16:25     Titel: Radbereiche bei Moving Average
  Antworten mit Zitat      
Hallo,

die Suche nach gleitender Mittelwertbildung hat einige Treffer hier im Forum, sodass ich keinen neuen Thread aufmachen wollte. Häufig wird
Code:
als Lösung vorgeschlagen.

Code:
filter(ones(1,windowsize)/windowsize, 1, X)


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 = [3 3 3 3];
>> filter(ones(1,WindowSize)/WindowSize,1,x)

ans =

     1     2     3     3

>>


Die beiden 3en sind klar aber was soll 1 und 2 sein?

Schöne Grüße
Micha
 
Winkow
Moderator

Moderator



Beiträge: 3.842
Anmeldedatum: 04.11.11
Wohnort: Dresden
Version: R2014a 2015a
     Beitrag Verfasst am: 06.03.2012, 16:35     Titel:
  Antworten mit Zitat      
3/3=1,(3+3)/3=2,(3+3+3)=3;
denke mal er nimmt am anfang die nicht vorhandenen vorgehenden werte als 0 mit rein.
Private Nachricht senden Benutzer-Profile anzeigen
 
MichaNoReg

Gast


Beiträge: ---
Anmeldedatum: ---
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 06.03.2012, 16:40     Titel:
  Antworten mit Zitat      
Hi Winkow,

Winkow hat Folgendes geschrieben:

er nimmt [...] 0 mit rein.

*lol* Okay, da hätte ich auch selbst drauf kommen können. Asche auf mein Haupt aber ich habe viel zu kompliziert gedacht....

Besten Dank
Micha
 
DSP
Forum-Meister

Forum-Meister



Beiträge: 2.117
Anmeldedatum: 28.02.11
Wohnort: ---
Version: R2014b
     Beitrag Verfasst am: 06.03.2012, 17:32     Titel:
  Antworten mit Zitat      
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.
 
Private Nachricht senden Benutzer-Profile anzeigen
 
Neues Thema eröffnen Neue Antwort erstellen



Einstellungen und Berechtigungen
Beiträge der letzten Zeit anzeigen:

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
.





 Impressum  | Nutzungsbedingungen  | Datenschutz | FAQ | goMatlab RSS Button RSS

Hosted by:


Copyright © 2007 - 2025 goMatlab.de | Dies ist keine offizielle Website der Firma The Mathworks

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.