kmatrix_impl.hpp

Go to the documentation of this file.
00001 // This file is part of kfilter.
00002 // kfilter is a C++ variable-dimension extended kalman filter library.
00003 //
00004 // Copyright (C) 2004        Vincent Zalzal, Sylvain Marleau
00005 // Copyright (C) 2001, 2004  Richard Gourdeau
00006 // Copyright (C) 2004        GRPR and DGE's Automation sector
00007 //                           École Polytechnique de Montréal
00008 //
00009 // Code adapted from algorithms presented in :
00010 //      Bierman, G. J. "Factorization Methods for Discrete Sequential
00011 //      Estimation", Academic Press, 1977.
00012 //
00013 // This library is free software; you can redistribute it and/or
00014 // modify it under the terms of the GNU Lesser General Public
00015 // License as published by the Free Software Foundation; either
00016 // version 2.1 of the License, or (at your option) any later version.
00017 //
00018 // This library is distributed in the hope that it will be useful,
00019 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00020 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00021 // Lesser General Public License for more details.
00022 //
00023 // You should have received a copy of the GNU Lesser General Public
00024 // License along with this library; if not, write to the Free Software
00025 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00026 
00027 #ifndef KMATRIX_IMPL_HPP
00028 #define KMATRIX_IMPL_HPP
00029 
00032 
00033 #include <strstream>
00034 
00035 namespace Kalman {
00036 
00038 
00045   class KMatrixContextImpl {
00046   public:
00047 
00049 
00057     KMatrixContextImpl(std::string elemDelim = " ",
00058                        std::string rowDelim = "\n",
00059                        std::string startDelim = std::string(),
00060                        std::string endDelim = std::string(),
00061                        unsigned prec = 4) 
00062       : elemDelim_(elemDelim), rowDelim_(rowDelim), startDelim_(startDelim), 
00063         endDelim_(endDelim), precision_(prec), width_(8+prec) {
00064       
00065       std::string ws(" \t\n");
00066       skipElemDelim_  = 
00067         ( elemDelim_.find_first_not_of(ws) != std::string::npos);
00068       skipRowDelim_   = 
00069         (  rowDelim_.find_first_not_of(ws) != std::string::npos);
00070       skipStartDelim_ = 
00071         (startDelim_.find_first_not_of(ws) != std::string::npos);
00072       skipEndDelim_   = 
00073         (  endDelim_.find_first_not_of(ws) != std::string::npos);
00074     }
00075 
00076     std::string elemDelim_;  
00077     std::string rowDelim_;   
00078     std::string startDelim_; 
00079     std::string endDelim_;   
00080     unsigned precision_;     
00081     unsigned width_;         
00082     bool skipElemDelim_;     
00083     bool skipRowDelim_;      
00084     bool skipStartDelim_;    
00085     bool skipEndDelim_;      
00086   };
00087 
00089 
00092   extern KMatrixContextImpl* currentMatrixContext;
00093 
00103   template<typename T, K_UINT_32 BEG, bool DBG>
00104   inline void KMatrix<T, BEG, DBG>::init(K_UINT_32 m, K_UINT_32 n) {
00105 
00106     if (m != 0 && n != 0) {
00107 
00108       // non-empty matrix
00109       vimpl_.resize(m);
00110       T* ptr = &Mimpl_[0] - BEG;
00111       T** M = &vimpl_[0];
00112       T** end = M + m;
00113       
00114       while (M != end) {
00115         *M++ = ptr;
00116         ptr += n;
00117       }
00118 
00119       M_ = &vimpl_[0] - BEG;
00120       m_ = m;
00121       n_ = n;
00122 
00123     } else {
00124 
00125       // empty matrix
00126       M_ = 0;
00127       m_ = 0;
00128       n_ = 0;
00129 
00130     }
00131 
00132   }
00133 
00134   template<typename T, K_UINT_32 BEG, bool DBG>
00135   inline KMatrix<T, BEG, DBG>::KMatrix() {
00136     init(0, 0);
00137   }
00138 
00143   template<typename T, K_UINT_32 BEG, bool DBG>
00144   inline KMatrix<T, BEG, DBG>::KMatrix(K_UINT_32 m, K_UINT_32 n)
00145     : Mimpl_(m*n) { 
00146     init(m, n);
00147   }
00148 
00154   template<typename T, K_UINT_32 BEG, bool DBG>
00155   inline KMatrix<T, BEG, DBG>::KMatrix(K_UINT_32 m, K_UINT_32 n, const T& a)
00156     : Mimpl_(m*n, a) {
00157     init(m, n);
00158   }
00159 
00171   template<typename T, K_UINT_32 BEG, bool DBG>
00172   inline KMatrix<T, BEG, DBG>::KMatrix(K_UINT_32 m, K_UINT_32 n, const T* v)
00173     : Mimpl_(v, v + m*n) {
00174     init(m, n);
00175   }
00176 
00179   template<typename T, K_UINT_32 BEG, bool DBG>
00180   inline KMatrix<T, BEG, DBG>::KMatrix(const KMatrix& M) 
00181     : Mimpl_(M.Mimpl_) {
00182     init(M.m_, M.n_);
00183   }
00184 
00185   template<typename T, K_UINT_32 BEG, bool DBG>
00186   inline KMatrix<T, BEG, DBG>::~KMatrix() {}
00187 
00193   template<typename T, K_UINT_32 BEG, bool DBG>
00194   inline T& KMatrix<T, BEG, DBG>::operator()(K_UINT_32 i, 
00195                                              K_UINT_32 j) {
00196     if (DBG) {
00197       if (i < BEG || i >= m_ + BEG || j < BEG || j >= n_ + BEG) {
00198         std::ostrstream oss;
00199         oss << "Trying to access element (" << i << ", " << j 
00200             << ") not included in [" << BEG << ", " << m_ + BEG - 1 << "][" 
00201             << BEG << ", " << n_ + BEG - 1 << "]." << '\0';
00202         throw OutOfBoundError(oss.str());
00203       }
00204     }
00205     return M_[i][j];
00206   }
00207 
00213   template<typename T, K_UINT_32 BEG, bool DBG>
00214   inline const T& KMatrix<T, BEG, DBG>::operator()(K_UINT_32 i, 
00215                                                    K_UINT_32 j) const {
00216     if (DBG) {
00217       if (i < BEG || i >= m_ + BEG || j < BEG || j >= n_ + BEG) {
00218         std::ostrstream oss;
00219         oss << "Trying to access element (" << i << ", " << j 
00220             << ") not included in [" << BEG << ", " << m_ + BEG - 1 << "][" 
00221             << BEG << ", " << n_ + BEG - 1 << "]." << '\0';
00222         throw OutOfBoundError(oss.str());
00223       }
00224     }
00225     return M_[i][j];
00226   }
00227 
00230   template<typename T, K_UINT_32 BEG, bool DBG>
00231   inline K_UINT_32 KMatrix<T, BEG, DBG>::nrow() const {
00232     return m_;
00233   }
00234 
00237   template<typename T, K_UINT_32 BEG, bool DBG>
00238   inline K_UINT_32 KMatrix<T, BEG, DBG>::ncol() const {
00239     return n_;
00240   }
00241 
00250   template<typename T, K_UINT_32 BEG, bool DBG>
00251   inline void KMatrix<T, BEG, DBG>::resize(K_UINT_32 m, K_UINT_32 n) {
00252 
00253     if (m == m_ && n == n_) {
00254       return;
00255     }
00256 
00257     Mimpl_.resize(m*n);
00258     init(m, n);
00259   }
00260 
00263   template<typename T, K_UINT_32 BEG, bool DBG>
00264   inline KMatrix<T, BEG, DBG>& KMatrix<T, BEG, DBG>::operator=(const T& a) {
00265     
00266     T* ptr = &Mimpl_[0];
00267     const T* end = ptr + Mimpl_.size();
00268 
00269     while (ptr != end) {
00270       *ptr++ = a;
00271     }
00272     return *this;
00273   }
00274 
00278   template<typename T, K_UINT_32 BEG, bool DBG>
00279   inline KMatrix<T, BEG, DBG>& 
00280   KMatrix<T, BEG, DBG>::operator=(const KMatrix& M) {
00281     KMatrix temp(M);
00282     swap(temp);    
00283     return *this;
00284   }
00285 
00293   template<typename T, K_UINT_32 BEG, bool DBG>
00294   inline void KMatrix<T, BEG, DBG>::assign(K_UINT_32 m, K_UINT_32 n, 
00295                                            const T* v) {
00296     KMatrix temp(m, n, v);
00297     swap(temp);
00298   }
00299 
00305   template<typename T, K_UINT_32 BEG, bool DBG>
00306   inline void KMatrix<T, BEG, DBG>::swap(KMatrix& M) {
00307     vimpl_.swap(M.vimpl_);
00308     Mimpl_.swap(M.Mimpl_);
00309     Util::swap(M_, M.M_);
00310     Util::swap(m_, M.m_);
00311     Util::swap(n_, M.n_);
00312   }
00313 
00320   template<typename T, K_UINT_32 BEG, bool DBG>
00321   inline void KMatrix<T, BEG, DBG>::get(std::istream& is) {
00322 
00323     T* ptr = &Mimpl_[0];
00324     std::string tmp;
00325     K_UINT_32 i, j;
00326 
00327     if (currentMatrixContext->skipStartDelim_) {
00328       is >> tmp;
00329     }
00330 
00331     if (currentMatrixContext->skipRowDelim_) {
00332 
00333       if (currentMatrixContext->skipElemDelim_) {
00334 
00335         for (i = 0; i < m_-1; ++i) {
00336           for (j = 0; j < n_; ++j) {
00337             is >> *ptr++ >> tmp;
00338           }
00339         }
00340 
00341         for (j = 0; j < n_-1; ++j) {
00342           is >> *ptr++ >> tmp;
00343         }
00344 
00345         is >> *ptr;
00346 
00347       } else {
00348 
00349         for (i = 0; i < m_-1; ++i) {
00350           for (j = 0; j < n_; ++j) {
00351             is >> *ptr++;
00352           }
00353           is >> tmp;
00354         }
00355 
00356         for (j = 0; j < n_; ++j) {
00357           is >> *ptr++;
00358         }
00359 
00360       }
00361 
00362     } else {
00363 
00364       if (currentMatrixContext->skipElemDelim_) {
00365 
00366         for (i = 0; i < m_; ++i) {
00367           for (j = 0; j < n_-1; ++j) {
00368             is >> *ptr++ >> tmp;
00369           }
00370           is >> *ptr++;
00371         }
00372 
00373       } else {
00374 
00375         for (i = 0; i < m_; ++i) {
00376           for (j = 0; j < n_; ++j) {
00377             is >> *ptr++;
00378           }
00379         }
00380 
00381       }
00382 
00383     }
00384 
00385     if (currentMatrixContext->skipEndDelim_) {
00386       is >> tmp;
00387     }
00388   }
00389 
00396   template<typename T, K_UINT_32 BEG, bool DBG>
00397   inline void KMatrix<T, BEG, DBG>::put(std::ostream& os) const {
00398     if (m_ == 0 || n_ == 0) {
00399       return;
00400     }
00401 
00402     const T* ptr = &Mimpl_[0];
00403     K_UINT_32 i, j;
00404 
00405     std::ios::fmtflags f = os.setf(std::ios::scientific, std::ios::floatfield);
00406     os.setf(std::ios::showpoint);
00407     std::streamsize p = os.precision(currentMatrixContext->precision_);
00408 
00409     os << currentMatrixContext->startDelim_;
00410 
00411     for (i = 0; i < m_-1; ++i) {
00412       for (j = 0; j < n_-1; ++j) {
00413         os.width(currentMatrixContext->width_);
00414         os << *ptr++ << currentMatrixContext->elemDelim_;
00415       }
00416       os.width(currentMatrixContext->width_);
00417       os << *ptr++ << currentMatrixContext->rowDelim_;
00418     }
00419 
00420     for (j = 0; j < n_-1; ++j) {
00421       os.width(currentMatrixContext->width_);
00422       os << *ptr++ << currentMatrixContext->elemDelim_;
00423     }
00424 
00425     os.width(currentMatrixContext->width_);
00426     os << *ptr++ << currentMatrixContext->endDelim_;
00427 
00428     os.precision(p);
00429     os.flags(f);
00430   }
00431 
00436   template<typename T, K_UINT_32 BEG, bool DBG>
00437   inline std::istream& operator>>(std::istream& is, 
00438                                   KMatrix<T, BEG, DBG>& M) {
00439     M.get(is);
00440     return is;
00441   }
00442 
00447   template<typename T, K_UINT_32 BEG, bool DBG>
00448   inline std::ostream& operator<<(std::ostream& os, 
00449                                   const KMatrix<T, BEG, DBG>& M) {
00450     M.put(os);
00451     return os;
00452   }
00453 
00454 }
00455 
00456 #endif

Generated on Sat Jan 28 21:02:01 2006 for KFilter by  doxygen 1.4.5