Verfasst am: 04.09.2019, 09:20
Titel: Matrix filtern mit schleife dauert zu lange
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? 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
Verfasst am: 04.09.2019, 12:22
Titel: Re: Matrix filtern mit schleife dauert zu lange
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.
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.
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,:);
Die Regel ist dabei: Alle wiederholten Berechnungen aus der Schleife rausziehen. Hier ist es DIFF, das man einsparen kann.
Gruß, Jan
Einstellungen und Berechtigungen
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.