Hallo,
ich beschäftige mich derzeit mit einer Programmierung für nichtlineare Ausgleichsprobleme und möchte hierfür den lsqnonlin()-Befehl nutzen. Meine Berechnung läuft zwar auch durch, aber das geplottete Ergebnis passt nicht zu meiner Punktwolke, durch die die Funktion letztlich laufen soll.
Mein Code siht bis dato wie folgt aus:
Code:
function main
%Punktwolke t,y-Werte
m.t = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20];
m.y = [25,22,21,19,17.5,16,14.8,13.5,12.8,12,11,10,9.5,9,8.2,7.5,7.1,6.7,6.5,6.2];
p0 = [000]; %Startwertbedingung
p = lsqnonlin(@(p)minFunc(p,m),p0); %lsqnonlin-Löser
figure(1);
plot(m.t,m.y,'+b'); %Plot der Punktwolke
hold on;
plot(m.t,fitFunc(m.t,p)); %Plot der "best-fit-Funktion"
title('lsqnonlin-Löser') %Titel
legend('Data','Best fit') xlabel('t') %Achsenbeschriftung
ylabel('y')
a = p(1); %Ausgabe der Parameter a,b &c
b = p(2);
c = p(3);
str1 = ['Parameter a = ' num2str(p(1))];
str2 = ['Parameter b = ' num2str(p(2))];
str3 = ['Parameter c = ' num2str(p(3))];
disp(str1) disp(str2) disp(str3) end
%%
function y = fitFunc(t,p)
y = zeros(size(t)); %Länge des Intervalls
for i = 1:length(t)
y(i) = p(1)+p(2)*exp(-p(3)*t(i)); %zu untersuchende Funktion
end end
%%
function J = minFunc(p,m)
J = sum((m.y-fitFunc(m.t,p)).^2);
end
%Warning: Trust-region-reflective algorithm requires at least as many equations as variables; using Levenberg-Marquardt algorithm
instead.
> In lsqncommon at 56
In lsqnonlin at 237
In lsqnonlin20 at 10
Solver stopped prematurely.
lsqnonlin stopped because it exceeded the function evaluation limit,
options.MaxFunEvals = 600(the default value).
Parameter a = 3.8961
Parameter b = 3.8979
Parameter c = -0.021466
Gibt es die Möglichkeit die Anzahl an Iteration im lsqnonlin-Verfahren zu erhöhen oder habe ich einfach einen Fehler in der Programmierung was zu der Abweichung führt?
Der Fit ist aber dennoch nicht gut. Das liegt daran, dass du lsqnonlin ungünstig verwendest: du summierst die quadrierten Abweichungen schon auf, der Sinn von lsqnonlin ist aber, dass du nur die quadrierten Abweichungen zurückgibst und der Solver das dann komponentenweise auf 0 bringt.
Wenn du das machst, konvergiert der Solver viel schneller und besser, und du brauchst die Optionen gar nicht mehr anzupassen.
Danke nochmals für deine Antwort Harald. Ich habe den Quellcode nochmals überarbeitet und komme nun zu einem schönen Ergebnis. Der Quellcode sieht dabei wie folgt aus:
Code:
% ----------------------------------------------------------------------- % Matlab-Löser "lsqnonlin" für nichtlineare Ausgleichsprobleme % n = 10 Messpunkte % ----------------------------------------------------------------------- clc% Leeren des Command Window clearall% Leeren des Workspace closeall% Schließung aller Fenster
p0=[2,22,0.1]; % Startwerte Parameter
n = length(t);
for i=1:n % Aufbau des Vektors in y
yn(1,i)=y(1,i);
end for i=1:n % Aufbau des Vektors in t
tn(1,i)=t(1,i);
end % ----------------------------------------------------------------------- % zu untersuchende Funktion % -----------------------------------------------------------------------
f = @(p)(p(1)+p(2)*exp(-p(3)*tn))-yn;
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.