last update 20 Sep 2009 |
00001 /* 00002 * Copyright (C) 1998-2004 00003 * Lehrstuhl fuer Technische Informatik, RWTH-Aachen, Germany 00004 * 00005 * This file is part of the Computer Vision and Robotics Library (CVR-Lib) 00006 * 00007 * The CVR-Lib is free software; you can redistribute it and/or 00008 * modify it under the terms of the BSD License. 00009 * 00010 * All rights reserved. 00011 * 00012 * Redistribution and use in source and binary forms, with or without 00013 * modification, are permitted provided that the following conditions are met: 00014 * 00015 * 1. Redistributions of source code must retain the above copyright notice, 00016 * this list of conditions and the following disclaimer. 00017 * 00018 * 2. Redistributions in binary form must reproduce the above copyright notice, 00019 * this list of conditions and the following disclaimer in the documentation 00020 * and/or other materials provided with the distribution. 00021 * 00022 * 3. Neither the name of the authors nor the names of its contributors may be 00023 * used to endorse or promote products derived from this software without 00024 * specific prior written permission. 00025 * 00026 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 00027 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00028 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00029 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 00030 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 00031 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 00032 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 00033 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 00034 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 00035 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 00036 * POSSIBILITY OF SUCH DAMAGE. 00037 */ 00038 00039 /** 00040 * \file cvrVector.h 00041 * Contains the template class cvr::vector, which is the mathematical 00042 * version of cvr::genericVector. Some arithmetical operations have 00043 * been added. 00044 * \author Pablo Alvarado 00045 * \date 09.04.1999 00046 * 00047 * $Id: cvrVector.h,v 1.8 2007/04/06 01:18:41 alvarado Exp $ 00048 */ 00049 00050 #ifndef _CVR_VECTOR_H_ 00051 #define _CVR_VECTOR_H_ 00052 00053 #define _CVR_GENERIC_VECTOR_DONT_INSTANTIATE_REQUEST 00054 #include "cvrGenericVector.h" 00055 #undef _CVR_GENERIC_VECTOR_DONT_INSTANTIATE_REQUEST 00056 00057 namespace cvr { 00058 /** 00059 * Mathematical vector container class. 00060 * 00061 * The cvr::vector class allows the representation of n-dimensional vectors. 00062 * The elements of the vector will be indexed between 0 an n-1. 00063 * 00064 * Note that this class is NOT intended to be a subtitute for std::vector. 00065 * If you need a vector of elements which use some sort of dynamic memory 00066 * allocation then you should use the std::vector class of the Standard 00067 * Template Library. 00068 * 00069 * Only following types are supported by cvr::vector: 00070 * - ubyte 00071 * - byte 00072 * - int32 00073 * - uint32 00074 * - long 00075 * - float 00076 * - double 00077 * - rgbaPixel 00078 * - rgbPixel<float> 00079 * - ipoint 00080 * - fpoint 00081 * - dpoint 00082 * - dpoint3D 00083 * - fcomplex 00084 * - dcomplex 00085 * 00086 * This restriction is done to avoid the typical template code explosion 00087 * due to frequently used types in the library. If you need the vector as 00088 * container of any other type, consider using the std::vector or the 00089 * cvr::genericVector. 00090 * 00091 * The vector class is a container class implemented as template, where the 00092 * template type T denotes the type of the elements. It is by no means a 00093 * generic container, since the types it supports must fulfill many 00094 * requirements, specially support for all arithmetical operators, and the 00095 * types supported are explicitely instantiated in the library. 00096 * 00097 * If you need to create a vector of floats with 256 elements, all 00098 * initialized with a value of 4.27 just create it: 00099 * 00100 * \code 00101 * cvr::vector<float> myVct(256,4.27f) // creates vector with 256 elements 00102 * // all initialized with 4.27f 00103 * \endcode 00104 * 00105 * To access the vector elements use the access operators at() (or the 00106 * overloaded operator[]()). For example: 00107 * 00108 * 00109 * \code 00110 * float accu = 0; // initialize accumulator 00111 * 00112 * for (int i = 0; i < myVct.size(); i++) { 00113 * tmp += myVct.at(i); // access each element of the vector 00114 * } 00115 * \endcode 00116 * 00117 * The vector has following methods: 00118 * - Constructors Constructors 00119 * - You can construct an empty vector with the default constructor 00120 * (vector()). 00121 * - If you know the number of elements use 00122 * vector(const int size,const T& initialValue) 00123 * - You can create the copy of another vector with the copy constructor 00124 * (vector(const vector<T>& otherVector)) 00125 * - You can create a vector with a copy of the data of a C++ array 00126 * the constructor (vector(const int theSize,const T data[])) 00127 * - Access members 00128 * - at(), operator[]() 00129 * - The size() member returns the number of elements of the vector. 00130 * - empty() returns true if the size of the vector is zero. 00131 * - The firstIndex() will return in a vector always 0 and the lastIndex() 00132 * will be always size()-1; 00133 * - Fill and Copy members 00134 * - With the fill() members you can fill the vector with a given 00135 * constant value or with values taken from other vectors. 00136 * - With the copy() member you can copy another vector, an interval of it 00137 * or specified elements to this vector. 00138 * - You can specify, that the vector should be used just as a 00139 * wrapper-object to access external memory regions: useExternData(). 00140 * To check if a vector is a wrapper-object you can use ownsData(). 00141 * - clear() sets the size of the vector to zero. 00142 * - Mathematical operations 00143 * - Scalar product: dot() 00144 * - Elementwise multiplication/division: emultiply(), edivide() 00145 * - Add (subtract) another vector to (from) the actual vector: 00146 * add(const vector<T>&), subtract(const vector<T>&) 00147 * - Add another vector \em scaled to the actual vector: addScaled() 00148 * - A constant is used as second argument of the functions add, 00149 * subtract, multiply, divide and all element of the vector as 00150 * first argument: add(const T), subtract(const T), 00151 * multiply(const T), divide(const T) 00152 * - sumOfElements() and productOfElements() return the sum and product 00153 * of all elements of the vector, respectively 00154 * - Extremes of the vector 00155 * - find minimum, maximum values or both: findMinimum(), findMaximum(), 00156 * findExtremes() 00157 * - find their indices: findIndexOfMinimum(), findIndexOfMaximum(), 00158 * findIndexOfExtremes() 00159 * - Iterators 00160 * - It is possible to iterate within the vector by making use of 00161 * the vector iterators. (see begin() for more information) 00162 * - Instead of reverse_iterators as in the STL we use iterators 00163 * going backwards, due to faster execution times (see 00164 * inverseBegin() for more information) 00165 * 00166 * @ingroup gAggregate 00167 * @ingroup gLinearAlgebra 00168 */ 00169 template<typename T> 00170 class vector : public genericVector<T> { 00171 public: 00172 00173 // inherit the iterator types from the generic vector 00174 typedef typename genericVector<T>::iterator iterator; 00175 typedef typename genericVector<T>::const_iterator const_iterator; 00176 00177 /** 00178 * Default constructor creates an empty vector; 00179 */ 00180 vector(); 00181 00182 /** 00183 * Create a vector of the given size. The content of the vector 00184 * is undefined. 00185 * 00186 * 00187 * \warning This is an interface change with the previous library. It has 00188 * been done to be consistent with the more basic features of the C++ 00189 * language. If you write for example "int c;", the content of \c c is 00190 * not defined, and in the same way, if you want a vector with initialized 00191 * data, you have to specify explicitely the value with which the elements 00192 * have to be initialized. 00193 * 00194 * @param theSize number of elements of the vector. 00195 */ 00196 explicit vector(const int theSize); 00197 00198 /** 00199 * Create a vector of the given size and initialize it with the 00200 * given value. 00201 * 00202 * @param theSize number of elements of the vector. 00203 * @param iniValue all elements will be initialized with this value. 00204 */ 00205 explicit vector(const int theSize,const T& iniValue); 00206 00207 /** 00208 * Create a vector of the given size and initialize it with the 00209 * given data. The \a data will be copied. 00210 * 00211 * @see useExternData() 00212 * 00213 * @param theSize number of elements of the vector. 00214 * @param data a pointer to the data that will be copied. 00215 */ 00216 vector(const int theSize,const T data[]); 00217 00218 /** 00219 * Create a vector of the given size and initialize it with the given 00220 * data, the same way "useExternData" does. The \a data will not be 00221 * copied!. 00222 * 00223 * @see useExternData() 00224 * 00225 * @param theSize number of elements of the vector. 00226 * @param data a pointer to the data that will be used. 00227 * @param constRef if this parameter is true, it will not be possible to 00228 * change the pointer to the external memory block nor 00229 * to resize the vector. Despite this, the value of each 00230 * element can be changed by the access 00231 * operators. For Example: 00232 */ 00233 vector(const int theSize,T data[],const eConstantReference constRef); 00234 00235 /** 00236 * Create this vector as a copy of another genericVector 00237 * 00238 * @param other the vector to be copied. 00239 */ 00240 vector(const genericVector<T>& other); 00241 00242 /** 00243 * Create this vector as a copy of specified interval of elements of 00244 * another vector. Indices below zero are set to zero, indices greater 00245 * than the size of the %vector to the size-1. 00246 * 00247 * @param other the vector to be copied. 00248 * @param from starting point included 00249 * @param to end point included. 00250 */ 00251 vector(const genericVector<T>& other, 00252 const int from, 00253 const int to=genericVector<T>::MaxIndex); 00254 00255 /** 00256 * Create this vector as a copy of specified elements of another vector. 00257 * 00258 * \a idx can contain the same index more than once. 00259 * 00260 * @param other the vector to be copied. 00261 * @param idx indices of the elements to be copied 00262 * 00263 */ 00264 vector(const genericVector<T>& other, const genericVector<int>& idx); 00265 00266 /** 00267 * Create this vector as a copy of another std::vector 00268 * 00269 * @param other the vector to be copied. 00270 */ 00271 vector(const std::vector<T>& other); 00272 00273 /** 00274 * Destructor 00275 */ 00276 virtual ~vector(); 00277 00278 /** 00279 * Returns the name of this class. 00280 */ 00281 const std::string& name() const; 00282 00283 /** 00284 * Create a clone of this vector. 00285 * 00286 * @return a pointer to a copy of this vector 00287 */ 00288 virtual vector<T>* clone() const; 00289 00290 /** 00291 * Create a new vector instance. 00292 * 00293 * @return a pointer to a new instance of vector 00294 */ 00295 virtual vector<T>* newInstance() const; 00296 00297 /** 00298 * Compare this vector with other, and use the given tolerance to 00299 * determine if the value of each element of the other vector 00300 * approximately equals the values of the actual vector elements. 00301 * 00302 * An element \a x is approximately equal to another element \a y 00303 * with a tolerance \a t, if following equation holds: 00304 * \a x-t < \a y < \a x+t 00305 * 00306 * @param other the other vector to be compared with 00307 * @param tolerance the tolerance to be used 00308 * 00309 * @return true if both vectors are approximatly equal 00310 */ 00311 bool prettyCloseTo(const genericVector<T>& other, 00312 const T& tolerance) const; 00313 00314 /** 00315 * @name Arithmetical Operations 00316 */ 00317 //@{ 00318 /** 00319 * Dot product with another vector of the \e same type. 00320 * 00321 * For complex types, this vector is complex conjugated. 00322 * 00323 * If the dimensions of both vector are not the same, an assertion will 00324 * be thrown. 00325 * 00326 * @param other the other vector to be multiplied with 00327 * @return a scalar value with the type of the vector elements 00328 */ 00329 T dot(const genericVector<T>& other) const; 00330 00331 /** 00332 * Elementwise multiplication. 00333 * Each element of this vector will be multiplied with the elements 00334 * of the other vector and the result will be left in this %object! 00335 * If both vectors have different size, an assertion will be thrown 00336 * The return vector is this %object! 00337 * @param other the other vector to be multiplied with 00338 * @return a reference to the actual vector 00339 */ 00340 vector<T>& emultiply(const genericVector<T>& other); 00341 00342 /** 00343 * Elementwise multiplication. 00344 * This vector will contain the elementwise multiplication of the 00345 * elements in \a first and \a second. 00346 * If both vectors have different size, an assertion will be thrown 00347 * @param first the first vector 00348 * @param second the second vector will be multiplied with the 00349 * first vector 00350 * @return a reference to the actual vector 00351 */ 00352 vector<T>& emultiply(const genericVector<T>& first, 00353 const genericVector<T>& second); 00354 00355 /** 00356 * Elementwise division. 00357 * 00358 * Each element of this vector will be divided by the elements 00359 * of the other vector and the result will be left in this %object! 00360 * The returned vector is this %object! 00361 * If both vectors have different size, an assertion will be thrown 00362 * @param other the other vector to be divided by 00363 * @return a reference to the actual vector 00364 */ 00365 vector<T>& edivide(const genericVector<T>& other); 00366 00367 /** 00368 * Elementwise division. 00369 * 00370 * This vector will contain the elementwise division of the 00371 * elements in \a first by \a second. 00372 * If both vectors have different size, an assertion will be thrown 00373 * @param first the first vector 00374 * @param second the second vector, is the divisor 00375 * @return a reference to the actual vector 00376 */ 00377 vector<T>& edivide(const genericVector<T>& first, 00378 const genericVector<T>& second); 00379 00380 /** 00381 * Divide this vector with a constant. This vector will changed! 00382 * Returns this vector. 00383 * synonym for divide(const T cst). 00384 * @param cst the elements of the vector will be divided with this 00385 * constant 00386 * @return a reference to the actual vector 00387 */ 00388 inline vector<T>& edivide(const T cst); 00389 00390 /** 00391 * Divide the other vector with a constant and leave the result here. 00392 * Returns a reference to this vector. <p> 00393 * synonym for divide(const vector<T>& other,const T cst). 00394 * @param other the vector to be divide by the constant value 00395 * @param cst the elements of the vector will be divided with this 00396 * constant 00397 * @return a reference to the actual vector 00398 */ 00399 inline vector<T>& edivide(const genericVector<T>& other,const T cst); 00400 00401 /** 00402 * Add another vector of the same type and same dimension and 00403 * leave the result in this %object. 00404 * If both vectors have different size, an assertion will be thrown 00405 * @param other the other vector to be added with 00406 * @return a reference to the actual vector 00407 */ 00408 vector<T>& add(const genericVector<T>& other); 00409 00410 /** 00411 * Add two vector and leave the result in this %object. 00412 * If both vectors have different size, an assertion will be thrown 00413 * @param first the first vector 00414 * @param second the second vector will be added with the first 00415 * vector 00416 * @return a reference to the actual vector 00417 */ 00418 vector<T>& add(const genericVector<T>& first, 00419 const genericVector<T>& second); 00420 00421 /** 00422 * Add constant to this vector. This vector is changed. 00423 * Returns this vector. 00424 * @param cst constant scalar to be added with each element 00425 * @return a reference to the actual vector 00426 */ 00427 vector<T>& add(const T cst); 00428 00429 /** 00430 * Add constant to the other vector and leave the result here. 00431 * Returns a reference to this vector. 00432 * @param other the other vector 00433 * @param cst constant scalar to be added with each element of the other 00434 * vector 00435 * @return a reference to the actual vector 00436 */ 00437 vector<T>& add(const genericVector<T>& other,const T cst); 00438 00439 /** 00440 * Alias for add(const T cst) 00441 */ 00442 inline vector<T>& operator+=(const T cst); 00443 00444 /** 00445 * Alias for add(const vector<T>& other) 00446 */ 00447 inline vector<T>& operator+=(const genericVector<T>& other); 00448 00449 /** 00450 * Add another vector scaled by \e b to this vector. The vectors 00451 * must be of the same types and dimensions. Let \e A be this vector 00452 * and \e B the other vector, then this method performs:<p> 00453 * \f$A=A+b\cdot B\f$ 00454 * If both vectors have different size, an assertion will be thrown 00455 * @param b scaling factor for \a other 00456 * @param other the vector to be added after scaling 00457 * @return a reference to this vector 00458 */ 00459 vector<T>& addScaled(const T b, const genericVector<T>& other); 00460 00461 /** 00462 * Leave the scaled %sum of two vectors in this vector. The vectors 00463 * must be of the same types and dimensions. Let \e A be the 00464 * first vector and \e B the second vector with corresponding 00465 * scaling factors \e a and \e b, further \e C this 00466 * vector, then this method performs:<p> 00467 * \f$C=a\cdot A+b\cdot B\f$ 00468 * If both vectors have different size, an assertion will be thrown 00469 * @param a scaling factor for \a first 00470 * @param first the first vector to be added after scaling 00471 * @param b scaling factor for \a second 00472 * @param second the second vector to be added after scaling 00473 * @return a reference to this vector 00474 */ 00475 vector<T>& addScaled(const T a, const genericVector<T>& first, 00476 const T b, const genericVector<T>& second); 00477 00478 00479 /** 00480 * Leave the addition of the first vector and the second vector 00481 * scaled with the given factor in this vector. The vectors must 00482 * be of the same types and dimensions. Let \e A be the first 00483 * vector and \e B the second vector with corresponding scaling 00484 * factor \e b, further \e C this vector, then this method 00485 * performs:<p> \f$C=A+b\cdot B\f$ 00486 * If both vectors have different size, an assertion will be thrown 00487 * @param first the first vector to be added after scaling 00488 * @param b scaling factor for \a second 00489 * @param second the second vector to be added after scaling 00490 * @return a reference to this vector 00491 */ 00492 vector<T>& addScaled(const genericVector<T>& first, 00493 const T b, 00494 const genericVector<T>& second); 00495 00496 /** 00497 * Subtract constant from this vector. This vector is changed. 00498 * Returns this vector. 00499 * @param cst constant scalar to be subtracted from each element 00500 * @return a reference to the actual vector 00501 */ 00502 vector<T>& subtract(const T cst); 00503 00504 /** 00505 * Subtract constant from the other vector and leave the result here. 00506 * Returns a reference to this vector. 00507 * @param other the other vector 00508 * @param cst constant scalar to be subtracted from each element of the 00509 * other vector 00510 * @return a reference to the actual vector 00511 */ 00512 vector<T>& subtract(const genericVector<T>& other, const T cst); 00513 00514 /** 00515 * Subtracts another vector of the same type and same dimension 00516 * and leaves the result in this %object 00517 * If both vectors have different size, an assertion will be thrown 00518 * @param other will be substracted from this vector 00519 * @return a reference to the actual vector 00520 */ 00521 vector<T>& subtract(const genericVector<T>& other); 00522 00523 /** 00524 * Subtracts two vectors and leaves the result in this %object. 00525 * If both vectors have different size, an assertion will be thrown 00526 * @param first the first vector 00527 * @param second the second vector will be substracted from the 00528 * first vector 00529 * @return a reference to the actual vector 00530 */ 00531 vector<T>& subtract(const genericVector<T>& first, 00532 const genericVector<T>& second); 00533 00534 /** 00535 * Alias for substract(const vector<T>& other) 00536 * If both vectors have different size, an assertion will be thrown 00537 */ 00538 inline vector<T>& operator-=(const genericVector<T>& other); 00539 00540 /** 00541 * Alias for subtract(const T& cst) 00542 */ 00543 inline vector<T>& operator-=(const T cst); 00544 00545 /** 00546 * Multiply this vector with a constant. This vector will changed! 00547 * Returns this vector. 00548 * If both vectors have different size, an assertion will be thrown 00549 * @param cst constant scalar to be multiplied with 00550 * @return a reference to the actual vector 00551 */ 00552 vector<T>& multiply(const T cst); 00553 00554 /** 00555 * Multiply the other %vector with a constant and leave the result here. 00556 * Returns a reference to this vector. 00557 * If both vectors have different size, an assertion will be thrown 00558 * @param other the other vector to be multiplied with the constant value 00559 * @param cst constant scalar to be multiplied with the other vector. 00560 * @return a reference to the actual vector 00561 */ 00562 vector<T>& multiply(const genericVector<T>& other,const T cst); 00563 00564 /** 00565 * Multiply with a constant. This vector is changed. 00566 * @param cst constant scalar to be multiplied with 00567 * @return a reference to the actual vector 00568 */ 00569 inline vector<T>& operator*=(const T cst); 00570 00571 /** 00572 * Divide this vector by a constant. This vector will changed! 00573 * Returns this vector. 00574 * @param cst the elements of the vector will be divided with this 00575 * constant 00576 * @return a reference to the actual vector 00577 */ 00578 vector<T>& divide(const T cst); 00579 00580 /** 00581 * Divide the other vector by a constant and leave the result here. 00582 * Returns a reference to this vector. 00583 * @param other the vector to be divide by the constant value 00584 * @param cst the elements of the vector will be divided with this 00585 * constant 00586 * @return a reference to the actual vector 00587 */ 00588 vector<T>& divide(const genericVector<T>& other,const T cst); 00589 00590 /** 00591 * Alias for divide(const T& cst) 00592 */ 00593 inline vector<T>& operator/=(const T cst); 00594 00595 /** 00596 * Calculate the sum of all elements of the vector. 00597 * This member can be used with classes which define the operator '+=' 00598 */ 00599 T computeSumOfElements() const; 00600 00601 /** 00602 * Calculate the product of all elements of the vector. 00603 * This member can be used with classes which define the operator '*=' 00604 */ 00605 T computeProductOfElements() const; 00606 //@} 00607 00608 00609 /** 00610 * @name Find extreme values 00611 */ 00612 //@{ 00613 00614 /** 00615 * Find the smallest element of the vector 00616 */ 00617 T findMinimum() const; 00618 00619 /** 00620 * Find the index of the smallest element of the vector 00621 */ 00622 int findIndexOfMinimum() const; 00623 00624 /** 00625 * Find the biggest element of the vector 00626 */ 00627 T findMaximum() const; 00628 00629 /** 00630 * Find the index of the biggest element of the vector 00631 */ 00632 int findIndexOfMaximum() const; 00633 00634 /** 00635 * Find the extremes of the vector (smallest and biggest elements) 00636 */ 00637 void findExtremes(T& theMinimum, T& theMaximum) const; 00638 00639 /** 00640 * Find the indices of the extremes of the vector 00641 * (smallest and biggest elements) 00642 */ 00643 void findIndexOfExtremes(int& theIdxMinimum, int& theIdxMaximum) const; 00644 //@} 00645 }; 00646 00647 } // namespace cvr 00648 00649 #include "cvrVector_inline.h" 00650 00651 namespace cvr { 00652 /** 00653 * Vector of double 00654 */ 00655 typedef vector<double> dvector; 00656 00657 /** 00658 * Vector of float 00659 */ 00660 typedef vector<float> fvector; 00661 00662 /** 00663 * Vector of integer 00664 */ 00665 typedef vector<int32> ivector; 00666 00667 } 00668 00669 #endif