/home/coin/SVN-release/CoinAll-1.1.0/cppad/cppad/vector.hpp

Go to the documentation of this file.
00001 # ifndef CPPAD_VECTOR_INCLUDED
00002 # define CPPAD_VECTOR_INCLUDED
00003 
00004 /* --------------------------------------------------------------------------
00005 CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-07 Bradley M. Bell
00006 
00007 CppAD is distributed under multiple licenses. This distribution is under
00008 the terms of the 
00009                     Common Public License Version 1.0.
00010 
00011 A copy of this license is included in the COPYING file of this distribution.
00012 Please visit http://www.coin-or.org/CppAD/ for information on other licenses.
00013 -------------------------------------------------------------------------- */
00014 
00015 /*
00016 $begin CppAD_vector$$
00017 $spell
00018         cppad.hpp
00019         Bool
00020         resize
00021         cout
00022         endl
00023         std
00024         Cpp
00025         const
00026         vec
00027         ostream
00028         elem
00029 $$
00030 
00031 $index vector, CppAD template class$$
00032 $index class, template CppAD vector$$
00033 $index template, CppAD vector class$$
00034 
00035 $section The CppAD::vector Template Class$$
00036 
00037 $head Syntax$$
00038 $code # include <cppad/vector.hpp>$$
00039 
00040 
00041 
00042 $head Description$$
00043 The include file $code cppad/vector.hpp$$ defines the
00044 vector template class $code CppAD::vector$$.
00045 This is a $xref/SimpleVector/$$ template class and in addition
00046 it has the features listed below:
00047 
00048 $head Include$$
00049 The file $code cppad/vector.hpp$$ is included by $code cppad/cppad.hpp$$
00050 but it can also be included separately with out the rest of the 
00051 CppAD include files.
00052 
00053 $head Assignment$$
00054 $index assignment, CppAD vector$$
00055 If $italic x$$ and $italic y$$ are 
00056 $syntax%CppAD::vector<%Scalar%>%$$ objects,
00057 $syntax%
00058         %y% = %x%
00059 %$$
00060 has all the properties listed for a
00061 $xref/SimpleVector/Assignment/simple vector assignment/$$
00062 plus the following:
00063 $pre
00064 
00065 $$
00066 The $code CppAD::vector$$ template class will check that
00067 the size of $italic x$$ is equal to the size of $italic y$$
00068 before doing the assignment.
00069 If the sizes are not equal, $code CppAD::vector$$ will use
00070 $xref/ErrorHandler/$$
00071 to generate an appropriate error report.
00072 $pre
00073 
00074 $$
00075 A reference to the vector $italic y$$ is returned.
00076 An example use of this reference is in multiple assignments of the form
00077 $syntax%
00078         %z% = %y% = %x%
00079 %$$
00080 
00081 $head Element Access$$
00082 $index [], CppAD vector$$
00083 $index vector, [] CppAD$$
00084 If $italic x$$ is a $syntax%CppAD::vector<%Scalar%>%$$ object
00085 and $code i$$ has type $code size_t$$,
00086 $syntax%
00087         %x%[%i%]
00088 %$$
00089 has all the properties listed for a
00090 $xref/SimpleVector/Element Access/simple vector element access/$$
00091 plus the following:
00092 $pre
00093 
00094 $$
00095 The object $syntax%%x%[%i%]%$$ has type $italic Scalar$$
00096 (is not possibly a different type that can be converted to $italic Scalar$$).
00097 $pre
00098 
00099 $$
00100 If $italic i$$ is not less than the size of the $italic x$$,
00101 $code CppAD::vector$$ will use
00102 $xref/ErrorHandler/$$
00103 to generate an appropriate error report.
00104 
00105 $head push_back$$
00106 $index push_back, CppAD vector$$
00107 $index vector, CppAD push_back$$
00108 If $italic x$$ is a $syntax%CppAD::vector<%Scalar%>%$$ object
00109 with size equal to $italic n$$ and
00110 $italic t$$ has type $italic Scalar$$,
00111 $syntax%
00112         %x%.push_back(%t%)
00113 %$$
00114 extends the vector $italic x$$ so that its new size is $italic n$$ plus one
00115 and $syntax%%x%[%n%]%$$ is equal to $italic t$$
00116 (in the sense of the $italic Scalar$$ assignment operator).
00117 
00118 $head Output$$
00119 If $italic x$$ is a $syntax%CppAD::vector<%Scalar%>%$$ object
00120 and $italic os$$ is an $code std::ostream$$,
00121 and the operation
00122 $syntax%
00123         %os% << %x%
00124 %$$
00125 will output the vector $italic x$$ to the standard
00126 output stream $italic os$$.
00127 The elements of $italic x$$ are enclosed at the beginning by a
00128 $code {$$ character,
00129 they are separated by $code ,$$ characters,
00130 and they are enclosed at the end by $code }$$ character.
00131 It is assumed by this operation that if $italic e$$
00132 is an object with type $italic Scalar$$,
00133 $syntax%
00134         %os% << %e%
00135 %$$
00136 will output the value $italic e$$ to the standard
00137 output stream $italic os$$.
00138 
00139 $head resize$$
00140 If the $code resize$$ member function is called with argument
00141 value zero, all memory allocated for the vector will be freed.
00142 The can be useful when using very large vectors
00143 and when checking for memory leaks (and there are global vectors).
00144 
00145 $head vectorBool$$
00146 $index vectorBool$$
00147 The file $code <cppad/vector.hpp>$$ also defines the class
00148 $code CppAD::vectorBool$$.
00149 This has the same specifications as $code CppAD::vector<bool>$$ 
00150 with the following exceptions
00151 
00152 $list number $$
00153 The class $code vectorBool$$ conserves on memory
00154 (on the other hand, $code CppAD::vector<bool>$$ is expected to be faster
00155 than $code vectorBool$$).
00156 
00157 $lnext
00158 The $code CppAD::vectorBool$$ output operator
00159 prints each boolean value as 
00160 a $code 0$$ for false,
00161 a $code 1$$ for true, 
00162 and does not print any other output; i.e.,
00163 the vector is written a long sequence of zeros and ones with no
00164 surrounding $code {$$, $code }$$ and with no separating commas or spaces. 
00165 
00166 $lnext
00167 If $italic x$$ has type $code vectorBool$$
00168 and $italic i$$ has type $code size_t$$,
00169 the element access value $syntax%%x%[%i%]%$$ has an unspecified type
00170 (referred to here as $italic elementType$$)
00171 that can be implicitly converted to $code bool$$.
00172 The return value of the assignment operator
00173 $syntax%
00174         %x%[%i%] = %y%
00175 %$$
00176 also has type $italic elementType$$. Thus, if $italic z$$
00177 has type $code bool$$, the syntax
00178 $syntax%
00179         %z% = %x%[%i%] = %y%
00180 %$$
00181 is valid.
00182 
00183 $lend
00184 
00185 $head Example$$
00186 $children%
00187         example/cpp_ad_vector.cpp%
00188         example/vector_bool.cpp
00189 %$$
00190 The files
00191 $xref/CppAD_vector.cpp/$$ and
00192 $xref/vectorBool.cpp/$$ each
00193 contain an example and test of this template class.
00194 They return true if they succeed and false otherwise.
00195 
00196 $head Exercise$$
00197 $index exercise, CppAD::vector$$
00198 Create and run a program that contains the following code:
00199 $codep
00200         CppAD::vector<double> x(3);
00201         size_t i;
00202         for(i = 0; i < 3; i++)
00203                 x[i] = 4. - i;
00204         std::cout << "x = " << x << std::endl;
00205 $$
00206 
00207 $end
00208 
00209 
00210 $end
00211 
00212 ------------------------------------------------------------------------ 
00213 */
00214 
00215 # include <cstddef>
00216 # include <iostream>
00217 # include <limits>
00218 # include <cppad/local/cppad_assert.hpp>
00219 # include <cppad/track_new_del.hpp>
00220 
00221 # ifndef CPPAD_NULL
00222 # define CPPAD_NULL 0
00223 # endif
00224 
00225 namespace CppAD { //  BEGIN CppAD namespace
00226 
00227 // ------------------ CppAD::vector<Type> ----------------------------------
00228 
00229 template <class Type>
00230 class vector {
00231 private:
00232         size_t capacity;
00233         size_t length;
00234         Type   * data;
00235 public:
00236         // type of the elements in the vector
00237         typedef Type value_type;
00238 
00239         // default constructor
00240         inline vector(void) : capacity(0), length(0) , data(CPPAD_NULL)
00241         { }
00242         // constructor with a specified size
00243         inline vector(size_t n) : capacity(n), length(n)
00244         {
00245                 data = CPPAD_NULL;
00246                 if( length > 0 )
00247                         data = CPPAD_TRACK_NEW_VEC(capacity, data);
00248         }
00249         // copy constructor
00250         inline vector(const vector &x) : capacity(x.length), length(x.length)
00251         {       size_t i;
00252                 data = CPPAD_NULL;
00253                 if( length > 0 )
00254                         data = CPPAD_TRACK_NEW_VEC(capacity, data);
00255 
00256                 for(i = 0; i < length; i++)
00257                         data[i] = x.data[i];
00258         }
00259         // destructor
00260         ~vector(void)
00261         {       if( data != CPPAD_NULL )
00262                         CPPAD_TRACK_DEL_VEC(data); 
00263         }
00264 
00265         // size function
00266         inline size_t size(void) const
00267         {       return length; }
00268 
00269         // resize function
00270         inline void resize(size_t n)
00271         {       length = n;
00272                 if( (capacity >= n) & (n > 0)  )
00273                         return;
00274                 if( data != CPPAD_NULL  )
00275                         CPPAD_TRACK_DEL_VEC(data);
00276                 capacity = n;
00277                 if( capacity == 0 )
00278                         data = CPPAD_NULL;
00279                 else    data = CPPAD_TRACK_NEW_VEC(capacity, data);
00280         }
00281         // assignment operator
00282         inline vector & operator=(const vector &x)
00283         {       size_t i;
00284                 CPPAD_ASSERT_KNOWN(
00285                         length == x.length ,
00286                         "size miss match in assignment operation"
00287                 );
00288                 for(i = 0; i < length; i++)
00289                         data[i] = x.data[i];
00290                 return *this;
00291         }
00292         // non-constant element access
00293         Type & operator[](size_t i)
00294         {       CPPAD_ASSERT_KNOWN(
00295                         i < length,
00296                         "vector index greater than or equal vector size"
00297                 );
00298                 return data[i]; 
00299         }
00300         // constant element access
00301         const Type & operator[](size_t i) const
00302         {       CPPAD_ASSERT_KNOWN(
00303                         i < length,
00304                         "vector index greater than or equal vector size"
00305                 );
00306                 return data[i]; 
00307         }
00308         // add to the back of the array
00309         void push_back(const Type &x)
00310         {       CPPAD_ASSERT_UNKNOWN( length <= capacity );
00311                 if( length == capacity )
00312                 {       // allocate more capacity
00313                         if( capacity == 0 )
00314                                 capacity = 2;
00315                         else    capacity = 2 * length;
00316                         data = CPPAD_TRACK_EXTEND(capacity, length, data);
00317                 }
00318                 data[length++] = x;
00319         }
00320 };
00321 
00322 // output operator
00323 template <class Type>
00324 inline std::ostream& operator << (
00325         std::ostream              &os  , 
00326         const CppAD::vector<Type> &vec )
00327 {       size_t i = 0;
00328         size_t n = vec.size();
00329 
00330         os << "{ ";
00331         while(i < n)
00332         {       os << vec[i++]; 
00333                 if( i < n )
00334                         os << ", ";
00335         }
00336         os << " }";
00337         return os;
00338 }
00339 
00340 /*
00341 --------------------------- vectorBool -------------------------------------
00342 */
00343 class vectorBoolElement {
00344         typedef size_t UnitType;
00345 private:
00346         UnitType *unit;
00347         UnitType mask;
00348 public:
00349         vectorBoolElement(UnitType *unit_, UnitType mask_)
00350         : unit(unit_) , mask(mask_)
00351         { }
00352         vectorBoolElement(const vectorBoolElement &e)
00353         : unit(e.unit) , mask(e.mask)
00354         { }
00355         operator bool() const
00356         {       return (*unit & mask) != 0; }
00357         vectorBoolElement& operator=(bool bit)
00358         {       if(bit)
00359                         *unit |= mask;
00360                 else    *unit &= ~mask;
00361                 return *this;
00362         } 
00363 };
00364 
00365 class vectorBool {
00366         typedef size_t UnitType;
00367 private:
00368         static const  size_t BitPerUnit 
00369                 = std::numeric_limits<UnitType>::digits;
00370         size_t    nunit;
00371         size_t    length;
00372         UnitType *data;
00373 public:
00374         // type of the elements in the vector
00375         typedef bool value_type;
00376 
00377         // default constructor
00378         inline vectorBool(void) : nunit(0), length(0), data(CPPAD_NULL)
00379         { }
00380         // constructor with a specified size
00381         inline vectorBool(size_t n) : nunit(0), length(0), data(CPPAD_NULL)
00382         {       if( n == 0 )
00383                         data = CPPAD_NULL;
00384                 else 
00385                 {       nunit    = (n - 1) / BitPerUnit + 1;
00386                         length   = n;
00387                         data     = CPPAD_TRACK_NEW_VEC(nunit, data);
00388                 }
00389         }
00390         // copy constructor
00391         inline vectorBool(const vectorBool &v) 
00392         : nunit(v.nunit), length(v.length)
00393         {       size_t i;
00394                 if( nunit == 0 )
00395                         data = CPPAD_NULL;
00396                 else    data = CPPAD_TRACK_NEW_VEC(nunit, data);
00397 
00398                 for(i = 0; i < nunit; i++)
00399                         data[i] = v.data[i];
00400         }
00401         // destructor
00402         ~vectorBool(void)
00403         {       if( data != CPPAD_NULL )
00404                         CPPAD_TRACK_DEL_VEC(data);
00405         }
00406 
00407         // size function
00408         inline size_t size(void) const
00409         {       return length; }
00410 
00411         // resize function
00412         inline void resize(size_t n)
00413         {       length = n;
00414                 if( (nunit * BitPerUnit >= n) & (n > 0) )
00415                         return;
00416                 if( data != CPPAD_NULL )
00417                         CPPAD_TRACK_DEL_VEC(data);
00418                 if( n == 0 )
00419                 {       nunit = 0;
00420                         data = CPPAD_NULL;
00421                 }
00422                 else
00423                 {       nunit    = (n - 1) / BitPerUnit + 1;
00424                         data     = CPPAD_TRACK_NEW_VEC(nunit, data);
00425                 }
00426         }
00427         // assignment operator
00428         inline vectorBool & operator=(const vectorBool &v)
00429         {       size_t i;
00430                 CPPAD_ASSERT_KNOWN(
00431                         length == v.length ,
00432                         "size miss match in assignment operation"
00433                 );
00434                 CPPAD_ASSERT_UNKNOWN( nunit == v.nunit );
00435                 for(i = 0; i < nunit; i++)
00436                         data[i] = v.data[i];
00437                 return *this;
00438         }
00439         // non-constant element access
00440         vectorBoolElement operator[](size_t k)
00441         {       size_t i, j;
00442                 CPPAD_ASSERT_KNOWN(
00443                         k < length,
00444                         "vector index greater than or equal vector size"
00445                 );
00446                 i    = k / BitPerUnit;
00447                 j    = k - i * BitPerUnit;
00448                 return vectorBoolElement(data + i , UnitType(1) << j );
00449         }
00450         // constant element access
00451         bool operator[](size_t k) const
00452         {       size_t i, j;
00453                 UnitType unit;
00454                 UnitType mask;
00455                 CPPAD_ASSERT_KNOWN(
00456                         k < length,
00457                         "vector index greater than or equal vector size"
00458                 );
00459                 i    = k / BitPerUnit;
00460                 j    = k - i * BitPerUnit;
00461                 unit = data[i];
00462                 mask = UnitType(1) << j;
00463                 return (unit & mask) != 0;
00464         }
00465         // add to the back of the array
00466         void push_back(bool bit)
00467         {       size_t i, j;
00468                 UnitType mask;
00469                 CPPAD_ASSERT_UNKNOWN( length <= nunit * BitPerUnit );
00470                 if( length == nunit * BitPerUnit )
00471                 {       // allocate another unit
00472                         data = CPPAD_TRACK_EXTEND(nunit+1, nunit, data);
00473                         nunit++;
00474                 }
00475                 i    = length / BitPerUnit;
00476                 j    = length - i * BitPerUnit;
00477                 mask = UnitType(1) << j;
00478                 if( bit )
00479                         data[i] |= mask;
00480                 else    data[i] &= ~mask;
00481                 length++;
00482         }
00483 };
00484 
00485 // output operator
00486 inline std::ostream& operator << (
00487         std::ostream     &os  , 
00488         const vectorBool &v   )
00489 {       size_t i = 0;
00490         size_t n = v.size();
00491 
00492         while(i < n)
00493                 os << v[i++]; 
00494         return os;
00495 }
00496 
00497 } // END CppAD namespace
00498 
00499 
00500 # endif

Generated on Sun Nov 14 14:06:33 2010 for Coin-All by  doxygen 1.4.7