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

iterative zeitreihenerstellung - wie beschleunigen?

 

Headfield
Forum-Anfänger

Forum-Anfänger


Beiträge: 14
Anmeldedatum: 01.02.11
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 30.06.2011, 14:49     Titel: iterative zeitreihenerstellung - wie beschleunigen?
  Antworten mit Zitat      
Hallo in die Runde,

ich habe ein kleines Problemchen:

Im Rahmen einer Simulation muss ich Zeitreihen immer mal wieder iterativ erstellen, da im Grunde ein Zirkelschluss vorliegt, der sich nicht verhindern lässt.

Grundsätzlich geht es darum, eine Zeitreihe eZR auf Basis einer anderen Zeitreihe gZR und Koeffizienten KV zu erstellen, wobei die Zeitreihe eZR zwangsläufig zeitverschoben auf sich selbst verweist. Das ist der besagte Zirkelschluss, der sich nicht verhindern lässt.

Hierzu ganz kurz:
Der Grund hierfür ist der Wert, durch den bei "iterative Zeitreihenerstellung" geteilt wird. Ist dieser zu klein, explodiert die Zeitreihe. Ist dieser "größte" Wert jedoch im Vektor KV nicht an erste oder an letzter Stelle, muss die Zeitreihe eben iterativ aufgebaut werden.

Mein Problem ist jetzt: Diese iterative Ermittlung funktioniert zwar, jedoch dauert sie Mitunter sehr lange. Die gesetzte Grenze von 50.000 Iterationen wird häufig verletzt. Mitunter können das auch zig Millionen werden.

Aktuell ist mein Abbruchkriterium das Unterschreiten einer minimalen Abweichung zwischen Iteration A und Iteration B, die Erreichung der maximalen Iterationsanzahl von aktuell 50.000 sowie im Idealfall die Situation, dass die aktuelle Zeitreihe einer der letzten 20 zeitreihen gleicht, d.h. die Iteration ist im Rahmen der Genauigkeit von Matlab konvergiert.

Grundsätzlich klappt das, jedoch dauert es ganz einfach viel zu lange. An den Grenzen kann ich eigentlich nicht viel ändern, da sofort die Genauigkeit und damit die Güte des zu testenden Ansatzes leidet.

Hat jemand eine Idee, wie sich so eine Iteration deutlich schneller lösen lässt? Gibt es vielleicht sogar in Matlab selbst die Möglichkeit, Iterationen schneller lösen zu lassen?

Für Hilfe wäre ich echt dankbar!

Anbei die Programmierung, die etwas unübersichtlich ist, da sie mit der Zeit wuchs und immer wieder verändert wurde. Dafür jetzt schon mal ein Sorry Wink

Noch ein paar Erläuterungen:

eZR = Zeitreihe die (gegebenenfalls durch Iteration) erstellt wird
gZR = Zeitreihe, die in die Erstellung von eZR einfließt
AK = Länge des Vektors KV
KV = Vektor mit Koeffizienten für die Erstellung der Zeitreihe eZR
PD = Position des größten Wertes im Vektor KV (durch diesen Wert wird stets geteilt, da sonst eZR explodiert)
eTRM = eine Hilfsmatrix, in der eZR Zeit- bzw. Zeilenverschoben steht, damit ich die Iteration selbst nicht mit einer for-Schleife zeilenweise machen muss
eZR2 = eine Hilfsmatrix, in der ich jeweils die letzten 20 Iterationen von eZR ablege, um die Abnahme der Abweichung der einzelnen Iterationen verfolgen zu können.

Code:
function [eZR] = zeitreiheniteration7(PD,AK,gZR,KV)

 eZR = ones(size(gZR,1)+AK-1,1)*mean(gZR);     % Platzhalter für Zeitreihe

 LV = KV;

 LV(PD,1) = 0;

 IT = 1;
 KS(1:4,1) = [1 2 3 4];
 iterationen = 0;

 eZR2(1:size(eZR,1),1:20) = rand(size(eZR,1),20);

 while isequal(IT,1)                      % Iterationsschleife für "stabile"  Zeitreihenaufstellung
               
  if isequal(IT,1)
   for i = 1:AK
    eTRM(:,i) = eZR(AK-i+1:end-i+1,1);
   end

   eZR((AK-PD)+1:end-PD+1,1) = (gZR(:,1)-eTRM*LV)/KV(PD,1);    %iterative Zeitreihenerstellung

   KS(1,1) = sum(abs(eZR));    
                 
   eZR2(1:size(eZR,1),2:20) = eZR2(1:size(eZR,1),1:19);
   eZR2(1:size(eZR,1),1) = eZR;
   Wert(1,1) = sum(abs(eZR2(:,1)-eZR2(:,2)));

   if isinf(KS(1,1))
    IT = 0;
   elseif isnan(KS(1,1))
    IT = 0;
   elseif isnan(KV)
    IT = 0;
   elseif  iterationen > 500000
    IT = 0;
    sprintf('Achtung, maximale Anzahl der Iterationen erreicht!');
   elseif Wert(1,1)/size(eZR,1) < mean(gZR)*1e-15
    IT = 0;
    sprintf('Abweichung klein genug');
   else
    IT = 1;
    iterationen = iterationen +1;
 
    marker = 0;  
    k = 1;
    while isequal(marker,0)
     k = k+1;
     if isequal(eZR2(:,1),eZR2(:,k))
      IT = 0 ;
      marker = 1;
      sprintf('Gleicher Wert!');
     elseif isequal(k,20)
      marker = 1;
     end
    end
   end
  end
 end    
end
 


_Peter_: Bitte Quellcode nicht unnötig breit machen. Danke.
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: 30.06.2011, 18:07     Titel:
  Antworten mit Zitat      
Hallo Headfield,

Das Programm ist nur mit großer Mühe lesbar. Kannst Du realistische Testdaten posten, so dass wir das Programm laufen lassen könnten? Ansonsten ist es schwer herauszubekommen, wo die Zeit verloren geht.
Ich habe zwar ein paar Ideen:
1. Vom Vektor K wird immer nur das erste Element verwendet, dann besser einen Skalar verwenden.
2. "marker==0" ist schneller als "isequal(marker, 0)"
3. Die Schleife für "marker" läßt sich aber auch ganz vermeiden:
Code:
if any(eZR2(:,1), eZR2(:, 1:20))
  IT = 0;
  sprintf('Gleicher Wert!');
end

4. Soweit ich sehe, ändert gZR nie seinen Wert. Dann musst Du auch nicht in jeder Iteration den MEAN neu berechnen.
5. Ist die Länge von eZR konstant? Dann wäre das wiederholte Berechnen der Länge per "size(eZR, 1)" auch Zeitverschwendung und sollte lediglich einmal ausgeführt werden.

Es gibt sicherlich noch einen Menge weiterer Möglichkeiten den Code zu beschleunigen. Soweit ich das sehen kann (was aber wegen der eingeschränkten Lesbarkeit nicht sehr weit her ist), wird das aber nicht um einen Faktor 10 schneller sein. Aber 20% schneller bringt Dir eigentlich nichts...

Also poste bitte einen kompakteren Code und irgendwelche Testdaten, die realistische Laufzeiten erzeugen - falls möglich einfach per RAND.

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

Forum-Anfänger

Forum-Anfänger


Beiträge: 14
Anmeldedatum: 01.02.11
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 30.06.2011, 19:01     Titel:
  Antworten mit Zitat      
Hallo Jan,

danke für die Antwort!

Mit deiner Schleife für den Zeitreihenvergleich komme ich noch nicht klar. Ansonsten habe ich mal das isequal ersetzt und zumindest hier bei dem einen Test die benötigte Zeit um fast 50 % reduzieren können ... krass!

Anbei einfach mal ein Zahlenbeispiel:

gZR:

0,0114264099314978
0,0114240613007175
0,0106207633741566
0,0121603086023545
0,0122021520854232
0,0120254103963610
0,0107121271413493
0,00944794752181335
0,0105228949617917
0,00957059048548592
0,0102720789574408
0,00806010514524803
0,00929605816828545
0,00923808407614110
0,0122855092350468
0,00882392514915546
0,0122610599458997
0,00829963158088822
0,00999456298955214
0,00954116904953782
0,00773937966117541
0,0101549964356722
0,00917144686823358
0,0116237831829995
0,0126295642665564
0,00956755936218945
0,0128007642643878
0,0102388075561738
0,0137091041485347
0,00948245911042750
0,0120801727895255
0,00893086594623689
0,0114762683287066
0,0115571146048140
0,0109885099158242
0,0105927283114948
0,0102459643377960
0,00999917134358828
0,0111348975234984
0,0112396815420543
0,0121106071052725
0,0108738568731913
0,0104793744357632
0,00696220453756387
0,0104852029555393
0,00760791323508864
0,0108874925897648
0,0114131130908331
0,0101406960721287
0,0113430334676612
0,0105705319698730
0,00926361118458984
0,0110204276810387
0,00882979850961884
0,0120723922452154
0,00931783258491734
0,0135632606541341
0,0115482766844254
0,0114072789497658
0,0115677945720784
0,00945877479243957
0,0107441239854865
0,0107145497902129
0,0112455862499124
0,00955065752849509
0,0104484474185855
0,00952512665330898
0,0115145386533446
0,0106546493191305
0,0120103399458781
0,0119615148877734
0,0116636745829666
0,0111254138486602
0,00981046337226065
0,0107185666077904
0,0107509062608211
0,0131535239565386
0,0113944545450021
0,0117041627358779
0,0104942323497246
0,0107551308416003
0,0121494055214408
0,0101136277346975
0,0109942796431424
0,0104064018079706
0,0102950733316764
0,00973257779260351
0,0108022007287582
0,00943960449819722
0,0118815146724175
0,00998084143719728
0,0106149260702125
0,0109483022904845
0,00970515478571915
0,0124786998761940
0,0124565018411587
0,0103796592350987
0,0117971424244746
0,0101552002254515
0,00984851665159221
0,0126123670710993
0,0105783146850507
0,0125369162532886
0,0112048734469297
0,0119792219879603
0,0109286265903431
0,0104099287924355
0,0105719091975682
0,00927190060296554
0,0102391724817562
0,00829229647489313
0,0101214946306137
0,00876271580365948
0,0111312105834790
0,0102490513809807
0,0109444814552726
0,0120730891316740
0,00987414679289314
0,0136457556307459
0,0108537830616783
0,0113575750254775
0,0105222671675279
0,00919226706217384
0,0104042738901556
0,0113290942440793
0,0123385648519580
0,0105495024878348
0,0111342109801949
0,00934098486520694
0,00920302957213834
0,00988546310530059
0,00914773714037156
0,0115298361513332
0,00916707624119006
0,0120071880287675
0,0107977222042046
0,0101932760188402
0,0106049033252073
0,00974856918119798
0,00830276484050508
0,0106697899667519
0,00959204220241966
0,0120498567763976
0,0132573054691086
0,0125735099666890
0,0102932895064628
0,0103375624965774
0,00724472550433481
0,0104254142845358
0,00968173856905059
0,0109899115087196
0,0103386751563983
0,0102204440605528
0,00954021511186982
0,00965262168735150
0,00872604525183906
0,0102186005243649
0,00856214110894033
0,0102658127453704
0,00923611644701555
0,0114255475128660
0,0108934372282549
0,0105328164091119
0,0125822891281069
0,0113496489770976
0,0125967843456346
0,0104087348454015
0,0108226510185240
0,00821367804140263
0,0103965422725354
0,00945597821979085
0,00802642852597698
0,0116302206035539
0,00744740709162514
0,0116622305644316
0,00876460701775126
0,00974582314729872
0,0101641613367825
0,0100731145655859
0,00971246332300855
0,0110890195188081
0,0105716493941968
0,0102568286236666
0,0120114207217015
0,00869884290137003
0,0124929486821156
0,00919442411001839
0,0134648775645393
0,0116523283818599
0,0125246204361820
0,0129613188790907
0,00923883113684780
0,0101485602295434
0,00912068381594948
0,0102660372629102
0,00911339249274297
0,0104940974935341
0,00964782241431767
0,0103079444274399
0,0124785408720366
0,0119659925351893
0,0116005945981878
0,0108479033373804
0,0103104714863319
0,00941522257149298
0,0109271721536402
0,0114594208569830
0,0115051707552948
0,0109403844363325
0,00975508165687327
0,00696177548291760
0,00668756293663728
0,00703759414629182
0,00711404442590142
0,00865238461158818
0,00726093750777849
0,00815406105960257
0,00792871278865747
0,00901649203448845
0,00995827567835262
0,0100851845050237
0,0115267141802880
0,00967276982478413
0,0114887344252365
0,0106121297233780
0,0110909622715866
0,00905400894038601
0,0109646897007210
0,00917701855803616
0,0108038863419201
0,0105818728527492
0,0126216113784859
0,00965635370119047
0,0122545287123621
0,00952711579946777
0,00988908985297347
0,0105833252992033
0,00913121685287665

KV

0,387397077849549
0,0253795034540769
0,497781295355822
0,00208380138119832
0,00208380138119831
0,0253795034540769
0,000200773391577038
0,0596942437325016

AK

8

PD

3


Leider habe ich direkt kein Beispiel parat, in dem es deutlich länger dauert. Aber die Funktionalität als solche sollte damit zu testen sein.

Diese Iteration ist eingebunden in eine Minimierung mit fmincon, welche wiederum mit Globalsearch verwendet wird. Ziel ist letztlich die Variierung der Werte in KV um eine Zielgröße zu minimieren.

[/code]
Private Nachricht senden Benutzer-Profile anzeigen
 
Headfield
Themenstarter

Forum-Anfänger

Forum-Anfänger


Beiträge: 14
Anmeldedatum: 01.02.11
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 30.06.2011, 19:10     Titel:
  Antworten mit Zitat      
Ich habe es nochmal ein klein wenig umgebaut und dabei direkt mal die Anmerkungen einfließen lassen, vielleicht wird es jetzt übersichtlicher:

Code:
function [eZR,zeit,iterationen] = zeitreiheniteration2(PD,AK,gZR,KV)

 tic

 mittelwert = mean(gZR);
 eZR = ones(size(gZR,1)+AK-1,1)*mittelwert;    
 anzahl = size(eZR,1);
 LV = KV;
 LV(PD,1) = 0;
 IT = 1;
 iterationen = 0;
 eZR2(1:anzahl,1:20) = rand(anzahl,20);

 %% Beginn der Iterationschleife
  while IT==1                      
  %  Aufstellen der Zeitreihe eZR      
   for i = 1:AK
    eTRM(:,i) = eZR(AK-i+1:end-i+1,1);
   end
   eZR((AK-PD)+1:end-PD+1,1) = (gZR(:,1)-eTRM*LV)/KV(PD,1);
   % Ablegen bisheriger Werte und Erstellung von Prüfgrößen
   KS = sum(abs(eZR));
   eZR2(1:anzahl,2:20) = eZR2(1:anzahl,1:19);
   eZR2(1:anzahl,1) = eZR;
   Wert = sum(abs(eZR2(:,1)-eZR2(:,2)));
                   
   % Überprüfung, ob Zeitreihe explodiert oder Abbruchkriterien erfüllt sind,
   % wenn alternierend gegen unendlich ==> IT = 0 oder wenn Abbruchkriterium
   % erfüllt ==> IT = 0, ansonsten nochmaliges Aufstellen der Zeitreihe eZR
                   
   if isinf(KS)
    IT = 0;
   elseif isnan(KS)
    IT = 0;
   elseif  iterationen > 500000
    IT = 0;
   elseif Wert/anzahl < mittelwert*1e-15
    IT = 0;
   else
    iterationen = iterationen +1;
    marker = 0;  
    k = 1;
    while marker==0
     k = k+1;
     if eZR2(:,1)==eZR2(:,k)
      IT = 0 ;
      marker = 1;
     elseif k==20
      marker = 1;
     end
    end
   end
  end  
  zeit = toc;
end


_Peter_: Bitte Quellcode nicht unnötig breit machen. Danke.
Private Nachricht senden Benutzer-Profile anzeigen
 
Headfield
Themenstarter

Forum-Anfänger

Forum-Anfänger


Beiträge: 14
Anmeldedatum: 01.02.11
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 30.06.2011, 19:30     Titel:
  Antworten mit Zitat      
bei der Gelegenheit fiel mir noch etwas ein:

Ich wiederhole die Schleife

Code:

for i = 1:AK
 eTRM(:,i) = eZR(AK-i+1:end-i+1,1);
end
eZR((AK-PD)+1:end-PD+1,1) = (gZR(:,1)-eTRM*LV)/KV;


Einfach für sich 500 mal, da ich diese ja sowieso je nach schwierigkeit einige hundert bis zu hundertausend malen durchführen muss - so spare ich mir, dass bei jedem umlauf die ganze folgende überprüfung durchgeführt werden muss. siehe da: wieder etwas reduziert ... jetzt bin ich von ca. 1,6 Sekunden auf ca. 0,25 Sekunden ... und das mit den paar Anpassungen.

Aber wie gesagt: für weitere Hilfe bin ich dankbar, insbesondere, ob sich die konvergenz obiges codes schneller erzielen lässt.
_Peter_: Bitte Quellcode nicht unnötig breit machen. Danke.
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: 01.07.2011, 03:50     Titel:
  Antworten mit Zitat      
Hallo Headfield!

Wieso ist Dein Sourcecode so tief eingerückt? Er ist auf meinem Laptop-Monitor deshalb breiter als eine Zeile und der Umbruch mach das Lesen schwer. (_Peter_: Habe ich angepasst.)

Code:
if eZR2(:,1) == eZR2(:,k)

Das ist zwar wohl richtig, aber Vektoren sind als IF-Bedingungen tückisch. Meinst Du:
Code:
if all(eZR2(:,1) == eZR2(:,k))

?

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

Forum-Anfänger

Forum-Anfänger


Beiträge: 14
Anmeldedatum: 01.02.11
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 01.07.2011, 08:44     Titel:
  Antworten mit Zitat      
Hallo Jan,

die Bedingung ist dann erfüllt, wenn alle Elemente der Vektoren identisch sind - alternativ müsste ich dann vielleicht mit der absoluten summe der Vektordifferenzen arbeiten ...

mfg

Mirko

_Peter_: Bitte Quellcode nicht unnötig breit machen. Danke.
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.