Hallo, ich habe ein Problem bei der Schätzung von Parametern.
Der Code läuft, allerdings bekomme ich als Ergebnis der Schätzung die Parameterwerte, mit denen ich starte. Geschätzt werden sollen die Parameter(1) bis Parameter(10)
Der Code ist wie folgt:
Code:
%Programm für Parameterschätzung
global c0 Data tRange %Global definition of needed variables
Data= xlsread('BI130_Average_Daten.xlsx','D3:S30'); %Experimental Data
tRange = Data(1:28,1);
%%
%Define starting values from experimental data
c0(1) = Data(1,2);
c0(2) = Data(1,4);
c0(3) = Data(1,6);
c0(4) = Data(1,8);
c0(5) = Data(1,10);
c0(6) = Data(1,12);
c0(7) = Data(1,14);
c0(8) = Data(1,16);
%%
%Definition of model parameters
%Sum of squares
Sum_of_squares=Weighting(1)*sum((abs(c(:,1)-Data(1:28,2))*Magnitude(1)).^2)+...
Weighting(2)*sum((abs(c(:,2)-Data(1:28,4))*Magnitude(2)).^2)+...
Weighting(3)*sum((abs(c(:,3)-Data(1:28,6))*Magnitude(3)).^2)+...
Weighting(4)*sum((abs(c(:,4)-Data(1:28,8))*Magnitude(4)).^2)+...
Weighting(5)*sum((abs(c(:,5)-Data(1:28,10))*Magnitude(5)).^2)+...
Weighting(6)*sum((abs(c(:,6)-Data(1:28,12))*Magnitude(6)).^2);
end
1.) Ask MATLAB Documentation
2.) Search gomatlab.de, google.de or MATLAB Answers
3.) Ask Technical Support of MathWorks
4.) Go mad, your problem is unsolvable ;)
Hallo Harald,
danke für die Antwort. Als ich die initialen Werte änderte, veränderten sich auch die geschätzten Parameter, allerdings zu den gleichen Werten wie die Initialen.
Die Toolbox besitze ich, stoße damit allerdings auf Probleme.
%Sum of squares
Sum_of_squares=Weighting(1)*sum((abs(c(:,1)-Data(1:28,2))*Magnitude(1)).^2)+... %Xv
Weighting(2)*sum((abs(c(:,2)-Data(1:28,4))*Magnitude(2)).^2)+... %Xt
Weighting(3)*sum((abs(c(:,3)-Data(1:28,6))*Magnitude(3)).^2)+... %Viability
Weighting(4)*sum((abs(c(:,4)-Data(1:28,8))*Magnitude(4)).^2)+... %Glc
Weighting(5)*sum((abs(c(:,5)-Data(1:28,10))*Magnitude(5)).^2)+... %cLac
Weighting(6)*sum((abs(c(:,6)-Data(1:28,12))*Magnitude(6)).^2)+... %Gln
Weighting(6)*sum((abs(c(:,7)-Data(1:28,14))*Magnitude(6)).^2)+...
Weighting(6)*sum((abs(c(:,8)-Data(1:28,16))*Magnitude(6)).^2);
end
bringt mir den Fehler:
Error using lsqncommon (line 64)
The Levenberg-Marquardt algorithm does not handle bound constraints and the trust-region-reflective algorithm requires at least as many equations as variables; aborting.
Error in lsqnonlin (line 252)
lsqncommon(funfcn,xCurrent,lb,ub,options,defaultopt,allDefaultOpts,caller,...
Ein Problem in der Zielfunktion: Weighting ist Eingabeargument der Zielfunktion und wird dann überschrieben. Das ist nicht sinnvoll.
Du hattest in deinem ursprünglichen Problem ja auch keine Bound Constraints. Lass sie doch mal weg?
Grüße,
Harald
_________________
1.) Ask MATLAB Documentation
2.) Search gomatlab.de, google.de or MATLAB Answers
3.) Ask Technical Support of MathWorks
4.) Go mad, your problem is unsolvable ;)
Die Optimierung läuft, allerdings war der Initial Point direkt in einem lokalen Minimum. Nach ändern der Startwerte befindet er sich immer noch in einem lokalen Minimum.
Es ist tatsächlich egal, mit welchen Werten ich den Optimierer füttere, er befindet sich immer im Minimum. Die Exitflag spuckt als Ergebnis 1 aus.
Mein Verdacht ist, dass das Problem woanders liegt. Wenn du unterschiedliche Startwerte wählst, kommen denn dann zumindest als Zielfunktionswert andere Werte raus?
Nutze doch mal den Debugger und schau, mit welchen Parameters die Funktion gefüttert wird. Ändert sich dann die Rückgabe von ode45? Ändern sich die weiteren Variablen?
Hast du die Tipps im Link von 9:48 versucht?
Viel mehr kann ich leider nicht dazu sagen, ohne das komplett selbst ausführen zu können.
Grüße,
Harald
_________________
1.) Ask MATLAB Documentation
2.) Search gomatlab.de, google.de or MATLAB Answers
3.) Ask Technical Support of MathWorks
4.) Go mad, your problem is unsolvable ;)
setze einen Haltepunkt in die Zeile, die den Fehler wirft und schaue dir die Dimensionen der beteiligten Variablen an. Insbesondere: hat y 28 Zeilen?
Grüße,
Harald
_________________
1.) Ask MATLAB Documentation
2.) Search gomatlab.de, google.de or MATLAB Answers
3.) Ask Technical Support of MathWorks
4.) Go mad, your problem is unsolvable ;)
y hat 54 Zeilen, also mehr als die Data Exceldatei mit 28.
Die Größe von y resultiert aus der variablen Step Size des ODE Solvers. Von einer festen Step Size, falls überhaupt möglich, wird generell abgeraten, sofern ich bisher gelesen habe.
Das Problem ist größer als ich dachte:
Meine Excel besteht nur aus insgesamt 28 Werten in einem Zeitbereich von 0 bis über 1000 Stunden. Der Solver hat schon in den ersten 72 Stunden 54 Messwerte genommen, danach sollte er in eine Schleife übergehen und weitere 72 Stunden mit anderen Initialwerten messen.
Mein Datenset ist also weitaus kleiner als die Steps des Solvers.
Wäre es sinnvoll, den solver laufen zu lassen, allerdings die Werte nur zu den gleichen Zeiten wie im Datenset anzeigen zu lassen?
du hast Werte zu bestimmten Zeiten. Du musst ode45 dazu bringen, Werte zu diesen Zeiten zu berechnen. Das kannst du erreichen, indem du einen Vektor mit mehr als 2 Elementen als tspan angibst.
Aktuell scheinst du das ja schon zu tun und trange mit 28 Werten zu verwenden? Das in einer Schleife aufgerufen und aneinandergehängt passt dann aber halt nicht zu den 28 Vergleichswerten.
Das Problem mit Weighting, auf das ich Gestern 17:19 hingewiesen hatte, besteht übrigens immer noch.
Grüße,
Harald
_________________
1.) Ask MATLAB Documentation
2.) Search gomatlab.de, google.de or MATLAB Answers
3.) Ask Technical Support of MathWorks
4.) Go mad, your problem is unsolvable ;)
die Schleife habe ich wieder entfernt, macht doch keinen Sinn. Durch das entfernen der Schleife scheint auch der Fehler mit den unterschiedlich großen Matrixen behoben zu sein, was für mich nicht viel Sinn ergibt. :
Zitat:
Weighting ist Eingabeargument der Zielfunktion und wird dann überschrieben. Das ist nicht sinnvoll.
Ich verstehe leider nicht ganz wo das überschrieben wird.
Für mich schon. trange sind 28 Werte, du bekommst also 28 Werte von ode45, und die kannst du mit anderen 28 Werten vergleichen.
Zitat:
Ich verstehe leider nicht ganz wo das überschrieben wird.
In deiner Funktion.
function Sum_of_squares=Objective_BI130_1(Parameters,Weighting)
%Weighting vector
Weighting(1)=100;
...
Grüße,
Harald
_________________
1.) Ask MATLAB Documentation
2.) Search gomatlab.de, google.de or MATLAB Answers
3.) Ask Technical Support of MathWorks
4.) Go mad, your problem is unsolvable ;)
ein struct Array geschrieben mit 10 Feldern, welche die jeweiligen Zeitpunkte beinhalten.
Mit der for-Schleife
Zitat:
n=10;
t=0;
y=[0,0,0,0,0,0,0,0];
%Laufdauer = [0 70.8;71.28 143.52 ;144 216.24;217.2 287.04;288.24 358.32;358.42 429.22;429.32 474.776 545.192;545.292 567.991 615.391 684.631;684.731 707.675 754.876 825.052; 825.152 847.448 894.348 965.532 1059.852]; %Laufdauer der einzelnen Stufen
for k = 1:n
Laufdauer= p(k,;
[tSpeicher,ySpeicher]=ode45(@Model_BI130_1,Laufdauer,c0_global,Parameters);
c0 = [ Xv0(k); Xt0(k); Viab0(k); cGlc0(k); cLac0(k); cGln0(k); cAmm0(k); v0(k)]; %Vector that contains all the Initial values
t = vertcat(t,tSpeicher);
y= vertcat(y,ySpeicher);
will ich nun für jede Iteration in ein neues Feld des Structs greifen und mir die Daten holen.
Scheinbar erkennt er aber die Zeit in dem Struct nicht als Spanne an, denn
Zitat:
Error using odearguments (line 21)
When the first argument to ode45 is a function handle, the tspan argument must have at least two elements.
Das ist dreifach gemoppelt. Time ist eine Struktur, die eine Struktur enthält, die Cells enthält.
Für diese Liste brauchst du doch gar keine Namen, also viel einfacher ein "normales" Cell Array:
Code:
p = cell(1,10);
p{1}= [070.8];
p{2}= [71.28143.52];
...
1.) Ask MATLAB Documentation
2.) Search gomatlab.de, google.de or MATLAB Answers
3.) Ask Technical Support of MathWorks
4.) Go mad, your problem is unsolvable ;)
Die ODE berechnet jetzt die y-Werte zu den vorher definierten Zeiten (aus einem Cell Array) und noch weiteren. Die Ergebnisse werden in (t,y) gespeichert.
Wie kann ich die y-Werte zu den Cell-Array Zeiten aus (t,y) extrahieren und in eine neue Variable schreiben?
Mein Ziel ist es, eine neue Variable, quasi ein komprimiertes y herzustellen, welches die y-Werte zu den Zeiten aus der p-Cell enthält und die untereinander auflistet. zum Beispiel. (Wobei jedes p für mehrere Zeitwerte steht).
Mein Ansatz war, ein weiteres Cell-Array zu erstellen, die Werte aus y da händisch einzutragen, aus dieser cell ein struct zu machen und von einem Struct zu einem table. Das Problem dabei ist, die table wird Richtung Columns verlängert, nicht Richtung rows. Außerdem ist es recht umständlich.
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
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.