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

For-Schelife mit find() zu langsam

 

Apocalypto
Forum-Anfänger

Forum-Anfänger


Beiträge: 23
Anmeldedatum: 25.03.15
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 24.05.2015, 22:44     Titel: For-Schelife mit find() zu langsam
  Antworten mit Zitat      
Guten Abend Zusammen,

ich habe folgenden Code:

Code:
for N = 1:31

      for I=1:86400
                       
                        idxAscend = find(Ascend(:,N) == Preise(I,N),1,'last');            
                        idxDescend = find(Descend(:,N) == Preise(I,N),1,'last');          
                       
                        if idxAscend <= idx                                                
                            FP(I,N) = 1;                                                  
                        elseif idxDescend <= idx                                          
                            FP(I,N) = -1;                                                  
                        else
                            FP(I,N) = 0;                                                  
                        end
                       
      end

end


Der Durchlauf der inneren for-Schleife dauert ca. 47 Sekunden. Das Array "Preise" und "Ascend" bzw. "Descend" sind 86400x31 double Arrays. Dementsprechend existieren 2.678.400 Werte.


Kann ich noch etwas an Rechenzeit mit irgendwelchen Tricks einsparen, oder liegt die lange Rechenzeit wirklich an dem sehr großen Array?

Vielen Dank für eure Antworten!
Private Nachricht senden Benutzer-Profile anzeigen


Winkow
Moderator

Moderator



Beiträge: 3.842
Anmeldedatum: 04.11.11
Wohnort: Dresden
Version: R2014a 2015a
     Beitrag Verfasst am: 24.05.2015, 22:50     Titel:
  Antworten mit Zitat      
es ist immer einfacher mit einem lauffähigen beispiel zu hantieren. vielleicht kannst du nochmal kurt in worten beschreiben was dein ziel ist Smile matlab code ist zwar meist besser aber beides zusammen kann ja nicht schaden Smile
_________________

richtig Fragen
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: 25.05.2015, 00:33     Titel: Re: For-Schelife mit find() zu langsam
  Antworten mit Zitat      
Hallo Apocalypto,

Wichtig wäre es zu wissen, ob FP vor den Schleifen pre-allociert wird. Denn dann könnte das iterative Vergrößern der Matrix das Haupt-Problem sein:

Code:
FP = zeros(86400, 31);  % Pre-allocation!!!
for N = 1:31
   for I=1:86400
      idxAscend = find(Ascend(:,N) == Preise(I,N),1,'last');
     
      if idxAscend <= idx
         FP(I,N) = 1;
      elseif find(Descend(:,N) == Preise(I,N),1,'last') <= idx
         FP(I,N) = -1;
      end
   end
end

Zusätzlich wird die Suche nach Descend nur durchgeführt, wenn Ascend nicht gefunden wurde.

Die Arrays sind mit 2.6 Millionen Elementen nicht besonders groß. Ich bin sicher, dass sich das deutlich beschleunigen lässt. Genauer lässt sich das aber nur sagen, wenn ein lauffähiger Code mit realitsischen Testdaten zur Verfügung steht (siehe Winkows Antwort).

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

Forum-Anfänger

Forum-Anfänger


Beiträge: 23
Anmeldedatum: 25.03.15
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 25.05.2015, 14:28     Titel: Beispieldaten
  Antworten mit Zitat      
Okay dann versuch ichs mal mit einem läuffähigen Beispiel:

Grundlade der Berechnung sind Preise am Strommarkt, mit der eine Batterie aufgeladen und entladen werden soll.

Mein Preisarray ist zunächst für den Monat Januar vorhanden.

Code:


eta_bat_B = 0.9;
eta_wr_B = 0.97;

Preise = reshape(Pintraday, [86400,31]);               % Aufteilung der Intradaypreise in 31 Tage und 24h Blöcke (Sekündlich Aufgelöst)
Ascend = sort(Preise,1,'ascend');                      % Sortieren der Preise aufsteigend
Descend = sort(Preise,1,'descend');                    % Sortieren der Preise absteigend    

FP = zeros(86400,31);
P = zeros(86400,31);

             
               
          %-------------------------------------------------------------------------%
          % In dem ersten Teil des Codes wird der Fahrplan der Batterie
          % anhand der Börsenpreise ermittelt. In einem ersten Schritt
          % wird abgefragt ob die Einkaufspreise geteilt durch den
          % Batterie- und Wechselrichterwirkungsgrad < dem Verkaufspreis
          % mal dem Batterie- und Wechselrichterwirkungsgrad sind. Anhand
          % der Ergebnisse wird durch Indexabfragen der jeweiligen
          % Gewinnspanne der Fahrplan der Batterie erstellt.
          %-------------------------------------------------------------------------%
                for N = 1:31      
                   
                   
                   
                    for I=1:86400
                       
                        if (Descend(I,N)*(eta_bat_B*eta_wr_B) - Ascend(I,N)*(1/(eta_bat_B*eta_wr_B))) >= 0 % Abfrage ob durch Wirkungsgradverluste Einkaufspreis < Verkaufspreis ist
                            P(I,N) = Descend(I,N)*(eta_bat_B*eta_wr_B) - Ascend(I,N)*(1/(eta_bat_B*eta_wr_B));  % Gewinn pro Preispaar
                        else
                            P(I,N) = 0;         % Übersteigen die Verluste beim Einkaufen den Verkaufspreis wird kein Preispaar gebildet
                        end
                    end
                   
                    idx = find(P(:,N) == (min(P(:,N))),1,'first')-1;    % Heraussuchen des Indexes des niedrigsten Preispaares > 0
                   
                    for I=1:86400
                       
                        idxAscend = find(Ascend(:,N) == Preise(I,N),1,'last');            % Heraussuchen des Indexes des aktuellen Strompreises im Array der Einkaufspreise
                        idxDescend = find(Descend(:,N) == Preise(I,N),1,'last');          % Heraussuchen des Indexes des aktuellen Strompreises im Array der Verkaufspreise
                       
                        if idxAscend <= idx                                                % Wenn Index des aktuellen Strompreises (Einkaufspreis) kleiner als Index des niedrigsten Preispaares
                            FP(I,N) = 1;                                                   % Batterie laden
                        elseif idxDescend <= idx                                           % Wenn Index des aktuellen Strompreises (Verkaufspreis) kleiner als Index des niedrigsten Preispaares
                            FP(I,N) = -1;                                                  % Batterie entladen
                        else
                            FP(I,N) = 0;                                                   % Keine Batterieladung
                        end
                       
                    end
                   
                   
                end


 


So sollte das Programm laufen. Es dauert 838 Sekunden bis das Programm durchlaufen wurde. Die Prealloziierung von FP und P wurde schon vorgenommen. Mit Jans Vorschlag, idxDescend in die if- Abfrage aufzunehmen konnte ich die Rechenzeit auf 727 Sekunden verkürzen.

Vielleicht kann nochwas an der Variablen idx verbessert werden? Ich möchte dort nämlich den letzen Wert > 0 ermitteln und den Index davon übernehmen.

Das Programm kann gestartet werden sobald die Preise im Workspace eingelesen wurden.
Private Nachricht senden Benutzer-Profile anzeigen
 
Apocalypto
Themenstarter

Forum-Anfänger

Forum-Anfänger


Beiträge: 23
Anmeldedatum: 25.03.15
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 25.05.2015, 14:32     Titel: asd
  Antworten mit Zitat      
Hmm irgendwie kann ich keine Datei anhängen...
Private Nachricht senden Benutzer-Profile anzeigen
 
Winkow
Moderator

Moderator



Beiträge: 3.842
Anmeldedatum: 04.11.11
Wohnort: Dresden
Version: R2014a 2015a
     Beitrag Verfasst am: 25.05.2015, 14:33     Titel: Re: asd
  Antworten mit Zitat      
Apocalypto hat Folgendes geschrieben:
Hmm irgendwie kann ich keine Datei anhängen...

du musst auf die gültigen formate achten. zur not kann man die daten zippen.
_________________

richtig Fragen
Private Nachricht senden Benutzer-Profile anzeigen
 
Apocalypto
Themenstarter

Forum-Anfänger

Forum-Anfänger


Beiträge: 23
Anmeldedatum: 25.03.15
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 25.05.2015, 14:34     Titel:
  Antworten mit Zitat      
So jetzt Smile

Danke

Preise_Intraday_2013_Sekundenraster_Januar.rar
 Beschreibung:

Download
 Dateiname:  Preise_Intraday_2013_Sekundenraster_Januar.rar
 Dateigröße:  40.91 KB
 Heruntergeladen:  348 mal
Private Nachricht senden Benutzer-Profile anzeigen
 
Winkow
Moderator

Moderator



Beiträge: 3.842
Anmeldedatum: 04.11.11
Wohnort: Dresden
Version: R2014a 2015a
     Beitrag Verfasst am: 25.05.2015, 16:26     Titel:
  Antworten mit Zitat      
da mir grade langweilig ist versuche ich mich mal in die problemstellung reinzudenken. da hab ich noch ne frage.
ich verstehe nicht ganz warum die eingkaufspreise und verkaufspreise die sortierten preise sind. da hängt es bei mir irgendwie.
eine schleife und ein find kann man rauszihen... das hat so gut wie keinen performance gewinn... siht aber finde ich besser im code aus.
Code:
         P=(Descend.*(eta_bat_B*eta_wr_B) - Ascend.*(1/(eta_bat_B*eta_wr_B))>= 0).*(Descend.*(eta_bat_B*eta_wr_B) - Ascend.*(1/(eta_bat_B*eta_wr_B)));
          [~,idx] = min(P,[],1);
          idx=idx-1;

ich bin mir fast sicher das man irgendwas mit unique und den rückgabe werten von sort machen kann aber ich verstehe halt die vorgehensweise noch nicht ganz.
_________________

richtig Fragen
Private Nachricht senden Benutzer-Profile anzeigen
 
Apocalypto
Themenstarter

Forum-Anfänger

Forum-Anfänger


Beiträge: 23
Anmeldedatum: 25.03.15
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 25.05.2015, 16:54     Titel:
  Antworten mit Zitat      
Also als Beispiel nehmen wir mal einfach folgendes:

Stunde 1 - 8,5 €
Stunde 2 - 9,3 €
Stunde 3 - 10,8 €
Stunde 4 - 6,5 €

Aufsteigend sortiert:

6,5
8,5
9,3
10,8

Absteigend sortiert:

10,8
9,3
8,5
6,5

Preispaare bilden (gegenüberstellen von absteigend und aufsteigend)

10,8 - 6,5 = 4,8
9,3 - 8,5 = 0,8

Die nächsten beiden Preispaare würden ja negativ werden, da sich die folge entgegengesetzt wiederholt.

Das bedeutet der Fahrplan der Batterie auf die Ursprünglich nicht sortieren Preise würde lauten:

Stunde 1: Laden
Stunde 2: Entladen
Stunde 3: Entladen
Stunde 4: Laden


Ist es einigermaßen verständlich?

Wenn ich mir das gerade überlege, müsste die Abfrage dann auch nur bis zur hälfte des Arrays passieren.
Private Nachricht senden Benutzer-Profile anzeigen
 
Winkow
Moderator

Moderator



Beiträge: 3.842
Anmeldedatum: 04.11.11
Wohnort: Dresden
Version: R2014a 2015a
     Beitrag Verfasst am: 25.05.2015, 17:29     Titel:
  Antworten mit Zitat      
ok das beispiel ist schonmal einfacher Smile vielleicht können wir uns ja gemeinsam da durchhangeln
das beispiel was du gegeben hast läst sich ohne schleife realisieren.
Code:
Preise=[8.5,9.3,10.8,6.5,4,5,11.5,2]';
[Ascend,Iasc] = sort(Preise,1,'ascend');  
[Descend,Ides] = sort(Preise,1,'descend');  
FB=zeros(size(Preise));
B=Descend-Ascend;
FB(Iasc(B>0))=1;
FB(Iasc(B<0))=-1;

_________________

richtig Fragen
Private Nachricht senden Benutzer-Profile anzeigen
 
Apocalypto
Themenstarter

Forum-Anfänger

Forum-Anfänger


Beiträge: 23
Anmeldedatum: 25.03.15
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 25.05.2015, 18:02     Titel:
  Antworten mit Zitat      
Danke für die Antwort Winkow, ich versuche das so in meinen Code mal einzubauen!
Private Nachricht senden Benutzer-Profile anzeigen
 
Harald
Forum-Meister

Forum-Meister


Beiträge: 24.501
Anmeldedatum: 26.03.09
Wohnort: Nähe München
Version: ab 2017b
     Beitrag Verfasst am: 25.05.2015, 18:09     Titel:
  Antworten mit Zitat      
Hallo,

noch eine Anmerkung: die absteigend sortierten Werte kann man mit flipud bestimmen, anstatt nochmal komplett zu sortieren.

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

Forum-Anfänger

Forum-Anfänger


Beiträge: 23
Anmeldedatum: 25.03.15
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 25.05.2015, 18:55     Titel:
  Antworten mit Zitat      
Noch zwei blöde Fragen Confused

1. Wie kriege ich denn in dem Beispiel FP mehrdimensional?
2. In dem Fall, dass durch die Wirkungsgradverluste Ascend > Descend wird, soll eine 0 in den Fahrplan.

Hier nochmal mein aktueller Code:



Code:
eta_bat_B = 0.9;
eta_wr_B = 0.97;

Preise = reshape(Pintraday, [86400,31]);              
[Ascend, Iasc] = sort(Preise,1,'ascend');                      
[Descend,Ides] = sort(Preise,1,'descend');                    

FP = zeros(86400,31);
P = zeros(86400,31);

P = Descend*eta_bat_B*eta_wr_B - Ascend*(1/(eta_bat_B*eta_wr_B));

FP(Iasc(P>0))= 1;
FP(Iasc(P<0))= -1;

 
Private Nachricht senden Benutzer-Profile anzeigen
 
Harald
Forum-Meister

Forum-Meister


Beiträge: 24.501
Anmeldedatum: 26.03.09
Wohnort: Nähe München
Version: ab 2017b
     Beitrag Verfasst am: 25.05.2015, 19:16     Titel:
  Antworten mit Zitat      
Hallo,

zu 1.: z.B.
Code:
FP = zeros(m, n, k)


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

Forum-Anfänger

Forum-Anfänger


Beiträge: 23
Anmeldedatum: 25.03.15
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 25.05.2015, 19:20     Titel:
  Antworten mit Zitat      
Ich frage man etwas präziser Smile

Vorher habe ich FP ja schon pre-alloziiert

FP = zeros(86400,31);

Code:
FP(Iasc(P>0))= 1;
FP(Iasc(P<0))= -1;


Bei diesem Code ist es allerdings so, dass nur FP(:,1) berücksichtigt ist oder?

Jedenfalls kriege ich als Ergebnis für die erste Spalte von FP nur -1 raus, der rest ist null.

Zuletzt bearbeitet von Apocalypto am 25.05.2015, 19:23, insgesamt einmal bearbeitet
Private Nachricht senden Benutzer-Profile anzeigen
 
Neues Thema eröffnen Neue Antwort erstellen

Gehe zu Seite 1, 2  Weiter

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.