LTI-Lib latest version v1.9 - last update 10 Apr 2010

ltiGenericVector.h

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 .......: ltiGenericVector.h
00027  * authors ....: Pablo Alvarado
00028  * organization: LTI, RWTH Aachen
00029  * creation ...: 09.04.99
00030  * revisions ..: $Id: ltiGenericVector.h,v 1.16 2008/08/17 22:20:13 alvarado Exp $
00031  */
00032 
00033 #ifndef _LTI_GENERIC_VECTOR_H_
00034 #define _LTI_GENERIC_VECTOR_H_
00035 
00036 #include "ltiMathObject.h"
00037 #include "ltiException.h"
00038 #include "ltiTypes.h"
00039 #include "ltiMath.h"
00040 #include <cstring> // for memcpy
00041 #include <vector>
00042 
00043 namespace lti {
00044   /**
00045    * Vector container class.
00046    *
00047    * The lti::genericVector class allows the representation of
00048    * n-dimensional vectors.  The elements of the vector will be
00049    * indexed between 0 an n-1.
00050    *
00051    * Note that this class is NOT intended to be a subtitute for
00052    * std::vector.  If you need a vector of elements which use some
00053    * sort of dynamic memory allocation then you should use the
00054    * std::vector class of the Standard Template Library.  This means,
00055    * you should not try to make lti::genericVector of other vectors or
00056    * matrices, which administrate some memory.  If you do so, the
00057    * behaviour of copy or fill operations will be unpredictable.
00058    *
00059    * The difference between lti::genericVector and its most used
00060    * inherited class lti::vector is the support for arithmetical
00061    * operations.  The generic vector is more a container than a
00062    * multi-dimensional point representation.  It inherits its memory
00063    * managment versatility to lti::vector.  Again, it is usually
00064    * employed as a container of any \e static type, which do not do by
00065    * itself any memory managment.
00066    *
00067    * The genericVector class is a generic container class implemented
00068    * as template.
00069    *
00070    * If you need to create a vector of floats with 256 elements all
00071    * initialized with a value of 4.27 just create it:
00072    *
00073    * \code
00074    * lti::genericVector<float> myVct(256,4.27f) // creates vector with 256
00075    *                                            // elements all initialized 
00076    *                                            // with 4.27f
00077    * \endcode
00078    *
00079    * To access the vector elements use the access operators at() (or the
00080    * overloaded operator[]()).  For example:
00081    *
00082    * \code
00083    * float accu = 0; // initialize accumulator
00084    *
00085    * for (int i = 0; i < myVct.size(); i++) {
00086    *   tmp += myVct.at(i); // access each element of the vector
00087    * }
00088    * \endcode
00089    *
00090    * @ingroup gAggregate
00091    */
00092   template<class T>
00093   class genericVector : public mathObject {
00094   public:
00095     /**
00096      * Type of the genericVector elements.
00097      */
00098     typedef T value_type;
00099 
00100     /**
00101      * constReferenceException class
00102      *
00103      * constReferenceException is thrown if a constant object is modified.
00104      * @see lti::genericVector::useExternData()
00105      */
00106     class constReferenceException : public exception {
00107     public:
00108       constReferenceException()
00109         : exception("const reference can not be changed") {};
00110       virtual const char* getTypeName() const {
00111         return "genericVector::constReferenceException";
00112       };
00113     };
00114 
00115 #   ifdef NDEBUG
00116     /**
00117      * iterator type (allows read and write operations) The use of the
00118      * iterator classes is similar to the iterators of the STL
00119      * (Standard Template Library). See lti::genericVector::begin() and
00120      * lti::genericVector::inverseBegin() for examples.
00121      *
00122      * For the debugging version of the iterators, boundary check will be
00123      * done!  This explains the low speed of the iterators of the debug
00124      * version.  In the release version, no boundary check will be done,
00125      * and the iterators are sometimes a factor 10 faster than the
00126      * debug iterators.
00127      *
00128      * The use of the access operator at(.) is faster than the iterators
00129      * in the debug version only.  If you need to iterate on a genericVector use
00130      * iterators instead (in the release version iterators are approx. a
00131      * factor 3 faster than "at(.)").
00132      *
00133      * CAUTION: Try to use the prefix incremental operator
00134      * (i.e. ++it) instead of the postfix operator (i.e. it++) to
00135      * allow efficient code also in debug-modus!
00136      *
00137      * see also const_iterator
00138      */
00139     typedef T* iterator;
00140 
00141     /**
00142      * const iterator type (allows read-only operations)
00143      * The use of the iterator classes is similar to the iterators of
00144      * the STL (Standard Template Library). See lti::genericVector::begin()
00145      * for an example.
00146      *
00147      * For the debugging version of the iterators, boundary check will be
00148      * done!  This explains the low speed of the iterators of the debug
00149      * version.  In the release version, no boundary check will be done,
00150      * and the iterators are sometimes a factor 10 faster than the
00151      * debug iterators.
00152      *
00153      * The use of the access operator at(.) is faster than the iterators
00154      * in the debug version only.  If you need to iterate on a genericVector use
00155      * iterators instead (in the release version iterators are approx. a
00156      * factor 3 faster than "at(.)").
00157      *
00158      * CAUTION: Try to use the prefix incremental operator (i.e. ++it)
00159      * instead of the postfix operator (i.e. it++) to allow efficient
00160      * code also in debug-modus!
00161      *
00162      * see also iterator
00163      */
00164     typedef const T* const_iterator;
00165 
00166 
00167 #   else
00168 
00169     class const_iterator;
00170     /**
00171      * iterator type (allows read and write operations).
00172      *
00173      * The use of the iterator classes is similar to the iterators of
00174      * the STL (Standard Template Library). See lti::genericVector::begin()
00175      * for an example
00176      *
00177      * For the debugging version of the iterators, boundary check will be
00178      * done!  This explains the low speed of the iterators of the debug
00179      * version.  In the release version, no boundary check will be done,
00180      * and the iterators are sometimes a factor 10 faster than the
00181      * debug iterators.
00182      *
00183      * The use of the access operator at(.) is faster than the iterators
00184      * in the debug version only.  If you need to iterate on a genericVector use
00185      * iterators instead (in the release version iterators are approx. a
00186      * factor 3 faster than "at(.)").
00187      *
00188      * CAUTION: Try to use the prefix incremental operator (i.e. ++it)
00189      * instead of the postfix operator (i.e. it++) to allow efficient
00190      * code also in debug-modus!
00191      *
00192      * see also const_iterator
00193      */
00194     class iterator {
00195       friend class genericVector<T>;
00196 #     ifdef _LTI_MSC_6
00197       friend class const_iterator;
00198 #     else
00199       friend class genericVector<T>::const_iterator;
00200 #     endif
00201     public:
00202       /**
00203        * Default constructor
00204        */
00205       iterator()
00206         : pos(0), theGenericVector(0) {};
00207 
00208       /**
00209        * copy constructor
00210        */
00211       iterator(const iterator& other)
00212         : pos(other.pos),theGenericVector(other.theGenericVector) {};
00213 
00214       /**
00215        * advance to next item
00216        */
00217       inline iterator& operator++() {++pos; return *this;};   // prefix
00218 
00219       /**
00220        * advance to next item
00221        */
00222       inline iterator operator++(int) {
00223         iterator tmp(*this);
00224         pos++; return tmp;
00225       }; // postfix
00226 
00227       /**
00228        * recede to previous item
00229        */
00230       inline iterator& operator--() {--pos; return *this;};   // prefix
00231 
00232       /**
00233        * recede to previous item
00234        */
00235       inline iterator operator--(int) {
00236         iterator tmp(*this);
00237         pos--; return tmp;
00238       }; // postfix
00239 
00240       /**
00241        * advance (skip) some elements.
00242        * Use this operator with care! Note that you can skip the end of
00243        * the genericVector, and read (or even worse: write!) out of bounds!
00244        */
00245       inline iterator& operator+=(const int n) {pos+=n; return *this;};
00246 
00247       /**
00248        * recede (skip) some elements.
00249        * Use this operator with care! Note that you can skip the beginning of
00250        * the genericVector, and read (or even worse: write!) out of bounds!
00251        */
00252       inline iterator& operator-=(const int n) {pos-=n; return *this;};
00253 
00254       /**
00255        * advance (skip) some elements.
00256        * Use this operator with care! Note that you can skip the end of
00257        * the genericVector, and read (or even worse: write!) out of bounds!
00258        */
00259       inline iterator operator+(const int n) {
00260         return iterator(pos+n,theGenericVector);
00261       };
00262 
00263       /**
00264        * recede (skip) some elements.
00265        * Use this operator with care! Note that you can skip the beginning of
00266        * the genericVector, and read (or even worse: write!) out of bounds!
00267        */
00268       inline iterator operator-(const int n) {
00269         return iterator(pos-n,theGenericVector);
00270       };
00271 
00272       /**
00273        * compare if both pointed positions are the same
00274        */
00275       inline bool operator==(const iterator& other) const {
00276         return (pos == other.pos);
00277       };
00278 
00279       /**
00280        * compare if both pointed positions are different
00281        */
00282       inline bool operator!=(const iterator& other) const {
00283         return (pos != other.pos);
00284       };
00285 
00286       /**
00287        * compare if the position of the first iterator is smaller than
00288        * the position of the second iterator
00289        */
00290       inline bool operator<(const iterator& other) const {
00291         return (pos < other.pos);
00292       };
00293 
00294       /**
00295        * compare if the position of the first iterator is greater than
00296        * the position of the second iterator
00297        */
00298       inline bool operator>(const iterator& other) const {
00299         return (pos > other.pos);
00300       };
00301 
00302       /**
00303        * compare if the position of the first iterator is smaller or equal than
00304        * the position of the second iterator
00305        */
00306       inline bool operator<=(const iterator& other) const {
00307         return (pos <= other.pos);
00308       };
00309 
00310       /**
00311        * compare if the position of the first iterator is greater or equal
00312        * than the position of the second iterator
00313        */
00314       inline bool operator>=(const iterator& other) const {
00315         return (pos >= other.pos);
00316       };
00317 
00318       /**
00319        * get pointed data
00320        */
00321       inline T& operator*() {return theGenericVector->at(pos);};
00322 
00323       /**
00324        * access the elements relative to the iterator position
00325        */
00326       inline T& operator[](const int i) {return theGenericVector->at(pos+i);};
00327 
00328       /**
00329        * copy member
00330        */
00331       inline iterator& operator=(const iterator& other) {
00332         pos = other.pos;
00333         theGenericVector = other.theGenericVector;
00334         return *this;
00335       };
00336 
00337     protected:
00338       /**
00339        * protected constructor (for internal use only)
00340        * NEVER USE EXPLICITLY THIS CONSTRUCTOR, OR YOUR CODE WILL NOT
00341        * COMPILE IN THE RELEASE VERSION!
00342        */
00343       explicit iterator(const int startPos,genericVector<T>* vct)
00344         : pos(startPos), theGenericVector(vct) {};
00345 
00346       /**
00347        * for internal use only!!!
00348        * This method does not exist in the release version!
00349        */
00350       const int& getPos() const {return pos;};
00351 
00352       /**
00353        * for internal use only!!!
00354        * This method does not exist in the release version!
00355        */
00356       const genericVector<T>* getGenericVector() const {
00357         return theGenericVector;
00358       };
00359 
00360     private:
00361       /**
00362        * actual genericVector index
00363        */
00364       int pos;
00365 
00366       /**
00367        * pointer to the actual genericVector
00368        */
00369       genericVector<T>* theGenericVector;
00370     };
00371 
00372     /**
00373      * const iterator type (allows read-only operations).
00374      *
00375      * The use of the iterator classes is similar to the iterators of
00376      * the STL (Standard Template Library). See lti::genericVector::begin()
00377      * for an example.
00378      *
00379      * For the debugging version of the iterators, boundary check will be
00380      * done!  This explains the low speed of the iterators of the debug
00381      * version.  In the release version, no boundary check will be done,
00382      * and the iterators are sometimes a factor 10 faster than the
00383      * debug iterators.
00384      *
00385      * The use of the access operator at(.) is faster than the
00386      * iterators in the debug version only.  If you need to iterate on
00387      * a genericVector use iterators instead (in the release version
00388      * iterators are approx. a factor 3 faster than "at(.)").
00389      *
00390      * CAUTION: Try to use the prefix incremental operator
00391      * (i.e. ++it) instead of the postfix operator (i.e. it++) to
00392      * allow efficient code also in debug-modus!
00393      *
00394      * see also iterator
00395      */
00396     class const_iterator {
00397       friend class genericVector<T>;
00398     public:
00399       /**
00400        * default constructor
00401        */
00402       const_iterator()
00403         : pos(0), theGenericVector(0) {};
00404 
00405       /**
00406        *  copy constructor
00407        */
00408       const_iterator(const const_iterator& other) {(*this)=other;};
00409 
00410       /**
00411        *  copy constructor
00412        */
00413       const_iterator(const iterator& other) {(*this)=other;};
00414 
00415       /**
00416        *  advance to next item  -- prefix
00417        */
00418       inline const_iterator& operator++() {++pos; return *this;};
00419 
00420       /**
00421        *  advance to next item  -- postfix
00422        */
00423       inline const_iterator operator++(int) {
00424         const_iterator tmp(*this); pos++; return tmp;
00425       };
00426 
00427       /**
00428        *  recede to previous item  -- prefix
00429        */
00430       inline const_iterator& operator--() {--pos; return *this;};
00431 
00432       /**
00433        *  recede to previous item  -- postfix
00434        */
00435       inline const_iterator operator--(int) {
00436         const_iterator tmp(*this); pos--; return tmp;
00437       };
00438 
00439       /**
00440        * advance (skip) some elements.
00441        * Use this operator with care! Note that you can skip the end of
00442        * the genericVector, and read (or even worse: write!) out of bounds!
00443        */
00444       inline const_iterator& operator+=(const int n) {pos+=n; return *this;};
00445 
00446       /**
00447        * recede (skip) some elements.
00448        * Use this operator with care! Note that you can skip the beginning of
00449        * the genericVector, and read (or even worse: write!) out of bounds!
00450        */
00451       inline const_iterator& operator-=(const int n) {pos-=n; return *this;};
00452 
00453       /**
00454        * advance (skip) some elements.
00455        * Use this operator with care! Note that you can skip the end of
00456        * the genericVector, and read (or even worse: write!) out of bounds!
00457        */
00458       inline const_iterator operator+(const int n) {
00459         return const_iterator(pos+n,theGenericVector);
00460       };
00461 
00462       /**
00463        * recede (skip) some elements.
00464        * Use this operator with care! Note that you can skip the beginning of
00465        * the genericVector, and read (or even worse: write!) out of bounds!
00466        */
00467       inline const_iterator operator-(const int n) {
00468         return const_iterator(pos-n,theGenericVector);
00469       };
00470 
00471       /**
00472        * compare if both pointed positions are the same
00473        */
00474       inline bool operator==(const const_iterator& other) const {
00475         return (pos == other.pos);
00476       };
00477 
00478       /**
00479        * compare if both pointed positions are different
00480        */
00481       inline bool operator!=(const const_iterator& other) const {
00482         return (pos != other.pos);
00483       };
00484 
00485       /**
00486        * compare if both pointed positions are the same
00487        */
00488       inline bool operator==(const iterator& other) const {
00489         return (pos == other.getPos());
00490       };
00491 
00492       /**
00493        * compare if both pointed positions are different
00494        */
00495       inline bool operator!=(const iterator& other) const {
00496         return (pos != other.getPos());
00497       };
00498 
00499       /**
00500        * compare if the position of the first iterator is smaller than
00501        * the position of the second iterator
00502        */
00503       inline bool operator<(const iterator& other) const {
00504         return (pos < other.pos);
00505       };
00506 
00507       /**
00508        * compare if the position of the first iterator is greater than
00509        * the position of the second iterator
00510        */
00511       inline bool operator>(const iterator& other) const {
00512         return (pos > other.pos);
00513       };
00514 
00515       /**
00516        * compare if the position of the first iterator is smaller or equal than
00517        * the position of the second iterator
00518        */
00519       inline bool operator<=(const iterator& other) const {
00520         return (pos <= other.pos);
00521       };
00522 
00523       /**
00524        * compare if the position of the first iterator is greater or equal
00525        * than the position of the second iterator
00526        */
00527       inline bool operator>=(const iterator& other) const {
00528         return (pos >= other.pos);
00529       };
00530 
00531       /**
00532        * compare if the position of the first iterator is smaller than
00533        * the position of the second iterator
00534        */
00535       inline bool operator<(const const_iterator& other) const {
00536         return (pos < other.pos);
00537       };
00538 
00539       /**
00540        * compare if the position of the first iterator is greater than
00541        * the position of the second iterator
00542        */
00543       inline bool operator>(const const_iterator& other) const {
00544         return (pos > other.pos);
00545       };
00546 
00547       /**
00548        * compare if the position of the first iterator is smaller or equal than
00549        * the position of the second iterator
00550        */
00551       inline bool operator<=(const const_iterator& other) const {
00552         return (pos <= other.pos);
00553       };
00554 
00555       /**
00556        * compare if the position of the first iterator is greater or equal
00557        * than the position of the second iterator
00558        */
00559       inline bool operator>=(const const_iterator& other) const {
00560         return (pos >= other.pos);
00561       };
00562 
00563       /**
00564        * get pointed data
00565        */
00566       inline const T& operator*() {return theGenericVector->at(pos);};
00567 
00568       /**
00569        * access the elements relative to the iterator position
00570        */
00571       inline const T& operator[](const int i) {
00572         return theGenericVector->at(pos+i);
00573       };
00574 
00575       /**
00576        * copy member
00577        */
00578       inline const_iterator& operator=(const const_iterator& other) {
00579         pos = other.pos;
00580         theGenericVector = other.theGenericVector;
00581         return *this;
00582       };
00583 
00584       /**
00585        * copy member
00586        */
00587       inline const_iterator& operator=(const iterator& other) {
00588         pos = other.getPos();
00589         theGenericVector = other.getGenericVector();
00590         return *this;
00591       };
00592 
00593     protected:
00594       /**
00595        * protected constructor
00596        * DO NOT EXPLICITLY USE THIS CONSTRUCTOR. OTHERWISE YOUR CODE WILL NOT
00597        * COMPILE IN THE RELEASE VERSION!
00598        */
00599       explicit const_iterator(int startPos,const genericVector<T>* vct)
00600         : pos(startPos), theGenericVector(vct) {};
00601 
00602     private:
00603 
00604       /**
00605        * actual genericVector index
00606        */
00607       int pos;
00608 
00609       /**
00610        * pointer to the actual genericVector
00611        */
00612       const genericVector<T>* theGenericVector;
00613     };
00614 
00615 #   endif
00616 
00617     /**
00618      * Default constructor creates an empty genericVector;
00619      */
00620     genericVector();
00621 
00622     /**
00623      * Create a genericVector of the given size and initialize it with the
00624      * given value.
00625      * @param theSize number of elements of the genericVector.
00626      * @param iniValue all elements will be initialized with this value.
00627      */
00628     explicit genericVector(int theSize,const T& iniValue = T());
00629 
00630     /**
00631      * Create a genericVector of the given size and initialize it with the
00632      * given data. The \a data will be copied.
00633      * @see useExternData()
00634      * @param theSize number of elements of the genericVector.
00635      * @param data a pointer to the data that will be copied.
00636      */
00637     genericVector(int theSize,const T data[]);
00638 
00639     /**
00640      * Create a genericVector of the given size and initialize it with the
00641      * given data, the same way "useExternData" does.
00642      * The \a data will not be copied!.
00643      * @see useExternData()
00644      * @param theSize number of elements of the genericVector.
00645      * @param data a pointer to the data that will be used.
00646      * @param constRef if this parameter is true, it will not be possible to
00647      *                change the pointer to the external memory block nor
00648      *                to resize the genericVector.  Despite this, the value of
00649      *                each element can be changed by the access operators.
00650      */
00651     genericVector(int theSize,T data[],const bool constRef);
00652 
00653     /**
00654      * Create this genericVector as a copy of another genericVector
00655      * @param other the genericVector to be copied.
00656      */
00657     genericVector(const genericVector<T>& other);
00658 
00659     /**
00660      * Create this genericVector as a copy of specified interval of
00661      * elements of another genericVector. Indices below zero are set
00662      * to zero, indices greater than the size of the %genericVector to
00663      * the size-1.
00664      * @param other the genericVector to be copied.
00665      * @param from starting point included
00666      * @param to end point included.
00667      */
00668     genericVector(const genericVector<T>& other,
00669                   int from, int to=MaxInt32);
00670 
00671     /**
00672      * Create this genericVector as a copy of specified elements of
00673      * another genericVector.  \a idx can contain the same index more
00674      * than once.
00675      * @param other the genericVector to be copied.
00676      * @param idx indices of the elements to be copied
00677      */
00678     genericVector(const genericVector<T>& other, 
00679                   const genericVector<int>& idx);
00680 
00681     /**
00682      * Create this genericVector as a copy of another std::genericVector
00683      * @param other the genericVector to be copied.
00684      */
00685     genericVector(const std::vector<T>& other);
00686 
00687     /**
00688      * If \a init is true this constructor is equivalent to calling
00689      * genericVector(int theSize), and thus initializing
00690      * all elements with T(). However, in some cases the elements need
00691      * not be initialized during construction, since complex
00692      * initializion is required. Especially for large genericVectors, the
00693      * unnecessary constructor initialization is very time consuming.
00694      *
00695      * If \a init is false, memory is allocated but no initialization
00696      * takes place. Thus the following is equivalent:
00697      * \code
00698      * genericVector<int> a(false,10000);
00699      *
00700      * matrix<int> a;
00701      * a.resize(10000,0,false,false);
00702      * \endcode
00703      *
00704      * @param init initialize matrix or not
00705      * @param theSize number of elements of the genericVector.
00706      */
00707     genericVector(bool init, int theSize);
00708 
00709     /**
00710      * destructor
00711      */
00712     virtual ~genericVector();
00713 
00714     /**
00715      * returns the name of this class: "genericVector"
00716      */
00717     const char* getTypeName() const {return "genericVector";};
00718 
00719     /**
00720      * Check whether this %object owns the data.
00721      * returns \a false if this genericVector contains a reference to extern
00722      * data.
00723      */
00724     inline bool ownsData() const;
00725 
00726     /**
00727      * If this object does not own its data, this member will create a
00728      * new memory buffer with the same data and will make this matrix
00729      * as its owner.  You can also be sure, that the new memory block
00730      * will be connected (see also getMode() ).  If this genericVector
00731      * already owns its data nothing happens.
00732      */
00733     void restoreOwnership();
00734 
00735     /**
00736      * Reference to extern data.
00737      *
00738      * This member allows the use of this %object as an wrapper-%object to
00739      * access some memory block as a genericVector.
00740      * The user must take care for memory allocation and deallocation of
00741      * the block.  This %object will never delete the external data!.
00742      * @param theSize number of \e elements in the external block.  Note that
00743      *                this is NOT the number of bytes of the external block.
00744      * @param data    pointer to the external memory block.
00745      * @param constRef if this parameter is true, it will not be possible to
00746      *                change the pointer to the external memory block nor
00747      *                to resize the genericVector.  Despite this, the value of
00748      *                each element can be changed by the access operators.
00749      * For Example:
00750      * \code
00751      * int i;
00752      * double tmp;
00753      * double a[10];               // memory block!
00754      *
00755      * for (i=0;i<10;i++) {
00756      *   a[i]=2*i;                 // initialize the memory block
00757      * }
00758      *
00759      * lti::genericVector<double> myVct;  // an empty genericVector
00760      *
00761      * myVct.resize(5,0);          // resize the genericVector: now 5 elements
00762      *                             // initialized with 0
00763      *
00764      * myVct.useExternData(10,a,true);   // use the genericVector as wrapper
00765      *                                   // for the memory block
00766      *
00767      * tmp = myVct.at(5);                // tmp is now 10
00768      *
00769      * myVct.at(9) = 3;                  // the last element of myVct
00770      *                                   // has now the value 3
00771      *
00772      * myVct.resize(5);            // INVALID!! this will throw an exception
00773      *                             // constReferenceException()
00774      * \endcode
00775      *
00776      *
00777      * If \a theSize is greater than the allocated memory, the behaviour could
00778      * be unpredictible.
00779      */
00780     void useExternData(int theSize,T* data,bool constRef=false);
00781 
00782     /**
00783      * Attach extern data to the matrix.
00784      *
00785      * This member allows the use of this %object as an access-functor for
00786      * the 'data'. An access to the element at (x) is equivalent to
00787      * data[x].
00788      * If \a theSize is an invalid dimension, the
00789      * behaviour will be unpredictible.
00790      *
00791      * The memory will be administrated by this genericVector
00792      * instance, and may be deleted if required (genericVector deleted
00793      * or resized!).  The user should not try to manipulate the memory
00794      * allocation of the data after the attachment!  See also
00795      * useExternData().
00796      *
00797      * @param theSize number of elements of the genericVector
00798      * @param data a pointer to the memory block to be used
00799      *
00800      * Example:
00801      * \code
00802      * lti::genericVector<int> myVct;
00803      * int block1[25];
00804      * int* block2;
00805      * block2 = new int[25];
00806      *
00807      * myVct.useExternData(25,block1); // ok
00808      * myVct.attach(25,block1); // wrong!!! matrix will try to manipulate
00809      *                          // stack memory: DO NOT DO THIS!!!!!
00810      * myVct.attach(25,block2); // ok!  but do not try to delete the memory
00811      *                          //      block2!!
00812      * \endcode
00813      */
00814     void attach(int theSize,T* data);
00815 
00816     /**
00817      * Free the data of this object and hand it over to the
00818      * "receiver". The value of ownsData is also transfered to the
00819      * receiver. (see Note).
00820      *
00821      * This function makes a "memory block transfusion" to another
00822      * genericVector.  It is a very efficient way to make a copy of
00823      * this genericVector, if you don't need the source data anymore!
00824      *
00825      * \b Note: Take care that if the attach() or useExternData()
00826      * methods of this genericVector have been called before detachment, the
00827      * same rules for memory management apply now for the receiver.
00828      *
00829      * At the end of the detachment, this genericVector will be empty.
00830      * @param receiver the genericVector which will receive the memory
00831      *        block.  All data of that genericVector will be first deleted!
00832      */
00833     void detach(genericVector<T>& receiver);
00834 
00835     /**
00836      * \deprecated Please use swap() instead.
00837      */
00838     void exchange(genericVector<T>& other);
00839 
00840     /**
00841      * Exchange (in a fast way) the data between this and the other
00842      * genericVector.  Similar to detach(), this method will exchange
00843      * the complete memory blocks, avoiding an element-wise copy.
00844      * @param other the genericVector with which the data will be
00845      * exchanged.
00846      */
00847     void swap(genericVector<T>& other);
00848 
00849     /**
00850      * Return type of the size() member
00851      */
00852     typedef int size_type;
00853 
00854     /**
00855      * Returns the number of elements of the genericVector
00856      */
00857     inline const int& size() const;
00858 
00859     /**
00860      * Returns first index (normally 0)
00861      */
00862     inline int firstIdx() const;
00863 
00864     /**
00865      * Returns first element as a const_iterator.
00866      *
00867      * Note that you can not change the values of the genericVector
00868      * elements when you use a const_iterator. See also begin()
00869      */
00870     inline const_iterator begin() const;
00871 
00872     /**
00873      * Returns iterator pointing to the first element.
00874      *
00875      * The use of the iterators is similar to the iterators of the
00876      * Standard Template Library (STL).
00877      * If you need to iterate on all elements of the genericVector, you can
00878      * use following code:
00879      *
00880      * \code
00881      *   int tmp,accu;                                  // a temporal variable
00882      *   lti::genericVector<int> myVct(10,1);                  // a genericVector with 10 elements
00883      *   lti::genericVector<int>::iterator it=myVct.begin();   // an iterator set to the beginning of myVct
00884      *   lti::genericVector<int>::iterator eit=myVct.begin();  // an iterator set to the end of myVct
00885      *
00886      *   for (; it!=eit ; ++it) {
00887      *     tmp = *it;                    // tmp has value of element pointed
00888      *                                   // by the iterator.
00889      *     accu += tmp;
00890      *     (*it) = accu;                 // change the value in the genericVector.
00891      *    }
00892      * \endcode
00893      *
00894      * \b NOTE: It is significantly faster in debug builds to use a
00895      * pre-increment with iterators (++it) than a post-increment
00896      * (it++).
00897      *
00898      * Please note that if you define \a it as a const_iterator,
00899      * you can not do something like \a *it=accu.
00900      */
00901     inline iterator begin();
00902 
00903     /**
00904      *  returns last index (in a genericVector this is always size()-1)
00905      */
00906     inline int lastIdx() const;
00907 
00908     /**
00909      * returns last index as a const iterator.
00910      * For an example see begin()
00911      */
00912     inline const_iterator end() const;
00913 
00914     /**
00915      * returns last index as an iterator
00916      * For an example see begin()
00917      */
00918     inline iterator end();
00919 
00920 
00921     /**
00922      * This method returns an iterator that points to the \b last
00923      * valid element of the genericVector. It is used for inverse order
00924      * iteration through the genericVector using normal iterators (as opposed
00925      * to reverse_iterators used in the STL). This has the advantage
00926      * that iterators going from front to end and in the inverse
00927      * direction are the same and can thus be compared, copied
00928      * etc. Further the implementation of reverse_iterators is not as
00929      * fast as that of iterators and thus not desired in the LTI-Lib.
00930      *
00931      * \code
00932      * igenericVector v(false,10);
00933      * int i,tmp;
00934      * for (i=0; i<10; i++) {
00935      *   v.at(i)=i;
00936      * }
00937      * igenericVector::iterator forwardIt=v.begin();
00938      * igenericVector::iterator backIt=v.inverseBegin();
00939      *
00940      * while (forwardIt<=backIt) {
00941      *   tmp = (*forwardIt); (*forwardIt)=(*backIt); (*backIt)=tmp;
00942      *   ++forwardIt; ++backIt;
00943      * }
00944      * \endcode
00945      */
00946     inline iterator inverseBegin();
00947 
00948     /**
00949      * This method returns an iterator that points to the \b last
00950      * valid element of the genericVector. See inverseBegin() for more details.
00951      */
00952     inline const_iterator inverseBegin() const;
00953 
00954     /**
00955      * This method returns an iterator that points to the element \b
00956      * before the \b first valid element of the genericVector. It is used to
00957      * mark the end for inverse order iteration through the genericVector
00958      * using normal iterators (as opposed to reverse_iterators as used
00959      * in the STL). This has the advantage that iterators going from
00960      * front to end and in the inverse direction are the same and can
00961      * thus be compared, copied etc.Further the implementation of
00962      * reverse_iterators is not as fast as that of iterators and thus
00963      * not desired in the LTI-Lib.
00964      */
00965     inline iterator inverseEnd();
00966 
00967     /**
00968      * This method returns an iterator that points to the element \b
00969      * before the \b first valid element of the genericVector.
00970      */
00971     inline const_iterator inverseEnd() const;
00972     
00973     /**
00974      * change dimension of the genericVector.
00975      * @param newSize the new size of the genericVector
00976      * @param iniValue the initialization value.
00977      * @param copyData if this parameter is true, the old data of the
00978      *                 genericVector will be copied.  If it is false, 
00979      *                 the old data will be lost.
00980      * @param initNew  if this parameter is true, then all new elements (if
00981      *                 they exist) will be initialized with
00982      *                 \a iniValue.
00983      *                 if \a initNew is false, then the new
00984      *                 elements are left uninitialized.
00985      *
00986      * For example:
00987      * \code
00988      *   lti::genericVector<int> myVct;  // creates empty genericVector
00989      *   myVct.resize(5,0);       // genericVector with 5 elements initialized
00990      *                            // with 0
00991      *   myVct.resize(10,2);      // genericVector has now 10 elements: the
00992      *                            // first five are still 0 and the
00993      *                            // rest have a 2
00994      *   myVct.resize(20,3,false,false); // now the genericVector has 20
00995      *                                   // elements but their values
00996      *                                   // are unknown.
00997      *   myVct.resize(5,1,false,true); // the genericVector has now 5
00998      *                                 // elements initialized with 1
00999      *
01000      *   // note that the last line could also be written:
01001      *
01002      *   myVct.resize(5,1,false);      // the genericVector has now 5
01003      *                                 // elements initialized with 1
01004      *
01005      * \endcode
01006      *
01007      *
01008      * If the new size is not equal to the old size, the genericVector
01009      * always owns the data afterwards (i.e. new memory is allocated)
01010      * even if it didn't own the data before. Otherwise the ownership
01011      * remains unchanged. You can use restoreOwnership() if you just
01012      * want to own the data.
01013      */
01014     void resize(int newSize,
01015                 const T& iniValue = T(),
01016                 bool copyData = true,
01017                 bool initNew = true);
01018 
01019     /**
01020      * clears the genericVector (dimension 0)
01021      */
01022     void clear();
01023 
01024     /**
01025      * returns true if the genericVector is empty
01026      */
01027     bool empty() const;
01028 
01029     /**
01030      * fills the genericVector elements with \a iniValue between
01031      * \a from and \a to.
01032      * @param iniValue the elements will be initialized with this
01033      *                 value.
01034      * @param from     first element index
01035      * @param to       last element index
01036      *
01037      * If \a from or \a to are out of bounds,
01038      * they will be (internaly) adjusted to to correct value.
01039      *
01040      * Example:
01041      * \code
01042      *   lti::genericVector<double> myVct(10,0);  // genericVector with 10 elements
01043      *                                     // with 0
01044      *   myVct.fill(9,1,3);                // myVct=[0,9,9,9,0,0,0,0,0,0]
01045      * \endcode
01046      */
01047     void fill(const T& iniValue,int from = 0,
01048               int to = MaxInt32);
01049 
01050     /**
01051      * fills the genericVector elements with data pointed by \a data
01052      * between \a from and \a to.
01053      * @param data the data to by copied into this genericVector
01054      * @param from     first element index
01055      * @param to       last element index
01056      *
01057      * If \a from or \a to are out of bounds,
01058      * they will be (internaly) adjusted to to correct value.
01059      *
01060      * Example:
01061      * \code
01062      *   double* data = {2,4,8,16};
01063      *   lti::genericVector<double> myVct(10,0);  // genericVector with 10 elements
01064      *                                     // with 0
01065      *   myVct.fill(data,1,3);             // myVct=[0,2,4,8,0,0,0,0,0,0]
01066      * \endcode
01067      */
01068     void fill(const T data[],int from = 0,
01069                              int to = MaxInt32);
01070 
01071     /**
01072      * fills the genericVector elements from \a from to
01073      * \a to with the elements of \a vct starting
01074      * at \a startAt.
01075      * @param vct genericVector with the elements to be copied
01076      * @param from first element index of the actual genericVector
01077      * @param to   last element index of the actual genericVector
01078      * @param startAt start index of the source genericVector \a vct.
01079      *
01080      * Example:  if a = [0 0 0 0 0] and b = [1 2 3], after a.fill(b,3,4,1)
01081      * results a = [0 0 0 2 3]
01082      */
01083     void fill(const genericVector<T>& vct,int from = 0,
01084               int to = MaxInt32,
01085               int startAt = 0);
01086 
01087     /**
01088      * access element x of the genericVector
01089      * @param x index of the genericVector element to be accessed. It should
01090      * be between firstIdx() and lastIdx()
01091      */
01092     inline T& at(const int x);
01093 
01094     /**
01095      * access element x of the genericVector in a read-only modus
01096      * @param x index of the genericVector element to be accessed. It should
01097      * be between firstIdx() and lastIdx()
01098      */
01099     inline const T& at(const int x) const;
01100 
01101     /**
01102      *  access operator (alias for at(const int x)).
01103      */
01104     inline T& operator[](const int x);
01105 
01106     /**
01107      *  const access operator (alias for at(const int x) const).
01108      */
01109     inline const T& operator[](const int x) const;
01110 
01111     /** assigment operator.
01112      * copy the contents of \a other in this %object.
01113      * @param other the source genericVector to be copied.
01114      */
01115     genericVector<T>& copy(const genericVector<T>& other);
01116 
01117     /**
01118      * assignment operator.
01119      * copy of specified interval of elements of another genericVector.
01120      * @param other the genericVector to be copied.
01121      * @param from starting point included
01122      * @param to end point included.
01123      */
01124     genericVector<T>& copy(const genericVector<T>& other,
01125                     int from, int to=MaxInt32);
01126 
01127     /**
01128      * assignment operator.
01129      * copy of specified elements of \a other in this %object.
01130      * \a idx can contain the same index more than once.
01131      * @param other the genericVector to be copied.
01132      * @param idx indices of the elements to be copied
01133      */
01134     genericVector<T>& copy(const genericVector<T>& other, const genericVector<int>& idx);
01135 
01136     /**
01137      * assigment operator (alias for copy(other)).
01138      * @param other the genericVector to be copied
01139      * @return a reference to the actual genericVector
01140      */
01141     genericVector<T>& operator=(const genericVector<T>& other) {return copy(other);};
01142 
01143     /**
01144      * create a clone of this genericVector
01145      * @return a pointer to a copy of this genericVector
01146      */
01147     virtual mathObject* clone() const;
01148 
01149     /**
01150      * compare this genericVector with other
01151      * @param other the other genericVector to be compared with
01152      * @return true if both genericVectors have the same elements and same size
01153      */
01154     bool equals(const genericVector<T>& other) const;
01155 
01156     /**
01157      * compare this genericVector with other
01158      * @param other the other genericVector to be compared with
01159      * @return true if both genericVectors have the same elements and same size
01160      */
01161     inline bool operator==(const genericVector<T>& other) const;
01162 
01163     /**
01164      * compare this genericVector with other
01165      * @param other the other genericVector to be compared with
01166      * @return true if both genericVectors different dimensions or elements
01167      */
01168     inline bool operator!=(const genericVector<T>& other) const;
01169 
01170     /**
01171      * copy the \a other genericVector by casting each of its
01172      * elements.
01173      * @param other The genericVector to be copied.
01174      *
01175      * For Example:
01176      * \code
01177      *   lti::genericVector<int> vctA(10,1);  // a genericVector of integers
01178      *   lti::genericVector<double> vctB;     // a genericVector of doubles
01179      *
01180      *   vctB.castFrom(vctA);          // this will copy vctA in vctB!!
01181      * \endcode
01182      */
01183     template<class U>
01184     genericVector<T>& castFrom(const genericVector<U>& other) {
01185       typename genericVector<U>::const_iterator it,eit;
01186       typename genericVector<T>::iterator dit;
01187 
01188       // only resize if necessary. castFrom doesn't guarantee ownership.
01189       if (other.size() != size()) {
01190         resize(other.size(),T(),false,false);
01191       }
01192 
01193       for (it=other.begin(),dit=begin(),eit=other.end();
01194            it!=eit;++it,++dit) {
01195         *dit = static_cast<T>(*it);
01196       }
01197 
01198       return *this;
01199     };
01200 
01201     /**
01202      * cast from a std::vector of the same type
01203      */
01204     template<class U>
01205     genericVector<T>& castFrom(const std::vector<U>& other) {
01206       typename std::vector<U>::const_iterator it,eit;
01207       typename genericVector<T>::iterator dit;
01208 
01209       // only resize if necessary. castFrom doesn't guarantee ownership.
01210       if (static_cast<int>(other.size()) != size()) {
01211         resize(static_cast<int>(other.size()),T(),false,false);
01212       }
01213 
01214       for (it=other.begin(),dit=begin(),eit=other.end();
01215            it!=eit;++it,++dit) {
01216         *dit = static_cast<T>(*it);
01217       }
01218 
01219       return *this;
01220     };
01221 
01222 
01223     /**
01224      * @name Apply Methods
01225      */
01226     //@{
01227 
01228     /**
01229      * applies a C-function to each element of the genericVector.
01230      * 
01231      * In the following example, %genericVector \a vct is initialized with
01232      * 4.0. After applying \a sqrt(), all elements of \a vct are 2.0.
01233      * \code
01234      * genericVector<float> vct(4,4.0);
01235      * vct.apply(sqrt);
01236      * \endcode
01237      * @param function a pointer to a C-function
01238      * @return a reference to the actual genericVector
01239      */
01240     genericVector<T>& apply(T (*function)(T));
01241 
01242     /**
01243      * applies a C-function to each element of the other genericVector and leaves
01244      * the result here.
01245      * @param other the source genericVector
01246      * @param function a pointer to a C-function
01247      * @return a reference to the actual genericVector
01248      */
01249     genericVector<T>& apply(const genericVector<T>& other,T (*function)(T));
01250 
01251     /**
01252      * applies a C-function to each element of the genericVector.
01253      * @param function a pointer to a C-function
01254      * @return a reference to the actual genericVector
01255      */
01256     genericVector<T>& apply(T (*function)(const T&));
01257 
01258     /**
01259      * applies a C-function to each element the other genericVector and
01260      * leaves the result here.
01261      * @param other the genericVector with the source data
01262      * @param function a pointer to a C-function
01263      * @return a reference to the actual genericVector
01264      */
01265     genericVector<T>& apply(const genericVector<T>& other,
01266                             T (*function)(const T&));
01267 
01268     /**
01269      * a two-parameter C-function receives the i-th elements of this
01270      * and the given genericVector and the result will be left in this
01271      * genericVector.  Note that both genericVectors MUST have the same size!
01272      * If both genericVectors have different size, the function will throw an
01273      * assertion without changing anything!
01274      * @param other the second genericVector to be considered (the first
01275      *              genericVector will be this object!)
01276      * @param function a pointer to a two parameters C-function
01277      * @return a reference to the actual genericVector
01278      */
01279     genericVector<T>& apply(const genericVector<T>& other,
01280                             T (*function)(const T&,const T&));
01281 
01282     /**
01283      * a two-parameter C-function receives the i-th elements of this
01284      * and the given genericVector and the result will be left in this
01285      * genericVector.  Note that both genericVectors MUST have the same size!
01286      * If both genericVectors have different size, the function will throw an
01287      * assertion without changing anything!
01288      * @param other the second genericVector to be considered (the first
01289      *              genericVector will be this object!)
01290      * @param function a pointer to a two parameters C-function
01291      * @return a reference to the actual genericVector
01292      */
01293     genericVector<T>& apply(const genericVector<T>& other,T (*function)(T,T));
01294 
01295     /**
01296      * a two-parameter C-function receives the i-th elements of the
01297      * given genericVectors and leaves the result here.
01298      * Note that both genericVectors MUST have the same size!
01299      * If both genericVectors have different size, the function will throw an
01300      * assertion without changing anything!
01301      *
01302      * The following example uses lti::min as function. The genericVectors \a
01303      * a and \a b contain the values [1,2,3,4] and [4,3,2,1],
01304      * respectively. After applying the function, %genericVector \a c
01305      * contains the values [1,2,2,1].
01306      * \code 
01307      * igenericVector a,b,c;
01308      * int i=0;
01309      * for (i=0; i<4; ++i) {
01310      *   a.at(i)=i+1;
01311      *   b.at(i)=4-i;
01312      * }
01313      * c.apply(a,b,lti::min);
01314      * \endcode
01315      * @param a the first genericVector
01316      * @param b the second genericVector
01317      * @param function a pointer to a two parameters C-function
01318      * @return a reference to the actual genericVector
01319      */
01320     genericVector<T>& apply(const genericVector<T>& a,
01321                      const genericVector<T>& b,
01322                      T (*function)(const T&,const T&));
01323 
01324     /**
01325      * a two-parameter C-function receives the i-th elements of the
01326      * given genericVectors and leaves the result here.
01327      * Note that both genericVectors MUST have the same size!
01328      * If both genericVectors have different size, the function will throw an
01329      * assertion without changing anything!
01330      * @param a the first genericVector
01331      * @param b the second genericVector
01332      * @param function a pointer to a two parameters C-function
01333      * @return a reference to the actual genericVector
01334      */
01335     genericVector<T>& apply(const genericVector<T>& a,
01336                      const genericVector<T>& b,
01337                      T (*function)(T,T));
01338 
01339     //@}
01340 
01341     /**
01342      * @name Input and Output
01343      */
01344     //@{
01345     /**
01346      * write the object in the given ioHandler
01347      */
01348     virtual bool write(ioHandler& handler,const bool complete = true) const;
01349 
01350     /**
01351      * read the object from the given ioHandler
01352      */
01353     virtual bool read(ioHandler& handler,const bool complete = true);
01354     //@}
01355 
01356   protected:
01357     /**
01358      *  dimension of the genericVector.
01359      */
01360     int vectorSize;
01361 
01362     /**
01363      * index of the last element of the genericVector (always
01364      * vectorSize-1)
01365      */
01366     int idxLastElement;
01367 
01368     /**
01369      *  pointer to the first element of the genericVector.
01370      */
01371     T* theElements;
01372 
01373     /**
01374      * reference to extern data.
01375      * if this value ist \a false, then the data pointed by
01376      * \a theElements will never be deleted in this
01377      * %object! (see useExternData())
01378      */
01379     bool ownData;
01380 
01381     /**
01382      * if constReference=true, is not possible to resize or change
01383      * the reference of this genericVector. Important for the matrix class!!
01384      * (see useExternData())
01385      */
01386     bool constReference;
01387   };
01388 
01389 } // namespace lti
01390 
01391 /*
01392  * outputs the elements of the genericVector on a stream
01393  */
01394 namespace std {
01395   template <class T>
01396   ostream& operator<<(ostream& s,const lti::genericVector<T>& v);
01397 }
01398 
01399 #include "ltiGenericVector_inline.h"
01400 #include "ltiGenericVector_template.h"
01401 
01402 #else
01403 #include "ltiGenericVector_template.h"
01404 #endif

Generated on Sat Apr 10 15:25:35 2010 for LTI-Lib by Doxygen 1.6.1