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

Modellfit mittels fminunc basierend auf Messdaten

 

MatlabNewbie2022
Forum-Newbie

Forum-Newbie


Beiträge: 7
Anmeldedatum: 24.10.22
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 24.10.2022, 14:24     Titel: Modellfit mittels fminunc basierend auf Messdaten
  Antworten mit Zitat      
Hi zusammen,

ich habe Messdaten, mit Hilfe derer ich ein Modell fitten möchte. Für den Fit möchte ich den Befehl "fminunc" verwenden, da ich später ein Modell mit mehreren Koeffizienten und Variablen haben werden. Um mein Skript aber überhaupt zum laufen zu bekommen, habe ich es reduziert und ihr findet es im folgenden als Minimalbeispiel:
Code:

kB = 8.617 * 1e-5; % in eV/K

x1 = [233; 264; 295; 326]; % temperature
x2 = [420000; 970000; 3800000; 10000000]; % lifetime

% Function to solve
fun = @(A0,EA) ((A0 .* exp(EA/kB./x1)) - x2).^2;
x0 = [2.7 * 1e10, 0.220];   % initial values

% Solve
[p, fval] = fminunc(fun,x0);
 


Allerdings bekomme ich dafür nur eine Fehlermeldung. Kann mir jemand weiterhelfen, wo hier mein Fehler liegt?

Besten Dank im Voraus!

VG Sebastian
Private Nachricht senden Benutzer-Profile anzeigen


Harald
Forum-Meister

Forum-Meister


Beiträge: 24.425
Anmeldedatum: 26.03.09
Wohnort: Nähe München
Version: ab 2017b
     Beitrag Verfasst am: 24.10.2022, 14:46     Titel:
  Antworten mit Zitat      
Hallo,

fminunc möchte ein Function Handle, das ein Argument entgegennimmt. Zudem willst du wahrscheinlich über die Abweichungen summieren?
Code:
% p(1) = A0, p(2) = EA
fun = @(p) sum(((p(1) .* exp(p(2)/kB./x1)) - x2).^2);


Für das Fitten von Modellen geeigneter wäre lsqcurvefit:
Code:
fun = @(p, x1) p(1) .* exp(p(2)/kB./x1);
[x, resnorm] = lsqcurvefit(fun,x0, x1, x2)


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 ;)
Private Nachricht senden Benutzer-Profile anzeigen
 
MatlabNewbie2022
Themenstarter

Forum-Newbie

Forum-Newbie


Beiträge: 7
Anmeldedatum: 24.10.22
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 24.10.2022, 14:57     Titel:
  Antworten mit Zitat      
Hallo,

vielen Dank für die schnelle Antwort. Ich habe mich nicht präzise ausgedrückt.

Der Ausdruck "A0 .* exp(EA/kB./x1)" ist nur ein Term, d.h. wenn mein Skript einmal läuft, werden später noch weitere derartige Terme hinzukommen. Insgesamt werden es 9 Koeffizienten und 5 Variablen sein. Meines Wissens kann "lsqcurvefit" das nicht mehr abbilden.
Diese Koeffizienten (in meinem Minimalbespiel sind das A0 und EA) sollen derart gefittet werden, dass die Funktion inkl. dieser gefitteten Koeffizienten das gesamte Ergebnis meiner Versuche bestmöglich abbildet (jeder Koeffizient ist eine Konstante für den gesamten Versuchsdatensatz). In meinem Minimalbeispiel hatte ich vier Versuchsdurchläufe bei verschiedenen Temperaturen (x1), woraus sich unterschiedliche Lebensdauern (x2) ergeben haben.

VG Sebastian
Private Nachricht senden Benutzer-Profile anzeigen
 
Harald
Forum-Meister

Forum-Meister


Beiträge: 24.425
Anmeldedatum: 26.03.09
Wohnort: Nähe München
Version: ab 2017b
     Beitrag Verfasst am: 24.10.2022, 16:44     Titel:
  Antworten mit Zitat      
Hallo,

stimmt, lsqcurvefit kann nur eine Variable.
Um dennoch den Least Squares - Aspekt nicht zu verlieren, würde ich zu lsqnonlin statt fminunc raten.

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 ;)
Private Nachricht senden Benutzer-Profile anzeigen
 
MatlabNewbie2022
Themenstarter

Forum-Newbie

Forum-Newbie


Beiträge: 7
Anmeldedatum: 24.10.22
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 25.10.2022, 12:25     Titel:
  Antworten mit Zitat      
Habe es jetzt mal mit lsqnonlin probiert und das Skript läuft auch schon mal durch. Folgende Code habe ich dafür verwendet:

Code:

kB = 8.617 * 1e-5; % in eV/K
x1 = [233; 264; 295; 326];
x2 = [420000; 970000; 3800000; 10000000];

% Function to solve
fun = @(x) sum((x(1) .* exp(-x(2)/kB ./x1) - x2).^2);
x0 = [2.5 * 1e10, 0.21];   % initial values

[y, resnorm] = lsqnonlin(fun, x0);

A1 = y(1);
EA = y(2);

temperature = 220 : 0.01 : 340;    % temperature vector for plot
for i = 1:length(temperature)
    cycles(i) = A1 * exp(-EA/ kB / temperature(i));  % cycles correspond to lifetime
end

figure
plot(temperature, cycles,'b',x1,x2,'or')
 


Allerdings habe ich noch das Problem, dass die zwei Koeffizienten A1 (=x(1)) und EA (=x(2)) nach dem Durchlauf weiterhin den Startwerten entsprechen (egal, welche Startwerte ich eingebe). Für einen Abgleich meines Minimalbeispiels habe ich die Lösung auch mal mit lsqcurvefit gefittet und auf dem Bild im Anhang sind die mit lsqcurvefit gefitteten Koeffizienten abgebildet. Die resultierende Kurve sieht auch plausibel aus. lsqnonlin findet aber diese Werte nicht. Kannst du dir vorstellen, woran das liegt?

Fit_with_lsqcurvefit.png
 Beschreibung:

Download
 Dateiname:  Fit_with_lsqcurvefit.png
 Dateigröße:  43.94 KB
 Heruntergeladen:  89 mal
Private Nachricht senden Benutzer-Profile anzeigen
 
MatlabNewbie2022
Themenstarter

Forum-Newbie

Forum-Newbie


Beiträge: 7
Anmeldedatum: 24.10.22
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 25.10.2022, 12:39     Titel:
  Antworten mit Zitat      
Eine Korrektur von "fun" in lsqnonlin führt zumindest dazu, dass EA (=x(2)) sich verändert. A1 (=x(1)) bleibt jedoch weiterhin immer der Startwert:

Code:
[y, resnorm] = lsqnonlin(@(x) fun(x), x0);


Fehlt möglicherweise lsqnonlin noch eine Information?
Private Nachricht senden Benutzer-Profile anzeigen
 
Harald
Forum-Meister

Forum-Meister


Beiträge: 24.425
Anmeldedatum: 26.03.09
Wohnort: Nähe München
Version: ab 2017b
     Beitrag Verfasst am: 25.10.2022, 12:41     Titel:
  Antworten mit Zitat      
Hallo,

du solltest bei lsqnonlin auch das Quadrieren und Summieren weglassen:
Code:
fun = @(x) x(1) .* exp(-x(2)/kB ./x1) - x2;


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 ;)
Private Nachricht senden Benutzer-Profile anzeigen
 
MatlabNewbie2022
Themenstarter

Forum-Newbie

Forum-Newbie


Beiträge: 7
Anmeldedatum: 24.10.22
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 25.10.2022, 12:58     Titel:
  Antworten mit Zitat      
Guter Punkt! Wenn ich für A1 (=x(1)) jetzt den gefitteten Wert aus dem lsqcurvefit -Fit als Startwert einsetze, dann wird EA (x=(2)) richtig approximiert - selbst wenn der Startwert von EA ein gutes Stück daneben liegt Smile

Wenn ich jedoch den Startwert von A1 verändere, wird lediglich EA (noch) bestmöglich gefittet, der gefittete Wert von A1 entspricht allerdings weiterhin dem Startwert (auch wenn ich den Wert nur knapp um den Zielwert variiere) - auch nachdem ich das Summieren und Quadrieren entfernt habe.

Hast du noch eine Idee woran das liegt?
Private Nachricht senden Benutzer-Profile anzeigen
 
Harald
Forum-Meister

Forum-Meister


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

ich würde generell die Parameter in einer ähnlichen Größenordnung wählen. Man kann sich da so behelfen:

Code:
fun = @(x) x(1)*1e9 .* exp(-x(2)/kB ./x1) - x2;
x0 = [1, 0.5];   % initial values

[y, resnorm] = lsqnonlin(fun, x0);

A1 = 1e9*y(1);
EA = y(2);


Generell ist es so, dass dahinter immer ein nichtlineares Optimierungsproblem steht und der Löser ausgehend vom Startwert ein lokales Minimum sucht. Es ist also wichtig, ausreichend gute Startwerte zu haben (was "ausreichend" ist, hängt stark vom Modell ab) oder man muss einen Ansatz für globale Optimierung verwenden, z.B. MultiStart.

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 ;)
Private Nachricht senden Benutzer-Profile anzeigen
 
MatlabNewbie2022
Themenstarter

Forum-Newbie

Forum-Newbie


Beiträge: 7
Anmeldedatum: 24.10.22
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 25.10.2022, 15:35     Titel:
  Antworten mit Zitat      
Alles klar, sieht top aus und bzgl. globaler Optimierung schaue ich mal. Ich versuche jetzt mal, mein Modell mit mehreren Termen aufzubauen und dann mal abwarten, inwieweit es funktioniert. Vielen Dank für deine Hilfe!

Gruß Seb
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 - 2024 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.