Verfasst am: 23.03.2020, 12:45
Titel: Nichtlinearer Fit - Fehler beim Iterieren
Hallo Leute,
im Folgenden habe ich eine kurzen Code gepostet, mit dem ich vorab simulierte Messdaten an eine Modellkurve anpassen möchte (und alles am Ende normiert haben möchte). Dabei taucht die folgende Fehlermeldung auf:
Code:
Field assignment to a non-structure array object.
Error in createOptionFeedback (line33)
options.(stopTestOptions{k}) = [];
Error in prepareOptionsForSolver (line57)
optionFeedback = createOptionFeedback(options);
Error in lsqnonlin(line170) [options, optionFeedback] = prepareOptionsForSolver(options, 'lsqnonlin');
Ich hatte es schon einmal soweit, dass es ohne Fehlermeldung gelaufen ist, habe aber zwischenzeitlich zu viel herumprobiert, sodass ich nicht mehr darauf komme. Vorher war das Problem, dass der Solver erst gar nicht begonnen hat zu iterieren, da immer lokale Minima möglich waren. Ich habe mir sehr viele Beiträge und Artikel im Internet durchgelesen, jedoch lies sich dieses Problem bis jetzt nicht lösen. Daher wäre ich über Anmerkungen und Tipps sehr dankbar.
%% Fit % Schätzwerte
alpha = 1.38 * L^2 ./ (th * pi.^(2));
tc = (L/pi)^2/alpha;
C = 1.5;
% Modellfunktion
fun = @(p) p(2)*p(1)*(1+2*(1-exp(-n(2:end)'.^2*tau)).*(p(1)./n(2:end).^2/tau)');
p0 = [tc, C];
lb = [0,0];
ub = [1,10];
p = lsqnonlin(fun,p0,xdata,ydata,lb,ub)
%% Plot % Plot simulierte Messdaten plot(xdata,ydata/max(ydata),'g');
hold on
% Plot Schätzwerte plot(xdata,fun(p0)/max(fun(p0)),'b');
hold on;
% Plot optimale Parameter plot(xdata,fun(p)/max(fun(p)),'r');
hold off
du rufst lsqnonlin auf, verwendest aber die Syntax von lsqcurvefit. Dazu passt aber wiederum die Form des Function Handles nicht.
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 ;)
Der Solver iteriert jetzt 13 mal. Das Ergebnis ist aber bei Weitem noch nicht das gewünschte. Meine Eingabe "levenberg-marquardt" in den Optionen scheint er wohl nicht zu übernehmen. Die neue Meldung sieht so aus:
firstorderopt: 1.0409e-07
iterations: 13
funcCount: 42
cgiterations: 0
algorithm: 'trust-region-reflective'
stepsize: 0.0436
message: 'Local minimum possible.↵↵lsqnonlin stopped because the final change in the sum of squares relative to ↵its initial value is less than the default value of the function tolerance.↵↵Stopping criteria details:↵↵Optimization stopped because the relative sum of squares (r)is changing↵by less than options.FunctionTolerance = 1.000000e-06.↵↵Optimization Metric Options↵relative change r = 4.22e-07 FunctionTolerance = 1e-06(default)'
ein möglicher Haken: du wolltest wohl irgendeine Kurvenanpassung machen. Dein jetziger Aufruf verwendet aber die Daten gar nicht.
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 ;)
nun kommt wieder die Meldung bzgl. des Minimums, welche bei mir immer Probleme bereitet:
Code:
firstorderopt: 8.4513e-07
iterations: 16
funcCount: 51
cgiterations: 0
algorithm: 'trust-region-reflective'
stepsize: 0.0086
message: 'Local minimum found.↵↵Optimization completed because the size of the gradientis less than↵the default value of the optimality tolerance.↵↵Stopping criteria details:↵↵Optimization completed: The first-order optimality measure, 8.451340e-07,↵is less than options.OptimalityTolerance = 1.000000e-06.↵↵Optimization Metric Options↵relative first-order optimality = 8.45e-07 OptimalityTolerance = 1e-06(default)'
diese Meldung ist kein Problem, sondern besagt, dass ausgehend vom Startwert ein Minimum gefunden wurde. Das einzige mögliche Problem ist, dass es sich um ein lokales statt dem globalen Minimum handelt. Das kann durch Änderung der Startwerte oder Wahl eines Lösers aus der Global Optimization Toolbox gelöst werden.
Mir kommt aber die Problemformulierung weiterhin suspekt vor. Du verwendest jetzt zwar ydata, aber immer noch kein ydata. Vermutlich willst du die Abweichungen auf 0 bringen:
fun = @(p) p(2)*(1+2*sum((1-exp(-n(2:end)'.^2.*xdata/p(1))) .* 1./(n(2:end)'.^2.*xdata/p(1)) ) ) - ydata
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 Global Optimization Toolbox steht mir leider nicht zur Verfügung.
Was empfiehlst du alternativ? Hab schon einiges mit fminsearch und fminunc erfolglos versucht.
Die "ydata" habe ich tatsächlich unterschlagen.
Genau, ich möchte die Modellkurve so gut wie möglich an die Messwerte anpassen (und am besten noch die Güte des Fits beurteilen).
lsqnonlin oder lsqcurvefit mit vernünftigen Startwerten sind gute Lösungen.
Wenn keine vernünftigen Startwerte bekannt sind, kann man versuchen, über verschiedene Startwerte zu iterieren.
Um die Güte des Fits gleich mitzubestimmen, könntest du fitnlm verwenden. Hinsichtlich der Ergebnisse sollte das aber wenig Unterschied machen.
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 ;)
vielen Dank Dir soweit!
Es scheint wohl vorerst zu funktionieren.
Gruß
mstp91
Einstellungen und Berechtigungen
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.