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

"Kompression" großer Datenmengen

 

Dschiehses
Forum-Anfänger

Forum-Anfänger


Beiträge: 11
Anmeldedatum: 12.01.14
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 12.01.2014, 13:22     Titel: "Kompression" großer Datenmengen
  Antworten mit Zitat      
Hallo zusammen,

ich arbeite momentan an einem Projekt in Matlab/Simulink, was einen Wärmespeicher mit Feststofffüllung berechnet, der in j Elemente unterteilt ist. Jedes Element wird in Simulink simuliert (for-schleife). Im späteren Anwendungsfall sollen ~200-300 Elemente untersucht werden. Die Simulink-Simulation eines solchen Tankelements dauert ca. 3-4 Sekunden.

Als Ergebnis erhalte ich (minimum, thermisch dünne Füllungselemente angenommen) 2 Vektoren pro Tankelement (Austrittstemperatur + Füllungstemperatur). In einem Beispiel, wenn die Simulation 6 Stunden dauert, wäre der Ergebnisvektor ein 6 * 3600 / 0.1 + 1 = 216001 x 1 Double mit Zahlenwerten (die 0.1 entspricht der Schrittweite für Simulink).

Auf meinem PC (32bit, 3GB ram) bricht die Simulation nach ca. 80 Elementen ab ("Out of Memory").

Meine Idee war nun, die Daten zu komprimieren. Da bei einer Schrittweite von 0.1s 10 Werte pro Sekunde anfallen, die Werte sich aber u.U. nicht ändern, wollte ich nur die Änderungen der Werte und die dazugehörigen Indices speichern, also ein XXXx2 Double erstellen:

600 | 1
0.8 | 123
0.6 | 156
1.2 | 357
etc.

Ein erster Ansatz dafür war, eine for-schleife über die Anzahl der Zeitschritte zu machen (also 1:216001), die Differenz zum letzten gespeicherten Wert zu bilden, und sofern sie einen Differenzwert (z.b. 0.5K) überschreitet, einen neuen Wert sowie den Index in einem neuen Vektor zu speichern.

Das hat durchaus funktioniert, ich konnte einen 216001x1 Double zu einem 200x2 Double zusammenfassen, allerdings dauerte der Komprimierungsvorgang für 3 Tankelemente (Simulationsdauer ca 10 Sekunden) etwa 5 Minuten. Das ist natürlich unzumutbar.

Ich weiß, dass for-Schleifen generell sehr langsam sind und man in Matlab besser mit Matrix-Operationen arbeiten sollte.

Gibt es eine Methode, diese Komprimierung schneller zu machen(beispielsweise mit arrayfun)?

Anbei noch der Quellcode der function compress(To = unkomprimiertes 216001x1 Double, T = Zielvektor):
Code:

function T = compress(obj, To)
% anfangswerte + anfangsindex
T.out{1,1} = To.out(1);
T.out{1,2} = 1;

% anzahl iterationsschritte
len = numel(To.out);

for i=1:len
  delta = To.out(i) - T.out{end,1};
    if abs(delta) > 0.5
      T.out{end+1,1} = delta; % differenz zum vorherigen Wert
      T.out{end, 2} = i; % index
    end

end % for
end % compress
 


Ich hoffe, ich konnte mein Problem verdeutlichen und ihr könnt mir weiterhelfen.

Viele Grüße,
Jan
Private Nachricht senden Benutzer-Profile anzeigen


Harald
Forum-Meister

Forum-Meister


Beiträge: 24.492
Anmeldedatum: 26.03.09
Wohnort: Nähe München
Version: ab 2017b
     Beitrag Verfasst am: 12.01.2014, 13:34     Titel:
  Antworten mit Zitat      
Hallo,

hänge bitte Beispieldaten als .mat-Datei an, damit man das testen kann.

Was mir auf den ersten Blick auffällt: warum verwendest du für T.out ein Cell Array? Zudem dürfte das ständige Indizieren in die Struktur zeitraubend sein.
Es dürfte auch geschickter sein, den Ausgang zunächst mit derselben Größe wie den Eingang vorzubelegen, die Elemente dann nach und nach zu überschreiben, und den nicht benötigten Platz am Ende freizugeben.

Die Frage ist aber, ob man nicht einen anderen Ansatz wählen kann, z.B.:
- nach der Simulation nur sekündliche Werte verwenden (wenn dabei nicht zu viel Detail verloren geht)
- sofern möglich, jeden Ergebnisvektor sofort nach Simulation wie gewünscht verarbeiten, und dann den alten Ergebnisvektor mit dem neuen überschreiben.

Grüße,
Harald
Private Nachricht senden Benutzer-Profile anzeigen
 
Dschiehses
Themenstarter

Forum-Anfänger

Forum-Anfänger


Beiträge: 11
Anmeldedatum: 12.01.14
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 12.01.2014, 16:47     Titel:
  Antworten mit Zitat      
Hi Harald,


... wie einfach die Lösung doch sein kann. Wenn ich nur sekündliche Werte nehme, läuft die Komprimierung auf einmal in Sekundenschnelle.

Ich hätte nicht erwartet, dass bei einer for-Schleife der Unterschied zwischen 21600 und 216000 Elementen so gravierend ist.


Vielen Dank für die Hilfe!
Private Nachricht senden Benutzer-Profile anzeigen
 
Harald
Forum-Meister

Forum-Meister


Beiträge: 24.492
Anmeldedatum: 26.03.09
Wohnort: Nähe München
Version: ab 2017b
     Beitrag Verfasst am: 12.01.2014, 17:28     Titel:
  Antworten mit Zitat      
Hallo,

wenn ich die Ausgangslage richtig verstehe, dann brauchst du bei sekündlichen Werten überhaupt keine Kompression mehr zu machen.

Grüße,
Harald
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 - 2024 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.