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

Zylinderapproxiamtion mit nlinfit

 

hacke78
Forum-Anfänger

Forum-Anfänger


Beiträge: 17
Anmeldedatum: 02.06.09
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 22.05.2012, 07:57     Titel: Zylinderapproxiamtion mit nlinfit
  Antworten mit Zitat      
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);

end

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.

Wie muss ich meine Funktion bitte abändern?

Grüße Jan
Private Nachricht senden Benutzer-Profile anzeigen


hacke78
Themenstarter

Forum-Anfänger

Forum-Anfänger


Beiträge: 17
Anmeldedatum: 02.06.09
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 22.05.2012, 08:11     Titel:
  Antworten mit Zitat      
Entschuldigung, das war nicht die aktuelle Funktion, meine schaut so aus :
Code:

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

Forum-Meister


Beiträge: 799
Anmeldedatum: 02.05.12
Wohnort: ---
Version: R2009b
     Beitrag Verfasst am: 22.05.2012, 09:26     Titel:
  Antworten mit Zitat      
Hallo,

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.
Private Nachricht senden Benutzer-Profile anzeigen
 
hacke78
Themenstarter

Forum-Anfänger

Forum-Anfänger


Beiträge: 17
Anmeldedatum: 02.06.09
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 22.05.2012, 09:48     Titel:
  Antworten mit Zitat      
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 :
Code:

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

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.

Kann es sein, dass in
Code:

a(7)*sqrt((a(1))^2+(a(2))^2+(a(3))^2));
 

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

Forum-Meister


Beiträge: 799
Anmeldedatum: 02.05.12
Wohnort: ---
Version: R2009b
     Beitrag Verfasst am: 22.05.2012, 10:09     Titel:
  Antworten mit Zitat      
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.
Private Nachricht senden Benutzer-Profile anzeigen
 
hacke78
Themenstarter

Forum-Anfänger

Forum-Anfänger


Beiträge: 17
Anmeldedatum: 02.06.09
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 22.05.2012, 10:09     Titel:
  Antworten mit Zitat      
Ich habe eine Wurzel schon einmal vergessen, nun scheint es besser zu klappen :
Code:

cyl = @(a,x)(sqrt((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));
 

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

Forum-Meister


Beiträge: 799
Anmeldedatum: 02.05.12
Wohnort: ---
Version: R2009b
     Beitrag Verfasst am: 22.05.2012, 10:31     Titel:
  Antworten mit Zitat      
Zu der Fehlermeldung siehe oben. Normiere den Richtungsvektor.

|a x M-P| = r*|a| <=> |a x M-P| - r*|a|=0

Der elegantere Code dazu:

Code:

a=1/norm(a)*a;
f=@(x,beta) norm(cross(a,M)-P)-r*norm(a)
 



Aber wie gesagt, ich sehe Probleme damit, dass die Funktion implizit ist!
Private Nachricht senden Benutzer-Profile anzeigen
 
hacke78
Themenstarter

Forum-Anfänger

Forum-Anfänger


Beiträge: 17
Anmeldedatum: 02.06.09
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 23.05.2012, 09:08     Titel:
  Antworten mit Zitat      
Danke erst einmal für deine Hilfe :
ich würde gerne meine Probleme Stück für Stück lösen :
erstmal zum eleganteren Code :
du schreibst da :
Code:

f=@(x,beta) norm(cross(a,M)-P)-r*norm(a)
 

muss das nicht erst einmal heissen :
Code:

f=@(beta,x) norm(cross(a,(M-P)))-r*norm(a)
 

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

cyl = @(b,x) norm(cross(b(1:3),(b(4:6)-x)))-b(7)*norm(b(1:3)) ;
 

Das funktioniert natürlich nicht, weil Operation b(4:6)-x) natürlich nicht erlaubt ist.
Ersetze ich das nun durch :
Code:

cyl = @(b,x) norm(cross(b(1:3),(b(4:6)-x(1,:))))-b(7)*norm(b(1:3)) ;
 

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

Forum-Meister


Beiträge: 799
Anmeldedatum: 02.05.12
Wohnort: ---
Version: R2009b
     Beitrag Verfasst am: 23.05.2012, 14:35     Titel:
  Antworten mit Zitat      
Welche restlichen Gleichungen sollen denn fehlen? Du hast doch einfach nur "cyl" anders geschrieben...
Private Nachricht senden Benutzer-Profile anzeigen
 
hacke78
Themenstarter

Forum-Anfänger

Forum-Anfänger


Beiträge: 17
Anmeldedatum: 02.06.09
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 23.05.2012, 15:41     Titel:
  Antworten mit Zitat      
Hallo
in
Code:

cyl = @(b,x) norm(cross(b(1:3),(b(4:6)-x(1,:))))-b(7)*norm(b(1:3)) ;
 

nutze ich doch nur die erste Zeile von meinem x und nicht das komplette x siehe
Code:
(b(4:6)-x(1,:))

aber
Code:
(b(4:6)-x)

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

Forum-Meister


Beiträge: 799
Anmeldedatum: 02.05.12
Wohnort: ---
Version: R2009b
     Beitrag Verfasst am: 23.05.2012, 15:53     Titel:
  Antworten mit Zitat      
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.
Private Nachricht senden Benutzer-Profile anzeigen
 
MaFam
Forum-Meister

Forum-Meister


Beiträge: 799
Anmeldedatum: 02.05.12
Wohnort: ---
Version: R2009b
     Beitrag Verfasst am: 23.05.2012, 16:31     Titel:
  Antworten mit Zitat      
hacke78 hat Folgendes geschrieben:

...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!
Private Nachricht senden Benutzer-Profile anzeigen
 
hacke78
Themenstarter

Forum-Anfänger

Forum-Anfänger


Beiträge: 17
Anmeldedatum: 02.06.09
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 24.05.2012, 08:37     Titel:
  Antworten mit Zitat      
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 :
Code:

cyl = @(b,x) norm( cross(b(1:3),(b(4:6)-x))) ;
 

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

cyl = @(b,x) norm( cross(b(1:3),(b(4:6)-x(1,:)))) ;
 

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

Forum-Meister


Beiträge: 799
Anmeldedatum: 02.05.12
Wohnort: ---
Version: R2009b
     Beitrag Verfasst am: 24.05.2012, 09:46     Titel:
  Antworten mit Zitat      
So ganz verstehe ich die Problematik nicht. Hier mein Codebeispiel, welches korrekt funktioniert:

Code:

clc
clear all

cyl = @(b,x) norm(cross(b(1:3),(b(4:6)-x)))-b(7)*norm(b(1:3));

% simple Beispieldaten
b_0=[1:7];
x_0=[1:3];
cyl(b_0,x_0)
 
Private Nachricht senden Benutzer-Profile anzeigen
 
hacke78
Themenstarter

Forum-Anfänger

Forum-Anfänger


Beiträge: 17
Anmeldedatum: 02.06.09
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 24.05.2012, 13:47     Titel:
  Antworten mit Zitat      
Das funktioniert bekomme ich halt aber nicht mit einer Matrix für nlinfit ans laufen :
Code:

clc
clear all

cyl = @(b,x) norm(cross(b(1:3),(b(4:6)-x)))-b(7)*norm(b(1:3));
y = ones(4,1);
% simple Beispieldaten
b_0= [1:7];
X=[1:3;4:6;7:9;10:12];
[b, resi] = nlinfit(X,y,cyl,b_0);
 

Danke schoneinmal für deine Mühen.
Private Nachricht senden Benutzer-Profile anzeigen
 
Neues Thema eröffnen Neue Antwort erstellen

Gehe zu Seite 1, 2  Weiter

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.