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

Code optimieren / Rechenzeit reduzieren

 

tomt0m

Gast


Beiträge: ---
Anmeldedatum: ---
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 04.03.2016, 11:27     Titel: Code optimieren / Rechenzeit reduzieren
  Antworten mit Zitat      
Hallo zusammen,

bin noch relativ frisch mit Matlab unterwegs und möchte ein Gleichungssystem iterativ lösen. Der Lösungsalgorithmus ist prinzipiell gegeben bzw. wird für meine Anwendung in der Literatur als ideal beschrieben. Dabei ist r der Vektor der Unbekannten und A ist die Koeffizientenmatrix. Die Originaldaten kann ich leider nicht raus geben. Zunächst habe ich das ganze mit geschachtelten for-Schleifen realisiert, dabei ist die Rechenzeit aber durch die Decke gegangen. Ich habe versucht die Rechnung zu vektorisieren, dabei ist der folgende Code entstanden und die Rechenzeit um Faktor 270 nach unten gegangen.
Dennoch gibt es bestimmt noch Optimierungspotential, daher meine Frage: Was kann man besser und idealerweise noch schneller machen? Best Practices?

Außerdem hätte ich gerne den Progressfortschritt angezeigt. Mittels waitbar geht hier die benötigte Zeit aber wieder stark nach oben. Alternativ habe ich den counter für die Iterationen im Command-Window anzeigen lassen aber selbst das erhöht meine Rechenzeit deutlich.

Code:
%----- Random Zahlenwerte
z=rand(170,1);
r=ones(540,1)*0.005;
A=rand(170,540);

% ----- Initialisierung
count=0;
count_max=10000;


%----Vorberechnung einzelner Terme
T=(1./sum(A(:,1:540)))';    
T2=bsxfun(@times, A, z);


%---- Iterative Lösung
tic

while count < count_max
T3=1./(A*r);
T4=bsxfun(@times, T2, T3);
T5=sum(bsxfun(@times, T4, r'));
r=T.*T5';
count=count+1;
end

toc


Besten Dank und schönes Wochenende!


Jan S
Moderator

Moderator


Beiträge: 11.057
Anmeldedatum: 08.07.10
Wohnort: Heidelberg
Version: 2009a, 2016b
     Beitrag Verfasst am: 06.03.2016, 16:11     Titel: Re: Code optimieren / Rechenzeit reduzieren
  Antworten mit Zitat      
Hallo tomt0m,

Der größte Gewinn wäre es natürlich, die Schleife abzubrechen, wenn r sich nicht mehr relevant ändert. Aber der Code lässt sich noch deutlich vereinfachen:

Code:
%----- Random Zahlenwerte
count_max = 10000;

%----Vorberechnung einzelner Terme
T  = (1 ./ sum(A(:,1:540)))';
T2 = bsxfun(@times, A, z).';

%---- Iterative Lösung
for count = 1:count_max
   T3 = 1 ./ (A * r);
   r  = T .* (T2 * T3) .* r;
end

Das läuft auf meinem Win7/64, Matlab 2015b, Core2Duo in 6.9 Sekunden statt der 28.9 des Original-Codes.

Gruß, Jan
Private Nachricht senden Benutzer-Profile anzeigen
 
tomt0m
Forum-Newbie

Forum-Newbie


Beiträge: 5
Anmeldedatum: 07.03.16
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 07.03.2016, 12:03     Titel:
  Antworten mit Zitat      
Hallo Jan,

wow, hätte nicht gedacht das man hier noch so viel rausholen kann! Vielen Dank!
Bei meinem System Win7/64, i7-4800MQ, Matlab 2013a hat sich die Rechenzeit von 3.9 auf 0.42s verkürzt.

Bezüglich des Schleifenabbruchs hast du natürlich recht, ich hatte auch geplant ein Abbruchkriterium einzubauen. Das ist relativ simpel da
Code:
sich
Code:
annähert, habs nur noch nicht umgesetzt Rolling Eyes .

Hat evtl. noch jemand Anmerkungen bzgl. einer Anzeige des Iterationsfortschritts mit möglichst geringem Rechenaufwand (siehe Eingangspost). Mein reales System kann beliebig groß werden (Messdaten) und i.d.R. sind relativ viele Iterationen notwendig, dementsprechend kann die Rechenzeit u.U. Stunden betragen.

PS: Top Forum, habe mich gleich mal angemeldet Very Happy
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: 07.03.2016, 13:23     Titel: Re: Code optimieren / Rechenzeit reduzieren
  Antworten mit Zitat      
Hallo tomt0m,

In jeder Iteration den Fortschritt anzeigen zu lassen, verbraucht natürlich einige Zeit. Aber wenn Du das nur in jeder 1000sten machst...
Code:
for count = 1:count_max
   T3 = 1 ./ (A * r);
   r  = T .* (T2 * T3) .* r;
   if mod(count, 1000) == 0
     fprintf('%d of %d\n', count, count_max);
   end
end

Das gleiche funmktioniert auch mit waitbar .

Gruß, Jan
Private Nachricht senden Benutzer-Profile anzeigen
 
tomt0m
Forum-Newbie

Forum-Newbie


Beiträge: 5
Anmeldedatum: 07.03.16
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 07.03.2016, 14:36     Titel:
  Antworten mit Zitat      
Hallo Jan,

top, genau das habe ich gesucht. Hätte man auch selber drauf kommen können Embarassed

Hier nochmal der Code mit waitbar und dem vorher erwähnten Abbruchkriteriu:

Code:

Rth=z(end);

h=waitbar(0,'Please wait...');
tic
for  count=1:count_max
T3=1./(A*r);
r=T1.*(T2*T3).*r;
if rem(count,1000)==0
    waitbar(count/count_max,h)
end
if abs(sum(r)-Rth) < 0.0001 , break, end
end
close(h)
toc
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: 07.03.2016, 16:52     Titel:
  Antworten mit Zitat      
Hallo tomt0m,

Eine Alternative ist now zu verwenden um die WAITBAR etwa einmal pro Sekunde zu upzudaten. Das hilft in Fällen, in denen auf jede 1000ste Iteration zu häufig ist, oder viel zu selten.

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
.





 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.