From 976b5047eef9b56956ef5bcc392c0c2730f4f331 Mon Sep 17 00:00:00 2001 From: gaillaro Date: Sun, 10 Apr 2005 11:22:09 +0000 Subject: calcul des eigenvalues et eigenvectors finis --- 2005/i/robert/src/ovision/see/hotelling.cc | 100 ++++++++++++++++++++---- 2005/i/robert/src/ovision/see/hotelling.hh | 59 +++++++++++--- 2005/i/robert/src/ovision/see/test_hotelling.cc | 46 +++++++++++ 3 files changed, 178 insertions(+), 27 deletions(-) create mode 100644 2005/i/robert/src/ovision/see/test_hotelling.cc (limited to '2005/i/robert/src/ovision/see') diff --git a/2005/i/robert/src/ovision/see/hotelling.cc b/2005/i/robert/src/ovision/see/hotelling.cc index b492510..ac490d0 100644 --- a/2005/i/robert/src/ovision/see/hotelling.cc +++ b/2005/i/robert/src/ovision/see/hotelling.cc @@ -7,46 +7,63 @@ #include "hotelling.hh" /// Constructeur -Hotelling::Hotelling (const std::vector &dataList) +Hotelling::Hotelling (const std::vector &dataList) { - e1_[0] = 0; e1_[1] = 0; e2_[0] = 0; e2_[1] = 0; oconfig_ = OConfig::getInstance (); - dataSize_ = dataList.size (); if (dataSize_ == 0) - { meanX_ = meanY_ = 0; - } else { + // Calcul de la moyenne mean (dataList); - data_[0] = new uint8_t[dataSize_]; - data_[1] = new uint8_t[dataSize_]; + // Initialisation des données + data_ = new Hpoint[dataSize_]; + // Changement de repère des données + int i = 0; + for (std::vector::const_iterator iter = dataList.begin (); + iter != dataList.end (); ++iter) + { + data_[i].set ((*iter)[0] - meanX_, (*iter)[1] - meanY_); + ++i; + } } - } /// Destructeur Hotelling::~Hotelling (void) { - delete [] covMatrix_; delete [] data_; } +/// Covariance +double +Hotelling::cov (const unsigned i, const unsigned j) +{ + double c = 0; + for (unsigned k = 0; k < dataSize_; ++k) + c += data_[k][i] * data_[k][j]; + c /= (dataSize_-1); + return c; +} + /// Calcul de la matrice de covariance -uint8_t* -Hotelling::cov () +void +Hotelling::covMatrix () { - uint8_t *tab; - return tab; + /// Calcul de la covariance + covMatrix_[0][0] = cov (0, 0); + covMatrix_[0][1] = cov (0, 1); + covMatrix_[1][0] = covMatrix_[0][1]; + covMatrix_[1][1] = cov (1, 1); } /// Calcul de la moyenne des deux composantes void -Hotelling::mean (const std::vector &dataList) +Hotelling::mean (const std::vector &dataList) { meanX_ = meanY_ = 0; - for (std::vector::const_iterator iter = dataList.begin (); + for (std::vector::const_iterator iter = dataList.begin (); iter != dataList.end (); ++iter) { meanX_ += (*iter)[0]; @@ -56,9 +73,62 @@ Hotelling::mean (const std::vector &dataList) meanY_ /= dataSize_; } +/// Calcul des eigenvalues +void +Hotelling::eigenValues () +{ + double apd = covMatrix_[0][0] + covMatrix_[1][1]; + double sqrtdelta = sqrt (apd*apd - 4* (covMatrix_[0][0]*covMatrix_[1][1] - covMatrix_[1][0]*covMatrix_[1][0])); + val1_ = (apd - sqrtdelta)/(2); + val2_ = (apd + sqrtdelta)/(2); +} + + /// Calcul des eigenvectors void Hotelling::eigenVectors () { + covMatrix (); + eigenValues (); + // Calcul des vecteurs + e2_.set (1, covMatrix_[1][0] / (val2_ - covMatrix_[1][1])); + e1_.set (1, covMatrix_[1][0] / (val1_ - covMatrix_[1][1])); + // Normalisation + e1_.norm (); + e2_.norm (); +} + +/// Accessors +void +Hotelling::getPC (Hpoint &pca) +{ + if (val1_>val2_) pca = e1_; + else pca = e2_; +} +void +Hotelling::getPC (double &x, double &y) +{ + Hpoint h; + getPC (h); + x = h[0]; y = h[1]; } +/// Affiche la matrice de covariance +void +Hotelling::showCovMatrix () const +{ + std::cout << "Matrice de covariance :\n" + << "\t" << covMatrix_[0][0] << "\n" + << "\t" << covMatrix_[0][1] << "\n" + << "\t" << covMatrix_[1][0] << "\n" + << "\t" << covMatrix_[1][1] << std::endl; +} + +/// Affiche les eigenvectors +void +Hotelling::showEigenVectors () const +{ + std::cout << "EigenVectors :\n" + << "\t" << e1_[0] << ", " << e1_[1] << "\n" + << "\t" << e2_[0] << ", " << e2_[1] << std::endl; +} diff --git a/2005/i/robert/src/ovision/see/hotelling.hh b/2005/i/robert/src/ovision/see/hotelling.hh index e3ac8bb..8acf3b3 100644 --- a/2005/i/robert/src/ovision/see/hotelling.hh +++ b/2005/i/robert/src/ovision/see/hotelling.hh @@ -27,39 +27,74 @@ #include "oconfig.hh" +class Hpoint +{ + double p_[2]; + public: + Hpoint () {p_[0]=0; p_[1]=0;} + Hpoint (const int i, const int j) {set (i, j);} + inline double operator [] (const unsigned i) const {return i<2?p_[i]:0;} + inline Hpoint& operator = (Hpoint &h) + { + if (&h != this) + { + h.p_[0] = p_[0]; + h.p_[1] = p_[1]; + } + return *this; + } + inline void set (const double i, const double j) + {p_[0]=i; p_[1]=j;} + inline void norm () + { + double n = sqrt (p_[0]*p_[0] + p_[1]*p_[1]); + p_[0] /= n; p_[1] /= n; + } +}; + /// Detecte l'orientation principale d'une masse de données class Hotelling { /// Classe oconfig OConfig *oconfig_; /// Matrice de covariance - uint8_t covMatrix_[2][2]; + double covMatrix_[2][2]; /// Données à traitées ajustées - uint8_t *data_[2]; + Hpoint *data_; /// Nombre d'échantillons de données unsigned dataSize_; /// Moyenne de la première et deuxième composante - int meanX_, meanY_; + double meanX_, meanY_; + /// EigenValues + double val1_, val2_; /// EigenVectors - uint8_t e1_[2], e2_[2]; + Hpoint e1_, e2_; public: /// Constructeur - Hotelling (const std::vector &dataList); + Hotelling (const std::vector &dataList); /// Destructeur ~Hotelling (void); + /// Affiche la matrice de covariance + void showCovMatrix () const; + /// Affiche les eigenvectors + void showEigenVectors () const; + /// Calcul des eigenvectors + void eigenVectors (); /// Accessors - void getEigenVectors (uint8_t* &e1, uint8_t* &e2) - {e1 = e1_; e2 = e2_;} - void getPCA (uint8_t* &pca) {pca = e1_;} + void getPC (Hpoint &pca); + void getPC (double &x, double &y); private: + /// Calcul des eigenvalues + void eigenValues (); + /// Calcul de la variance + double cov (const unsigned i, const unsigned j); /// Calcul de la matrice de covariance - uint8_t* cov (); + void covMatrix (); /// Calcul de la moyenne - void mean (const std::vector &dataList); - /// Calcul des eigenvectors - void eigenVectors (); + void mean (const std::vector &dataList); }; + #endif // hotelling_h diff --git a/2005/i/robert/src/ovision/see/test_hotelling.cc b/2005/i/robert/src/ovision/see/test_hotelling.cc new file mode 100644 index 0000000..5288e73 --- /dev/null +++ b/2005/i/robert/src/ovision/see/test_hotelling.cc @@ -0,0 +1,46 @@ +// test_hotelling.cc +// robert - Programme du robot APBteam +// Copyright (C) 2005 Olivier Gaillard + +#include +#include +#include + +#include "oconfig.hh" +#include "hotelling.hh" + +int +main(int argc, char **argv) +{ + ///////////////////////////////////////////////////////////////////////////////////////// + /// Initialisation de oconfig + OConfig *oconfig_; + try + { + oconfig_ = new OConfig ("rc/vision.conf"); + } + catch (std::string &e) + { + std::cerr << e << std::endl; + return 1; + } + ///////////////////////////////////////////////////////////////////////////////////////// + /// Initialisation des données + const int dataSize = 10; + double t [] = {2.5, 2.4, 0.5, 0.7, 2.2, 2.9, 1.9, 2.2, 3.1, 3.0, + 2.3, 2.7, 2, 1.6, 1, 1.1, 1.5, 1.6, 1.1, 0.9}; + Hpoint d; + std::vector list; + for (int i=0; i