latest version v1.9 - last update 10 Apr 2010 |
00001 /* 00002 * Copyright (C) 2003, 2004, 2005, 2006 00003 * Lehrstuhl fuer Technische Informatik, RWTH-Aachen, Germany 00004 * 00005 * This file is part of the LTI-Computer Vision Library (LTI-Lib) 00006 * 00007 * The LTI-Lib is free software; you can redistribute it and/or 00008 * modify it under the terms of the GNU Lesser General Public License (LGPL) 00009 * as published by the Free Software Foundation; either version 2.1 of 00010 * the License, or (at your option) any later version. 00011 * 00012 * The LTI-Lib is distributed in the hope that it will be 00013 * useful, but WITHOUT ANY WARRANTY; without even the implied warranty 00014 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 * GNU Lesser General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU Lesser General Public 00018 * License along with the LTI-Lib; see the file LICENSE. If 00019 * not, write to the Free Software Foundation, Inc., 59 Temple Place - 00020 * Suite 330, Boston, MA 02111-1307, USA. 00021 */ 00022 00023 00024 /*-------------------------------------------------------------------- 00025 * project ....: LTI-Lib: Image Processing and Computer Vision Library 00026 * file .......: ltiBackSubstitution.h 00027 * authors ....: Peter Doerfler 00028 * organization: LTI, RWTH Aachen 00029 * creation ...: 20.5.2003 00030 * revisions ..: $Id: ltiBackSubstitution.h,v 1.10 2006/02/08 12:12:17 ltilib Exp $ 00031 */ 00032 00033 #ifndef _LTI_BACK_SUBSTITUTION_H_ 00034 #define _LTI_BACK_SUBSTITUTION_H_ 00035 00036 #include "ltiLinearAlgebraFunctor.h" 00037 #include "ltiVector.h" 00038 #include "ltiMatrix.h" 00039 #include "ltiTriangularMatrixType.h" 00040 00041 namespace lti { 00042 /** 00043 * Backsubstitution. Let \a L be a lower triangular matrix and 00044 * \a U an upper triangular matrix. Backsubstitution solves the 00045 * following linear equation systems for \a x: 00046 * 00047 * U*x=b or x*L=b 00048 * 00049 * In the first case, \a x and \a b are column vectors, in the latter 00050 * case they are row vectors. The data %matrix can be given to 00051 * the functor via the parameters or directly in the apply 00052 * methods. There are also apply methods that calculate the 00053 * backsubstitution for multiple right-sides \a b. The vectors are 00054 * treated as before, ie they are in columns for the first case and 00055 * in rows for the second. 00056 * 00057 * \b Note that the column vector matrix will be transposed twice 00058 * and thus takes longer to compute, try to use the vector-apply 00059 * instead. 00060 * 00061 * @see lti::backSubstitution 00062 */ 00063 template<class T> 00064 class backSubstitution : public linearAlgebraFunctor { 00065 public: 00066 /** 00067 * the parameters for the class backSubstitution 00068 */ 00069 class parameters 00070 : public linearAlgebraFunctor::parameters, 00071 virtual public triangularMatrixType { 00072 public: 00073 00074 /** 00075 * default constructor. The triangularType is Upper by default. 00076 */ 00077 parameters() : linearAlgebraFunctor::parameters(), theMatrix() { 00078 //TODO: Initialize your parameter values! 00079 // If you add more parameters manually, do not forget to do following: 00080 // 1. indicate in the default constructor the default values 00081 // 2. make sure that the copy member also copy your new parameters 00082 // 3. make sure that the read and write members also read and 00083 // write your parameters 00084 00085 triangularType = Upper; 00086 }; 00087 00088 /** 00089 * copy constructor 00090 * @param other the parameters object to be copied 00091 */ 00092 parameters(const parameters& other) : linearAlgebraFunctor::parameters() { 00093 copy(other); 00094 } 00095 00096 /** 00097 * destructor 00098 */ 00099 ~parameters() { 00100 }; 00101 00102 /** 00103 * returns name of this type 00104 */ 00105 const char* getTypeName() const { 00106 return "backSubstitution::parameters"; 00107 }; 00108 00109 /** 00110 * copy the contents of a parameters object 00111 * @param other the parameters object to be copied 00112 * @return a reference to this parameters object 00113 */ 00114 parameters& copy(const parameters& other) { 00115 # ifndef _LTI_MSC_6 00116 // MS Visual C++ 6 is not able to compile this... 00117 linearAlgebraFunctor::parameters::copy(other); 00118 # else 00119 // ...so we have to use this workaround. 00120 // Conditional on that, copy may not be virtual. 00121 functor::parameters& (functor::parameters::* p_copy) 00122 (const functor::parameters&) = 00123 functor::parameters::copy; 00124 (this->*p_copy)(other); 00125 # endif 00126 triangularMatrixType::copy(other); 00127 00128 theMatrix.copy(other.theMatrix); 00129 00130 return *this; 00131 }; 00132 00133 /** 00134 * copy the contents of a parameters object 00135 * @param other the parameters object to be copied 00136 * @return a reference to this parameters object 00137 */ 00138 parameters& operator=(const parameters& other) { 00139 return copy(other); 00140 }; 00141 00142 /** 00143 * returns a pointer to a clone of the parameters 00144 */ 00145 virtual functor::parameters* clone() const { 00146 return new parameters(*this); 00147 }; 00148 00149 # ifndef _LTI_MSC_6 00150 /** 00151 * write the parameters in the given ioHandler 00152 * @param handler the ioHandler to be used 00153 * @param complete if true (the default) the enclosing begin/end will 00154 * be also written, otherwise only the data block will be written. 00155 * @return true if write was successful 00156 */ 00157 virtual bool write(ioHandler& handler,const bool complete=true) const 00158 # else 00159 /** 00160 * this function is required by MSVC only, as a workaround for a 00161 * very awful bug, which exists since MSVC V.4.0, and still by 00162 * V.6.0 with all bugfixes (so called "service packs") remains 00163 * there... This method is also public due to another bug, so please 00164 * NEVER EVER call this method directly: use write() instead 00165 */ 00166 bool writeMS(ioHandler& handler,const bool complete=true) const 00167 # endif 00168 { 00169 bool b = true; 00170 if (complete) { 00171 b = handler.writeBegin(); 00172 } 00173 00174 if (b) { 00175 00176 lti::write(handler,"theMatrix", theMatrix); 00177 00178 } 00179 00180 # ifndef _LTI_MSC_6 00181 // This is the standard C++ code, which MS Visual C++ 6 is not able to 00182 // compile... 00183 b = b && linearAlgebraFunctor::parameters::write(handler,false); 00184 # else 00185 bool (linearAlgebraFunctor::parameters::* p_writeMS)(ioHandler&, 00186 const bool) const = 00187 linearAlgebraFunctor::parameters::writeMS; 00188 b = b && (this->*p_writeMS)(handler,false); 00189 # endif 00190 b = b && triangularMatrixType::write(handler,false); 00191 00192 if (complete) { 00193 b = b && handler.writeEnd(); 00194 } 00195 00196 return b; 00197 } 00198 00199 # ifdef _LTI_MSC_6 00200 /** 00201 * write the parameters in the given ioHandler 00202 * @param handler the ioHandler to be used 00203 * @param complete if true (the default) the enclosing begin/end will 00204 * be also written, otherwise only the data block will be written. 00205 * @return true if write was successful 00206 */ 00207 bool write(ioHandler& handler, 00208 const bool complete=true) const { 00209 // ...we need this workaround to cope with another really 00210 // awful MSVC bug. 00211 return writeMS(handler,complete); 00212 } 00213 # endif 00214 00215 00216 # ifndef _LTI_MSC_6 00217 /** 00218 * read the parameters from the given ioHandler 00219 * @param handler the ioHandler to be used 00220 * @param complete if true (the default) the enclosing begin/end will 00221 * be also written, otherwise only the data block will be written. 00222 * @return true if write was successful 00223 */ 00224 virtual bool read(ioHandler& handler,const bool complete=true) 00225 # else 00226 /** 00227 * this function is required by MSVC only, as a workaround for a 00228 * very awful bug, which exists since MSVC V.4.0, and still by 00229 * V.6.0 with all bugfixes (so called "service packs") remains 00230 * there... This method is also public due to another bug, so please 00231 * NEVER EVER call this method directly: use read() instead 00232 */ 00233 bool readMS(ioHandler& handler,const bool complete=true) 00234 # endif 00235 { 00236 bool b = true; 00237 if (complete) { 00238 b = handler.readBegin(); 00239 } 00240 00241 if (b) { 00242 00243 lti::read(handler,"theMatrix", theMatrix); 00244 } 00245 00246 # ifndef _LTI_MSC_6 00247 // This is the standard C++ code, which MS Visual C++ 6 is not 00248 // able to compile... 00249 b = b && linearAlgebraFunctor::parameters::read(handler,false); 00250 # else 00251 bool (linearAlgebraFunctor::parameters::* p_readMS)(ioHandler&, 00252 const bool) = 00253 linearAlgebraFunctor::parameters::readMS; 00254 b = b && (this->*p_readMS)(handler,false); 00255 # endif 00256 b = b && triangularMatrixType::read(handler,false); 00257 00258 if (complete) { 00259 b = b && handler.readEnd(); 00260 } 00261 00262 return b; 00263 } 00264 00265 # ifdef _LTI_MSC_6 00266 /** 00267 * read the parameters from the given ioHandler 00268 * @param handler the ioHandler to be used 00269 * @param complete if true (the default) the enclosing begin/end will 00270 * be also written, otherwise only the data block will be written. 00271 * @return true if write was successful 00272 */ 00273 bool read(ioHandler& handler,const bool complete=true) { 00274 // ...we need this workaround to cope with another really awful MSVC 00275 // bug. 00276 return readMS(handler,complete); 00277 } 00278 # endif 00279 00280 // ------------------------------------------------ 00281 // the parameters 00282 // ------------------------------------------------ 00283 00284 00285 /** 00286 * The data matrix. 00287 */ 00288 matrix<T> theMatrix; 00289 00290 }; 00291 00292 /** 00293 * default constructor 00294 */ 00295 backSubstitution(); 00296 00297 /** 00298 * constructor, sets the data matrix and its triangular type in 00299 * the parameters. 00300 * 00301 * \b Note: Using this constructor, the data matrix is copied 00302 * twice (Once to internally put it into a parameters object and 00303 * then when setting the parameters). It can be better to let 00304 * parameters::theMatrix use the data of some matrix you have: 00305 * 00306 * \code 00307 * matrix<double> myData; //let this contain the data 00308 * backSubstitution<double>::parameters param; 00309 * param.theMatrix.useExternData(myData.rows(),myData.columns(),&myData.at(0,0)) 00310 * backSubstitution<double> mySubst(param); 00311 * \endcode 00312 * 00313 * The fastest method is to use one of the apply-methods where the 00314 * data matrix is an argument. 00315 * 00316 * @param theMatrix the data matrix 00317 * @param tType triangularType of \a theMatrix 00318 */ 00319 backSubstitution(const matrix<T>& theMatrix, 00320 const typename parameters::eTriangularType& tType= 00321 parameters::Lower); 00322 00323 /** 00324 * Construct a functor using the given parameters 00325 */ 00326 backSubstitution(const parameters& par); 00327 00328 /** 00329 * copy constructor 00330 * @param other the object to be copied 00331 */ 00332 backSubstitution(const backSubstitution& other); 00333 00334 /** 00335 * destructor 00336 */ 00337 virtual ~backSubstitution(); 00338 00339 /** 00340 * returns the name of this type ("backSubstitution") 00341 */ 00342 virtual const char* getTypeName() const; 00343 00344 //TODO: comment your apply methods! 00345 00346 00347 /** 00348 * Performs backsubstitution with unknown \a x. U*x=b if \a 00349 * theMatrix is upper triagonal and x*L=b if \a theMatrix is lower 00350 * triagonal. The result \a x is left in \a b. The matrix in the 00351 * parameters is used. 00352 * 00353 * @param b the right side of the backsubstitution. The result 00354 * will be left here too. 00355 * @return true if apply successful or false otherwise. 00356 */ 00357 bool apply(vector<T>& b) const; 00358 00359 /** 00360 * Performs backsubstitution with unknown \a x. U*x=b if \a 00361 * theMatrix is upper triagonal and x*L=b if \a theMatrix is lower 00362 * triagonal. The matrix in the parameters is used. 00363 * 00364 * @param b the right side of the backsubstitution. 00365 * @param x the result. 00366 * @return true if apply successful or false otherwise. 00367 */ 00368 bool apply(const vector<T>& b, vector<T>& x) const; 00369 00370 /** 00371 * Performs backsubstitution with unknown \a x. U*x=b if \a 00372 * theMatrix is upper triagonal and x*L=b if \a theMatrix is lower 00373 * triagonal. The result \a x is left in \a b. 00374 * 00375 * @param theMatrix data matrix (L or U) 00376 * @param b the right side of the backsubstitution. The result 00377 * will be left here too. 00378 * @param tType defines whether theMatrix is lower or upper triangular 00379 * @return true if apply successful or false otherwise. 00380 */ 00381 bool apply(const matrix<T>& theMatrix, vector<T>& b, 00382 const typename parameters::eTriangularType& tType) const; 00383 00384 /** 00385 * Performs backsubstitution with unknown \a x. U*x=b if \a 00386 * theMatrix is upper triagonal and x*L=b if \a theMatrix is lower 00387 * triagonal. 00388 * 00389 * @param theMatrix data matrix (L or U) 00390 * @param b the right side of the backsubstitution. The result 00391 * will be left here too. 00392 * @param x the result. 00393 * @param tType defines whether theMatrix is lower or upper triangular 00394 * @return true if apply successful or false otherwise. 00395 */ 00396 bool apply(const matrix<T>& theMatrix, const vector<T>& b, 00397 vector<T>& x, 00398 const typename parameters::eTriangularType& tType) const; 00399 00400 00401 /** 00402 * Performs backsubstitution with unknowns \a X. U*X=B if \a 00403 * theMatrix is upper triagonal and X*L=B if \a theMatrix is lower 00404 * triagonal. In the first case \a X and \a B contain the vectors 00405 * in colums, in the latter case in rows. The result \a x is left 00406 * in \a b. The matrix in the parameters is used. 00407 * 00408 * @param b the right side of the backsubstitution. The result 00409 * will be left here too. 00410 * @return true if apply successful or false otherwise. 00411 */ 00412 bool apply(matrix<T>& b) const; 00413 00414 /** 00415 * Performs backsubstitution with unknowns \a X. U*X=B if \a 00416 * theMatrix is upper triagonal and X*L=B if \a theMatrix is lower 00417 * triagonal. In the first case \a X and \a B contain the vectors 00418 * in colums, in the latter case in rows. The data matrix in the 00419 * parameters is used. 00420 * 00421 * @param b the right side of the backsubstitution. 00422 * @param x the result 00423 * @return true if apply successful or false otherwise. 00424 */ 00425 bool apply(const matrix<T>& b, matrix<T>& x) const; 00426 00427 /** 00428 * Performs backsubstitution with unknowns \a X. U*X=B if \a 00429 * theMatrix is upper triagonal and X*L=B if \a theMatrix is lower 00430 * triagonal. In the first case \a X and \a B contain the vectors 00431 * in colums, in the latter case in rows. The result \a x is left 00432 * in \a b. 00433 * 00434 * @param theMatrix data matrix (L or U) 00435 * @param b the right side of the backsubstitution. The result 00436 * will be left here too. 00437 * @param tType defines whether theMatrix is lower or upper triangular 00438 * @return true if apply successful or false otherwise. 00439 */ 00440 bool apply(const matrix<T>& theMatrix, matrix<T>& b, 00441 const typename parameters::eTriangularType& tType) const; 00442 00443 /** 00444 * Performs backsubstitution with unknowns \a X. U*X=B if \a 00445 * theMatrix is upper triagonal and X*L=B if \a theMatrix is lower 00446 * triagonal. In the first case \a X and \a B contain the vectors 00447 * in colums, in the latter case in rows. 00448 * 00449 * @param theMatrix data matrix (L or U) 00450 * @param b the right side of the backsubstitution. The result 00451 * will be left here too. 00452 * @param x the result 00453 * @param tType defines whether theMatrix is lower or upper triangular 00454 * @return true if apply successful or false otherwise. 00455 */ 00456 bool apply(const matrix<T>& theMatrix, const matrix<T>& b, 00457 matrix<T>& x, 00458 const typename parameters::eTriangularType& tType) const; 00459 00460 /** 00461 * copy data of "other" functor. 00462 * @param other the functor to be copied 00463 * @return a reference to this functor object 00464 */ 00465 backSubstitution& copy(const backSubstitution& other); 00466 00467 /** 00468 * alias for copy member 00469 * @param other the functor to be copied 00470 * @return a reference to this functor object 00471 */ 00472 backSubstitution& operator=(const backSubstitution& other); 00473 00474 /** 00475 * returns a pointer to a clone of this functor. 00476 */ 00477 virtual functor* clone() const; 00478 00479 /** 00480 * returns used parameters 00481 */ 00482 const parameters& getParameters() const; 00483 00484 //TODO: comment the attributes of your functor 00485 // If you add more attributes manually, do not forget to do following: 00486 // 1. indicate in the default constructor the default values 00487 // 2. make sure that the copy member also copy your new attributes, or 00488 // to ensure there, that these attributes are properly initialized. 00489 00490 }; 00491 } 00492 00493 #endif