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

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

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