Mein MATLAB Forum - goMatlab.de

Mein MATLAB Forum

 
Gast > Registrieren       Autologin?   

Bücher:

Elektrotechnik für Informatiker mit MATLAB und Multisim

Fachkräfte:
weitere Angebote

Partner:


Vermarktungspartner


Forum
      Option
[Erweitert]
  • Diese Seite per Mail weiterempfehlen
     


Gehe zu:  
Neues Thema eröffnen Neue Antwort erstellen

Matrix filtern mit schleife dauert zu lange

 

Alexfromgalax
Forum-Anfänger

Forum-Anfänger


Beiträge: 48
Anmeldedatum: 28.05.19
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 04.09.2019, 10:20     Titel: Matrix filtern mit schleife dauert zu lange
  Antworten mit Zitat      
Hallo Leute,
ich habe mit Hilfe dieses Forums eine Funktion geschrieben die eine Matrix( 15 Spalten und richtig viele Zeilen) auf bestimmte Ereignisse prüft und dann einen bestimmten Bereich in der Matrix löscht. Soweit funktioniert auch alles, allerdings dauert es besonders bei großen Matrizen oft länger als 10 Sekunden.

Code:
%%Filter nach Gangwechsel bis AnaPedal= 95 +1Sekunde
   while i<a

Gearchange_idx=find(diff(RaceMatrixunfiltered(i:end,12))==1|diff(RaceMatrixunfiltered(i:end,12))==1,1);%finde den nächsten Gangwechsel
    Gearchangerow= i+Gearchange_idx;
    AnaPedal_idx=find(RaceMatrixunfiltered(Gearchangerow:end,7)>=95,1);% finde die erste Zeile in der AnaPedal>=95 nach dem Gangwechsel
    AnaPedalrow= Gearchangerow+AnaPedal_idx;
    Time_idx= find(RaceMatrixunfiltered(AnaPedalrow:end,1)>=(RaceMatrixunfiltered(AnaPedalrow,1)+1),1);% finde die Zeile nach dem AnaPedal >=95 und eine Sekunde vergangen ist
    Timerow= AnaPedalrow+Time_idx;
    RaceMatrixunfiltered(Gearchangerow:Timerow,:)=[]; %Lösche die Zeilen
    i=Gearchangerow+1;
    a= length(RaceMatrixunfiltered);% checke die Länge von RaceMatrixunfiltered
end    


Habt ihr eine Idee wie man heir vielleicht Zeit sparen kann?
Ich habe mir schon überlegt zuerst alle Zeilen in der Schleife zu merken und danach alle Bereiche auf einmal zu löschen. Das könnte allerdings zu Problemen führen da die Gangwechsel oft kurz hintereinander getätigt werden. Wenn man nun nach der Schleife zum Beispeil den Bereich Zeile 4 bis 18 und Zeile 6 bis 25 löschen will, löscht das Programm doch die Zeile 4 bis 18 und danach erst die neue Zeile 6 bis 25, oder? Question Das bedeute doch, dass Daten, die gar nicht gelöscht hätten werden dürfen gelöscht wurden oder verstehe ich da was falsch?
Naja ich hoffe ich konnte euch die Problematik erklären und ihr habt ein paar Lösungsvorschläge.
Vielen Dank
Alex
Private Nachricht senden Benutzer-Profile anzeigen


Jan S
Moderator

Moderator


Beiträge: 11.050
Anmeldedatum: 08.07.10
Wohnort: Heidelberg
Version: 2009a, 2016b
     Beitrag Verfasst am: 04.09.2019, 13:22     Titel: Re: Matrix filtern mit schleife dauert zu lange
  Antworten mit Zitat      
Hallo Alexfromgalax,

Das iterative Ändern der Größe eines Arrays ist extrem teuer. Der Ansatz zunächst die zu löschenden Zeilen zu finden und sie erst im Nachhinein zu löschen, klingt gut. Allerdings versteh ich den Code nicht und die Erklärungen in den Kommentaren sind nicht eindeutig. Die Sehr langen Namen der Variablen sind auch eher verwirrend als hilfreich.

Code:
Gearchange_idx = find( ...
diff(RaceMatrixunfiltered(i:end,12))==1 | ...
diff(RaceMatrixunfiltered(i:end,12))==1,1);

Wozu dient hier der OR-Operator, wenn erste und zweiter Operand identisch sind?

Gruß, Jan
Private Nachricht senden Benutzer-Profile anzeigen
 
Alexfromgalax
Themenstarter

Forum-Anfänger

Forum-Anfänger


Beiträge: 48
Anmeldedatum: 28.05.19
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 04.09.2019, 17:17     Titel:
  Antworten mit Zitat      
Hallo Jan
du hast natürlich recht. Ich habe beim zweiten diff ein Minus bei der 1 vegessen. So sollte es eigentlich heißen:
Code:
Gearchange_idx=find(diff(RaceMatrixunfiltered(i:end,12))==1|diff(RaceMatrixunfiltered(i:end,12))==-1,1);%find the first gearchange


Der Code soll die erste Zeile finden, in der in Spalte 12 der Wert um 1 nach oben oder 1 nach unten springt merkt er sich in Gearchange_idx. Diese Zeile addiert er zu 'i' und speichert sie als Gearchangerow ab da im nächsten Schritt erst ab dieser Zeile gesucht werden soll( quasi in einer verkleienrten Matrix von RaceMatrixunfiltered).
Als nächstes sucht er ab dieser Zeile von Gearchangerow wo die nächste Zeile ist, in der in Spalte 7 mindestens eine 95 steht. Danach wird um die Zeilenzahl in RaceMatrixunfiltered zu bekommen AnaPedal_idx wieder mit Gearchangerow addiert. Im nächsten Schritt wird wieder ausgehend von AnaPedalrow gesucht wann in Spalte 1 eine Sekunde vergangen ist. um wieder auf die Zeile der gesamten Matrix zu kommen wird dieser Wert mit AnaPedalrow addiert und im nächsten Schritt werden alle Zeilen von Gangwechsel (Gearchangerow) bis Timerow gelöscht.
Als nächstes wird 'i' mit Gearchangerow addiert um im nächsten Durchgang nicht wieder am Anfang zu starten sonder kurz nach dem gefilterten Gangwechsel.

Das mit den langen Variablennamen stört mich auch und ich werde es beim nächsten versuch auf jeden Fall ändern.
Private Nachricht senden Benutzer-Profile anzeigen
 
Jan S
Moderator

Moderator


Beiträge: 11.050
Anmeldedatum: 08.07.10
Wohnort: Heidelberg
Version: 2009a, 2016b
     Beitrag Verfasst am: 05.09.2019, 16:19     Titel: Re: Matrix filtern mit schleife dauert zu lange
  Antworten mit Zitat      
Hallo Alexfromgalax,

Hier erst mal eine vereinfachte Form deines Codes:
Code:
Race = RaceMatrixunfiltered;
RaceIs1 = abs(diff(Race(i:end,12))) == 1;
while i < a
    gear  = i + find(RaceIs1(i:end), 1);
    pedal = gear  + find(Race(gear:end,7) >= 95, 1);
    time  = pedal + find(Race(pedal:end,1) >= Race(pedal, 1) + 1, 1);
    Race(gear:time, :) = [];
    i = gear + 1;
    a = size(Race, 1);
end

Jetzt könnte man das so ändern, dass Race nicht mehr iterative verkleinert wird:
Code:
Race = RaceMatrixunfiltered;
nRace = size(Race, 1);
RaceIs1 = find(abs(diff(Race(i:end,12))) == 1);
Race95 = Race(:, 7) > 95;
keep = true(1, nRace);
for k = RaceIs1.'
    pedal = k + find(Race95(k:end), 1);
    time  = pedal + find(Race(pedal:end, 1) >= Race(pedal, 1) + 1, 1);
    keep(k:time, :) = false;
end
Race = Race(keep, :);

Macht das genau das gleiche wie dein Code? Ist das schneller?

Gruß, Jan
Private Nachricht senden Benutzer-Profile anzeigen
 
Alexfromgalax
Themenstarter

Forum-Anfänger

Forum-Anfänger


Beiträge: 48
Anmeldedatum: 28.05.19
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 06.09.2019, 10:27     Titel:
  Antworten mit Zitat      
Hallo Jan. Danke für deinen Vorschlag. Der Code ging tatsächlich schneller durch. Nach langem überlegen filtere ich jetzt aber bereits alle Daten, die ANaPedal unter 95 sind bevor sie überhaupt in die Matrix kommen. Beim eigentlichen Gangwechselfilter langt es nun die Gangwechsel beim Runterschalten zu finden, dann entfällt der Anapedal Index und es muss nur noch um 1 Sekunde verlängert werden. Das eigentliche Löschen passiert dann über den Gearchange_index außerhalb der Schleife. Das ist bis jetzt die schnellste Methode.
Code:
while i<a
      Gearchange_idx=find(diff(RaceMatrixfiltered(i:end,Gear))==-1,1);%find the first gearchange
      Gearchangerow= i+Gearchange_idx;
      Time_idx= find(RaceMatrixfiltered(Gearchangerow:end,Time)>=(RaceMatrixfiltered(Gearchangerow,Time)+1),1);% find where 1 second passed after the anapedal idx
      Timerow= Gearchangerow+Time_idx;
      Gearchange(Gearchangerow:Timerow,1) =1 ;
      i = Timerow;
end
 Gearchange_idx= (Gearchange(:,Time)==1);
RaceMatrixfinal= RaceMatrixfiltered(Gearchange_idx,:);
 
Private Nachricht senden Benutzer-Profile anzeigen
 
Jan S
Moderator

Moderator


Beiträge: 11.050
Anmeldedatum: 08.07.10
Wohnort: Heidelberg
Version: 2009a, 2016b
     Beitrag Verfasst am: 07.09.2019, 12:35     Titel:
  Antworten mit Zitat      
Hallo Alexfromgalax,

Sieht gut aus. Du kannst noch dies aus der Schleife raus ziehen
Code:
gearDown = diff(RaceMatrixfiltered(:,Gear))==-1;

und dann in der Schleife nur noch
Code:
Gearchange_idx = find(gearDown(i:end),1)

abfragen.

Die Regel ist dabei: Alle wiederholten Berechnungen aus der Schleife rausziehen. Hier ist es DIFF, das man einsparen kann.

Gruß, Jan
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
.


goMatlab ist ein Teil des goForen-Labels
goForen.de goMATLAB.de goLaTeX.de


 Impressum  | Nutzungsbedingungen  | Datenschutz  | Werbung/Mediadaten | Studentenversion | FAQ | goMatlab RSS Button RSS


Copyright © 2007 - 2021 goMatlab.de | Dies ist keine offizielle Website der Firma The Mathworks
Partner: LabVIEWforum.de

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.