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

Optimierungsproblem

 

2more
Forum-Newbie

Forum-Newbie


Beiträge: 8
Anmeldedatum: 27.05.13
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 10.02.2015, 21:13     Titel: Optimierungsproblem
  Antworten mit Zitat      
Hallo allerseits,

Ich sitze mal wieder an einem Matlab Problem dessen theoretische Lösung eigentlich nicht so schwer sein sollte, mir es aber wohl am nötigen Knowhow-fehlt wie ich das ganze in einen fehlerfreien Code darstellen kann.

Es geht darum dass ich ein ODE bestehend aus 4 Gleichungen gegeben habe und dieses ODE optimieren soll, dafür stehen 2 Stellgrößen zur Verfügung um eine der Ausgangsgrößen zu maximieren.

Hier nun erstmal mein Code, ich hoffe es ist nicht allzu unübersichtlich, um ehrlich zu sein, habe ich versucht mir den Anhand eines Beispiels zurecht zu basteln, mir fehlen aber wohl noch wesentliche Grundlagen, was das Aufrufen von Funktionen in anderen Funktionen angeht.

Jedenfalls sollen die Größen PARAMS(Cool und (9) die Stellgrößen darstellen und Y(2) soll maximiert werden.

Wenn ich das Programm starte, scheitert es schon an einem wohl sehr simplen Problem (Not enough input arguments.) aber ich versteh es einfach nicht Sad

Bin ich auf dem richtigen Weg?
Mach ich's mir unnötig kompliziert?
Hat jemand Idee wo meine Fehler liegen könnten?

Hoffe dass man da als aussenstehender überhaupt durchblickt, ich tu es selbst ja kaum Smile

Code:
%% Objective function

function f = objFunc(u)
   
    % declare interval of independent variable
   X_START=0.0;
   X_END=18000.0;
   X_INTERVAL=[X_START X_END];   % e0_t

   % specify the initial values for the state variables
   Y_INIT(1) = 333.0;     % e0_T  
   Y_INIT(2) = 8.0;     % e0_c_A  
   Y_INIT(3) = 20.0;     % e0_c_B  
   Y_INIT(4) = 0.0;     % e0_c_C
   

   % declare parameters
   PARAMS(1) = 45000.0;     % e0_greek_Deltah_A
   PARAMS(2) = -55000.0;     % e0_greek_Deltah_B
   PARAMS(3) = 800.0;     % e0_greek_rho
   PARAMS(4) = 69000.0;     % e0_E_A
   PARAMS(5) = 72000.0;     % e0_E_B
   PARAMS(6) = 6.5E-4;     % e0_F
   PARAMS(7) = 8.3144621;     % e0_R
   PARAMS(8) = u(1);     % e0_T_j
   PARAMS(9) = u(2);     % e0_T_o
   PARAMS(10) = 1.4;     % e0_UA
   PARAMS(11) = 1.0;     % e0_V
   PARAMS(12) = 5.0;     % e0_c_A0
   PARAMS(13) = 15.0;     % e0_c_B0
   PARAMS(14) = 0.0;     % e0_c_C0
   PARAMS(15) = 3.5;     % e0_c_p
   PARAMS(16) = 2.718281828459045;     % e0_e
   PARAMS(17) = 5000000.0;     % e0_k_A0
   PARAMS(18) = 1.0E7;     % e0_k_B0

   [X,Y] = ode45(@(X,Y)calculateDifferentials(X,Y,PARAMS),X_INTERVAL,Y_INIT');
   
    f = -Y(2);

end

%% evaluate the differential function.

function[DYDX] = calculateDifferentials(X,Y,PARAMS)

   % read out variables  
   e0_T = Y(1);
   e0_c_A = Y(2);
   e0_c_B = Y(3);
   e0_c_C = Y(4);

   % read out differential variable
   e0_t = X;

   % read out parameters
   e0_greek_Deltah_A = PARAMS(1);
   e0_greek_Deltah_B = PARAMS(2);
   e0_greek_rho = PARAMS(3);
   e0_E_A = PARAMS(4);
   e0_E_B = PARAMS(5);
   e0_F = PARAMS(6);
   e0_R = PARAMS(7);
   e0_T_j = PARAMS(8);
   e0_T_o = PARAMS(9);
   e0_UA = PARAMS(10);
   e0_V = PARAMS(11);
   e0_c_A0 = PARAMS(12);
   e0_c_B0 = PARAMS(13);
   e0_c_C0 = PARAMS(14);
   e0_c_p = PARAMS(15);
   e0_e = PARAMS(16);
   e0_k_A0 = PARAMS(17);
   e0_k_B0 = PARAMS(18);

   % evaluate the function values  
   DYDX(1) = ( e0_F )/( e0_V ) * ( e0_T_o - e0_T ) + ( e0_UA )/( e0_greek_rho * e0_c_p * e0_V ) * ( e0_T_j - e0_T ) + ( (  - e0_greek_Deltah_A ) )/( e0_greek_rho * e0_c_p ) * e0_k_A0 * e0_c_A * ( ( e0_e ) )^(  - ( e0_E_A )/( ( e0_R * e0_T ) ) ) + ( (  - e0_greek_Deltah_B ) )/( e0_greek_rho * e0_c_p ) * e0_k_B0 * e0_c_B * ( ( e0_e ) )^(  - ( e0_E_B )/( ( e0_R * e0_T ) ) );
   DYDX(2) = ( e0_F )/( e0_V ) * ( e0_c_A0 - e0_c_A ) - e0_k_A0 * e0_c_A * ( ( e0_e ) )^(  - ( e0_E_A )/( ( e0_R * e0_T ) ) ) + e0_k_B0 * e0_c_B * ( ( e0_e ) )^(  - ( e0_E_B )/( ( e0_R * e0_T ) ) );
   DYDX(3) = ( e0_F )/( e0_V ) * ( e0_c_B0 - e0_c_B ) - e0_k_B0 * e0_c_B * ( ( e0_e ) )^(  - ( e0_E_B )/( ( e0_R * e0_T ) ) );
   DYDX(4) = ( e0_F )/( e0_V ) * ( e0_c_C0 - e0_c_C ) + e0_k_A0 * e0_c_A * ( ( e0_e ) )^(  - ( e0_E_A )/( ( e0_R * e0_T ) ) );

   DYDX=DYDX';

end

%% optimization via LSQNONLIN

function best_u = odeParamID()

u0(1) = 333;    % e0_T_j
u0(2) = 333;    % e0_T_o

best_u = lsqnonlin(@(u)objFunc,u0,273,373)

end
Private Nachricht senden Benutzer-Profile anzeigen


Harald
Forum-Meister

Forum-Meister


Beiträge: 24.499
Anmeldedatum: 26.03.09
Wohnort: Nähe München
Version: ab 2017b
     Beitrag Verfasst am: 10.02.2015, 21:20     Titel:
  Antworten mit Zitat      
Hallo,

das Function Handle für lsqnonlin ist falsch. Es müsste @objFunc oder auch @(u) objFunc(u) heißen.

Desweiteren ist die Angabe von lb und ub so nicht sinnvoll.
Zum einen sollten es Vektoren derselben Länge sein wie der Anfangsvektor (also 2), zum anderen ist es sehr unüblich, sie gleich zu wählen.

Außerdem sollten auch die Tipps auf
http://de.mathworks.com/help/optim/.....ifferential-equation.html
berücksichtigt werden, was das Setzen von FinDiffRelStep angeht.

Bitte immer die komplette Fehlermeldung angeben.

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

Forum-Newbie

Forum-Newbie


Beiträge: 8
Anmeldedatum: 27.05.13
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 11.02.2015, 02:06     Titel:
  Antworten mit Zitat      
Hallo Harald, danke für die schnelle Antwort. Ich hab den Code ein wenig angepasst, leider hört der nach ein paar Iterationsschirtten (2-3 Schritte nur) auf mit der Fehlermeldung:

Subscripted assignment dimension mismatch.

Error in finitedifferences (line 273)



Error in sfdnls (line 8Cool
[J,~,~,numEvals] = finitedifferences(x,fun,[],lb,ub,valx,[],[], ...

Error in snls (line 340)
[newA, findiffevals] = sfdnls(xcurr,newfvec,Jstr,group,[], ...

Error in lsqncommon (line 150)
[xC,FVAL,LAMBDA,JACOB,EXITFLAG,OUTPUT,msgData]=...

Error in lsqnonlin (line 237)
[xCurrent,Resnorm,FVAL,EXITFLAG,OUTPUT,LAMBDA,JACOB] = ...

Error in odeParamID (line 2Cool
best_T = lsqnonlin(objective, u, lb, ub, options)

Hier nochmal der Code:

Code:
function best_T = odeParamID()

    clear all
    close all
    clc

    u = 333;             % Init Tj, To
    %u(2) = 333;         % Init To

    % declare interval of independent variable
   X_START=0.0;
   X_END=18000.0;
   X_INTERVAL=[X_START X_END];   % e0_t

   % specify the initial values for the state variables
   Y_INIT(1) = u;     % e0_T  
   Y_INIT(2) = 8.0;     % e0_c_A  
   Y_INIT(3) = 20.0;     % e0_c_B  
   Y_INIT(4) = 0.0;     % e0_c_C

    %% Set up optimization
    objective = @(u)objFcn(u,X_INTERVAL,Y_INIT');
    lb = 273;
    ub = 373;
    options = optimoptions('lsqnonlin','FinDiffRelStep',1e-16,'FinDiffType','central');


    best_T = lsqnonlin(objective, u, lb, ub, options)
   
end

function c_A = objFcn(u,X_INTERVAL,Y_INIT)

   % declare parameters
   PARAMS(1) = 45000.0;     % e0_greek_Deltah_A
   PARAMS(2) = -55000.0;     % e0_greek_Deltah_B
   PARAMS(3) = 800.0;     % e0_greek_rho
   PARAMS(4) = 69000.0;     % e0_E_A
   PARAMS(5) = 72000.0;     % e0_E_B
   PARAMS(6) = 6.5E-4;     % e0_F
   PARAMS(7) = 8.3144621;     % e0_R
   PARAMS(8) = u;     % e0_T_j
   PARAMS(9) = u;     % e0_T_o
   PARAMS(10) = 1.4;     % e0_UA
   PARAMS(11) = 1.0;     % e0_V
   PARAMS(12) = 5.0;     % e0_c_A0
   PARAMS(13) = 15.0;     % e0_c_B0
   PARAMS(14) = 0.0;     % e0_c_C0
   PARAMS(15) = 3.5;     % e0_c_p
   PARAMS(16) = 2.718281828459045;     % e0_e
   PARAMS(17) = 5000000.0;     % e0_k_A0
   PARAMS(18) = 1.0E7;     % e0_k_B0

       
    %ODE_Sol = ode45(@(t,z)updateStates(t,z,x), tSpan, z0);
    [X,Y] = ode45(@(X,Y)calculateDifferentials(X,Y,PARAMS),X_INTERVAL,Y_INIT');
    c_A = -Y(:,2)
    save('XYfile.mat','X','Y');
    %save('params.mat','PARAMS');

end

%% evaluate the differential function.

function[DYDX] = calculateDifferentials(X,Y,PARAMS)

   % read out variables  
   e0_T = Y(1);
   e0_c_A = Y(2);
   e0_c_B = Y(3);
   e0_c_C = Y(4);

   % read out differential variable
   e0_t = X;

   % read out parameters
   e0_greek_Deltah_A = PARAMS(1);
   e0_greek_Deltah_B = PARAMS(2);
   e0_greek_rho = PARAMS(3);
   e0_E_A = PARAMS(4);
   e0_E_B = PARAMS(5);
   e0_F = PARAMS(6);
   e0_R = PARAMS(7);
   e0_T_j = PARAMS(8);
   e0_T_o = PARAMS(9);
   e0_UA = PARAMS(10);
   e0_V = PARAMS(11);
   e0_c_A0 = PARAMS(12);
   e0_c_B0 = PARAMS(13);
   e0_c_C0 = PARAMS(14);
   e0_c_p = PARAMS(15);
   e0_e = PARAMS(16);
   e0_k_A0 = PARAMS(17);
   e0_k_B0 = PARAMS(18);

   % evaluate the function values  
   DYDX(1) = ( e0_F )/( e0_V ) * ( e0_T_o - e0_T ) + ( e0_UA )/( e0_greek_rho * e0_c_p * e0_V ) * ( e0_T_j - e0_T ) + ( (  - e0_greek_Deltah_A ) )/( e0_greek_rho * e0_c_p ) * e0_k_A0 * e0_c_A * ( ( e0_e ) )^(  - ( e0_E_A )/( ( e0_R * e0_T ) ) ) + ( (  - e0_greek_Deltah_B ) )/( e0_greek_rho * e0_c_p ) * e0_k_B0 * e0_c_B * ( ( e0_e ) )^(  - ( e0_E_B )/( ( e0_R * e0_T ) ) );
   DYDX(2) = ( e0_F )/( e0_V ) * ( e0_c_A0 - e0_c_A ) - e0_k_A0 * e0_c_A * ( ( e0_e ) )^(  - ( e0_E_A )/( ( e0_R * e0_T ) ) ) + e0_k_B0 * e0_c_B * ( ( e0_e ) )^(  - ( e0_E_B )/( ( e0_R * e0_T ) ) );
   DYDX(3) = ( e0_F )/( e0_V ) * ( e0_c_B0 - e0_c_B ) - e0_k_B0 * e0_c_B * ( ( e0_e ) )^(  - ( e0_E_B )/( ( e0_R * e0_T ) ) );
   DYDX(4) = ( e0_F )/( e0_V ) * ( e0_c_C0 - e0_c_C ) + e0_k_A0 * e0_c_A * ( ( e0_e ) )^(  - ( e0_E_A )/( ( e0_R * e0_T ) ) );

   DYDX=DYDX';

end


Wie gesagt, es sollen die Parameter 8 und 9 angepasst werden um den Vektor Y(:,2) zu maximieren. Da der solver wohl nur eine Größe optimieren kann, werden die beiden Parameter gleichgesetzt, zu mindest fürs erste um eine erste Näherung zu erhalten. Naja ist auch schon spät, vielleicht sollte ich erstmal drüber schlafen.
Private Nachricht senden Benutzer-Profile anzeigen
 
Harald
Forum-Meister

Forum-Meister


Beiträge: 24.499
Anmeldedatum: 26.03.09
Wohnort: Nähe München
Version: ab 2017b
     Beitrag Verfasst am: 11.02.2015, 23:34     Titel:
  Antworten mit Zitat      
Hallo,

gegenwärtig wählt ode45 je nach Durchlauf unterschiedliche Schritte, d.h. die Länge von c_A ist unterschiedlich. Das ist wohl nicht sinnvoll. Eine mögliche Wahl wäre
Code:
X_INTERVAL=linspace(X_START, X_END);


FinDiffRelStep sollte nicht klein, sondern relativ groß (z.B. 1e-3) gewählt werden.

Momentan minimierst du zudem die Summe der Quadrate von c_A - ist das gewollt?

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

Forum-Newbie

Forum-Newbie


Beiträge: 8
Anmeldedatum: 27.05.13
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 12.02.2015, 01:44     Titel:
  Antworten mit Zitat      
Danke Harald ! Dein Tip war wohl die Ursache des Problems, nachdem ich deinen vorgeschlagenen Code verwendet habe, funktioniert das Problem wie gewollt !
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.