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 Digital Image/Signal Processing Library 00026 * file .......: ltiTridiagonalEquationSystem.h 00027 * authors ....: Peter Doerfler 00028 * organization: LTI, RWTH Aachen 00029 * creation ...: 15.04.2003 00030 * revisions ..: $Id: ltiTridiagonalEquationSystem.h,v 1.6 2006/02/08 12:49:51 ltilib Exp $ 00031 */ 00032 00033 #ifndef _LTI_TRIDIAGONAL_EQUATION_SYSTEM_H_ 00034 #define _LTI_TRIDIAGONAL_EQUATION_SYSTEM_H_ 00035 00036 #include "ltiEquationSystem.h" 00037 00038 namespace lti { 00039 00040 /** 00041 * Solves a special kind of linear equation system, where only the 00042 * main diagonal and the first lower and upper sub-diagonals are 00043 * non-zero. The solution can be found in O(n) time. Let the system 00044 * be \f$A\cdot x=r\f$ with 00045 * \f[ 00046 * \begin{bmatrix} 00047 * b_1 & c_1 & 0 & 0 & \cdots & & & & \\ 00048 * a_2 & b_2 & c_2 & 0 & \cdots & & & & \vdots \\ 00049 * 0 & & & & \cdots & & & & 0 \\ 00050 * \vdots & & & & \cdots & 0 & a_{n-1} & b_{n-1} & c_{n-1}\\ 00051 * & & & & \cdots & 0 & 0 & a_n & b_n 00052 * \end{bmatrix} \cdot \begin{bmatrix} 00053 * x_1\\ x_2 \\ \vdots \\ x_{n-1}\\ x_n 00054 * \end{bmatrix} = \begin{bmatrix} 00055 * r_1\\ r_2\\ \vdots\\ r_{n-1}\\ r_n \end{bmatrix} 00056 * \f] 00057 * 00058 * The diagonals a, b, and c can be stored in the parameters of this 00059 * functor or given directly via the appropriate apply method. 00060 * 00061 * \b Note: The algorithm does not perform pivoting and can thus 00062 * fail. In this case the apply methods return false. Use 00063 * luSolution or qrSolution instead. 00064 * 00065 * \b Note: The first element of the main diagonal b must not be 0! 00066 */ 00067 template<class T> 00068 class tridiagonalEquationSystem : public linearEquationSystemSolutionMethod<T> { 00069 public: 00070 /** 00071 * tridiagonalEquationSystem parameter class 00072 */ 00073 class parameters : public linearEquationSystemSolutionMethod<T>::parameters { 00074 public: 00075 /** 00076 * default constructor 00077 */ 00078 parameters() 00079 : linearEquationSystemSolutionMethod<T>::parameters() { 00080 a.clear(); b.clear(); c.clear(); 00081 }; 00082 00083 /** 00084 * copy constructor 00085 */ 00086 parameters(const parameters& other) 00087 : linearEquationSystemSolutionMethod<T>::parameters() { 00088 copy(other); 00089 }; 00090 00091 /** 00092 * lower sub-diagonal 00093 */ 00094 vector<T> a; 00095 00096 /** 00097 * main diagonal 00098 */ 00099 vector<T> b; 00100 00101 /** 00102 * upper sub-diagonal 00103 */ 00104 vector<T> c; 00105 00106 /** 00107 * returns the name of this type 00108 */ 00109 virtual const char* getTypeName() const { 00110 return "tridiagonalEquationSystem::parameters"; 00111 }; 00112 00113 /** 00114 * copy member. 00115 */ 00116 parameters& copy(const parameters& other) { 00117 # ifndef _LTI_MSC_6 00118 // MS Visual C++ 6 is not able to compile this... 00119 linearEquationSystemSolutionMethod<T>::parameters::copy(other); 00120 # else 00121 // ...so we have to use this workaround. 00122 // Conditional on that, copy may not be virtual. 00123 functor::parameters& (functor::parameters::* p_copy) 00124 (const functor::parameters&) = functor::parameters::copy; 00125 (this->*p_copy)(other); 00126 # endif 00127 00128 a.copy(other.a); 00129 b.copy(other.b); 00130 c.copy(other.c); 00131 00132 return (*this); 00133 }; 00134 00135 /** 00136 * returns a pointer to a clone of the parameters. 00137 */ 00138 virtual functor::parameters* clone() const { 00139 return (new parameters(*this)); 00140 }; 00141 }; 00142 00143 /** 00144 * default constructor 00145 */ 00146 tridiagonalEquationSystem() : linearEquationSystemSolutionMethod<T>() {}; 00147 00148 /** 00149 * constructor, sets the parameters 00150 */ 00151 tridiagonalEquationSystem(const parameters& theParams); 00152 00153 /** 00154 * constructor, sets the diagonals 00155 * @param a lower sub-diagonal 00156 * @param b main diagonal 00157 * @param c upper sub-diagonal 00158 */ 00159 tridiagonalEquationSystem(const vector<T> a, const vector<T> b, 00160 const vector<T> c); 00161 00162 /** 00163 * returns the current parameters. 00164 */ 00165 const parameters& getParameters() const; 00166 00167 /** 00168 * copy data of "other" functor. 00169 */ 00170 tridiagonalEquationSystem& copy(const tridiagonalEquationSystem& other); 00171 00172 /** 00173 * returns a pointer to a clone of the functor. 00174 */ 00175 virtual functor* clone() const { 00176 return (new tridiagonalEquationSystem<T>(*this)); 00177 }; 00178 00179 /** 00180 * returns the name of this type 00181 */ 00182 virtual const char* getTypeName() const { 00183 return "tridiagonalEquationSystem"; 00184 }; 00185 00186 /** 00187 * onPlace version of apply. 00188 * 00189 * Uses the diagonals from the parameters to calculate a 00190 * solution. \a r also contains the result. 00191 * @param r right side of the equation as input and solution of the 00192 * equation system as output 00193 */ 00194 bool apply(vector<T>& r); 00195 00196 /** onCopy version of apply. 00197 * 00198 * Uses the diagonals from the parameters to calculate a 00199 * solution. 00200 * @param r right side of the equation 00201 * @param x solution of the equation system 00202 */ 00203 bool apply(const vector<T>& r,vector<T>& x); 00204 00205 /** 00206 * Uses the given diagonals instead of those in the parameters to 00207 * calculate the solution. 00208 * @param a lower sub-diagonal 00209 * @param b main diagonal 00210 * @param c upper sub-diagonal 00211 * @param r right side of the equation 00212 * @param x solution of the equation system 00213 */ 00214 bool apply(const vector<T>& a, const vector<T>& b, const vector<T>& c, 00215 const vector<T>& r, vector<T>& x); 00216 00217 }; 00218 00219 } 00220 00221 #endif