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

Lsqcurvefit funktioniert nicht wie erhofft

 

Hundekuchen
Forum-Newbie

Forum-Newbie


Beiträge: 3
Anmeldedatum: 27.02.23
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 27.02.2023, 15:36     Titel: Lsqcurvefit funktioniert nicht wie erhofft
  Antworten mit Zitat      
Brauche eure Hilfe, Ich will aus einer elektrischen Schaltung die unbekannten Variablen berechenn anhand von Messwerten und habe dafür lsqcurvefit ausgewählt.
Folgend das Script:
clear
% Dateiname
filename = 'DI-Wasser_100mV.csv';


% Lesen Sie die Daten aus der CSV-Datei
T = readtable(filename, 'Delimiter', ',');

% Konvertieren Sie die Tabelle in ein Array
A = table2array(T);

Frequenz = A(:,1);
Impedanz_abs = A(:,2);
Phase = A(:,3);
% Array für Frequenzen definieren
%x = Frequenz;
%y = Impedanz_abs;
f=Frequenz;
y=Impedanz_abs;

fun=@(a,f)abs(1i*2*pi.*f*a(1) + 1i*2*pi.*f*a(2) + ...
(1./(((1/a(2) +1i*2*pi.*f*a(4)).^-1 + a(5)) + ((1/a(6) +1i*2*pi.*f*a(7)).^-1 + a(Cool) ...
+ 1i*2*pi.*f*a(9) + 1i*2*pi.*f*a(10) + ((1/a(11) + 1i*2*pi.*f*a(12)).^-1)) + 1i*2*pi.*f*a(13)).^-1);

% Startwerte der Variablen
f0=[5 5 5 5 5 5 5 5 5 5 5 5 5];
x=lsqcurvefit(fun,f0,f,y)

Ich bekomme ein Ergebnis, nicht ansatzweise an die Messwerte rankommt.
Habe ich einen Fehler gemacht ? oder muss ich eine andere Funktion benutzen?

Beste Grüße
Hundekuchen

Bild1.fig
 Beschreibung:

Download
 Dateiname:  Bild1.fig
 Dateigröße:  119.67 KB
 Heruntergeladen:  112 mal
Private Nachricht senden Benutzer-Profile anzeigen


Harald
Forum-Meister

Forum-Meister


Beiträge: 24.448
Anmeldedatum: 26.03.09
Wohnort: Nähe München
Version: ab 2017b
     Beitrag Verfasst am: 27.02.2023, 17:02     Titel:
  Antworten mit Zitat      
Hallo,

das Hauptproblem dürften die Startwerte sein. MATLAB sucht ausgehend von den Startwerten mit einem Abstiegsverfahren nach einem Minimum. Wenn die Startwerte nicht ausreichend gut sind, kann das ein lokales Minimum sein.
Wenn du keine ausreichend guten Startwerte hast, kann Globale Optimierung eine Alternative sein, z.B. mit MultiStart um lsqcurvefit herum.

Nach Möglichkeit würde ich auch versuchen, das Modell zu vereinfachen. 13 Parameter sind ziemlich viel. Wo kommt denn a(3) vor? Sind die Terme für a(9) und a(10) nicht gleich?

Generell ist es gut, wenn du die Beispieldaten mit zur Verfügung stellst, so dass man das Problem reproduzieren kann.

Bitte auch die Code-Umgebung verwenden, damit in den Code keine Smileys gesetzt werden.

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
 
Hundekuchen
Themenstarter

Forum-Newbie

Forum-Newbie


Beiträge: 3
Anmeldedatum: 27.02.23
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 27.02.2023, 17:18     Titel:
  Antworten mit Zitat      
Danke für die schnelle Antwort. Das mit A3 ist ein fehler, den hab ich korregiert.
Bei der Funktion handelt sich sich um eine elektrische Schaltgruppe. mit 13 Bauteilen(Spule, Kapazität und Widerstand), mit unbekannten paramter.

Mit Mulistart hab ich noch nicht gearbeitet und die Startwerte sind einfach ins Blaue geraten.


Code:
%

clear
% Dateiname
filename = 'DI-Wasser_100mV.txt';


% Lesen Sie die Daten aus der txt-Datei
T = readtable(filename, 'Delimiter', ',');

% Konvertieren Sie die Tabelle in ein Array
A = table2array(T);

Frequenz =  A(:,1);
Impedanz_abs = A(:,2);
Phase = A(:,3);
% Array für Frequenzen definieren
%x = Frequenz;
%y = Impedanz_abs;
f=Frequenz;
y=Impedanz_abs;



% Formeln aus Schaltbild
%Z_s = (1/R_s + 1i*2*pi*f*C_s)^-1;
%Zj_e = (1/Rj_e +1i*2*pi*f*Cj_e)^-1 + Rj_b;
%Zi_e = (1/Ri_e +1i*2*pi*f*Ci_e)^-1 + Ri_b;
%Z_ww = Zj_e + Zi_e + 1i*2*pi*f*Lj_w + 1i*2*pi*f*Li_w + Z_s;
%Zp = (1/Z_ww + 1i*2*pi*f*Cij)^-1;
%Z_Li_c = 1i*2*pi*f*Li_c;
%Z_Lj_c = 1i*2*pi*f*Lj_c;

%Z_ges = Z_Li_c + Z_Lj_c + Zp;


% Alle Formeln in Z_ges eingefügt


%Funktion = 1i*2*pi*f*Li_c + 1i*2*pi*f*Lj_c + (1/Z_ww + 1i*2*pi*f*Cij)^-1
% Zw, Zi_e, Zj_e und Z_s ausgeschrieben

%Funktion2 = 1i*2*pi*f*Li_c + 1i*2*pi*f*Lj_c + ...
 %   (1/(((1/Rj_e +1i*2*pi*f*Cj_e)^-1 + Rj_b) + ((1/Ri_e +1i*2*pi*f*Ci_e)^-1 + Ri_b) ...
 %   + 1i*2*pi*f*Lj_w + 1i*2*pi*f*Li_w + ((1/R_s + 1i*2*pi*f*C_s)^-1)) + 1i*2*pi*f*Cij)^-1;
%Funktion anpassen, sodass damit gerechnet werden kann

%Funktion3 = 1i*2*pi.*f*Li_c + 1i*2*pi.*f*Lj_c + ...
  %  (1/(((1/Rj_e +1i*2*pi.*f*Cj_e).^-1 + Rj_b) + ((1/Ri_e +1i*2*pi.*f*Ci_e)^-1 + Ri_b) ...
  %  + 1i*2*pi.*f*Lj_w + 1i*2*pi.*f*Li_w + ((1/R_s + 1i*2*pi.*f*C_s)^-1)) + 1i*2*pi.*f*Cij).^-1;

%a(1)= Li_c;
%a(2)= Lj_c;
%a(3)= Rj_e;
%a(4)= Cj_e;
%a(5)= Rj_b;
%a(6) = Ri_e;
%a(7) = Ci_e;
%a(8) = Ri_b;
%a(9) = Lj_w;
%a(10)= Li_w;
%a(11)= R_s;
%a(12)= C_s;
%a(13)= Cij;


%fun=@(a,f)(1i*2*pi.*f*a(1) + 1i*2*pi.*f*a(2) + ...
   % (1./(((1/a(2) +1i*2*pi.*f*a(4)).^-1 + a(5)) + ((1/a(6) +1i*2*pi.*f*a(7)).^-1 + a(Cool) ...
   % + 1i*2*pi.*f*a(9) + 1i*2*pi.*f*a(10) + ((1/a(11) + 1i*2*pi.*f*a(12)).^-1)) + 1i*2*pi.*f*a(13)).^-1);
   
fun=@(a,f)abs(1i*2*pi.*f*a(1) + 1i*2*pi.*f*a(2) + ...
    (1./(((1/a(3) +1i*2*pi.*f*a(4)).^-1 + a(5)) + ((1/a(6) +1i*2*pi.*f*a(7)).^-1 + a(8)) ...
    + 1i*2*pi.*f*a(9) + 1i*2*pi.*f*a(10) + ((1/a(11) + 1i*2*pi.*f*a(12)).^-1)) + 1i*2*pi.*f*a(13)).^-1);

% Startwerte der Variablen
f0=[5 5 5 5 5 5 5 5 5 5 5 5 5];

ydata2=y.*cos(Phase)+y.*sin(Phase)*1i;
x=lsqcurvefit(fun,f0,f,y)

figure(1)
plot(f,y,f,fun(x,f))
%loglog(f,y,'k',times,fun(x,times),'b-')
legend('Data','Fitted')
xlabel('Frequency')
ylabel('Impedance')

figure(2)
loglog(f,y,f,fun(x,f))
legend('Data','Fitted')
xlabel('Frequency')
ylabel('Impedance')


 


DI-Wasser_100mV.txt
 Beschreibung:
Messwerte

Download
 Dateiname:  DI-Wasser_100mV.txt
 Dateigröße:  98.65 KB
 Heruntergeladen:  106 mal
Private Nachricht senden Benutzer-Profile anzeigen
 
Harald
Forum-Meister

Forum-Meister


Beiträge: 24.448
Anmeldedatum: 26.03.09
Wohnort: Nähe München
Version: ab 2017b
     Beitrag Verfasst am: 27.02.2023, 19:05     Titel:
  Antworten mit Zitat      
Hallo,

es bleibt das Problem, dass die Terme für a(9) und a(10) gleich sind: Solange deren Summe gleich ist, kommt immer das gleiche heraus, egal was a(9) und a(10) für sich genommen sind. Das gleiche gilt nun für a(1) und a(2).

Ins Blaue geratene Startwerte sind bei lsqcurvefit meist keine gute Idee.
Schau dir MultiStart doch mal an.

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
 
Hundekuchen
Themenstarter

Forum-Newbie

Forum-Newbie


Beiträge: 3
Anmeldedatum: 27.02.23
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 28.03.2023, 12:35     Titel:
  Antworten mit Zitat      
Hallo habe jetzt nochmal Multistart und auch mit erweiterten Einstellungen von Matlab experementiert, jedoch bekomme ich keine sonderloch gute verbesserung.

Ich habe neue startwerte ausprobieren bekommen, jedoch werden diese kaum mit den solvern geändert. Habe noch einen sehr großen Error. auch wenn der Graph schon in die richtige aussieht.

Code:
%  
clear
% Dateiname
filename = '150mmolNaCl_100mV.csv'; % Letzte Zeile mit "END" aus Tabelle löschen


% Lesen Sie die Daten aus der CSV-Datei
T = readtable(filename, 'Delimiter', ',');

% Konvertieren Sie die Tabelle in ein Array
A = table2array(T);

Frequenz =  A(:,1);
Impedanz_abs = A(:,2);
Phase = A(:,3);
% Array für Frequenzen definieren
%x = Frequenz;
%y = Impedanz_abs;
f=Frequenz;
y=Impedanz_abs;

%ydata2=y.*cos(Phase)+y.*sin(Phase)*1i;


%% Formeln aus Schaltbild
%Z_s = (1/R_s + 1i*2*pi*f*C_s)^-1;
%Zj_e = (1/Rj_e +1i*2*pi*f*Cj_e)^-1 + Rj_b;
%Zi_e = (1/Ri_e +1i*2*pi*f*Ci_e)^-1 + Ri_b;
%Z_ww = Zj_e + Zi_e + 1i*2*pi*f*Lj_w + 1i*2*pi*f*Li_w + Z_s;
%Zp = (1/Z_ww + 1i*2*pi*f*Cij)^-1;
%Z_Li_c = 1i*2*pi*f*Li_c;
%Z_Lj_c = 1i*2*pi*f*Lj_c;

%Z_ges = Z_Li_c + Z_Lj_c + Zp;


%% Alle Formeln in Z_ges eingefügt




%Funktion = 1i*2*pi*f*Li_c + 1i*2*pi*f*Lj_c + (1/Z_ww + 1i*2*pi*f*Cij)^-1
% Zw, Zi_e, Zj_e und Z_s ausgeschrieben

%Funktion2 = 1i*2*pi*f*Li_c + 1i*2*pi*f*Lj_c + ...
 %   (1/(((1/Rj_e +1i*2*pi*f*Cj_e)^-1 + Rj_b) + ((1/Ri_e +1i*2*pi*f*Ci_e)^-1 + Ri_b) ...
 %   + 1i*2*pi*f*Lj_w + 1i*2*pi*f*Li_w + ((1/R_s + 1i*2*pi*f*C_s)^-1)) + 1i*2*pi*f*Cij)^-1;
%Funktion anpassen, sodass damit gerechnet werden kann

%Funktion3 = 1i*2*pi.*f*Li_c + 1i*2*pi.*f*Lj_c + ...
  %  (1/(((1/Rj_e +1i*2*pi.*f*Cj_e).^-1 + Rj_b) + ((1/Ri_e +1i*2*pi.*f*Ci_e)^-1 + Ri_b) ...
  %  + 1i*2*pi.*f*Lj_w + 1i*2*pi.*f*Li_w + ((1/R_s + 1i*2*pi.*f*C_s)^-1)) + 1i*2*pi.*f*Cij).^-1;

%% Deklarierung der Paramter  
%a(1)= Li_c; 1e-10
%a(2)= Lj_c; 1e-10
%a(3)= Rj_e; 12000
%a(4)= Cj_e; 4e-8
%a(5)= Rj_b; 1
%a(6) = Ri_e; 5e5
%a(7) = Ci_e; 4e-8
%a(8) = Ri_b; 400
%a(9) = Lj_w; 1e-10
%a(10)= Li_w; 1e-10
%a(11)= R_s; 2e4
%a(12)= C_s; 2.3e-8
%a(13)= Cij; 0.8e-12


%fun=@(a,f)(1i*2*pi.*f*a(1) + 1i*2*pi.*f*a(2) + ...
   % (1./(((1/a(2) +1i*2*pi.*f*a(4)).^-1 + a(5)) + ((1/a(6) +1i*2*pi.*f*a(7)).^-1 + a(Cool) ...
   % + 1i*2*pi.*f*a(9) + 1i*2*pi.*f*a(10) + ((1/a(11) + 1i*2*pi.*f*a(12)).^-1)) + 1i*2*pi.*f*a(13)).^-1);
   
fun=@(a,f)abs(1i*2*pi.*f*a(1) + 1i*2*pi.*f*a(2) + ...
    (1./(((1/a(3) +1i*2*pi.*f*a(4)).^-1 + a(5)) + ((1/a(6) +1i*2*pi.*f*a(7)).^-1 + a(8)) ...
    + 1i*2*pi.*f*a(9) + 1i*2*pi.*f*a(10) + ((1/a(11) + 1i*2*pi.*f*a(12)).^-1)) + 1i*2*pi.*f*a(13)).^-1);

% Startwerte der Variablen
f0=[1e-10 1e-10 12000 4e-8 1 5e5 4e-8 400 1e-10 1e-10 2e+4 2.3e-8 0.8e-12];
f2=[10 10 100 10 1 100 1 20 0.001 0.001 100 10 1];  %Für Typicalx einstellung
ub=[inf inf inf inf inf inf inf inf inf inf inf inf inf];
lb=[0 0 0 0 0 0 0 0 0 0 0 0 0];
options = optimoptions(@lsqcurvefit,'MaxFunctionEvaluations',1e+3,'MaxIterations',1000,'TolFun',1e-100,'TolX',1e-110,'Typicalx',f2*1.11)
[x,errorfitted]=lsqcurvefit(fun,f0,f,y,lb,ub,options)

%% fminsearch


%% Startwertproblem lösen mit Multistart
problem = createOptimProblem('lsqcurvefit','x0',x,'objective',fun,...
        'xdata',f,'ydata',y);
%options = optimoptions(@MultiStart,'NumTrialPoints',5000)

ms = MultiStart('PlotFcns',@gsplotbestf);
[xmulti,errormulti] = run(ms,problem,50)

%% Plots


figure(2)
loglog(f,y,f,fun(x,f))
legend('Data','Fitted')
xlabel('Frequency')
ylabel('Impedance')
title('Lsqcurvefit-Lösung-Log')

figure(3)
loglog(f,y,f,fun(xmulti,f))
legend('Data','Fitted')
xlabel('Frequency')
ylabel('Impedance')
title('Multistart-Lösung-Log')
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.