Verfasst am: 11.02.2014, 19:03
Titel: Least Squares Verfahren optimieren
Servus liebe Matlaber,
ich möchte für meine Diplomarbeit mit meinem GUI verschiedene Modelle an experimentell gewonnene Messdaten, die ich in Form von Kraft-Weg-Kurven darstelle, anritten. Um den "Best fit" zu bekommen, nutze ich das Least Squares Verfahren, und zwar im Moment so:
Code:
for E_zw = 1:1:250 %E_zw ist der Parameter, den ich bestimmen möchte. D. h. für welchen E_zw - Wert ist die Differenz zwischen den ermittelten Messwerten für die Kraft und den mit dem Modell berechneten Werten, bzw. die Fehlerquadratsumme am kleinsten
Eeff_kehr(E_zw) = ((1-(v_zelle^2))/(E_zw))+((1-(v_ind^2))/(E_ind));
Eeff(E_zw) = 1./Eeff_kehr(E_zw);
for k = 1:length(newdata(:,2)) %Berechnung des Kraftvektors mit einem Modell
Kraft(k) = (((4/3)*(Eeff(E_zw)/(1-v_zelle^2))*(Reff^0.5)*((newdata(k,1)*0.000000001)^1.5))).*10^12;
Kraft_trans = Kraft.';
end;
Ich habe jedoch leider das Gefühl, dass mit meiner Methode nicht immer der "Best fit" herauskommt und in meiner Grafik angezeigt wird... Auch kann ich so natürlich nur ganze Zahlen für E_zw bestimmen, worunter die Genauigkeit auch ein wenig leidet. Daher 2 Fragen:
1. Wie könnte ich E_zw auch genauer, z. B. auf 2 Nachkommastellen, bestimmen? Ich kann ja die Schrittweite bei der Schleife anpassen, aber dann funktioniert
nicht mehr...
2. Gibt es eine Möglichkeit meinen Code zu dem Least Squares Verfahren zu optimieren, wodurch ich vielleicht auch genauere Ergebnisse bekomme?
Vielen herzlichen Dank schon einmal für eure Hilfe! Dieses Forum hat mir schon so viel weitergeholfen, ich hoffe ihr lasst mich auch dieses Mal nicht im Stich
danke für den Hinweis. Ich habe es jetzt mit lsqcurvefit gemacht und der Fit sieht so aus wie ich es mir vorstelle. Hier der Code dazu:
Code:
% --- Executes on button press in hertzkugel. function hertzkugel_Callback(hObject, eventdata, handles) % hObject handle to hertzkugel (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA)
% Hint: get(hObject,'Value') returns toggle state of hertzkugel
newdata = handles.newdata;
newdata = cell2mat(newdata);
data = handles.data;
Reff = 0.000000025;
y = newdata(:,2);
t = newdata(:,1);
axes(handles.modelplot);
cla(handles.modelplot, 'reset');
scatter((t./1000), y, 'g');
hold on;
plot((t./1000), F(x,t),'rx-');
title('Berstkurve mit Modelfit');
xlabel('Deformation [µm]');
ylabel('Kraft [µN]');
legend('Berstkurve', 'Hertz Modell Kugel-Halbraum');
hold off;
set(handles.ezedittext,'String',x(1));
for j = 1:length(data)
N = get(handles.(['radiobutton' num2str(j)]),'String');
A = get(handles.(['radiobutton' num2str(j)]),'Value');
if A == 1
Index = sscanf(N, '%d');
end;
end;
new_row = [x(1)];
modelwertematrix(Index,1) = [modelmatrix;new_row];
Ich wähle also über Radiobuttons verschiedene (ca. 60) Messreihen aus, diese werden dann geplottet. Bei Aktiviertung der Checkbox für das oben beschriebene Modell wird dann der Modelfit mit angezeigt, so soll es sein.
Jetzt noch eine (vielleicht dumme) Frage. Im Moment nutze ich
for j = 1:length(data)
N = get(handles.(['radiobutton' num2str(j)]),'String');
A = get(handles.(['radiobutton' num2str(j)]),'Value');
if A == 1
Index = sscanf(N, '%d');
end;
end;
new_row = [x(1)];
modelwertematrix(Index,1) = [modelmatrix;new_row];
um eine Matrix mit den erhaltenen Ergebniswerten (x(1)) zu füllen, um sie dann in einem anderen Callback als .txt abzuspeichern.
Wie erhalte ich die x(1)-Werte für alle Messreihen? Ich habe es mit einer for-Schleife probiert, da wird die Matrix dann aber von 1:length(newdata) mit demselben x(1)-Wert (für die Messreihe, deren Radiobutton geklickt ist) gefüllt...
Im Endeffekt möchte ich mit der Aktivierung der Checkbox für das Modell sofort alle Werte berechnen und in einer Matrix abspeichern lassen. Gibt es da einen Weg?
Vielen Dank für deine/eure Hilfe!!
Grüße,
Peedschee
vielen Dank für deine Rückmeldung. Ok, dann versuche ich mein Problem mal näher zu erläutern.
Mit dem oben genannten Code (innerhalb eines Checkbox-Callbacks) und lsqcurvefit fitte ich ein Modell an eine Messwertreihe (Kraft-Weg-Kurve) und plotte dann beide Kurven in einem Graphen. Die Messwertreihen habe ich vorher importiert (ca. 60 Stück) und die wähle ich mit Radiobuttons an. D. h. ich wähle z. B. Radiobutton5 aus, aktiviere die Checkbox für den Modellfit und es erscheinen beide Kurven im Graphen. Mit
for j = 1:length(data)
N = get(handles.(['radiobutton' num2str(j)]),'String');
A = get(handles.(['radiobutton' num2str(j)]),'Value');
if A == 1
Index = sscanf(N, '%d');
end;
end;
new_row = [x(1)];
modelwertematrix(Index,1) = [modelmatrix;new_row];
frage ich nun ab, welcher Radiobutton aktiviert ist und schreibe dann den für diese Messwertreihe erhaltenen Wert (x(1) mittels lsqcurvefit bekommen) in die modelwertematrix. Die Matrix wird dann laufend, mit jedem Radiobutton-Klick aktualisiert. Geht das auch einfacher, also vielleicht ohne Überschreiben von N und A?
So weit so gut...
Ich möchte jetzt, wenn ich die Checkbox aktiviere, zwar den Modellfit nur für den gecheckten Radiobutton im Graphen anzeigen, aber den Wert x(1) mit lsqcurvefit für JEDE Messwertreihe berechnen und in einer Matrix speichern. Einfach, damit ich nicht jeden Radiobutton aktivieren und die Checkbox checken muss, damit ich alle Werte in meine Matrix bekomme.
Ich hoffe, ich habe jetzt ein wenig Licht ins Dunkel bringen können
du schreibst von x(1), aber wo soll dieses x(1) denn herkommen?
Statt Value jedes einzelnen Radiobuttons abzufragen, kannst du die 'SelectedObject' - Eigenschaft der Buttongroup abfragen.
Zitat:
Ich möchte jetzt, wenn ich die Checkbox aktiviere, zwar den Modellfit nur für den gecheckten Radiobutton im Graphen anzeigen, aber den Wert x(1) mit lsqcurvefit für JEDE Messwertreihe berechnen und in einer Matrix speichern. Einfach, damit ich nicht jeden Radiobutton aktivieren und die Checkbox checken muss, damit ich alle Werte in meine Matrix bekomme.
In welche Matrix?
Es dürfte am geschicktesten sein, das in der OpeningFcn zu machen oder wenn sich die Messwertreihen ändern.
x(1) ist sozusagen mein Anpassungsparameter für den optimalen Fit an meine Messwertreihen.
Danke für den Hinweis auf die SelectdObject-Eigenschaft, ich werd mal schauen ob ich das damit besser hinbekomme.
Ich würde dann einfach irgendeine Matrix, z.B. wertematrix_komplett, preallocieren und die möchte ich dann per Checkbox-Aktivierung sofort mit allen Werten befüllen. Es geht hierbei nur um die x(1)-Werte für alle Messwertreihen. Wahrscheinlich stehe ich gerade einfach voll auf dem Schlauch, aber ich möchte NICHT mit
Code:
for j = 1:length(data)
N = get(handles.(['radiobutton' num2str(j)]),'String');
A = get(handles.(['radiobutton' num2str(j)]),'Value');
if A == 1
Index = sscanf(N, '%d');
end;
end;
new_row = [x(1)];
modelwertematrix(Index,1) = [modelmatrix;new_row];
die Matrix zeilenweise zu befüllen - d.h. es wird die Zeilennummer befüllt, die dem Index des aktivierten Radiobuttons entspricht - sondern meine wertematrix_komplett sofort mit allen berechneten x(1)-Werten befüllen. Das muss doch irgendwie mit einer Schleife gehen oder nicht?
Sorry für die vielleicht blöde Frage, aber ich kriege es gerade irgendwie nicht auf die Reihe...
Hallo,
ich versuche schon die ganze Zeit eine Lösung zu finden, aber ich komme einfach nicht weiter...
Ich möchte lsqcurvefit mit der dazugehörigen Funktion in eine fortschleife verpacken, damit ich den Anpassungsparameter x (hatte ich vorher als x(1) definiert, ist aber nicht so relevant) für alle meine Messwertreihen berechnen kann. Einzeln klappt das ja auch wunderbar, aber eben nicht mit einem Klick für alle Datensätze.
Ich habe also die Funktion
Code:
F = @(x,xdata)(((4/3)*(1./(((1-(v_zelle.^2))...
/(x))+((1-(v_ind.^2))/(E_ind)))/(1-v_zelle.^2))...
*(Reff.^0.5)*((t*0.000000001).^1.5))).*10.^12;
mein x und ich habe den Wert, für den die Modellkurve am besten an die Messwerte gefittet ist. Passt also.
Wie bekomme ich das ganze jetzt in einer Schleife hin? Sorry, aber ich check es einfach nicht... Ich habe also beispielsweise 10 Datensätze und für jeden möchte ich mein x berechnen.
Die benötigten Werte sind
Code:
Reff = 0.000000025;
y = newdata(:,2);
t = newdata(:,1);
ich blicke bei deinem Code leider nicht durch.
Du brauchst eine for-Schleife, die lsqcurvefit mit verschiedenen t und y aufruft. Welche das sind, weiß ich nicht.
Vielleicht kannst du das Problem ja auf ein ähnliches mit wenigen Codezeilen reduzieren? Dann kann man dir die Lösung daran aufzeigen, und du kannst das auf dein originales Problem übertragen.
Grüße,
Harald
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.