2010-10-14 34 views
1

Je suis actuellement en train d'écrire une fonction pour trouver une sphère de délimitation "exacte" pour un ensemble de points dans l'espace 3D. Je pense que j'ai une bonne compréhension du processus jusqu'à maintenant, mais je me suis coincé.Trouver des vecteurs propres de la matrice de covariance pour créer une sphère de délimitation 3D

Voici ce que je travaille avec: A) Points dans l'espace 3D B) de la matrice de covariance 3x3 stockées dans une classe de matrice 4x4 (référencé par les cellules m0, m1, m2, m3, m4, ect, au lieu de lignes et cols)

J'ai trouvé les 3 valeurs propres pour la matrice de covariance des points, et j'ai mis en place une fonction pour convertir une matrice en forme d'échelon de ligne réduite (rref) via l'élimination gaussienne.

J'ai testé ces deux fonctions par rapport aux figures des exemples que j'ai trouvés en ligne, et elles semblent fonctionner correctement.

L'étape suivante consiste à trouver les vecteurs propres en utilisant l'équation: (M - & lambda; * I) * V

... où M est la matrice de covariance, et lambda; est l'une des valeurs propres, I est la matrice d'identité, et V est le vecteur propre.

Cependant, je ne semble pas construire correctement la matrice 4x3 avant de la ré-exécuter, car la colonne la plus à droite où les composantes propres du vecteur doivent être calculées est 0 avant et après l'exécution de rref. Je comprends pourquoi ils sont nuls après (sans constantes, la solution la plus simple à un système linéaire d'équations est tous les coefficients de zéro), mais je ne sais pas quoi mettre là.

est ici la fonction jusqu'à présent:

 
Vect eigenVector(const Matrix &M, const float eval) { 
    Matrix A = Matrix(M); 
    A -= Matrix(IDENTITY)*eval; 
    A.rref(); 
    return Vect(A[m3],A[m7],A[m11]); 
} 

La matrice de covariance 3x3 est passé comme M, et la valeur propre comme eval. Matrix (IDENTITY) renvoie une matrice d'identité. m3, m7 et m11 correspondent à la colonne d'extrême droite d'une matrice 4x3.

est ici l'exemple matrice 3x3 (stockée dans une classe de matrice 4x4) J'utilise pour tester les fonctions:

 
Matrix(1.5f, 0.5f, 0.75f, 0, 
     0.5f, 0.5f, 0.25f, 0, 
     0.75f, 0.25f, 0.5f, 0, 
      0,  0, 0, 0); 

Je suis bien obtenir les valeurs propres de 2,097, 0,3055, 0,09756 de (?) mon autre fonction.

vecteur propre() soustrait au-dessus de la valeur propre correctement passé de la diagonale (0,0 1,1 2,2)

matrice A après Rref():

 
[(1, 0, 0, -0), 
(-0, 1, 0, -0), 
(-0, -0, 1, -0), 
(0, 0, 0, -2.09694)] 

Pour la Rref() fonction, j'utilise une fonction python traduite trouvée ici: http://elonen.iki.fi/code/misc-notes/python-gaussj/index.html

Que devrait faire la matrice que je passe à rref() pour obtenir un vecteur propre?

Merci

Répondre

1

(M - & lambda; I) V n'est pas une équation, il est juste une expression. Cependant, (M - & lambda; I) V = 0 est. Et c'est l'équation qui relie les vecteurs propres aux valeurs propres.Donc, en supposant que votre fonction rref fonctionne, j'imagine que vous créez une matrice augmentée comme [(M - λI) | 0], où 0 indique un zéro-vecteur. Cela ressemble à ce que vous faites déjà, donc je devrais supposer que votre fonction rref est cassée. Ou encore, il ne sait pas comment gérer les matrices 4x4 (contrairement aux matrices 4x3, ce qui est ce à quoi il s'attendrait pour une matrice augmentée).

+0

C'est ce que je pensais aussi, et j'ai passé pas mal de temps à essayer différentes variantes. Ce qui se passait réellement, je pense, était que <0,0,0> est l'une des solutions infinies qui résout ce système d'équations linéaires. Je devais d'abord lancer le système avec une valeur arbitraire avant de pouvoir obtenir des résultats significatifs. Voir ma réponse ci-dessous pour ce que j'ai fini par faire. Merci d'avoir pris le temps de donner un coup de main, bien que :) –

1

Ah, après quelques heures de recherches exténuantes, j'ai réussi à résoudre mon problème. Le problème est qu'il n'y a pas de "un" ensemble de vecteurs propres mais plutôt un nombre infini avec des amplitudes variables. La méthode que j'ai choisie consistait à utiliser une forme REF (rangée échelonnée) au lieu de RREF, laissant suffisamment d'informations dans la matrice pour me permettre de substituer une valeur arbitraire pour z, et retravailler pour y et x. J'ai ensuite normalisé le vecteur pour obtenir un vecteur propre d'unité, ce qui devrait fonctionner pour mes fins.

Mon code final:

 
Vect eigenVector(const Matrix &M, const float eVal) { 
    Matrix A = Matrix(M); 
    A -= Matrix(IDENTITY)*eVal; 
    A.ref(); 
    float K = 16; // Arbitrary value 
    float J = -K*A[m6]; // Substitute in K to find J 
    float I = -K*A[m2]-J*A[m1]; // Substitute in K and J to find I 

    Vect eVec = Vect(I,J,K); 
    eVec.norm(); // Normalize eigenvector 

    return eVec; 
} 

La seule chose bizarre est que les vecteurs propres sortent face dans la direction opposée que prévu (ils ont été réduits à néant!), Mais c'est un problème sans objet.