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

Schnelle Art um Matrix zu erstellen.Bitte dringend um Hilfe.

 

scapa
Forum-Newbie

Forum-Newbie


Beiträge: 9
Anmeldedatum: 09.05.11
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 09.05.2011, 21:44     Titel: Schnelle Art um Matrix zu erstellen.Bitte dringend um Hilfe.
  Antworten mit Zitat      
Hallo zusammen
Ich habe folgende Problemstellung, welche ich zwar gelöst habe, jedoch mit absolut unbefriedigender performance.

Ich habe eine seeehr Lange Funktion P (automatisch generiert) von der Form

P(x,y)=F1*a(x,y)+F2*b(x,y)+F3*c(x,y),......,+Fn*zzz(x,y)
Dabei sind Fj unbekannte und a,b,c,zzz Funktionen in Abhängigkeit von x und y (ohne Unbekannte). Jede Unbekannte Fj kann mehrmals vorkommen.

Nun werte ich für k Punkte mit Koordianten (x,y) die Funktion P(x,y) aus. Diese ausgewerteten Funktionen möchte ich nun in einer Matrize, geordnet nach den Unbekannten Fi sammeln, so dass ich anschliessend ein lineares Gleichungssystem lösen kann. Dazu muss matlab die ausgewertete Funktion nach den Fn Unbekannten durchsuchen und den zugehörigen Term in den entsprechenden Platz der Koeffizientenmatrix einfügen.

Ich habe diese "suche und einfügen" routine mit dem matlab Befehl "coeffs" wie folgt gelöst:

Code:


l=40   %Länge; (Nullpunkt x=0 bei l/2);
b=30   %Breite (Nullpunkt y=0 bei b/2);


n=13   %Anzahl Punkte in x
m=13   %Anzahl Punkte in y


%Zusammenfügen der Koeffizientenmatrix
for i=1:n;
    x=l/(n-1)*(i-1)-l/2;
    for j=1:m;
        y=b/(m-1)*(j-1)-b/2;
        Pk=subs(P);
        for u=1:t;
            term=['F' num2str(u)];
            E=coeffs(Pk,term);
            if size(E)==[1,2];
                A(j+(i-1)*n,u)=E(2);
            else A(j+(i-1)*n,u)=0;
            end
        end
    end
end

 



Das Problem nun ist, dass diese Routine zum Zusammenfügen extrem lange dauert.
Für ein konkretes Beispiel warte ih z.B. insgesamt ca. 20 Minuten! bis die Matrix zusammengestellt ist.
Die Lösung des Gleichungssystems erfolgt dann in 0.016 Sekunden!

Ich suche also eine viel schnellere Methode um die Koeffizientenmatrix zusammenzustellen.
Ich muss dieses Problem leider nicht nur einmal lösen, sondern im Rahmen meiner Masterarbeit sehr oft. Dabei würde ich bis zum Ende meiner Tage warten.

Vielen Dank für eure Hilfe

Gruss Scapa
Private Nachricht senden Benutzer-Profile anzeigen


Gast

Gast


Beiträge: ---
Anmeldedatum: ---
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 10.05.2011, 09:07     Titel:
  Antworten mit Zitat      
Hi,
Ohne etwas getestet zu haben, vll ein paar Dinge die dir helfen könnten:

Ich glaube du berechnest einige Dinge mehrmals, obwohl sie sich nicht ändern.
1.
Code:

Muss das jedesmal neu berechnet werden? eventuell vor die Schleife ziehen.

2.

Code:

term=['F' num2str(u)];
            E=coeffs(Pk,term);
 

Ich denke auch das kannst du aus der Schleife nehmen und z.b. als Cell zwischenspeichern, etwa so (wie gesagt, nicht getestet):
Code:

for i=1:t
term=['F' num2str(u)];
E{i}=coeffs(Pk,term);
 

und dann innerhalb der Schleife mit:

Code:


aufrufen

3. Denn Profiler benutzen um Flaschenhälse zu finden
 
scapa
Themenstarter

Forum-Newbie

Forum-Newbie


Beiträge: 9
Anmeldedatum: 09.05.11
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 10.05.2011, 10:25     Titel:
  Antworten mit Zitat      
Merci für deine Antwort

Zum 1. Punkt:
Mit Pk = subs(P) setze ich die Punktkoordinaten des Punktes i,j in die Funktion P ein, so dass die einzigen Unbekannten die F's (F1 F2 F3, ... Fu, ... Ft) verbleiben. Für jeden Punkt (i,j) wird schlussendlich eine Gleichung des Gleichungssystems (und somit Zeile der Koeffizientenmatrix A) erstellt. Ich denke nicht, dass ich diesen Schritt aus der Schleife herausnehmen könnte. Wenn doch, wäre der Performancegewinn wahrscheinlich riesen gross.

Zum 2. Punkt:
Ich glaube, es wäre denkbar die "Coeffs" Geschichte statt über eine Schlaufe vektorisiert auszuführen wie du es vorgeschlagen hast. Ich habe nun den bisherigen ganzen Morgen ausprobiert. Ich bin jedoch bereits daran gescheitert, dass ich automatisch einen Vektor mit den Unbekannten F erzeugen muss der lautet:

term = [F1 F2 F3 ... Fu ... Fn]. Der beste Ansatz war:
Code:

u=1:t
term=['F' num2str(u)]
 


Der erzeugt jedoch term = [F1 2 3... u... t].
Ich müsst etwas haben wie term(u) = ['F' num2str(u)]

Anschliessend könnte ich mit deinem Tip fortfahren.
Ich poste mal noch das gesamte File, welches ich verwende.

matlab file komplett.zip
 Beschreibung:

Download
 Dateiname:  matlab file komplett.zip
 Dateigröße:  2.6 KB
 Heruntergeladen:  317 mal
Private Nachricht senden Benutzer-Profile anzeigen
 
scapa
Themenstarter

Forum-Newbie

Forum-Newbie


Beiträge: 9
Anmeldedatum: 09.05.11
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 10.05.2011, 13:44     Titel:
  Antworten mit Zitat      
Ok, bin einen Schritt weiter.

Ich kriege die Koeffizienten von Pk bezüglich F1..Ft raus mit (ohne zusätzliche Schleife) mit:

Code:

syms zero
for i=1:t;
    P=P+['F' num2str(i)]*zero;
end

for u = 1:t;
    syms(['F' num2str(u)]);
    F(u) = eval(['F' num2str(u)]);
end

u=1:t;
   
tic
%Zusammenfügen der Koeffizientenmatrix
for i=1:n;
    x=l/(n-1)*(i-1)-l/2;
    for j=1:m;
        y=b/(m-1)*(j-1)-b/2;
        Pk=subs(P);
        T=coeffs(Pk,F);
        A(j+(i-1)*n,:)=T(1,:);
    end
end
zero=0;
A=subs(A);
toc
 


Bemerkung: Die Variable zero musste ich einfügen, damit die Dimension von T immer gleich der Anzahl unbekannten F bleibt. Ist die Funktion nicht abhängig von Fu (z.B. F23) dann wird die Dimension von T um 1 kleiner.

Der Performancegewinn ist ca. 15%. Leider ist mir dies immer noch zu wenig. Das müsste doch noch schneller gehen.

Ich frage mich noch: Wäre die Performance nicht wesentlich besser, wenn ich statt den Coeffs Funktionen mit einer manuellen Schleife die Funktion Pk als String nach den Termen mit Fu durchsuchen würde und irgendwie den zugehörigen Term rausschreiben und in die Matrix setzen lassen.

Gruss
Private Nachricht senden Benutzer-Profile anzeigen
 
scapa
Themenstarter

Forum-Newbie

Forum-Newbie


Beiträge: 9
Anmeldedatum: 09.05.11
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 10.05.2011, 22:26     Titel:
  Antworten mit Zitat      
So funktionierts:

Code:

syms zero
for i=1:t;
    P=P+['F' num2str(i)]*zero;
end

for u = 1:t;
    syms(['F' num2str(u)]);
    F(u) = eval(['F' num2str(u)]);
end

%Zusammenfügen der Koeffizientenmatrix
tic
[x,y]=meshgrid(-l/2:l/(m-1):l/2,-b/2:b/(n-1):b/2);
Pk=subs(P);
for i=1:m
    for j=1:n
        [T,E]=coeffs(Pk(i,j),F);
        A(j+(i-1)*n,:)=T(1,:);
    end
end
toc
 


Gegenüber dem Ursprung erfolgt die Zusammenstellung der Koeffizientenmatrix ca. doppelt so schnell. Aber eigentlich sollte (und müsste) es doch noch viel schneller gehen.

Gibt es da kein Optimierungspotential mehr?

Gruss
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.