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

Polstellen einer Funktion annähern

 

Fr3yr
Forum-Newbie

Forum-Newbie


Beiträge: 7
Anmeldedatum: 27.09.14
Wohnort: ---
Version: R2012
     Beitrag Verfasst am: 27.09.2014, 13:18     Titel: Polstellen einer Funktion annähern
  Antworten mit Zitat      
Hallo zusammen,
ich hoffe hier ist der richtige Ort für meine Frage. Im Zusammenhang mit Polstellen habe ich bisher nur Beiträge im Bezug auf Regelungstechnische Systeme gefunden.

Mein Problem ist folgendes: Ich habe Messwerte gegeben und möchte den Verlauf dieser Messwerte annähern. Die Messwerte enthalten jedoch augenscheinlich mehrere Polstellen, daher dachte ich mir, dass diese Annäherung mit einer Padé-Approximation möglich sein müsste.

Da die grundsätzliche Form einer Padé-Approximation die folgende zu sein scheint:



dachte ich mir, dass ich mithilfe des Curve Fitting Tools unter Verwendung einer Custom Equation mit eben solch einer Gleichung bereits eine Annäherung erreichen könnte, die Polstellen scheinen aber ein Problem darzustellen. Der Fit ist lediglich eine Gerade.

Ich habe das Problem erstmal vereinfacht und versucht folgende Funktion mit einer einzigen Polstelle anzunähern:

Code:

x = 0.9:0.001:1.1
y = x.^2 ./ (x-1)
 


Wenn ich diese Daten jetzt im Curve Fitting Tool betrachte und wieder über Custom Euqation einen Fit mit folgender Gleichung

Code:
(a0 + a1*x + a2*x^2) /
    (1 + b1*x)


durchführe, bleibt der Fit in diesem Ausschnitt wieder annähernd eine Gerade: der Pol wird komplett ignoriert (Er merkt auch an: "! Ignoring Inf in Data").

Kann mir jemand helfen? Ich weiß gerade nicht was ich falsch mache. Gibt es einen anderen Weg Polstellen in Funktionen anzunähern?
Ich bin leider noch nicht so erfahren in Matlab, daher hoffe ich, dass diese Frage jetzt nicht allzu dämlich ist...
Bin für jede Hilfe dankbar.
Private Nachricht senden Benutzer-Profile anzeigen


Harald
Forum-Meister

Forum-Meister


Beiträge: 24.492
Anmeldedatum: 26.03.09
Wohnort: Nähe München
Version: ab 2017b
     Beitrag Verfasst am: 27.09.2014, 14:54     Titel:
  Antworten mit Zitat      
Hallo,

wenn die Daten inf enthalten:
Code:


Falls in einer Funktion nach dem Pol gesucht wird: Nullstelle des Kehrwerts suchen (fzero/fsolve).

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

Forum-Newbie

Forum-Newbie


Beiträge: 7
Anmeldedatum: 27.09.14
Wohnort: ---
Version: R2012
     Beitrag Verfasst am: 28.09.2014, 18:36     Titel:
  Antworten mit Zitat      
Hallo Harald,
danke für die schnelle Antwort.

Mein Problem ist jedoch, dass ich eigentlich nur Messwerte habe, und keinen Funktionsausdruck von dem ich Polstellen aus dem Nennerpolynom ermitteln könnte. Ich suche ja gerade einen Funktionsausdruck (als Näherung) für meine Messwerte.

Da mir
Code:

ja quasi die Polstellen zurückgibt, könnte ch mir jetzt vorstellen, ein Script zu schreiben, das das Nennerpolynom so modelliert, dass es die Pole an diesen Stellen erzeugt, aber ist das wirklich der einzige/beste weg?

Den restlichen Verlauf habe ich so ja noch nicht berücksichtigt, und müsste dann ja die Optimierung der Koeffizienten selber durch Methode der kleinsten Quadrate o.ä. von Hand schreiben.
Private Nachricht senden Benutzer-Profile anzeigen
 
Harald
Forum-Meister

Forum-Meister


Beiträge: 24.492
Anmeldedatum: 26.03.09
Wohnort: Nähe München
Version: ab 2017b
     Beitrag Verfasst am: 28.09.2014, 18:59     Titel:
  Antworten mit Zitat      
Hallo,

das Problem mit dem Curve Fitting Tool dürften schlechte Startwerte sein.

Einfache Nullstellen / Pole haben Vorzeichenwechsel, vielleicht hilft das:
Code:
wechsel = diff(sign(y)) ~= 0


Ansonsten: es gibt sicher viele Wege, in diesem einfachen Beispiel den Pol zu finden. Kannst du echte Beispieldaten zur Verfügung stellen, damit man sehen kann, was da geht?

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

Forum-Newbie

Forum-Newbie


Beiträge: 7
Anmeldedatum: 27.09.14
Wohnort: ---
Version: R2012
     Beitrag Verfasst am: 29.10.2014, 13:43     Titel:
  Antworten mit Zitat      
Hallo,
tut mir Leid, dass ich nicht mehr geantwortet habe, ich hatte zwischenzeitlich andere Probleme und meine Frage hier fast vergessen.

Im Anhang habe ich mal einen Ausschnitt des Verlaufs der Daten angefügt.
Das Problem ist halt, dass es Messdaten sind und da natürlich nie ein Pol im Sinne von unendlichen Messwerten gemessen wird.
In der Zwischenzeit wurde mir eine Optimierungsroutine für lineare Funktionen zur Verfügung gestellt, diese habe ich etwas abgewandelt:


Ich erzeuge eine Modellfunktion (welchen Grades auch immer):

Code:
y_modell=@(a0,a1,a2,a3,b1,b2,b3) (a0*x_mess.^3+a1*x_mess.^2+a2*x_mess+a3)./(b1*x_mess.^2+b2*x_mess+b3);

%Startparameter:
a0=1;
a1=1;
...


Berechne die Fehlersumme zwischen den Messwerten und meinem Modell:

Code:

fehlersumme=@(parameter) sum(((y_mess-((parameter(1)*x_mess.^3+parameter(2)*x_mess.^2+parameter(3)*x_mess+parameter(4))./(parameter(5)*x_mess.^2+parameter(6)*x_mess+parameter(7))))./y_mess).^2);
 


Und versuche dann anhand des Fehlers die Parameter zu optimieren:

Code:
[parameter,fval,exitflag,output]=fminsearch(fehlersumme,[a0,a1,a2,a3,b1,b2,b3])



Für lineare Funktionen (also der Form m*x + b), quadratische, kubische, ... etc. funktioniert das auch wunderbar. Sobald ich jedoch einen Nennerterm in der Modellfunktion habe
funktioniert das gar nicht mehr. Egal wieviele Iterationen ich durchlaufen lasse, die Parameter bleiben exakt die Startparameter, es wird also nichts optimiert.
Ich weiß auch nicht so recht wie ich hier erkennen kann wo das Problem liegt, da ich ja nicht wirklich sehe was fminsearch im Hintergrund eigentlich macht.

Wenn ich mal Messwerte einer bekannten Funktion generiere und die Startwerte für die Parameter auf die Koeffizienten der bekannten Funktion setze, passt die Approximation
natürlich, aber dann brauch ich ja auch nichts mehr zu optimieren....


Hat evtl. jemand Rat für mich warum diese Methode bei gebrochenrationalen Funktionen in meinem Fall versagt? Ich habe mich etwas zu dem hinter fminsearch steckenden
Nelder-Mead Simplex Algorithmus belesen, konnte aber nicht erkennen, warum dieser hier nicht funktionieren sollte.

Viele Dank schonmal.

messwerte.txt
 Beschreibung:

Download
 Dateiname:  messwerte.txt
 Dateigröße:  13.41 KB
 Heruntergeladen:  641 mal
Private Nachricht senden Benutzer-Profile anzeigen
 
Harald
Forum-Meister

Forum-Meister


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

bitte ein lauffähiges Beispiel posten, das die genannten Probleme aufweist.

sum ist hier meines Erachtens nicht sinnvoll, da sich so positive und negative Abweichungen aufheben. Ich würde stattdessen wenn norm verwenden.
Noch besser wäre es allerdings, das als Kurvenanpassungsproblem zu sehen, also z.B. lsqcurvefit zu verwenden.

Hilfreich wäre auch die Selbstdiagnose des Solvers.

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

Forum-Newbie

Forum-Newbie


Beiträge: 7
Anmeldedatum: 27.09.14
Wohnort: ---
Version: R2012
     Beitrag Verfasst am: 31.10.2014, 02:39     Titel:
  Antworten mit Zitat      
Hallo Harald,

ein lauffähiges Beispiel wäre folgendes:

Code:
x_mess = -10:0.05:10;
y_mess = (3*x_mess.^3+4*x_mess.^2+1*x_mess+0) ./ (x_mess.^2+2*x_mess+1);

y_modell=@(a0,a1,a2,a3,b1,b2,b3) (a0*x_mess.^3+a1*x_mess.^2+a2*x_mess+a3)./(b1*x_mess.^2+b2*x_mess+b3);

a0=4;   %beispielhafte Startwerte
a1=4;
a2=2;
a3=0;
b1=1;
b2=2;
b3=1;

fehlersumme=@(parameter) sum(((y_mess-((parameter(1)*x_mess.^3+parameter(2)*x_mess.^2+parameter(3)*x_mess+parameter(4))./(parameter(5)*x_mess.^2+parameter(6)*x_mess+parameter(7))))./y_mess).^2);

[parameter,fval,exitflag,output]=fminsearch(fehlersumme,[a0,a1,a2,a3,b1,b2,b3],optimset('MaxFunEvals',1e10))

a0=parameter(1);
a1=parameter(2);
a2=parameter(3);
a3=parameter(4);
b1=parameter(5);
b2=parameter(6);
b3=parameter(7);

plot(x_mess, y_mess, 'red--');
hold on;
plot(x_mess, y_modell(a0,a1,a2,a3,b1,b2,b3), 'blue');
hold off;


Die Werte für die Koeffizienten a0, a1, ... ändern sich hierbei gar nicht.

Da mir im Command Window gemeldet wird:

"Maximum number of function evaluations has been exceeded
- increase MaxFunEvals option."
bzw.
"Exiting: Maximum number of iterations has been exceeded
- increase MaxIter option."

Habe ich mit diesen beiden Optionen schon rumprobiert, allerdings ohne Erfolg. Die Rechenzeiten steigen sehr stark an und es müssten sich die Koeffizienten ja wenigstens ein bisschen verbessern, auch wenn die Funktion irgendwann abbricht...

Ein Diagnose-Menü kenne ich nur aus Simulink, was meinst du mit Selbstdiagnose des Solvers?

Ich habe bisher fminsearch verwendet, weil ich auf spezielle Toolboxes weitestgehend verzichten wollte, werde mir jedoch mal lsqcurvefit anschauen.

Danke für deine Geduld mit mir!
Private Nachricht senden Benutzer-Profile anzeigen
 
Harald
Forum-Meister

Forum-Meister


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

y_mess enthält NaN. Das sollte zunächst gefiltert werden.

Bei deinem Ansatz war zudem das Problem, dass in der Zielfunktion durch y_mess und somit auch durch 0 geteilt wird, also immer inf herauskommt.

Mit lsqcurvefit läuft es:

Code:
x_mess = -10:0.05:10;
y_mess = (3*x_mess.^3+4*x_mess.^2+1*x_mess+0) ./ (x_mess.^2+2*x_mess+1);

missing = isnan(y_mess);
x_mess(missing) = [];
y_mess(missing) = [];

y_modell=@(a0,a1,a2,a3,b1,b2,b3) (a0*x_mess.^3+a1*x_mess.^2+a2*x_mess+a3)./(b1*x_mess.^2+b2*x_mess+b3);

a0=4;   %beispielhafte Startwerte
a1=4;
a2=2;
a3=0;
b1=1;
b2=2;
b3=1;

% fehlersumme=@(parameter) norm(((y_mess-((parameter(1)*x_mess.^3+parameter(2)*x_mess.^2+parameter(3)*x_mess+parameter(4))./(parameter(5)*x_mess.^2+parameter(6)*x_mess+parameter(7))))./y_mess).^2);
%
% [parameter,fval,exitflag,output]=fminsearch(fehlersumme,[a0,a1,a2,a3,b1,b2,b3],...
%     optimset('MaxFunEvals',1e10, 'MaxIter', 1e4))

fehler=@(parameter, x_mess) (parameter(1)*x_mess.^3+parameter(2)*x_mess.^2+parameter(3)*x_mess+parameter(4))./(parameter(5)*x_mess.^2+parameter(6)*x_mess+parameter(7));

[parameter,fval,exitflag,output]=lsqcurvefit(fehler,[a0,a1,a2,a3,b1,b2,b3],...
    x_mess, y_mess, [], [], optimset('MaxFunEvals',1e10, 'MaxIter', 1e4));

a0=parameter(1);
a1=parameter(2);
a2=parameter(3);
a3=parameter(4);
b1=parameter(5);
b2=parameter(6);
b3=parameter(7);

plot(x_mess, y_mess, 'rx');
hold on;
plot(x_mess, y_modell(a0,a1,a2,a3,b1,b2,b3), 'bo:');
hold off;


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

Forum-Newbie

Forum-Newbie


Beiträge: 7
Anmeldedatum: 27.09.14
Wohnort: ---
Version: R2012
     Beitrag Verfasst am: 04.11.2014, 17:11     Titel:
  Antworten mit Zitat      
Hallo,

das macht Sinn. Bei dem generierten Beispiel funktioniert das jetzt tatsächlich. Ist zwar noch sehr stark von der Wahl der Anfangsparameter abhängig, aber ok.

Bei den Messdaten versagt es allerdings immernoch komplett, vielleicht liegt das echt an den Anfangswerten, im Gegensatz zur bekannten Funktion kann ich die hier ja nur schwer schätzen.

Vielen Dank jedenfalls für deine Hilfe! Hab wieder einiges gelernt.
Private Nachricht senden Benutzer-Profile anzeigen
 
Harald
Forum-Meister

Forum-Meister


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

was die Startwerte angeht: siehe auch 28.09.2014, 18:59

Kannst du denn mal die Messdaten und das Modell posten?
Ansonsten ist es schwierig, dir noch irgendwie weiterzuhelfen.

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

Forum-Newbie

Forum-Newbie


Beiträge: 7
Anmeldedatum: 27.09.14
Wohnort: ---
Version: R2012
     Beitrag Verfasst am: 06.11.2014, 02:46     Titel:
  Antworten mit Zitat      
Hallo,

naja, ich hatte oben ja schonmal so einen Ausschnitt der Messwerte angehängt. Der komplette Verlauf besteht nur aus mehreren solchen Polen, ich wäre ja erstmal zufrieden wenn es mit einem einzigen klappt.

Eigentlich erscheint mir der Verlauf nicht so verschieden zu generierten Funktionen bei denen das ganze funktioniert und soweit ich das sehe, sollte dafür auch kein Polynom wesentlich höherer Ordnung nötig sein.
Wenn ich das Beispiel aber durchlaufen lasse erhalte ich nur eine Gerade...

Ich hatte gedacht, dass die doch recht großen X-Werte (im Verhältnis zu den kleinen Startwerten) evtl. ein Problem darstellen, und habe daher mal von den X-Werten den Mittelwert abgezogen und auch mal mit der "TypicalX" Option rumgespielt (wobei mir deren Auswirkung noch nicht ganz einleuchtet) aber beides ergab keine Verbesserung.


Hier nochmal die Beispieldaten im Anhang:

messwerte.txt
 Beschreibung:

Download
 Dateiname:  messwerte.txt
 Dateigröße:  5.61 KB
 Heruntergeladen:  691 mal
Private Nachricht senden Benutzer-Profile anzeigen
 
Harald
Forum-Meister

Forum-Meister


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

sorry, als du die Datei zuerst gepostet hattest, war nur bruchstückhaft klar, was du damit machst. Daher hatte ich die Datei da nicht weiter beachtet, und jetzt nicht nochmal alles durchgeschaut.

Das Problem liegt in der Tat in den hohen x-Werten. Wenn du sie vorher skalierst, klappt es problemlos:
Code:
x_mess = (x_mess - min(x_mess)) / range(x_mess);


Die Option 'TypicalX' hat nichts mit deinen x-Werten zu tun, sondern bezieht sich auf die zu schätzenden Parameter.

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

Forum-Newbie

Forum-Newbie


Beiträge: 7
Anmeldedatum: 27.09.14
Wohnort: ---
Version: R2012
     Beitrag Verfasst am: 10.11.2014, 22:06     Titel:
  Antworten mit Zitat      
Ah, ok.

Ich hatte sowas ähnliches gemacht, die ganzen X-Werte quasi um ihren Mittelwert verringert, das funktionierte nur nicht so ganz. So wie du es gemacht hast geht es aber wunderbar.

Den Ausschnitt aus den Messwerten den ich geposted habe kann ich damit ganz gut annähern. Für den kompletten Verlauf muss ich noch ein bisschen rumspielen, da der viele Polstellen enthält, aber es funktioniert schonmal und man sieht eindeutig, dass es eine Näherung des Verlaufes wird Smile

Du hast mir sehr geholfen, Danke nochmal.

Ich setze das jetzt mal auf beantwortet.
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.