CppAD: A C++ Algorithmic Differentiation Package 20110419
compare.hpp
Go to the documentation of this file.
00001 /* $Id$ */
00002 # ifndef CPPAD_COMPARE_INCLUDED
00003 # define CPPAD_COMPARE_INCLUDED
00004 
00005 /* --------------------------------------------------------------------------
00006 CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-11 Bradley M. Bell
00007 
00008 CppAD is distributed under multiple licenses. This distribution is under
00009 the terms of the 
00010                     Common Public License Version 1.0.
00011 
00012 A copy of this license is included in the COPYING file of this distribution.
00013 Please visit http://www.coin-or.org/CppAD/ for information on other licenses.
00014 -------------------------------------------------------------------------- */
00015 
00016 /*
00017 -------------------------------------------------------------------------------
00018 $begin Compare$$
00019 $spell
00020         cos
00021         Op
00022         bool
00023         const
00024 $$
00025 
00026 $index binary, AD compare operator$$
00027 $index AD, binary compare operator$$
00028 $index compare, AD binary operator$$
00029 $index operator, AD binary compare$$
00030 
00031 $index <, AD operator$$
00032 $index <=, AD operator$$
00033 $index >, AD operator$$
00034 $index >=, AD operator$$
00035 $index ==, AD operator$$
00036 $index !=, AD operator$$
00037 
00038 $section AD Binary Comparison Operators$$
00039 
00040 
00041 $head Syntax$$
00042 
00043 $syntax%%b% = %x% %Op% %y%$$
00044 
00045 
00046 $head Purpose$$
00047 Compares two operands where one of the operands is an
00048 $syntax%AD<%Base%>%$$ object.
00049 The comparison has the same interpretation as for 
00050 the $italic Base$$ type.
00051 
00052 
00053 $head Op$$
00054 The operator $italic Op$$ is one of the following:
00055 $table
00056 $bold Op$$ $pre $$  $cnext $bold Meaning$$                           $rnext
00057 $code <$$   $cnext is $italic x$$ less than $italic y$$              $rnext
00058 $code <=$$  $cnext is $italic x$$ less than or equal $italic y$$     $rnext
00059 $code >$$   $cnext is $italic x$$ greater than $italic y$$           $rnext
00060 $code >=$$  $cnext is $italic x$$ greater than or equal $italic y$$  $rnext
00061 $code ==$$  $cnext is $italic x$$ equal to $italic y$$               $rnext
00062 $code !=$$  $cnext is $italic x$$ not equal to $italic y$$
00063 $tend
00064  
00065 $head x$$
00066 The operand $italic x$$ has prototype
00067 $syntax%
00068         const %Type% &%x%
00069 %$$
00070 where $italic Type$$ is $syntax%AD<%Base%>%$$, $italic Base$$, or $code int$$.
00071 
00072 $head y$$
00073 The operand $italic y$$ has prototype
00074 $syntax%
00075         const %Type% &%y%
00076 %$$
00077 where $italic Type$$ is $syntax%AD<%Base%>%$$, $italic Base$$, or $code int$$.
00078 
00079 $head b$$
00080 The result $italic b$$ has type
00081 $syntax%
00082         bool %b%
00083 %$$
00084 
00085 $head Operation Sequence$$
00086 The result of this operation is a $code bool$$ value
00087 (not an $xref/glossary/AD of Base/AD of Base/$$ object).
00088 Thus it will not be recorded as part of an
00089 AD of $italic Base$$
00090 $xref/glossary/Operation/Sequence/operation sequence/1/$$.
00091 $pre
00092 
00093 $$
00094 For example, suppose 
00095 $italic x$$ and $italic y$$ are $syntax%AD<%Base%>%$$ objects,
00096 the tape corresponding to $syntax%AD<%Base%>%$$ is recording,
00097 $italic b$$ is true,
00098 and the subsequent code is
00099 $syntax%
00100         if( %b% )
00101                 %y% = cos(%x%);
00102         else    %y% = sin(%x%); 
00103 %$$
00104 only the assignment $syntax%%y% = cos(%x%)%$$ is recorded on the tape
00105 (if $italic x$$ is a $cref/parameter/glossary/Parameter/$$, 
00106 nothing is recorded).
00107 The $xref/CompareChange/$$ function can yield
00108 some information about changes in comparison operation results.
00109 You can use $xref/CondExp/$$ to obtain comparison operations
00110 that depends on the 
00111 $cref/independent variable/glossary/Tape/Independent Variable/$$ 
00112 values with out re-taping the AD sequence of operations.
00113 
00114 $head Assumptions$$
00115 If one of the $italic Op$$ operators listed above
00116 is used with an $syntax%AD<%Base%>%$$ object,
00117 it is assumed that the same operator is supported by the base type 
00118 $italic Base$$.
00119 
00120 $head Example$$
00121 $children%
00122         example/compare.cpp
00123 %$$
00124 The file
00125 $xref/Compare.cpp/$$
00126 contains an example and test of these operations.
00127 It returns true if it succeeds and false otherwise.
00128 
00129 $end
00130 -------------------------------------------------------------------------------
00131 */
00132 //  BEGIN CppAD namespace
00133 namespace CppAD {
00134 
00135 template <class Base>
00136 
00137 // -------------- RecordCompare(cop, result, left, right) --------------------
00138 /// All these operations are done in \c Rec_, so we should move this
00139 /// routine to <tt>recorder<Base></tt>.
00140 void ADTape<Base>::RecordCompare(
00141         enum CompareOp  cop   ,
00142         bool           result ,
00143         const AD<Base> &left  ,
00144         const AD<Base> &right )
00145 {       size_t ind0, ind1, ind2, ind3;
00146 
00147         // ind[1] = base 2 representation of [result, Var(left), Var(right])
00148         ind1 = 0;
00149 
00150         // ind[2] = left address
00151         if( Parameter(left) )
00152                 ind2 = Rec_.PutPar(left.value_);
00153         else
00154         {       ind1 += 2;
00155                 ind2 =  left.taddr_;
00156         }
00157 
00158         // ind[3] = right address
00159         if( Parameter(right) )
00160                 ind3 = Rec_.PutPar(right.value_);
00161         else
00162         {       ind1 += 4;
00163                 ind3 =  right.taddr_;
00164         }
00165 
00166         // If both left and right are parameters, do not need to record
00167         if( ind1 == 0 )
00168                 return;
00169 
00170         // ind[1] & 1 = result
00171         if( result )
00172                 ind1+= 1;
00173 
00174         // ind[0] = cop 
00175         ind0 = size_t (cop);
00176 
00177         CPPAD_ASSERT_UNKNOWN( ind1 > 1 );
00178         CPPAD_ASSERT_UNKNOWN( NumArg(ComOp) == 4 );
00179         CPPAD_ASSERT_UNKNOWN( NumRes(ComOp) == 0 );
00180 
00181         // put the operator in the tape
00182         Rec_.PutOp(ComOp);
00183         Rec_.PutArg(ind0, ind1, ind2, ind3);
00184 }
00185 
00186 // -------------------------------- < -------------------------
00187 # ifdef NDEBUG
00188 
00189 template <class Base>
00190 CPPAD_INLINE bool operator < (const AD<Base> &left , const AD<Base> &right)
00191 {       bool result =  (left.value_ < right.value_); 
00192         return result;
00193 }
00194 
00195 # else
00196 template <class Base>
00197 CPPAD_INLINE bool operator < (const AD<Base> &left , const AD<Base> &right)
00198 {       bool result =  (left.value_ < right.value_); 
00199 
00200         ADTape<Base> *tape = CPPAD_NULL;
00201         if( Variable(left) )
00202                 tape = left.tape_this();
00203         else if ( Variable(right) )
00204                 tape = right.tape_this();
00205 
00206         if( tape != CPPAD_NULL )
00207                 tape->RecordCompare(CompareLt, result, left, right);
00208 
00209         return result;
00210 }
00211 # endif
00212 
00213 // convert other cases into the case above
00214 CPPAD_FOLD_BOOL_VALUED_BINARY_OPERATOR(<)
00215 
00216 // -------------------------------- <= -------------------------
00217 # ifdef NDEBUG
00218 
00219 template <class Base>
00220 CPPAD_INLINE bool operator <= (const AD<Base> &left , const AD<Base> &right)
00221 {       bool result =  (left.value_ <= right.value_); 
00222         return result;
00223 }
00224 
00225 # else
00226 template <class Base>
00227 CPPAD_INLINE bool operator <= (const AD<Base> &left , const AD<Base> &right)
00228 {       bool result =  (left.value_ <= right.value_); 
00229 
00230         ADTape<Base> *tape = CPPAD_NULL;
00231         if( Variable(left) )
00232                 tape = left.tape_this();
00233         else if ( Variable(right) )
00234                 tape = right.tape_this();
00235 
00236         if( tape != CPPAD_NULL )
00237                 tape->RecordCompare(CompareLe, result, left, right);
00238 
00239         return result;
00240 }
00241 # endif
00242 
00243 // convert other cases into the case above
00244 CPPAD_FOLD_BOOL_VALUED_BINARY_OPERATOR(<=)
00245 
00246 
00247 // -------------------------------- > -------------------------
00248 # ifdef NDEBUG
00249 
00250 template <class Base>
00251 CPPAD_INLINE bool operator > (const AD<Base> &left , const AD<Base> &right)
00252 {       bool result =  (left.value_ > right.value_); 
00253         return result;
00254 }
00255 
00256 # else
00257 template <class Base>
00258 CPPAD_INLINE bool operator > (const AD<Base> &left , const AD<Base> &right)
00259 {       bool result =  (left.value_ > right.value_); 
00260 
00261         ADTape<Base> *tape = CPPAD_NULL;
00262         if( Variable(left) )
00263                 tape = left.tape_this();
00264         else if ( Variable(right) )
00265                 tape = right.tape_this();
00266 
00267         if( tape != CPPAD_NULL )
00268                 tape->RecordCompare(CompareGt, result, left, right);
00269 
00270 
00271         return result;
00272 }
00273 # endif
00274 
00275 // convert other cases into the case above
00276 CPPAD_FOLD_BOOL_VALUED_BINARY_OPERATOR(>)
00277 
00278 // -------------------------------- >= -------------------------
00279 # ifdef NDEBUG
00280 
00281 template <class Base>
00282 CPPAD_INLINE bool operator >= (const AD<Base> &left , const AD<Base> &right)
00283 {       bool result =  (left.value_ >= right.value_); 
00284         return result;
00285 }
00286 
00287 # else
00288 template <class Base>
00289 CPPAD_INLINE bool operator >= (const AD<Base> &left , const AD<Base> &right)
00290 {       bool result =  (left.value_ >= right.value_); 
00291 
00292         ADTape<Base> *tape = CPPAD_NULL;
00293         if( Variable(left) )
00294                 tape = left.tape_this();
00295         else if ( Variable(right) )
00296                 tape = right.tape_this();
00297 
00298         if( tape != CPPAD_NULL )
00299                 tape->RecordCompare(CompareGe, result, left, right);
00300 
00301         return result;
00302 }
00303 # endif
00304 
00305 // convert other cases into the case above
00306 CPPAD_FOLD_BOOL_VALUED_BINARY_OPERATOR(>=)
00307 
00308 
00309 // -------------------------------- == -------------------------
00310 # ifdef NDEBUG
00311 
00312 template <class Base>
00313 CPPAD_INLINE bool operator == (const AD<Base> &left , const AD<Base> &right)
00314 {       bool result =  (left.value_ == right.value_); 
00315         return result;
00316 }
00317 
00318 # else 
00319 template <class Base>
00320 CPPAD_INLINE bool operator == (const AD<Base> &left , const AD<Base> &right)
00321 {       bool result =  (left.value_ == right.value_); 
00322 
00323         ADTape<Base> *tape = CPPAD_NULL;
00324         if( Variable(left) )
00325                 tape = left.tape_this();
00326         else if ( Variable(right) )
00327                 tape = right.tape_this();
00328 
00329         if( tape != CPPAD_NULL )
00330                 tape->RecordCompare(CompareEq, result, left, right);
00331 
00332         return result;
00333 }
00334 # endif
00335 
00336 // convert other cases into the case above
00337 CPPAD_FOLD_BOOL_VALUED_BINARY_OPERATOR(==)
00338 
00339 // -------------------------------- != -------------------------
00340 # ifdef NDEBUG
00341 
00342 template <class Base>
00343 CPPAD_INLINE bool operator != (const AD<Base> &left , const AD<Base> &right)
00344 {       bool result =  (left.value_ != right.value_);
00345         return result;
00346 }
00347 
00348 # else
00349 template <class Base>
00350 CPPAD_INLINE bool operator != (const AD<Base> &left , const AD<Base> &right)
00351 {       bool result =  (left.value_ != right.value_);
00352 
00353         ADTape<Base> *tape = CPPAD_NULL;
00354         if( Variable(left) )
00355                 tape = left.tape_this();
00356         else if ( Variable(right) )
00357                 tape = right.tape_this();
00358 
00359         if( tape != CPPAD_NULL )
00360                 tape->RecordCompare(CompareNe, result, left, right);
00361 
00362         return result;
00363 }
00364 # endif
00365 
00366 // convert other cases into the case above
00367 CPPAD_FOLD_BOOL_VALUED_BINARY_OPERATOR(!=)
00368 
00369 } // END CppAD namespace
00370 
00371 # endif