Jafar
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
gaussian.hpp
Go to the documentation of this file.
00001 
00010 #ifndef GAUSSIAN_HPP_
00011 #define GAUSSIAN_HPP_
00012 
00013 #include <string.h>
00014 #include "jmath/jblas.hpp"
00015 #include "jmath/indirectArray.hpp"
00016 #include "rtslam/rtslamException.hpp"
00017 
00018 #define ENABLE_REINIT 0
00019 
00020 namespace jafar {
00021   namespace rtslam {
00022 
00023 #if ENABLE_REINIT
00024     /*
00025      * This functions use really dirty memcpy, but it is the only way to truly reinit a vec_indirect (change its reference),
00026      * which is necessary if we don't know the size of the state of an object before its construction
00027      * (which is the case e.g. for a robot when sensors require additional state parameters to be estimated).
00028      * It works ok because closure_type is a vector_reference that only contain references and no pointer.
00029      */
00030 
00031     template<class V, class V2>
00032     void vec_indirect_init(ublas::vector_indirect<V> & vi, V2 & v, jblas::ind_array const & ia)
00033     {
00034       typename V::closure_type d(v);
00035       memcpy(&vi.data(), &d, sizeof(typename V::closure_type));
00036       vi.indirect() = ia;
00037     }
00038 
00039     template<class M, class M2>
00040     void mat_indirect_init(ublas::matrix_indirect<M> & mi, M2 & m, jblas::ind_array const & ia1, jblas::ind_array const & ia2)
00041     {
00042       typename M::closure_type d(m);
00043       memcpy(&mi.data(), &d, sizeof(typename M::closure_type));
00044       mi.indirect1() = ia1;
00045       mi.indirect2() = ia2;
00046     }
00047 #endif
00048 
00050     //    CLASS Gaussian
00052 
00173     class Gaussian {
00174       public:
00178         typedef enum {
00179           REMOTE, 
00180           LOCAL, 
00181           UNCHANGED 
00182         } storage_t;
00183 
00184       private:
00185         bool hasNullCov_; 
00186         std::size_t size_; 
00187         storage_t storage_; 
00188         jblas::vec x_local; 
00189         jblas::sym_mat P_local; 
00190         jblas::ind_array ia_; 
00191         jblas::vec_indirect x_; 
00192         jblas::sym_mat_indirect P_; 
00193 
00194       public:
00195 
00196 #if ENABLE_REINIT
00197         void init(Gaussian & g)
00198         {
00199           vec_indirect_init(x_, g.x_.data().expression(), g.ia_);
00200           mat_indirect_init(P_, g.P_.data().expression(), g.ia_, g.ia_);
00201         }
00202         void init(jblas::vec & x, jblas::sym_mat & P, jblas::ind_array const & ia)
00203         {
00204           vec_indirect_init(x_, x, ia);
00205           mat_indirect_init(P_, P, ia, ia);
00206         }
00207 #endif
00208 
00209         Gaussian() :
00210           hasNullCov_ (false),
00211           size_       (0),
00212           storage_    (LOCAL),
00213           x_local     (0),
00214           P_local     (0, 0),
00215           ia_         (0),
00216           x_          (x_local, ia_.all()),
00217           P_          (P_local, ia_.all(), ia_.all())
00218         {}
00219 
00225         inline Gaussian(const size_t _size) :
00226           hasNullCov_ (false),
00227           size_       (_size),
00228           storage_    (LOCAL),
00229           x_local     (size_),
00230           P_local     (size_, size_),
00231           ia_         (size_),
00232           x_          (x_local, ia_.all()),
00233           P_          (P_local, ia_.all(), ia_.all())
00234         {
00235           clear();
00236           for (size_t i = 0; i < size_; i++)
00237             ia_(i) = i;
00238         }
00239 
00240 #if ENABLE_REINIT
00241 
00244         virtual void operator()(const size_t _size)
00245         {
00246           hasNullCov_  = false;
00247           size_        = _size;
00248           storage_     = LOCAL;
00249           x_local.resize(size_);
00250           P_local.resize(size_, size_);
00251           ia_          = jmath::ublasExtra::ia_set(0, size_);
00252           init(x_local, P_local, ia_);
00253           //x_           = jblas::vec_indirect(x_local, ia_.all());
00254           //P_           = jblas::sym_mat_indirect(P_local, ia_.all(), ia_.all());
00255           clear();
00256         }
00257 #endif
00258 
00265         inline Gaussian(const jblas::vec & _x) :
00266           hasNullCov_ (true),
00267           size_       (_x.size()),
00268           storage_    (LOCAL),
00269           x_local     (_x),
00270           P_local     (size_, size_),
00271           ia_         (size_),
00272           x_          (x_local, ia_.all()),
00273           P_          (P_local, ia_.all(), ia_.all())
00274         {
00275           for (size_t i = 0; i < size_; i++)
00276             ia_(i) = i;
00277         }
00278 
00279 
00287         inline Gaussian(const jblas::vec& _x, const jblas::sym_mat& _P) :
00288           hasNullCov_ (false),
00289           size_       (_x.size()),
00290           storage_    (LOCAL),
00291           x_local     (_x),
00292           P_local     (_P),
00293           ia_         (size_),
00294           x_          (x_local, ia_.all()),
00295           P_          (P_local, ia_.all(), ia_.all())
00296         {
00297           JFR_ASSERT(_x.size() == _P.size1(), "gaussian::Gaussian():: x and P sizes do not match.");
00298           for (size_t i = 0; i < size_; i++)
00299             ia_(i) = i;
00300         }
00301 
00302 
00313         // Thanks to C. Roussillon for this constructor.
00314         inline Gaussian(const Gaussian & G, storage_t _storage = UNCHANGED) :
00315           hasNullCov_ (G.hasNullCov_),
00316           size_       (G.size_),
00317           //        # check storage       ?              # is local                                  : # is remote
00318           storage_(_storage == UNCHANGED  ?  G.storage_                                              : _storage),
00319           x_local (_storage == LOCAL      ?  G.x_                                                    : G.x_local),
00320           P_local (_storage == LOCAL      ?  G.P_                                                    : G.P_local),
00321           ia_     (_storage == LOCAL      ?  jafar::jmath::ublasExtra::ia_set(0, size_)              : G.ia_),
00322           x_      (storage_ == LOCAL      ?  jblas::vec_indirect     (x_local, ia_.all())            : G.x_),
00323           P_      (storage_ == LOCAL      ?  jblas::sym_mat_indirect (P_local, ia_.all(), ia_.all()) : G.P_)
00324         {
00325         }
00326 
00327 #if ENABLE_REINIT
00328 
00331         virtual void operator()(Gaussian & G, storage_t _storage = UNCHANGED)
00332         {
00333           hasNullCov_ = G.hasNullCov_;
00334           size_ = G.size_;
00335           //       #     check storage       ?              # is local                                  : # is remote
00336           storage_ = (_storage == UNCHANGED  ?  G.storage_                                              : _storage);
00337           x_local  = (_storage == LOCAL      ?  G.x_                                                    : G.x_local);
00338           P_local  = (_storage == LOCAL      ?  G.P_                                                    : G.P_local);
00339           ia_      = (_storage == LOCAL      ?  jafar::jmath::ublasExtra::ia_set(0, size_)              : G.ia_);
00340           if         (storage_ == LOCAL)        init(x_local, P_local, ia_.all());                   else init(G);
00341 //          x_       = (storage_ == LOCAL      ?  jblas::vec_indirect     (x_local, ia_.all())            : G.x_);
00342 //          P_       = (storage_ == LOCAL      ?  jblas::sym_mat_indirect (P_local, ia_.all(), ia_.all()) : G.P_);
00343         }
00344 #endif
00345 
00358         inline Gaussian(Gaussian & G, const jblas::ind_array & _ia) :
00359           hasNullCov_ (false),
00360           size_       (_ia.size()),
00361           storage_    (REMOTE),
00362           x_local     (0),
00363           P_local     (0),
00364           //     # check storage   ?                   # is local                   :             # is remote
00365           ia_(G.storage_ == LOCAL  ?  _ia                                           : G.ia_.compose(_ia)),
00366           x_ (G.storage_ == LOCAL  ?  jblas::vec_indirect     (G.x_local, ia_)      : jblas::vec_indirect     (G.x_.data(), ia_, 1)     ),
00367           P_ (G.storage_ == LOCAL  ?  jblas::sym_mat_indirect (G.P_local, ia_, ia_) : jblas::sym_mat_indirect (G.P_.data(), ia_, ia_, 1))
00368         {
00369         }
00370 
00371 #if ENABLE_REINIT
00372 
00375         virtual void operator()(Gaussian & G, const jblas::ind_array & _ia)
00376         {
00377           hasNullCov_ = false;
00378           size_       = _ia.size();
00379           storage_    = REMOTE;
00380           x_local.resize(0);
00381           P_local.resize(0);
00382           //     # check storage   ?                   # is local                   :             # is remote
00383           ia_ = (G.storage_ == LOCAL  ?  _ia                                           : G.ia_.compose(_ia));
00384           if    (G.storage_ == LOCAL)    init(G.x_local, G.P_local, ia_);           else init(G.x_.data().expression(), G.P_.data().expression(), ia_);
00385           //x_  = (G.storage_ == LOCAL  ?  jblas::vec_indirect     (G.x_local, ia_)      : jblas::vec_indirect     (G.x_.data(), ia_, 1)     );
00386           //P_  = (G.storage_ == LOCAL  ?  jblas::sym_mat_indirect (G.P_local, ia_, ia_) : jblas::sym_mat_indirect (G.P_.data(), ia_, ia_, 1));
00387         }
00388 #endif
00389 
00390 
00401         inline Gaussian(jblas::vec & _x, jblas::sym_mat & _P, const jblas::ind_array& _ia) :
00402           hasNullCov_ (false),
00403           size_       (_ia.size()),
00404           storage_    (REMOTE),
00405           x_local     (0),
00406           P_local     (0),
00407           ia_         (_ia),
00408           x_          (_x, ia_),
00409           P_          (_P, ia_, ia_)
00410         {
00411           JFR_ASSERT(_x.size() == _P.size1(), "gaussian::Gaussian():: x and P sizes do not match.");
00412         }
00413 
00414 #if ENABLE_REINIT
00415 
00418         virtual void operator()(jblas::vec & _x, jblas::sym_mat & _P, const jblas::ind_array& _ia)
00419         {
00420           hasNullCov_ = false;
00421           size_       = _ia.size();
00422           storage_    = REMOTE;
00423           x_local.resize(0);
00424           P_local.resize(0);
00425           ia_         = _ia;
00426           init(_x, _P, ia_);
00427 //          x_          = jblas::vec_indirect    (_x, ia_);
00428 //          P_          = jblas::sym_mat_indirect(_P, ia_, ia_);
00429           JFR_ASSERT(_x.size() == _P.size1(), "gaussian::Gaussian():: x and P sizes do not match.");
00430         }
00431 #endif
00432 
00433         void resize(size_t n, bool preserve = true)
00434         {
00435           JFR_ASSERT(storage_ == LOCAL, "cannot extend a LOCAL storage gaussian with size_t!");
00436           size_ = n;
00437           x_local.resize(size_, preserve);
00438           P_local.resize(size_, size_, preserve);
00439 
00440           ia_ = jmath::ublasExtra::ia_set(0, size_);
00441           x_.indirect() = ia_;
00442           P_.indirect1() = ia_;
00443           P_.indirect2() = ia_;
00444 
00445         }
00446 
00447         void resize(const jblas::ind_array& _ia)
00448         {
00449           JFR_ASSERT(storage_ == REMOTE, "cannot extend a LOCAL storage gaussian with ind_array!");
00450           ia_ = _ia;
00451           size_ = ia_.size();
00452           x_.indirect() = ia_;
00453           P_.indirect1() = ia_;
00454           P_.indirect2() = ia_;
00455         }
00456 
00457         void extend(size_t n)
00458         {
00459           resize(size_+n, true);
00460         }
00461 
00462         void extend(const jblas::ind_array& _ia)
00463         {
00464           resize(jmath::ublasExtra::ia_union(ia_, _ia));
00465         }
00466 
00467 
00468         // Getters
00469         inline bool                      hasNullCov() const    { return hasNullCov_; }
00470         inline storage_t                 storage() const       { return storage_;    }
00471         inline size_t                    size() const          { return size_;       }
00472         inline jblas::ind_array        & ia()                  { return ia_;         }
00473         inline const jblas::ind_array  & ia() const            { return ia_;         }
00474         inline jblas::vec_indirect     & x()                   { return x_;          }
00475         inline const jblas::vec_indirect & x() const           { return x_;          }
00476         inline jblas::sym_mat_indirect & P()                   { return P_;          }
00477         inline const jblas::sym_mat_indirect & P() const       { return P_;          }
00478         inline double                  & x(size_t i)           { return x_(i);       }
00479         inline double                  & P(size_t i, size_t j) { return P_(i, j);    }
00480 
00481          // Setters
00482         inline void  storage(const storage_t & _s) {
00483           storage_ = _s;
00484           if (_s == REMOTE)
00485             hasNullCov_ = false;
00486         }
00487         inline void  hasNullCov(bool _hasNullCov) {
00488           hasNullCov_ = _hasNullCov;
00489         }
00490         inline void  x(const jblas::vec & _x) {
00491           JFR_ASSERT(_x.size() == size_, "gaussian.hpp: set_x: size mismatch.");
00492           x_.assign(_x);
00493         }
00494         inline void  P(const jblas::sym_mat & _P) {
00495           JFR_ASSERT(_P.size1() == size_, "gaussian.hpp: set_P: size mismatch.");
00496           hasNullCov_ = false;
00497           P_.assign(_P);
00498         }
00499 
00504         inline void std(const jblas::vec& _std) {
00505           JFR_ASSERT(_std.size() == P_.size1(), "gaussian.hpp: set_P: size mismatch.");
00506           hasNullCov_ = false;
00507           P_.assign(jblas::zero_mat(size_));
00508           for (std::size_t i = 0; i < size_; i++) {
00509             P_(i, i) = _std(i) * _std(i);
00510           }
00511         }
00512 
00517         inline void std(double _std) {
00518           hasNullCov_ = false;
00519           P_.assign(jblas::zero_mat(size_));
00520           for (std::size_t i = 0; i < size_; i++) {
00521             P_(i, i) = _std * _std;
00522           }
00523         }
00524 
00532         inline void P(const jblas::mat & M, const jblas::ind_array & ia1, const jblas::ind_array & ia2) {
00533           hasNullCov_ = false;
00534           project(P_local, ia1, ia2) = M;
00535         }
00536 
00541         virtual void clear(void) {
00542           x_.assign(jblas::zero_vec(size_));
00543           P_.assign(jblas::zero_mat(size_, size_));
00544         }
00545 
00546 
00551         double probabilityDensity(const jblas::vec& v) const;
00552 
00559         friend std::ostream& operator <<(std::ostream & s, Gaussian const & g_) {
00560 
00561           if (g_.storage() == LOCAL) {
00562             if (g_.hasNullCov()) {
00563               s << std::endl << "  .x : " << g_.x_ << std::endl;
00564             }
00565             else { // Null covariance
00566               s << std::endl << "  .x : " << g_.x_ << std::endl;
00567               s << "  .P : " << g_.P_;
00568             }
00569           }
00570           else { // REMOTE
00571             s << "  .ia: " << g_.ia_ << std::endl;
00572             s << "  .x : " << g_.x_ << std::endl;
00573             s << "  .P : " << g_.P_;
00574           }
00575           return s;
00576         }
00577 
00578     };
00579 
00580   }
00581 }
00582 
00583 #endif /* GAUSSIAN_HPP_ */
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Generated on Wed Oct 15 2014 00:37:26 for Jafar by doxygen 1.7.6.1
LAAS-CNRS