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

Viele Gleichungen mittels Solve lösen

 

MenschMeier
Forum-Anfänger

Forum-Anfänger


Beiträge: 43
Anmeldedatum: 22.09.11
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 10.01.2012, 11:09     Titel: Viele Gleichungen mittels Solve lösen
  Antworten mit Zitat      
Hallo,
ich habe viele unterschiedliche Gleichung die ich mittels solve lösen möchte. Bis jetzt habe ich eine Schleife, die jede Gleichung einzeln mit solve löst. Das dauert nur ziemlich lange (ca. 300.000 Gleichungen). Alternativ habe ich einen Vektor zur Verfügung, der alle Gleichungen enthält. Jetzt würde ich diesen gerne komplett an solve übergeben, um alle Gleichungen parallel zu lösen. Leider "denkt" Matlab nun, dass es sich um ein Gleichungssystem mit n Gleichungen und 1 Unbekannten handelt. Nur möchte ich die Gleichungen ja unabhängig von einander lösen. Gibt es da eine Möglichkeit?

Danke und lg
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: 10.01.2012, 11:29     Titel:
  Antworten mit Zitat      
Hallo,

kannst du ein konkretes Beispiel mit wenigen Gleichungen (2-3 sollten reichen) geben?

Grüße,
Harald
Private Nachricht senden Benutzer-Profile anzeigen
 
Pinky
Forum-Anfänger

Forum-Anfänger


Beiträge: 34
Anmeldedatum: 14.11.11
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 10.01.2012, 11:32     Titel:
  Antworten mit Zitat      
Hallo,

ich hatte das selbe Problem und die Antwort ist ein klares Jein.

Matlab kennt die Solver nur mit EINER Variablen die aber MEHRERE Dimensionen haben kann. Du musst also alle deine Variablen in einen Vektor schreiben. Das sieht dann ungefähr so aus:

Code:

f_y = @(t,y) [ f1(y); f2(y);...];
y    = [x1;x2...]
sol = ode45(f_y,tspan,y_0);
 


Ich muss dich allerdings warnen, ich habe circa 6k Gleichungen und es dauert schon ewig.

gruß Pinky
Private Nachricht senden Benutzer-Profile anzeigen
 
MenschMeier
Themenstarter

Forum-Anfänger

Forum-Anfänger


Beiträge: 43
Anmeldedatum: 22.09.11
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 10.01.2012, 11:53     Titel:
  Antworten mit Zitat      
Hey,
schonmal danke für die antworten. ich poste mal meinen Quelltext:

1. Idee (funktioniert, dauert sehr lange):

for i=1:length(Data(:,2))
term = (Data(i,2)*log(90/x))^2)-x; %Funktion i die gelöst werden soll
z0=solve(term, x);
% Ausgabe des Bearbeitungsschrittes
fprintf('%i / %i \n',i, length(Data(:,2)));
end

2. Idee (funktioniert nicht):


term= ((1/log(90/x))^2).*Data_cut(1:1000,2)^2)-x; %Vektor aller Gleichungen mit jeweils der selben Unbekannten x
%Vordefinition des Lösungsvektors
z0=zeros(1,length(Data(:,2)));
%Lösung (führt zu einem Fehler von matlab)
z0=solve(term);

3. Lösungsidee:

% Erstellen eines Unbekannten-Vektor x=(x1;x2;x3 ...) -> dauert sehr lange (verbeserung der Laufzeit gegenüber 1. fraglich)
for i=1:length(Data_cut(:,2))
a=['syms x' num2str(i)];
eval(a);
a=['x(' num2str(i) ',1)=x' num2str(i)];
eval(a);
end

%Vektor aller Gleichungen mit jeweils dem Unbekannten-Vektor x
term= ((1/log(90/x))^2).*Data_cut(1:1000,2)^2)-x;
%Vordefinition des Lösungsvektors
z0=zeros(1,length(Data(:,2)));
%Lösung (führt auch zu einem Fehler von matlab Sad )
z0=solve(term);

ps:
Mir fällt zu 1. noch auf, dass das Lösen der Gleichungen im Laufe der Zeit immer Langsamer wird. Zu Beginn (i<1000) lief es noch schnell (5 Lösungen /s). Nun bei i=100.000 nur noch etwa 1,5 Gleichungen/s. Hat jemand eine Idee wieso das so ist?
Private Nachricht senden Benutzer-Profile anzeigen
 
Pinky
Forum-Anfänger

Forum-Anfänger


Beiträge: 34
Anmeldedatum: 14.11.11
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 10.01.2012, 12:08     Titel:
  Antworten mit Zitat      
Ich kann es leider gerade nicht überprüfen aber hast du einfach mal folgendes probiert:
Code:

sym ('x',[size(Data,1),1]);
solve((Data(:,2).*log(90/x))^2)-x,x)


In der MATLAB hilfe steht, dass solve auch Systeme von Gleichungen für einzelne Variablen lösen kann.

gruß Pinky
Private Nachricht senden Benutzer-Profile anzeigen
 
MenschMeier
Themenstarter

Forum-Anfänger

Forum-Anfänger


Beiträge: 43
Anmeldedatum: 22.09.11
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 10.01.2012, 12:15     Titel:
  Antworten mit Zitat      
Ich habe mich in meinen obigen Post etwas blöd ausgerückt. Hier nochmal die komplette Funktion.

Code:
syms x;
Data_cut(:,1) %Eingelesene Daten
k=1/sqrt(6.25);
alpha=0.011;        %open sea
%alpha=0.034;       %coast
g=9.81;
I15=0.14;

term=(alpha/g*(Data_cut(:,2)*k/log(90/x))^2)-x


Wie Pinky vorgeschlagen hat, habe ich die Gleichungen einfach in den Solver geschrieben:

Code:
z0=solve((alpha/g*(Data_cut(1:100,2)*k/log(90/x))^2)-x,x)


Dann kam folgendes:
Code:
Error using mupadmex
Error in MuPAD command: not a square matrix [(Dom::Matrix(Dom::ExpressionField()))::_power]

Error in sym/mpower (line 207)
            B = mupadmex('symobj::mpower',A.s,p.s);

Error in calcTI_OFFSHORE (line 76)
z0=solve((alpha/g*(Data_cut(1:100,2)*k/log(90/x))^2)-x,x)



ps: Ich berechne zu Testzwecken immer nur 1-100 Gleichungen, nicht 1-300.000
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: 10.01.2012, 12:43     Titel:
  Antworten mit Zitat      
Hallo,

ich nehme an, dass x eine symbolische Variable ist und Data eine Double-Matrix.

Die Ergebnisse werden dann ohnehin nur numerisch; es ist also deutlich effizienter, direkt mit dem numerischen Löser FSOLVE zu arbeiten.

Code:
z1 = zeros(1,20);
opts = optimset('Display', 'off');
for i=1:length(Data(:,2))
    term = @(x) (Data(i,2)*log(90/x))^2-x; %Funktion i die gelöst werden soll
    z1(i)=fsolve(term, 1, opts);
    % Ausgabe des Bearbeitungsschrittes
    fprintf('%i / %i \n',i, length(Data(:,2)));
end
 


Eine schönere Variante für die Fortschrittsanzeige wäre WAITBAR. Achtung, das Aktualisieren der Fortschrittsanzeige kann länger dauern als die eigentliche Berechnung, sollte also ggf. nicht in jeder Iteration durchgeführt werden.

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

Forum-Anfänger

Forum-Anfänger


Beiträge: 43
Anmeldedatum: 22.09.11
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 10.01.2012, 13:01     Titel:
  Antworten mit Zitat      
Auch das will nicht so wie ich will ...

Code:
% calculate and add TI_OFFSHORE
syms x;
k=1/sqrt(6.25);
alpha=0.011;        %open sea
%alpha=0.034;       %coast
g=9.81;
I15=0.14;
%z0=zeros(100,1);
opts = optimset('Display', 'off');

% for i=1:length(Data_cut(:,2))
for i=1:100
   term=(alpha/g*(Data_cut(i,2)*k/log(90/x))^2)-x;
   z0=fsolve(term, 0.001, opts);
   % Speichere das Ergebnis in einem Ausgabearray
   Data_cut(i,7)=z0;
   % Weitere Berechnungen folgen
   Sigma=(Data_cut(i,2)/log(90/z0)+1.28*1.44*I15);
   Data_cut(i,8)=Sigma;
   fprintf('Bearbeitungsschritt: %i / %i \n',i, length(Data_cut(:,2)));
end


Antwort:

Code:
>> calcTI_OFFSHORE(data)
Error using lsqfcnchk (line 109)
If FUN is a MATLAB object, it must have an feval method.

Error in fsolve (line 223)
    funfcn = lsqfcnchk(FUN,'fsolve',length(varargin),funValCheck,gradflag);

Error in calcTI_OFFSHORE (line 82)
   z0=fsolve(term, 0.001, opts);
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: 10.01.2012, 13:06     Titel:
  Antworten mit Zitat      
Hallo,

das "syms x" brauchst du bei FSOLVE nicht, dafür ein Function Handle:

Code:
term = @(x) ...

siehe mein Beispiel.

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

Forum-Anfänger

Forum-Anfänger


Beiträge: 43
Anmeldedatum: 22.09.11
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 10.01.2012, 13:11     Titel:
  Antworten mit Zitat      
Danke, hat funktioniert. Jetzt schmeiße ich die 300.00 Gleichungen mal rein und schaue, wie lange es dauert.

Rückmeldung:
Es läuft nun viel besser und die Geschwindigkeit sinkt nicht wie vorher. Aktueller Stand: 88.000/330.000 Gleichungen gelöst.

danke und lg
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: 11.01.2012, 10:31     Titel:
  Antworten mit Zitat      
Hallo,

noch 1-2 Ideen:

1. Man könnte sich von FSOLVE noch EXITFLAG zurückholen um sicherzustellen, dass der Algorithmus konvergiert hat:
Code:
[x,fval,exitflag] = fsolve(...)
if exitflag < 0
% Fehlerbehandlung
end


2. Man könnte die 2. Spalte zunächst sortieren (wenn sie recht zufällig angeordnet sind; wenn die Daten einigermaßen kontinuierliche Verläufe enthalten, ist das nicht nötig), und dann immer die vorherige Lösung als Startwert für die nächste Iteration nehmen. Dann sollte das deutlich schneller gehen. Natürlich muss man dann ggf. die Daten auch wieder "zurücksortieren".
Durch die besseren Startwerte sollte es deutlich schneller gehen.

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