latest version v1.9 - last update 10 Apr 2010 |
00001 /* 00002 * Copyright (C) 1999, 2000, 2001, 2002, 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 .......: ltiArray.h 00027 * authors ....: Pablo Alvarado 00028 * organization: LTI, RWTH Aachen 00029 * creation ...: 09.04.99 00030 * revisions ..: $Id: ltiArray.h,v 1.12 2006/02/08 12:11:50 ltilib Exp $ 00031 */ 00032 00033 #ifndef _LTI_ARRAY_H_ 00034 #define _LTI_ARRAY_H_ 00035 00036 #include "ltiVector.h" 00037 #include "ltiAssert.h" 00038 00039 namespace lti { 00040 /** 00041 * Array class. 00042 * 00043 * A n-dimensional array indexed between \a from and \a to, where 00044 * <em>to-from+1 = n</em>. The indices \a from and \a to can be negative, 00045 * but \a from must be lower or equal \a to. 00046 * 00047 * All inherited arithmetical operations still need to be reviewed, since 00048 * the vector methods will only check if the size \a n of the array is 00049 * correct. Use these operations at your own risk. It is safer if you use 00050 * the on-place version of the arithmetical methods, since they won't change 00051 * the index range of the array. Otherwise, the range will be change to 00052 * [0,n-1]. 00053 * 00054 * @ingroup gAggregate 00055 */ 00056 template<class T> class array : public vector<T> { 00057 public: 00058 /** 00059 * default constructor creates an empty array; 00060 */ 00061 array(); 00062 00063 /** 00064 * constructor. 00065 * creates an array indexed between \p from and \p to 00066 * and initializes it with \p iniValue 00067 */ 00068 array(int from,int to,const T& iniValue = T()); 00069 00070 00071 /** 00072 * copy constructor. 00073 * copy contents of \p other array in this array. 00074 */ 00075 array(const array<T>& other); 00076 00077 /** 00078 * copy constructor. 00079 * copy contents of \p other vector in this array. 00080 */ 00081 array(const vector<T>& other,int theOffset=0); 00082 00083 /** 00084 * If \a init is true this constructor is equivalent to calling 00085 * array(int theSize), and thus initializing 00086 * all elements with T(). However, in some cases the elements need 00087 * not be initialized during construction, since complex 00088 * initializion is required. Especially for large arrays, the 00089 * unnecessary constructor initialization is very time consuming. 00090 * 00091 * If \a init is false, memory is allocated but no initialization 00092 * takes place. 00093 * 00094 * @param init initialize matrix or not 00095 * @param from first index 00096 * @param to last index 00097 */ 00098 array(bool init, int from, int to); 00099 00100 00101 /** 00102 * destructor 00103 */ 00104 virtual ~array(); 00105 00106 /** 00107 * returns the name of this type 00108 */ 00109 virtual const char* getTypeName() const; 00110 00111 /** 00112 * change the dimension and/or range of the array. 00113 * 00114 * If the new dimension of the array (to-from+1) is different from 00115 * the old one or if this array doesn't own the data, new memory 00116 * is allocated. 00117 * 00118 * If \p copyData is true the data is copied according to the 00119 * indices, e.g. if the old array is (-2, 2) and contains the 00120 * values 0 to 4 and a resize(0,4,10) is performed the new array 00121 * will be [2, 3, 4, 10, 10]. If the indices don't overlap no 00122 * copying takes place. 00123 * 00124 * To adjust the range of an array, i.e. the data contained and 00125 * the size stays the same, but the start and end indices change, 00126 * use shift(int). 00127 * 00128 * If the new size is not equal to the old size (i.e. to-from+1), 00129 * the array always owns the data afterwards (i.e. new memory is 00130 * allocated) even if it didn't own the data before. Otherwise the 00131 * ownership remains unchanged. You can use restoreOwnership() if 00132 * you just want to own the data. 00133 */ 00134 void resize(int from, 00135 int to, 00136 const T& iniValue = T(), 00137 bool copyData = true, 00138 bool initNew = true); 00139 00140 /** 00141 * Shift all indices of the array by the given value \p 00142 * sh. Negative values result in a left shift, positive values in 00143 * a right shift. 00144 * 00145 * An array with range (-2,2) will have range (0,4) after shift(2) 00146 * is performed. 00147 */ 00148 void shift(int sh); 00149 00150 /** 00151 * fills the array with value \p data between \p from 00152 * and \p to. 00153 */ 00154 void fill(const T& data, int from = MinInt32, 00155 int to = MaxInt32); 00156 00157 /** 00158 * returns first index. the returned value is equal to \p from by 00159 * construction or resizing. 00160 */ 00161 inline int firstIdx() const {return firstArrayElement;}; 00162 00163 /** 00164 * change the first index of the array, without changing the content 00165 */ 00166 void setFirstIdx(int newIdx); 00167 00168 /** 00169 * returns last index. 00170 * the returned value is equal to \p to by contruction or 00171 * resizing 00172 */ 00173 inline int lastIdx() const {return lastArrayElement;}; 00174 00175 /** 00176 * access operator. 00177 * access element x with firstIdx() <= x <= lastIdx(). 00178 */ 00179 inline T& at(int x) { 00180 assert ( (firstIdx() <= x) && (x <= lastIdx()) ); 00181 assert ( this->theElements != 0 ); 00182 return ( theElement0[x] ); 00183 }; 00184 00185 /** 00186 * const access operator. 00187 * access element x with firstIdx() <= x <= lastIdx(). 00188 */ 00189 inline const T& at(int x) const { 00190 assert ( (firstIdx() <= x) && (x <= lastIdx()) ); 00191 assert ( this->theElements != 0 ); 00192 return ( theElement0[x] ); 00193 }; 00194 00195 /** 00196 * access operator (alias for at(x)). 00197 */ 00198 inline T& operator[](int x) {return at(x);}; 00199 00200 /** 00201 * const access operator (alias for at(x)) 00202 */ 00203 inline const T& operator[](int x) const {return at(x);}; 00204 00205 /** 00206 * assigment operator. 00207 * copy content of vector \p other 00208 */ 00209 array<T>& copy(const vector<T>& other); 00210 00211 /** 00212 * assigment operator. 00213 * copy content of array \p other 00214 */ 00215 array<T>& copy(const array<T>& other); 00216 00217 /** 00218 * assigment operator. (alias for copy(other). 00219 */ 00220 array<T>& operator=(const vector<T>& other) {return copy(other);}; 00221 00222 /** 00223 * assigment operator. (alias for copy(other). 00224 */ 00225 array<T>& operator=(const array<T>& other) {return copy(other);}; 00226 00227 /** 00228 * cast and copy the elements of the "other" array 00229 */ 00230 template<class U> 00231 array<T>& castFrom(const array<U>& other) { 00232 00233 vector<T>::castFrom(other); 00234 00235 offset = -other.firstIdx(); 00236 firstArrayElement = other.firstIdx(); 00237 lastArrayElement = other.lastIdx(); 00238 theElement0 = this->theElements + offset; 00239 00240 return (*this); 00241 } 00242 00243 00244 /** 00245 * @name Apply Methods 00246 */ 00247 //@{ 00248 00249 /** 00250 * applies a C-function to each element of the array. 00251 * 00252 * In the following example, %array \a vct is initialized with 00253 * 4.0. After applying \a sqrt(), all elements of \a vct are 2.0. 00254 * \code 00255 * array<float> vct(4,4.0); 00256 * vct.apply(sqrt); 00257 * \endcode 00258 * @param function a pointer to a C-function 00259 * @return a reference to the actual array 00260 */ 00261 array<T>& apply(T (*function)(T)); 00262 00263 /** 00264 * applies a C-function to each element of the other array and leaves 00265 * the result here. 00266 * @param other the source array 00267 * @param function a pointer to a C-function 00268 * @return a reference to the actual array 00269 */ 00270 array<T>& apply(const array<T>& other,T (*function)(T)); 00271 00272 /** 00273 * applies a C-function to each element of the array. 00274 * @param function a pointer to a C-function 00275 * @return a reference to the actual array 00276 */ 00277 array<T>& apply(T (*function)(const T&)); 00278 00279 /** 00280 * applies a C-function to each element the other array and 00281 * leaves the result here. 00282 * @param other the array with the source data 00283 * @param function a pointer to a C-function 00284 * @return a reference to the actual array 00285 */ 00286 array<T>& apply(const array<T>& other,T (*function)(const T&)); 00287 00288 /** 00289 * a two-parameter C-function receives the i-th elements of this 00290 * and the given array and the result will be left in this 00291 * array. Note that both arrays MUST have the same size! 00292 * If both arrays have different size, the function will throw an 00293 * assertion without changing anything! 00294 * @param other the second array to be considered (the first 00295 * array will be this object!) 00296 * @param function a pointer to a two parameters C-function 00297 * @return a reference to the actual array 00298 */ 00299 array<T>& apply(const array<T>& other,T (*function)(const T&,const T&)); 00300 00301 /** 00302 * a two-parameter C-function receives the i-th elements of this 00303 * and the given array and the result will be left in this 00304 * array. Note that both arrays MUST have the same size! 00305 * If both arrays have different size, the function will throw an 00306 * assertion without changing anything! 00307 * @param other the second array to be considered (the first 00308 * array will be this object!) 00309 * @param function a pointer to a two parameters C-function 00310 * @return a reference to the actual array 00311 */ 00312 array<T>& apply(const array<T>& other,T (*function)(T,T)); 00313 00314 /** 00315 * a two-parameter C-function receives the i-th elements of the 00316 * given arrays and leaves the result here. 00317 * Note that both arrays MUST have the same size! 00318 * If both arrays have different size, the function will throw an 00319 * assertion without changing anything! 00320 * 00321 * The following example uses lti::min as function. The arrays \a 00322 * a and \a b contain the values [1,2,3,4] and [4,3,2,1], 00323 * respectively. After applying the function, %array \a c 00324 * contains the values [1,2,2,1]. 00325 * \code 00326 * iarray a,b,c; 00327 * int i=0; 00328 * for (i=0; i<4; ++i) { 00329 * a.at(i)=i+1; 00330 * b.at(i)=4-i; 00331 * } 00332 * c.apply(a,b,lti::min); 00333 * \endcode 00334 * @param a the first array 00335 * @param b the second array 00336 * @param function a pointer to a two parameters C-function 00337 * @return a reference to the actual array 00338 */ 00339 array<T>& apply(const array<T>& a, 00340 const array<T>& b, 00341 T (*function)(const T&,const T&)); 00342 00343 /** 00344 * a two-parameter C-function receives the i-th elements of the 00345 * given arrays and leaves the result here. 00346 * Note that both arrays MUST have the same size! 00347 * If both arrays have different size, the function will throw an 00348 * assertion without changing anything! 00349 * @param a the first array 00350 * @param b the second array 00351 * @param function a pointer to a two parameters C-function 00352 * @return a reference to the actual array 00353 */ 00354 array<T>& apply(const array<T>& a, 00355 const array<T>& b, 00356 T (*function)(T,T)); 00357 00358 //@} 00359 00360 00361 /** 00362 * write the object in the given ioHandler 00363 */ 00364 virtual bool write(ioHandler& handler,const bool complete = true) const; 00365 00366 /** 00367 * read the object from the given ioHandler 00368 */ 00369 virtual bool read(ioHandler& handler,const bool complete = true); 00370 00371 00372 protected: 00373 /** 00374 * offset for the 0-th element 00375 */ 00376 int offset; 00377 00378 /** 00379 * index of the first element of the array 00380 */ 00381 int firstArrayElement; 00382 00383 /** 00384 * index of the last element of the array. 00385 * 00386 * if the array is casted to a vector, the "lastIdx()" should return 00387 * size()-1 instead of the array lastIdx!. That's the reason why 00388 * we use a new member for the last index in the array! 00389 */ 00390 int lastArrayElement; 00391 00392 /** 00393 * A pointer to the element at index 0 00394 * (This allows a faster access than adding the offset each time) 00395 */ 00396 T* theElement0; 00397 }; 00398 00399 } 00400 00401 #endif