Verfasst am: 22.05.2012, 07:57
Titel: Zylinderapproxiamtion mit nlinfit
Hallo
ich versuche aus einer Punktwolke einen Zylinder zu berechnen. Näherungswerte für die 7 Zylinder Parameter habe ich ( x,y,z Koordinaten eines Punktes auf der Zylinderachse, x,y,z Koordinaten des Richtungsvektors der Achse und den Radius ).
Diese Werte möchte ich nun mittels nlinfit verbessern. Dafür habe ich folgende Funktion geschrieben :
Code:
function[ Mx,My,Mz,ax,ay,az,r,resi ] = computeCylinder(X, Mx0,My0,Mz0, ax0,ay0,az0,r0 )
%COMPUTECYLINDER Summary of this function goes here
% Detailed explanation goes here size(X)
y = zeros(length(X),1);
cyl = @(a,x)((a(2).*(a(6)-x(:,3))-a(3).*(a(5)-x(:,2)))^2 +
(a(3).*(a(4)-x(:,1))-a(1).*(a(6)-x(:,3)))^2 +
(a(1).*(a(5)-x(:,2))-a(2).*(a(4)-x(:,1)))^2 -
a(7).*sqrt((a(1))^2+(a(2))^2+(a(3))^2));
a0 = [Mx0,My0,Mz0,ax0,ay0,az0,r0];
[aComp, resi] = nlinfit(X,y,cyl,a0);
Mx= aComp(4);
My= aComp(5);
Mz= aComp(6);
ax= aComp(1);
ay= aComp(2);
az= aComp(3);
r = aComp(7);
Die 4 Zeilen zwischen cyl = und (a(3))^2)); sind eine Zeile, ich habe dies nur für bessere Lesbarkeit aufgesplittet.
Wenn ich nun diese Funktion mit einer Matrix X, welche 115568x3 groß ist, aufrufe, die anderen Input Parameter sind meine Startwerte, kommt folgende Fehlermeldung :
Error using nlinfit (line 126)
MODELFUN must be a function that returns a vector of fitted values the same size as Y (115568-by-1). The model
function you provided returned a result that was 1-by-1.
One common reason for a size mismatch is using matrix operators (*, /, ^) in your function instead of the
corresponding elementwise operators (.*, ./, .^).
Den Tip mit den elementwise operators habe ich bereits ausprobiert.
ich denke, dass nlinfit() nur für Funktionen IR -> IR geeignet ist, womit du einen Zylinder im dreidimensionalen Raum schon mal nicht beschreiben kannst.
In der Doku steht immerhin: "However, X can be any array that fun accepts." Man könnte also wenigstens eine Funktion IR^2 -> IR verwenden, da y auf jeden Fall ein Vektor sein soll.
So kann man einen Zylinder aber im Allgemeinen nicht parametrisieren. Ich denke, man muss einen anderen Ansatz wählen.
Grüße, Marc
Edit: Deine neue Funktion "cyl" ist sogar IR^3 -> IR?! Das ist geometrisch nicht mehr sinnvoll.
Ich glaube, die Parametrisierung stimmt. Habe aus einem PDF folgende Zylindergleichung :
|a x M-P| = r*|a|
mit a dem Richtungsvektor der Achse, M einem Punkt auf der Achse und P ist ein beliebiger Punkt auf der Zylinderoberfläche. x ist das Kreuzprodukt. Sollte eigentlich meine Gleichung ergeben. Ich habe auch den Fehler mittlerweile gefunden :
Nun rechnet er, gibt aber komische Werte raus. Die Startwerte stimmen soweit denke ich ganz gut, aber er sagt mir :
Warning: Some columns of the Jacobian are effectively zero at the solution, indicating that the model is
insensitive to some of its parameters. That may be because those parameters are not present in the model, or
otherwise do not affect the predicted values. It may also be due to numerical underflow in the model function,
which can sometimes be avoided by choosing better initial parameter values, or by rescaling or recentering.
Parameter estimates may be unreliable.
welches der rechten Seite der Gleichung entspricht, der Radius quasi von der Länge des Richtungsvektors abhängt.
Weil genau hier kommt ein schlechtes Ergebnis raus und das verstehe ich nicht wirklich.
Grüße
Jan
OK, |a x M-P| = r*|a| ist korrekt, aber das ist doch eine implizite Funktion, dein "cyl" jedoch nicht. Ich frage mich gerade, ob das wirklich funktionieren kann.
Ansonsten muss die Uneindeutigkeit aufgelöst werden, indem der Richtungsvektor normiert wird, denn das führt zu Singularitäten der Jacobi-Matrix.
Trotzdem würde ich gerne wissen, was die Warnung bedeutet :
Warning: Some columns of the Jacobian are effectively zero at the solution, indicating that the model is
insensitive to some of its parameters. That may be because those parameters are not present in the model, or
otherwise do not affect the predicted values. It may also be due to numerical underflow in the model function,
which can sometimes be avoided by choosing better initial parameter values, or by rescaling or recentering.
Parameter estimates may be unreliable.
und diese auch :
Warning: Rank deficient, rank = 3, tol = 1.856292e-009.
und dann weiter ( ich nehme übrigens b im code statt beta, das erspart ab hier Schreibarbeit ) das Programm kennt ja kein a,M,P und r, muss das also umschreiben:
wir die Funktion angenommen, aber nlinfit fehlen die restlichen Gleichungen ( habe dann ja nur die erste Zeile verwendet ) .
Implizit und explizit ignorier ich erst einmal, bis ich das gelöst habe. Des weiteren weiss ich nicht, ob ich nicht zuviele Parameter verwende. mMn sollte es ja 7 sein, aber ich lese im Netz immer von 5, da weiss ich dann aber gar nicht mehr wie ich das darstellen kann.
funktioniert selbstredend nicht, da ich versuchen würde, von einer Matrix einen Vektor zu subtrahieren, ich bräuchte eine Funktion, die den Vaktor b(4:6) von jeder Zeile meiner Matrix x abzieht.
Grüße Jan
Die Funktion hängt ab von b_i und x_i. Nicht mehr und nicht weniger. Du musst unterscheiden zwischen x und X. X ist die Matrix, welche du an nlinfit() übergibst. "cyl" wird dann für jede Zeile aus X ausgewertet.
Mit anderen Worten: Du musst "cyl" also keineswegs beibringen mit Matrizen umzugehen.
...funktioniert selbstredend nicht, da ich versuchen würde, von einer Matrix einen Vektor zu subtrahieren, ich bräuchte eine Funktion, die den Vaktor b(4:6) von jeder Zeile meiner Matrix x abzieht.
Vielleicht noch etwas deutlicher: genau diesen Job macht nlinfit() selbst!
Also ich verstehe ja natürlich was du meinst, aber muss noch einmal nachhaken. Also in meiner Funktion cyl nutze ich nur x, was eine Zeile von X ist.
Sprich :
das ergibt aber :
Error evaluating model function '@(b,x)norm(cross(b(1:3),(b(4:6)-x)))'.
Caused by:
Error using -
Matrix dimensions must agree.
Also scheint mir x doch kein Vektor ( Zeile der Matrix ), sondern die Matrix zu sein.
ergibt :
MODELFUN must be a function that returns a vector of fitted values the same size as Y (115568-by-1). The model
function you provided returned a result that was 1-by-1.
Ich stehe echt immer noch auf dem Schlauch, vor allem als Matlab Neuling.
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.