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

Fsolve dimension mismatch

 

Henrik123
Forum-Fortgeschrittener

Forum-Fortgeschrittener


Beiträge: 87
Anmeldedatum: 25.01.17
Wohnort: ---
Version: 2011a, 2017a
     Beitrag Verfasst am: 26.11.2017, 15:31     Titel: Fsolve dimension mismatch
  Antworten mit Zitat      
Hallo liebe Community. Aktuelle versuche ich, zwei Funktionen zu fitten die zusammenhängen. Soll heißen, dass die zu suchenden Parameter in beiden Funktionen stecken. Dafür wollte ich fsolve verwenden. Laut Dokumentaion kann der ja sowas. Das ist mein Ergebnis.

Zu erst erstelle ich mir eine Funktion, so wie in der Dokumentation

function F = nonlinmodel( x, C_0, R_m, L_m, C_m, tan_d, w, Re_Y, Im_Y)
%       C_0, R_m, L_m, C_m, tan_d are the parameters I have to fit.
%
%       x(1) to x(5) are there relativ changes
%
%       w is the step of the x-Axis
%
%       Re_Y and Im_Y are the data sets.
%
%       F(1) and F(2) are almost an array of 0. As in the documentation
%           They are not exactly 0 due to the error
%           in the inital condition

% Real part
% Function out of theory minus measured data
F(1) = x(2)*R_m./((x(2)*R_m).^2 + (w*x(3)*L_m - 1./(w*x(4)*C_m)).^2) + w*x(5)*tan_d*x(1)*C_0 - Re_Y;      

% Imaginary part
% Function out of theory minus measured data
F(2) = (-w*x(3)*L_m + 1./(w*x(4)*C_m))./((x(1)*R_m).^2 + (w*x(3)*L_m - 1./(w*x(4)*C_m)).^2) + w*x(1)*C_0 - Im_Y;
end

 


Das Programm mit der Fitroutine sieht so aus.

Code:
clear all
close all

%% Load data
Aktor = importdata(['Aktor1.w_l']);
Aktor_freq = Aktor(:,1);
Aktor_ampl = Aktor(:,2);
Aktor_phase = Aktor(:,3);

Re_Y = Aktor_ampl.*cos(deg2rad(Aktor_phase));
Im_Y = Aktor_ampl.*sin(deg2rad(Aktor_phase));
w = 2*pi*Aktor_freq;

%% Define inital values
C_0 = 3.948675967565607e-08;
R_m = 7.120051155668139e+03;
L_m = 25.35529039370214e+00;
C_m = 6.242970891780357e-10;
tan_d = 0.054859859155354e-00;

%% relativ change of the inital values
x1 = [1,1,1,1,1];

%% Start fit routine
f = @(x)nonlinmodel(x, C_0, R_m, L_m, C_m, tan_d, w, Re_Y, Im_Y);
optimal_x = fsolve(f,x1);


Leider bekomme ich dann immer eine Fehlermeldung, mit der ich nichts anfangen kann.

Code:
Subscripted assignment dimension mismatch.

Error in nonlinmodel (line 16)
F(1) = x(2)*R_m./((x(2)*R_m).^2 + (w*x(3)*L_m - 1./(w*x(4)*C_m)).^2) +
w*x(5)*tan_d*x(1)*C_0 - Re_Y;

Error in Fitting>@(x)nonlinmodel(x,C_0,R_m,L_m,C_m,tan_d,w,Re_Y,Im_Y)

Error in fsolve (line 230)
            fuser = feval(funfcn{3},x,varargin{:});

Error in Fitting (line 26)
optimal_x = fsolve(f,x1);

Caused by:
    Failure in initial objective function evaluation. FSOLVE cannot continue.


Habt Ihr eine Idee? Die Messdaten sind im Anhang. Eigentlich mache ich das doch wie in der Dokumentation, oder nicht?
Besten Gruß Henrik123

Aktor1.txt
 Beschreibung:

Download
 Dateiname:  Aktor1.txt
 Dateigröße:  26.95 KB
 Heruntergeladen:  485 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: 26.11.2017, 22:49     Titel:
  Antworten mit Zitat      
Hallo,

am besten ist es in solchen Fällen, die Funktion mal mit den Anfangswerten aufzurufen.

Du versuchst einen Vektor einem einzelnen Wert zuzuweisen, und das geht nunmal nicht.
Wenn du die Abweichungen komponentenweise auf 0 bekommen willst, würde ich
Code:
F1 = ...
F2 = ...
F = [F1; F2]

verwenden. Zudem erscheint mir lsqnonlin von der Zielsetzung her geeigneter.

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

Forum-Fortgeschrittener

Forum-Fortgeschrittener


Beiträge: 87
Anmeldedatum: 25.01.17
Wohnort: ---
Version: 2011a, 2017a
     Beitrag Verfasst am: 01.12.2017, 22:42     Titel:
  Antworten mit Zitat      
Ich habe das Programm versucht zum laufen zu bekommen. Habe mich, wie du mir empfholen hast, an dem lsqnonlin Versucht.

clear all
close all

%% Laden der Daten
Aktor = importdata(['Aktor1.txt']);
Aktor_freq = Aktor(:,1);
Aktor_ampl = Aktor(:,2);
Aktor_phase = Aktor(:,3);

Re_Y = Aktor_ampl.*cos(deg2rad(Aktor_phase));
Im_Y = Aktor_ampl.*sin(deg2rad(Aktor_phase));
f = (1:1:3000)';

%% Startwerte aus Berechnungen
C_0 = 3.948675967565607e-08;
R_m = 7.120051155668139e+03;
L_m = 25.35529039370214e+00;
C_m = 6.242970891780357e-10;
tan_d = 0.054859859155354e-00;

%% Relative Änderung der Parameter
%x_0=[C_0, R_m, L_m, C_m, tan_d]
x =  [  1,   1,   1,   1,    1];
lb = [0.1, 0.1, 0.1, 0.1, 0.1,];
ub = [ 10,  10,  10,  10,   10];

%% Funktionen definieren
Fun = {@(f)(x(2)*R_m./((x(2)*R_m).^2 + (2*pi*f*x(3)*L_m - 1./(2*pi*f*x(4)*C_m)).^2) + 2*pi*f*x(5)*tan_d*x(1)*C_0); ...
       @(f)(-2*pi*f*x(3)*L_m + 1./(2*pi*f*x(4)*C_m))./((x(1)*R_m).^2 + (2*pi*f*x(3)*L_m - 1./(2*pi*f*x(4)*C_m)).^2) + 2*pi*f*x(1)*C_0};

%% Start der Fitroutine
options = optimoptions(@lsqnonlin,'Algorithm','trust-region-reflective', 'StepTolerance',1.0000e-10, 'FunctionTolerance', 1.0000e-10);
optimal_x = lsqnonlin (Fun,x,lb,ub,options);


%% Ausgabe der Daten
figure(1);
set(gcf, 'Units', 'normalized', 'Position', [0, 0.5, 0.3, 0.3]);
plot(Aktor_freq, Re_Y,'*b','MarkerSize',1); hold all;
plot(f, Fun{1}(f),'r');
ylabel('Realteil');
xlabel('Frequenz');

figure(2);
set(gcf, 'Units', 'normalized', 'Position', [0.35, 0.5, 0.3, 0.3]);
plot(Aktor_freq, Im_Y, '*b','MarkerSize',1); hold all;
plot(f, Fun{2}(f),'r');
ylabel('Imaginärteil');
xlabel('Frequenz');

figure(3);
set(gcf, 'Units', 'normalized', 'Position', [0.7, 0.5, 0.3, 0.3]);
plot(Re_Y, Im_Y, 'b*','MarkerSize',1); hold all;
plot(Fun{1}(f), Fun{2}(f),'r');
ylabel('Imaginärteil');
xlabel('Realteil');


Die Daten in Figure(3) müssen halt einigermaßen passen. Das tun sie aber leider nicht, da der lsqnonline die Werte nicht ändert. Die Startwete sind gleich die Optimalen Werte. Kann ja nicht sein. Er sagt mir im command window:

Code:
Warning: Jacobian function provided but
OPTIONS.SpecifyObjectiveGradient=false;
 ignoring Jacobian function and using finite-differencing.
 Rerun with OPTIONS.SpecifyObjectiveGradient=true to use
 Jacobian function.
> In lsqfcnchk (line 96)
  In lsqnsetup (line 46)
  In lsqnonlin (line 185)
  In Hauptprogram (line 33)

Initial point is a local minimum.

Optimization completed because the size of the gradient at the initial point
is less than the default value of the optimality tolerance.

<stopping criteria details>
 


Hast du vielleicht eine Idee für mich?

Gruß Henrik

Aktor1.txt
 Beschreibung:

Download
 Dateiname:  Aktor1.txt
 Dateigröße:  26.95 KB
 Heruntergeladen:  359 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: 04.12.2017, 10:57     Titel:
  Antworten mit Zitat      
Hallo,

der Code erzeugt ja eine Warnung. Ist es deine Absicht, Gradienten zu nutzen? Wenn ja, solltest du die Warnung befolgen. Wenn nein, was ist der Sinn der 2. Funktion?

Willst du f variieren oder x? Du definierst Funktionen von f, also würde auch f variiert.

Wenn du möchtest, dass der Verlauf wie (Re_Y, Im_Y) ist, dann sollten diese schon auch in der Zielfunktion vorkommen.

f hat 3000 Elemente, die Datei 600 Zeilen. Sollte das nicht zusammenpassen?

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

Forum-Fortgeschrittener

Forum-Fortgeschrittener


Beiträge: 87
Anmeldedatum: 25.01.17
Wohnort: ---
Version: 2011a, 2017a
     Beitrag Verfasst am: 04.12.2017, 13:13     Titel:
  Antworten mit Zitat      
Was ich möchte ist folgendes.

Re_Y und Im_Y haben beide die gleichen Systemparameter. In Re_Y stecken C_0, R_m, C_m, L_m und tand und in Im_Y stecken C_0, R_m, C_m und L_m. Wenn ich nur Re_Y fitte, kann es sein, dass die Daten aber nicht für Im_Y gut passen. Man kann das sehen, wenn man sich Im_Y über Re_Y (Ortskurve) auftragen lässt.

Es sollen also beide Kurven optimal an der Verlauf der Daten angepasst werden. Daher habe ich ja zwei Funktionen definiert.

Der Schritt mit f = (1:1:3000)'; sollte nur die Darstellung verbessern, da 600 Punkte die Ortskurve etwas zackig aussehen lässt. Es kann sein, somit den Programmcode negativ zu beeinflussen? Ich will die Startwerte verfeinern. Welchen Schritt sollte ich dann gehen?
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: 04.12.2017, 14:15     Titel:
  Antworten mit Zitat      
Hallo,

setze doch mal die Vorschläge um und poste dann den aktuellen Code.

Zitat:
Es sollen also beide Kurven optimal an der Verlauf der Daten angepasst werden. Daher habe ich ja zwei Funktionen definiert.

Das Thema, dass das in der Form nicht geht, hatten wir eigentlich schon. Die Abhilfe auch, siehe 26.11.2017, 21:49.

Du kannst für die Darstellung am Ende ein verfeinertes f verwenden, aber nicht für das Fitten. Da muss die Anzahl der vorhergesagten und der vorhandenen Werte ja zusammenpassen.

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

Forum-Fortgeschrittener

Forum-Fortgeschrittener


Beiträge: 87
Anmeldedatum: 25.01.17
Wohnort: ---
Version: 2011a, 2017a
     Beitrag Verfasst am: 04.12.2017, 15:49     Titel:
  Antworten mit Zitat      
Ok. Ich habe das jetzt angepasst. Die Funktion variiert jetzt die Startwerte.

Code:
clear all
close all

%% Laden der Daten
Aktor = importdata(['Aktor1.txt']);
Aktor_freq = Aktor(:,1);
Aktor_ampl = Aktor(:,2);
Aktor_phase = Aktor(:,3);

Re_Y = Aktor_ampl.*cos(deg2rad(Aktor_phase));
Im_Y = Aktor_ampl.*sin(deg2rad(Aktor_phase));

fdata = Aktor_freq

%% Startwerte aus Berechnungen
C_0 = 3.948675967565607e-08;
R_m = 7.120051155668139e+03;
L_m = 25.35529039370214e+00;
C_m = 6.242970891780357e-10;
tan_d = 0.054859859155354e-00;

%% Relative Änderung der Parameter
%x_0=[C_0, R_m, L_m, C_m, tan_d]
x0 = [  1,   1,   1,   1,    1];
lb = [0.1, 0.1, 0.1, 0.1, 0.1,];
ub = [ 10,  10,  10,  10,   10];

%% Funktionen definieren
Fun = {@(x)(x(2)*R_m./((x(2)*R_m).^2 + (2*pi*fdata*x(3)*L_m - 1./(2*pi*fdata*x(4)*C_m)).^2) + 2*pi*fdata*x(5)*tan_d*x(1)*C_0); ...
       @(x)(-2*pi*fdata*x(3)*L_m + 1./(2*pi*fdata*x(4)*C_m))./((x(1)*R_m).^2 + (2*pi*fdata*x(3)*L_m - 1./(2*pi*fdata*x(4)*C_m)).^2) + 2*pi*fdata*x(1)*C_0};

%% Start der Fitroutine
options = optimoptions(@lsqnonlin,'Algorithm','trust-region-reflective', 'StepTolerance',1.0000e-10, 'FunctionTolerance', 1.0000e-10);
optimal_x = lsqnonlin (Fun,x0,lb,ub,options);


%% Ausgabe der Daten
figure(1);
set(gcf, 'Units', 'normalized', 'Position', [0, 0.5, 0.3, 0.3]);
plot(Aktor_freq, Re_Y,'*b','MarkerSize',1); hold all;
plot(fdata, Fun{1}(optimal_x),'r');
ylabel('Realteil');
xlabel('Frequenz');

figure(2);
set(gcf, 'Units', 'normalized', 'Position', [0.35, 0.5, 0.3, 0.3]);
plot(Aktor_freq, Im_Y, '*b','MarkerSize',1); hold all;
plot(fdata, Fun{2}(optimal_x),'r');
ylabel('Imaginärteil');
xlabel('Frequenz');

figure(3);
set(gcf, 'Units', 'normalized', 'Position', [0.7, 0.5, 0.3, 0.3]);
plot(Re_Y, Im_Y, 'b*','MarkerSize',1); hold all;
plot(Fun{1}(optimal_x), Fun{2}(optimal_x),'r');
ylabel('Imaginärteil');
xlabel('Realteil');
 


Die info bekomme ich dazu:

Code:
Warning: Jacobian function provided but
OPTIONS.SpecifyObjectiveGradient=false;
 ignoring Jacobian function and using finite-differencing.
 Rerun with OPTIONS.SpecifyObjectiveGradient=true to use
 Jacobian function.
> In lsqfcnchk (line 96)
  In lsqnsetup (line 46)
  In lsqnonlin (line 185)
  In Hauptprogram (line 34)

Local minimum found.

Optimization completed because the size of the gradient is less than
the default value of the optimality tolerance.

<stopping criteria details>

Leider ist das Ergebnis sehr schlecht. Hast du eine weiterführende Idee? Gruß Henrik123
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: 04.12.2017, 15:58     Titel:
  Antworten mit Zitat      
Hallo,

du bekommst immer noch die Warnung. Du berücksichtigst immer noch nicht Re_Y und Im_Y in der Optimierung.

Meine Vermutung wäre, dass du diese Funktion optimieren möchtest:
Code:
Fun2 = @(x) (Fun{1}(x)-Re_Y).^2 + (Fun{2}(x)-Im_Y).^2;


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

Forum-Fortgeschrittener

Forum-Fortgeschrittener


Beiträge: 87
Anmeldedatum: 25.01.17
Wohnort: ---
Version: 2011a, 2017a
     Beitrag Verfasst am: 04.12.2017, 16:32     Titel:
  Antworten mit Zitat      
Durch die Gleichung würde ich die Fehlerquadrate beider Funktionen minimieren. Das leuchtet mir ein. Ich versuche das mal.
Private Nachricht senden Benutzer-Profile anzeigen
 
Henrik123
Themenstarter

Forum-Fortgeschrittener

Forum-Fortgeschrittener


Beiträge: 87
Anmeldedatum: 25.01.17
Wohnort: ---
Version: 2011a, 2017a
     Beitrag Verfasst am: 04.12.2017, 16:45     Titel:
  Antworten mit Zitat      
Ich habe das jetzt so versucht:
Code:

%% Funktionen definieren
Fun = {@(x)(x(2)*R_m./((x(2)*R_m).^2 + (2*pi*fdata*x(3)*L_m - 1./(2*pi*fdata*x(4)*C_m)).^2) + 2*pi*fdata*x(5)*tan_d*x(1)*C_0); ...
       @(x)(-2*pi*fdata*x(3)*L_m + 1./(2*pi*fdata*x(4)*C_m))./((x(1)*R_m).^2 + (2*pi*fdata*x(3)*L_m - 1./(2*pi*fdata*x(4)*C_m)).^2) + 2*pi*fdata*x(1)*C_0};

Fun2 = @(x) (Fun{1}(x)-Re_Y).^2 + (Fun{2}(x)-Im_Y).^2;

%% Start der Fitroutine
options = optimoptions(@lsqnonlin,'Algorithm','trust-region-reflective', 'StepTolerance',1.0000e-15, 'FunctionTolerance', 1.0000e-15, 'OptimalityTolerance', 1.0000e-20);
optimal_x = lsqnonlin (Fun2,x0,lb,ub,options);


Mit dem anpassen von OptimalityTolerance passt das ganze einigermaßen. Danke für die Hilfe.
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.