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 .......: ltiVector.h 00027 * authors ....: Pablo Alvarado 00028 * organization: LTI, RWTH Aachen 00029 * creation ...: 09.04.99 00030 * revisions ..: $Id: ltiVector.h,v 1.12 2006/02/08 12:52:54 ltilib Exp $ 00031 */ 00032 00033 #ifndef _LTI_VECTOR_H_ 00034 #define _LTI_VECTOR_H_ 00035 00036 #include "ltiMathObject.h" 00037 #include "ltiException.h" 00038 #include <vector> 00039 00040 #define _LTI_GENERIC_VECTOR_DONT_INSTANTIATE_REQUEST 00041 #include "ltiGenericVector.h" 00042 #undef _LTI_GENERIC_VECTOR_DONT_INSTANTIATE_REQUEST 00043 00044 namespace lti { 00045 /** 00046 * Vector container class. 00047 * 00048 * The lti::vector class allows the representation of n-dimensional vectors. 00049 * The elements of the vector will be indexed between 0 an n-1. 00050 * 00051 * Note that this class is NOT intended to be a subtitute for std::vector. 00052 * If you need a vector of elements which use some sort of dynamic memory 00053 * allocation then you should use the std::vector class of the Standard 00054 * Template Library. 00055 * 00056 * Only following types are supported by lti::vector: 00057 * - ubyte 00058 * - byte 00059 * - signed/unsigned int 00060 * - long 00061 * - float 00062 * - double 00063 * - rgbPixel 00064 * - trgbPixel<float> 00065 * - point 00066 * - tpoint<float> 00067 * - tpoint<double> 00068 * - tpoint3D<float> 00069 * - complex<float> 00070 * - complex<double> 00071 * 00072 * If you need the vector as container of any other type, consider using the 00073 * std::vector or the lti::genericVector. 00074 * 00075 * The vector class is a container class implemented as template, but it is 00076 * by no means a generic container, since the types it supports must fulfill 00077 * many requirenments, specially support for all arithmetical operators. 00078 * 00079 * If you need to create a vector of floats with 256 elements all 00080 * initialized with a value of 4.27 just create it: 00081 * 00082 * \code 00083 * lti::vector<float> myVct(256,4.27f) // creates vector with 256 elements 00084 * // all initialized with 4.27f 00085 * \endcode 00086 * 00087 * To access the vector elements use the access operators at() (or the 00088 * overloaded operator[]()). For example: 00089 * 00090 * 00091 * \code 00092 * float accu = 0; // initialize accumulator 00093 * 00094 * for (int i = 0; i < myVct.size(); i++) { 00095 * tmp += myVct.at(i); // access each element of the vector 00096 * } 00097 * \endcode 00098 * 00099 * The vector has following methods: 00100 * - Constructors Constructors 00101 * - You can construct an empty vector with the default constructor 00102 * (vector()). 00103 * - If you know the number of elements use 00104 * vector(const int& size,const T& initialValue) 00105 * - You can create the copy of another vector with the copy constructor 00106 * (vector(const vector<T>& otherVector)) 00107 * - You can create a vector with a copy of the data of a C++ array 00108 * the constructor (vector(const int& theSize,const T data[])) 00109 * - Access members 00110 * - at(), operator[]() 00111 * - The size() member returns the number of elements of the vector. 00112 * - empty() returns true if the size of the vector is zero. 00113 * - The firstIdx() will return in a vector always 0 and the lastIdx() 00114 * will be always size()-1; 00115 * - Fill and Copy members 00116 * - With the fill() members you can fill the vector with a given 00117 * constant value or with values taken from other vectors. 00118 * - With the copy() member you can copy another vector, an interval of it 00119 * or specified elements to this vector. 00120 * - You can specify, that the vector should be used just as a 00121 * wrapper-object to access external memory regions: useExternData(). 00122 * To check if a vector is a wrapper-object you can use ownsData(). 00123 * - clear() sets the size of the vector to zero. 00124 * - Mathematical operations 00125 * - Scalar product: dot() 00126 * - Elementwise multiplication/division: emultiply(), edivide() 00127 * - Add (subtract) another vector to (from) the actual vector: 00128 * add(const vector<T>&), subtract(const vector<T>&) 00129 * - Add another vector \em scaled to the actual vector: addScaled() 00130 * - A constant is used as second argument of the functions add, 00131 * subtract, multiply, divide and all element of the vector as 00132 * first argument: add(const T), subtract(const T), 00133 * multiply(const T), divide(const T) 00134 * - sumOfElements() and productOfElements() return the sum and product 00135 * of all elements of the vector, respectively 00136 * - Extremes of the vector 00137 * - find minimum, maximum values or both: minimum(), maximum(), 00138 * getExtremes() 00139 * - find their indices: getIndexOfMinimum(), getIndexOfMaximum(), 00140 * getIndexOfExtremes() 00141 * - Iterators 00142 * - It is possible to iterate within the vector by making use of 00143 * the vector iterators. (see begin() for more information) 00144 * - Instead of reverse_iterators as in the STL we use iterators 00145 * going backwards, due to faster execution times (see 00146 * inverseBegin() for more information) 00147 * 00148 * @ingroup gAggregate 00149 * @ingroup gLinearAlgebra 00150 */ 00151 template<class T> 00152 class vector : public genericVector<T> { 00153 public: 00154 00155 // inherit the iterator types from the generic vector 00156 typedef typename genericVector<T>::iterator iterator; 00157 typedef typename genericVector<T>::const_iterator const_iterator; 00158 00159 /** 00160 * default constructor creates an empty vector; 00161 */ 00162 vector(); 00163 00164 /** 00165 * create a vector of the given size and initialize it with the 00166 * given value. 00167 * @param theSize number of elements of the vector. 00168 * @param iniValue all elements will be initialized with this value. 00169 */ 00170 explicit vector(const int& theSize,const T& iniValue = T()); 00171 00172 /** 00173 * create a vector of the given size and initialize it with the 00174 * given data. The \a data will be copied. 00175 * @see useExternData() 00176 * @param theSize number of elements of the vector. 00177 * @param data a pointer to the data that will be copied. 00178 */ 00179 vector(const int& theSize,const T data[]); 00180 00181 /** 00182 * create a vector of the given size and initialize it with the 00183 * given data, the same way "useExternData" does. 00184 * The \a data will not be copied!. 00185 * @see useExternData() 00186 * @param theSize number of elements of the vector. 00187 * @param data a pointer to the data that will be used. 00188 * @param constRef if this parameter is true, it will not be possible to 00189 * change the pointer to the external memory block nor 00190 * to resize the vector. Despite this, the value of each 00191 * element can be changed by the access 00192 * operators. For Example: 00193 */ 00194 vector(const int& theSize,T data[],const bool constRef); 00195 00196 /** 00197 * create this vector as a copy of another vector 00198 * @param other the vector to be copied. 00199 */ 00200 vector(const vector<T>& other); 00201 00202 /** 00203 * create this vector as a copy of another genericVector 00204 * @param other the vector to be copied. 00205 */ 00206 vector(const genericVector<T>& other); 00207 00208 /** 00209 * create this vector as a copy of specified interval of elements of 00210 * another vector. Indices below zero are set to zero, indices greater 00211 * than the size of the %vector to the size-1. 00212 * @param other the vector to be copied. 00213 * @param from starting point included 00214 * @param to end point included. 00215 */ 00216 vector(const vector<T>& other, const int& from, const int& to=MaxInt32); 00217 00218 /** 00219 * create this vector as a copy of specified elements of another vector. 00220 * \a idx can contain the same index more than once. 00221 * @param other the vector to be copied. 00222 * @param idx indices of the elements to be copied 00223 */ 00224 vector(const vector<T>& other, const genericVector<int>& idx); 00225 00226 /** 00227 * create this vector as a copy of another std::vector 00228 * @param other the vector to be copied. 00229 */ 00230 vector(const std::vector<T>& other); 00231 00232 /** 00233 * If \a init is true this constructor is equivalent to calling 00234 * vector(const int& theSize), and thus initializing 00235 * all elements with T(). However, in some cases the elements need 00236 * not be initialized during construction, since complex 00237 * initializion is required. Especially for large vectors, the 00238 * unnecessary constructor initialization is very time consuming. 00239 * 00240 * If \a init is false, memory is allocated but no initialization 00241 * takes place. Thus the following is equivalent: 00242 * \code 00243 * vector<int> a(false,10000); 00244 * 00245 * matrix<int> a; 00246 * a.resize(10000,0,false,false); 00247 * \endcode 00248 * 00249 * @param init initialize matrix or not 00250 * @param theSize number of elements of the vector. 00251 */ 00252 vector(const bool& init, const int& theSize); 00253 00254 /** 00255 * destructor 00256 */ 00257 virtual ~vector(); 00258 00259 /** 00260 * returns the name of this class: "vector" 00261 */ 00262 const char* getTypeName() const {return "vector";}; 00263 00264 /** 00265 * create a clone of this genericVector 00266 * @return a pointer to a copy of this genericVector 00267 */ 00268 virtual mathObject* clone() const; 00269 00270 /** 00271 * compare this vector with other, and use the given tolerance to 00272 * determine if the value of each element of the other vector 00273 * approximately equals the values of the actual vector elements. 00274 * 00275 * An element \a x is approximately equal to another element \a y 00276 * with a tolerance \a t, if following equation holds: 00277 * \a x-t < \a y < \a x+t 00278 * 00279 * @param other the other vector to be compared with 00280 * @param tolerance the tolerance to be used 00281 * 00282 * @return true if both vectors are approximatly equal 00283 */ 00284 bool prettyCloseTo(const vector<T>& other,const T& tolerance) const; 00285 00286 /** 00287 * @name Arithmetical Operations 00288 */ 00289 //@{ 00290 /** 00291 * Dot product with another vector of the \e same type. 00292 * If the dimensions of both vector are not the same, an assertion will 00293 * be thrown. 00294 * @param other the other vector to be multiplied with 00295 * @return a scalar value with the type of the vector elements 00296 */ 00297 T dot(const vector<T>& other) const; 00298 00299 /** 00300 * Elementwise multiplication. 00301 * Each element of this vector will be multiplied with the elements 00302 * of the other vector and the result will be left in this %object! 00303 * If both vectors have different size, an assertion will be thrown 00304 * The return vector is this %object! 00305 * @param other the other vector to be multiplied with 00306 * @return a reference to the actual vector 00307 */ 00308 vector<T>& emultiply(const vector<T>& other); 00309 00310 /** 00311 * Elementwise multiplication. 00312 * This vector will contain the elementwise multiplication of the 00313 * elements in \a first and \a second. 00314 * If both vectors have different size, an assertion will be thrown 00315 * @param first the first vector 00316 * @param second the second vector will be multiplied with the 00317 * first vector 00318 * @return a reference to the actual vector 00319 */ 00320 vector<T>& emultiply(const vector<T>& first,const vector<T>& second); 00321 00322 /** 00323 * Elementwise division. 00324 * Each element of this vector will be divided by the elements 00325 * of the other vector and the result will be left in this %object! 00326 * The returned vector is this %object! 00327 * If both vectors have different size, an assertion will be thrown 00328 * @param other the other vector to be divided by 00329 * @return a reference to the actual vector 00330 */ 00331 vector<T>& edivide(const vector<T>& other); 00332 00333 /** 00334 * Elementwise division. 00335 * This vector will contain the elementwise division of the 00336 * elements in \a first by \a second. 00337 * If both vectors have different size, an assertion will be thrown 00338 * @param first the first vector 00339 * @param second the second vector, is the divisor 00340 * @return a reference to the actual vector 00341 */ 00342 vector<T>& edivide(const vector<T>& first,const vector<T>& second); 00343 00344 /** 00345 * Divide this vector with a constant. This vector will changed! 00346 * Returns this vector. 00347 * synonym for divide(const T cst). 00348 * @param cst the elements of the vector will be divided with this 00349 * constant 00350 * @return a reference to the actual vector 00351 */ 00352 inline vector<T>& edivide(const T cst); 00353 00354 /** 00355 * Divide the other vector with a constant and leave the result here. 00356 * Returns a reference to this vector. <p> 00357 * synonym for divide(const vector<T>& other,const T cst). 00358 * @param other the vector to be divide by the constant value 00359 * @param cst the elements of the vector will be divided with this 00360 * constant 00361 * @return a reference to the actual vector 00362 */ 00363 inline vector<T>& edivide(const vector<T>& other,const T cst); 00364 00365 /** 00366 * Add another vector of the same type and same dimension and 00367 * leave the result in this %object. 00368 * If both vectors have different size, an assertion will be thrown 00369 * @param other the other vector to be added with 00370 * @return a reference to the actual vector 00371 */ 00372 vector<T>& add(const vector<T>& other); 00373 00374 /** 00375 * Add two vector and leave the result in this %object. 00376 * If both vectors have different size, an assertion will be thrown 00377 * @param first the first vector 00378 * @param second the second vector will be added with the first 00379 * vector 00380 * @return a reference to the actual vector 00381 */ 00382 vector<T>& add(const vector<T>& first,const vector<T>& second); 00383 00384 /** 00385 * Add constant to this vector. This vector is changed. 00386 * Returns this vector. 00387 * @param cst constant scalar to be added with each element 00388 * @return a reference to the actual vector 00389 */ 00390 vector<T>& add(const T cst); 00391 00392 /** 00393 * Add constant to the other vector and leave the result here. 00394 * Returns a reference to this vector. 00395 * @param other the other vector 00396 * @param cst constant scalar to be added with each element of the other 00397 * vector 00398 * @return a reference to the actual vector 00399 */ 00400 vector<T>& add(const vector<T>& other,const T cst); 00401 00402 /** 00403 * Alias for add(const T cst) 00404 */ 00405 vector<T>& operator+=(const T cst); 00406 00407 /** 00408 * Alias for add(const vector<T>& other) 00409 */ 00410 vector<T>& operator+=(const vector<T>& other); 00411 00412 /** 00413 * Add another vector scaled by \e b to this vector. The vectors 00414 * must be of the same types and dimensions. Let \e A be this vector 00415 * and \e B the other vector, then this method performs:<p> 00416 * \f$A=A+b\cdot B\f$ 00417 * If both vectors have different size, an assertion will be thrown 00418 * @param b scaling factor for \a other 00419 * @param other the vector to be added after scaling 00420 * @return a reference to this vector 00421 */ 00422 vector<T>& addScaled(const T b, const vector<T>& other); 00423 00424 /** 00425 * Leave the scaled %sum of two vectors in this vector. The vectors 00426 * must be of the same types and dimensions. Let \e A be the 00427 * first vector and \e B the second vector with corresponding 00428 * scaling factors \e a and \e b, further \e C this 00429 * vector, then this method performs:<p> 00430 * \f$C=a\cdot A+b\cdot B\f$ 00431 * If both vectors have different size, an assertion will be thrown 00432 * @param a scaling factor for \a first 00433 * @param first the first vector to be added after scaling 00434 * @param b scaling factor for \a second 00435 * @param second the second vector to be added after scaling 00436 * @return a reference to this vector 00437 */ 00438 vector<T>& addScaled(const T a, const vector<T>& first, 00439 const T b, const vector<T>& second); 00440 00441 00442 /** 00443 * Leave the addition of the first vector and the second vector 00444 * scaled with the given factor in this vector. The vectors must 00445 * be of the same types and dimensions. Let \e A be the first 00446 * vector and \e B the second vector with corresponding scaling 00447 * factor \e b, further \e C this vector, then this method 00448 * performs:<p> \f$C=A+b\cdot B\f$ 00449 * If both vectors have different size, an assertion will be thrown 00450 * @param first the first vector to be added after scaling 00451 * @param b scaling factor for \a second 00452 * @param second the second vector to be added after scaling 00453 * @return a reference to this vector 00454 */ 00455 vector<T>& addScaled(const vector<T>& first, 00456 const T b, const vector<T>& second); 00457 00458 /** 00459 * Subtract constant from this vector. This vector is changed. 00460 * Returns this vector. 00461 * @param cst constant scalar to be subtracted from each element 00462 * @return a reference to the actual vector 00463 */ 00464 vector<T>& subtract(const T cst); 00465 00466 /** 00467 * Subtract constant from the other vector and leave the result here. 00468 * Returns a reference to this vector. 00469 * @param other the other vector 00470 * @param cst constant scalar to be subtracted from each element of the 00471 * other vector 00472 * @return a reference to the actual vector 00473 */ 00474 vector<T>& subtract(const vector<T>& other, const T cst); 00475 00476 /** 00477 * Subtracts another vector of the same type and same dimension 00478 * and leaves the result in this %object 00479 * If both vectors have different size, an assertion will be thrown 00480 * @param other will be substracted from this vector 00481 * @return a reference to the actual vector 00482 */ 00483 vector<T>& subtract(const vector<T>& other); 00484 00485 /** 00486 * Subtracts two vectors and leaves the result in this %object. 00487 * If both vectors have different size, an assertion will be thrown 00488 * @param first the first vector 00489 * @param second the second vector will be substracted from the 00490 * first vector 00491 * @return a reference to the actual vector 00492 */ 00493 vector<T>& subtract(const vector<T>& first,const vector<T>& second); 00494 00495 /** 00496 * Alias for substract(const vector<T>& other) 00497 * If both vectors have different size, an assertion will be thrown 00498 */ 00499 vector<T>& operator-=(const vector<T>& other); 00500 00501 /** 00502 * Alias for subtract(const T& cst) 00503 */ 00504 vector<T>& operator-=(const T cst); 00505 00506 /** 00507 * Multiply this vector with a constant. This vector will changed! 00508 * Returns this vector. 00509 * If both vectors have different size, an assertion will be thrown 00510 * @param cst constant scalar to be multiplied with 00511 * @return a reference to the actual vector 00512 */ 00513 vector<T>& multiply(const T cst); 00514 00515 /** 00516 * Multiply the other %vector with a constant and leave the result here. 00517 * Returns a reference to this vector. 00518 * If both vectors have different size, an assertion will be thrown 00519 * @param other the other vector to be multiplied with the constant value 00520 * @param cst constant scalar to be multiplied with the other vector. 00521 * @return a reference to the actual vector 00522 */ 00523 vector<T>& multiply(const vector<T>& other,const T cst); 00524 00525 /** 00526 * Multiply with a constant. This vector is changed. 00527 * @param cst constant scalar to be multiplied with 00528 * @return a reference to the actual vector 00529 */ 00530 vector<T>& operator*=(const T cst); 00531 00532 /** 00533 * Divide this vector by a constant. This vector will changed! 00534 * Returns this vector. 00535 * @param cst the elements of the vector will be divided with this 00536 * constant 00537 * @return a reference to the actual vector 00538 */ 00539 vector<T>& divide(const T cst); 00540 00541 /** 00542 * Divide the other vector by a constant and leave the result here. 00543 * Returns a reference to this vector. 00544 * @param other the vector to be divide by the constant value 00545 * @param cst the elements of the vector will be divided with this 00546 * constant 00547 * @return a reference to the actual vector 00548 */ 00549 vector<T>& divide(const vector<T>& other,const T cst); 00550 00551 /** 00552 * Alias for divide(const T& cst) 00553 */ 00554 vector<T>& operator/=(const T cst); 00555 00556 /** 00557 * calculate the sum of all elements of the vector. 00558 * This member can be used with classes which define the operator '+=' 00559 */ 00560 T sumOfElements() const; 00561 00562 /** 00563 * calculate the product of all elements of the vector. 00564 * This member can be used with classes which define the operator '*=' 00565 */ 00566 T productOfElements() const; 00567 //@} 00568 00569 00570 /** 00571 * @name find extreme values 00572 */ 00573 //@{ 00574 00575 /** 00576 * get the smallest element of the vector 00577 */ 00578 T minimum() const; 00579 00580 /** 00581 * get the index of the smallest element of the vector 00582 */ 00583 int getIndexOfMinimum() const; 00584 00585 /** 00586 * get the biggest element of the vector 00587 */ 00588 T maximum() const; 00589 00590 /** 00591 * get the index of the biggest element of the vector 00592 */ 00593 int getIndexOfMaximum() const; 00594 00595 /** 00596 * get the extremes of the vector (smallest and biggest elements) 00597 */ 00598 void getExtremes(T& theMinimum, T& theMaximum) const; 00599 00600 /** 00601 * get the indices of the extremes of the vector 00602 * (smallest and biggest elements) 00603 */ 00604 void getIndexOfExtremes(int& theIdxMinimum, int& theIdxMaximum) const; 00605 //@} 00606 }; 00607 00608 } // namespace lti 00609 00610 #include "ltiVector_inline.h" 00611 #include "ltiTypes.h" 00612 00613 namespace lti { 00614 /** 00615 * Vector of double 00616 */ 00617 typedef vector<double> dvector; 00618 /** 00619 * Vector of float 00620 */ 00621 typedef vector<float> fvector; 00622 /** 00623 * Vector of integer 00624 */ 00625 typedef vector<int32> ivector; 00626 } 00627 00628 00629 #endif