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

Least Squares Verfahren optimieren

 

Peedschee
Forum-Anfänger

Forum-Anfänger


Beiträge: 30
Anmeldedatum: 21.10.13
Wohnort: ---
Version: R2013a
     Beitrag Verfasst am: 11.02.2014, 19:03     Titel: Least Squares Verfahren optimieren
  Antworten mit Zitat      
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;

    Kraftcell{E_zw} = Kraft_trans;

    %"Mein" Least Squares Verfahren
    differenz = Kraft_trans-newdata(:,2);
    differenzcell{E_zw} = differenz;
    fq = (differenz.^2);
    fqcell{E_zw} = fq;
    fqs = sum(fq);    
    fqsmatrix(E_zw) = fqs;
    fqsmatrix_trans = fqsmatrix.';
end;
fqs_min = find(fqsmatrix_trans==min(fqsmatrix_trans));
for E_zw = fqs_min
    plot((newdata(:,1)./1000), Kraft_trans,'rx-');   %Für den "besten E_zw-Wert die Funktion plotten
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
Code:
for E_zw = fqs_min
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 Cool

Viele Grüße,
Peedschee
Private Nachricht senden Benutzer-Profile anzeigen


Harald
Forum-Meister

Forum-Meister


Beiträge: 24.501
Anmeldedatum: 26.03.09
Wohnort: Nähe München
Version: ab 2017b
     Beitrag Verfasst am: 14.02.2014, 21:09     Titel:
  Antworten mit Zitat      
Hallo,

warum nutzt du denn nicht vorgefertigte Least-Squares - Methoden, wie lsqnonlin?

Grüße,
Harald
Private Nachricht senden Benutzer-Profile anzeigen
 
Peedschee
Themenstarter

Forum-Anfänger

Forum-Anfänger


Beiträge: 30
Anmeldedatum: 21.10.13
Wohnort: ---
Version: R2013a
     Beitrag Verfasst am: 20.02.2014, 12:25     Titel:
  Antworten mit Zitat      
Hi,

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);

if get(handles.hertzkugel, 'Value') == 1
    if get(handles.editvindenter,'String') == 0.2
        v_ind = 0.2;
    else
        v_ind = str2double(get(handles.editvindenter, 'String'));
    end;
   
    if get(handles.editvzelle,'String') == 0.5
        v_zelle = 0.5;
    else
        v_zelle = str2double(get(handles.editvzelle, 'String'));
    end;
   
    if get(handles.editemodulindenter,'String') == 1000000
        E_ind = 1000000;
    else
        E_ind = str2double(get(handles.editemodulindenter, 'String'));
    end;

F = @(x,xdata)(((4/3)*(1./(((1-(v_zelle.^2))...
    /(x(1)))+((1-(v_ind.^2))/(E_ind)))/(1-v_zelle.^2))...
    *(Reff.^0.5)*((t*0.000000001).^1.5))).*10.^12;

x0 = 1;

[x,resnorm,~,exitflag,output] = lsqcurvefit(F,x0,t,y);

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));
   
modelmatrix = getappdata(0,'ModelData');
modelwertematrix = getappdata(0,'ModelMatrixData');
   
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];
       
set(handles.modeldatatable,'data',modelwertematrix);
setappdata(0,'ModelData',modelmatrix);
setappdata(0,'ModelMatrixData',modelwertematrix);
   
else
    scatter(t, y, 'g');
    title('Berstkurve bis Berstpunkt');
    xlabel('Deformation [nm]');
    ylabel('Kraft [µN]');
    grid on;
    set(handles.ezedittext,'String', []);
    set(handles.editvindenter,'String',0.2);
    set(handles.editvzelle,'String',0.5);
    set(handles.editemodulindenter,'String',1000000);
end;

guidata(hObject, handles);
 


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
Code:

modelmatrix = getappdata(0,'ModelData');
modelwertematrix = getappdata(0,'ModelMatrixData');
   
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];
       
set(handles.modeldatatable,'data',modelwertematrix);
setappdata(0,'ModelData',modelmatrix);
setappdata(0,'ModelMatrixData',modelwertematrix);
 

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
Private Nachricht senden Benutzer-Profile anzeigen
 
Harald
Forum-Meister

Forum-Meister


Beiträge: 24.501
Anmeldedatum: 26.03.09
Wohnort: Nähe München
Version: ab 2017b
     Beitrag Verfasst am: 20.02.2014, 21:30     Titel:
  Antworten mit Zitat      
Hallo,

das ist nun recht viel Code ;)
Kannst du deine Frage etwas konkretisieren?

Was mir auffällt: im unteren Code werden N und A laufend überschrieben - ist das beabsichtigt?

Ansonsten müsste ich verstehen, was du erreichen willst, um dir dabei helfen zu können.

Grüße,
Harald
Private Nachricht senden Benutzer-Profile anzeigen
 
Peedschee
Themenstarter

Forum-Anfänger

Forum-Anfänger


Beiträge: 30
Anmeldedatum: 21.10.13
Wohnort: ---
Version: R2013a
     Beitrag Verfasst am: 20.02.2014, 22:16     Titel:
  Antworten mit Zitat      
Hallo Harald,

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
Code:

modelmatrix = getappdata(0,'ModelData');
modelwertematrix = getappdata(0,'ModelMatrixData');
   
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];
       
set(handles.modeldatatable,'data',modelwertematrix);
setappdata(0,'ModelData',modelmatrix);
setappdata(0,'ModelMatrixData',modelwertematrix);
 

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 Wink

Vielen Dank für deine Hilfe!

Grüße
Private Nachricht senden Benutzer-Profile anzeigen
 
Harald
Forum-Meister

Forum-Meister


Beiträge: 24.501
Anmeldedatum: 26.03.09
Wohnort: Nähe München
Version: ab 2017b
     Beitrag Verfasst am: 21.02.2014, 23:21     Titel:
  Antworten mit Zitat      
Hallo,

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.

Grüße,
Harald
Private Nachricht senden Benutzer-Profile anzeigen
 
Peedschee
Themenstarter

Forum-Anfänger

Forum-Anfänger


Beiträge: 30
Anmeldedatum: 21.10.13
Wohnort: ---
Version: R2013a
     Beitrag Verfasst am: 22.02.2014, 14:34     Titel:
  Antworten mit Zitat      
Hi Harald,

das x(1) kommt aus
Code:

F = @(x,xdata)(((4/3)*(1./(((1-(v_zelle.^2))...
    /(x(1)))+((1-(v_ind.^2))/(E_ind)))/(1-v_zelle.^2))...
    *(Reff.^0.5)*((t*0.000000001).^1.5))).*10.^12;
 


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];
       
set(handles.modeldatatable,'data',modelwertematrix);
setappdata(0,'ModelData',modelmatrix);
setappdata(0,'ModelMatrixData',modelwertematrix);
 

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...

Danke und Grüße,
Peedschee
Private Nachricht senden Benutzer-Profile anzeigen
 
Peedschee
Themenstarter

Forum-Anfänger

Forum-Anfänger


Beiträge: 30
Anmeldedatum: 21.10.13
Wohnort: ---
Version: R2013a
     Beitrag Verfasst am: 26.02.2014, 18:02     Titel:
  Antworten mit Zitat      
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;

%und berechne dann mit

x0 = 1;

[x,resnorm,~,exitflag,output] = lsqcurvefit(F,x0,t,y);
 

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... Sad 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);

if get(handles.hertzkugel, 'Value') == 1
    if get(handles.editvindenter,'String') == 0.2
        v_ind = 0.2;
    else
        v_ind = str2double(get(handles.editvindenter, 'String'));
    end;
   
    if get(handles.editvzelle,'String') == 0.5
        v_zelle = 0.5;
    else
        v_zelle = str2double(get(handles.editvzelle, 'String'));
    end;
   
    if get(handles.editemodulindenter,'String') == 1000000
        E_ind = 1000000;
    else
        E_ind = str2double(get(handles.editemodulindenter, 'String'));
    end;
 


Ich hoffe wirklich mir kann jemand helfen, sonst geh ich hier noch bananas... Shocked

Vielen Dank schon mal für eure Bemühungen!
Grüße,
Peedschee
Private Nachricht senden Benutzer-Profile anzeigen
 
Harald
Forum-Meister

Forum-Meister


Beiträge: 24.501
Anmeldedatum: 26.03.09
Wohnort: Nähe München
Version: ab 2017b
     Beitrag Verfasst am: 26.02.2014, 21:39     Titel:
  Antworten mit Zitat      
Hallo,

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
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 - 2025 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.