CppAD: A C++ Algorithmic Differentiation Package  20130102
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-12 Bradley M. Bell
00007 
00008 CppAD is distributed under multiple licenses. This distribution is under
00009 the terms of the 
00010                     Eclipse 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 $icode%b% = %x% %Op% %y%$$
00044 
00045 
00046 $head Purpose$$
00047 Compares two operands where one of the operands is an
00048 $codei%AD<%Base%>%$$ object.
00049 The comparison has the same interpretation as for 
00050 the $icode Base$$ type.
00051 
00052 
00053 $head Op$$
00054 The operator $icode Op$$ is one of the following:
00055 $table
00056 $bold Op$$ $pre $$  $cnext $bold Meaning$$                           $rnext
00057 $code <$$   $cnext is $icode x$$ less than $icode y$$              $rnext
00058 $code <=$$  $cnext is $icode x$$ less than or equal $icode y$$     $rnext
00059 $code >$$   $cnext is $icode x$$ greater than $icode y$$           $rnext
00060 $code >=$$  $cnext is $icode x$$ greater than or equal $icode y$$  $rnext
00061 $code ==$$  $cnext is $icode x$$ equal to $icode y$$               $rnext
00062 $code !=$$  $cnext is $icode x$$ not equal to $icode y$$
00063 $tend
00064  
00065 $head x$$
00066 The operand $icode x$$ has prototype
00067 $codei%
00068      const %Type% &%x%
00069 %$$
00070 where $icode Type$$ is $codei%AD<%Base%>%$$, $icode Base$$, or $code int$$.
00071 
00072 $head y$$
00073 The operand $icode y$$ has prototype
00074 $codei%
00075      const %Type% &%y%
00076 %$$
00077 where $icode Type$$ is $codei%AD<%Base%>%$$, $icode Base$$, or $code int$$.
00078 
00079 $head b$$
00080 The result $icode b$$ has type
00081 $codei%
00082      bool %b%
00083 %$$
00084 
00085 $head Operation Sequence$$
00086 The result of this operation is a $code bool$$ value
00087 (not an $cref/AD of Base/glossary/AD of Base/$$ object).
00088 Thus it will not be recorded as part of an
00089 AD of $icode Base$$
00090 $cref/operation sequence/glossary/Operation/Sequence/$$.
00091 $pre
00092 
00093 $$
00094 For example, suppose 
00095 $icode x$$ and $icode y$$ are $codei%AD<%Base%>%$$ objects,
00096 the tape corresponding to $codei%AD<%Base%>%$$ is recording,
00097 $icode b$$ is true,
00098 and the subsequent code is
00099 $codei%
00100      if( %b% )
00101           %y% = cos(%x%);
00102      else %y% = sin(%x%); 
00103 %$$
00104 only the assignment $icode%y% = cos(%x%)%$$ is recorded on the tape
00105 (if $icode x$$ is a $cref/parameter/glossary/Parameter/$$, 
00106 nothing is recorded).
00107 The $cref CompareChange$$ function can yield
00108 some information about changes in comparison operation results.
00109 You can use $cref 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 $icode Op$$ operators listed above
00116 is used with an $codei%AD<%Base%>%$$ object,
00117 it is assumed that the same operator is supported by the base type 
00118 $icode Base$$.
00119 
00120 $head Example$$
00121 $children%
00122      example/compare.cpp
00123 %$$
00124 The file
00125 $cref 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 {    addr_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_FRIEND_TEMPLATE_FUNCTION
00191 bool operator < (const AD<Base> &left , const AD<Base> &right)
00192 {    bool result =  (left.value_ < right.value_); 
00193      return result;
00194 }
00195 
00196 # else
00197 template <class Base>
00198 CPPAD_INLINE_FRIEND_TEMPLATE_FUNCTION
00199 bool operator < (const AD<Base> &left , const AD<Base> &right)
00200 {    bool result =  (left.value_ < right.value_); 
00201 
00202      ADTape<Base> *tape = CPPAD_NULL;
00203      if( Variable(left) )
00204           tape = left.tape_this();
00205      else if ( Variable(right) )
00206           tape = right.tape_this();
00207 
00208      if( tape != CPPAD_NULL )
00209           tape->RecordCompare(CompareLt, result, left, right);
00210 
00211      return result;
00212 }
00213 # endif
00214 
00215 // convert other cases into the case above
00216 CPPAD_FOLD_BOOL_VALUED_BINARY_OPERATOR(<)
00217 
00218 // -------------------------------- <= -------------------------
00219 # ifdef NDEBUG
00220 
00221 template <class Base>
00222 CPPAD_INLINE_FRIEND_TEMPLATE_FUNCTION
00223 bool operator <= (const AD<Base> &left , const AD<Base> &right)
00224 {    bool result =  (left.value_ <= right.value_); 
00225      return result;
00226 }
00227 
00228 # else
00229 template <class Base>
00230 CPPAD_INLINE_FRIEND_TEMPLATE_FUNCTION
00231 bool operator <= (const AD<Base> &left , const AD<Base> &right)
00232 {    bool result =  (left.value_ <= right.value_); 
00233 
00234      ADTape<Base> *tape = CPPAD_NULL;
00235      if( Variable(left) )
00236           tape = left.tape_this();
00237      else if ( Variable(right) )
00238           tape = right.tape_this();
00239 
00240      if( tape != CPPAD_NULL )
00241           tape->RecordCompare(CompareLe, result, left, right);
00242 
00243      return result;
00244 }
00245 # endif
00246 
00247 // convert other cases into the case above
00248 CPPAD_FOLD_BOOL_VALUED_BINARY_OPERATOR(<=)
00249 
00250 
00251 // -------------------------------- > -------------------------
00252 # ifdef NDEBUG
00253 
00254 template <class Base>
00255 CPPAD_INLINE_FRIEND_TEMPLATE_FUNCTION
00256 bool operator > (const AD<Base> &left , const AD<Base> &right)
00257 {    bool result =  (left.value_ > right.value_); 
00258      return result;
00259 }
00260 
00261 # else
00262 template <class Base>
00263 CPPAD_INLINE_FRIEND_TEMPLATE_FUNCTION
00264 bool operator > (const AD<Base> &left , const AD<Base> &right)
00265 {    bool result =  (left.value_ > right.value_); 
00266 
00267      ADTape<Base> *tape = CPPAD_NULL;
00268      if( Variable(left) )
00269           tape = left.tape_this();
00270      else if ( Variable(right) )
00271           tape = right.tape_this();
00272 
00273      if( tape != CPPAD_NULL )
00274           tape->RecordCompare(CompareGt, result, left, right);
00275 
00276 
00277      return result;
00278 }
00279 # endif
00280 
00281 // convert other cases into the case above
00282 CPPAD_FOLD_BOOL_VALUED_BINARY_OPERATOR(>)
00283 
00284 // -------------------------------- >= -------------------------
00285 # ifdef NDEBUG
00286 
00287 template <class Base>
00288 CPPAD_INLINE_FRIEND_TEMPLATE_FUNCTION
00289 bool operator >= (const AD<Base> &left , const AD<Base> &right)
00290 {    bool result =  (left.value_ >= right.value_); 
00291      return result;
00292 }
00293 
00294 # else
00295 template <class Base>
00296 CPPAD_INLINE_FRIEND_TEMPLATE_FUNCTION
00297 bool operator >= (const AD<Base> &left , const AD<Base> &right)
00298 {    bool result =  (left.value_ >= right.value_); 
00299 
00300      ADTape<Base> *tape = CPPAD_NULL;
00301      if( Variable(left) )
00302           tape = left.tape_this();
00303      else if ( Variable(right) )
00304           tape = right.tape_this();
00305 
00306      if( tape != CPPAD_NULL )
00307           tape->RecordCompare(CompareGe, result, left, right);
00308 
00309      return result;
00310 }
00311 # endif
00312 
00313 // convert other cases into the case above
00314 CPPAD_FOLD_BOOL_VALUED_BINARY_OPERATOR(>=)
00315 
00316 
00317 // -------------------------------- == -------------------------
00318 # ifdef NDEBUG
00319 
00320 template <class Base>
00321 CPPAD_INLINE_FRIEND_TEMPLATE_FUNCTION
00322 bool operator == (const AD<Base> &left , const AD<Base> &right)
00323 {    bool result =  (left.value_ == right.value_); 
00324      return result;
00325 }
00326 
00327 # else 
00328 template <class Base>
00329 CPPAD_INLINE_FRIEND_TEMPLATE_FUNCTION
00330 bool operator == (const AD<Base> &left , const AD<Base> &right)
00331 {    bool result =  (left.value_ == right.value_); 
00332 
00333      ADTape<Base> *tape = CPPAD_NULL;
00334      if( Variable(left) )
00335           tape = left.tape_this();
00336      else if ( Variable(right) )
00337           tape = right.tape_this();
00338 
00339      if( tape != CPPAD_NULL )
00340           tape->RecordCompare(CompareEq, result, left, right);
00341 
00342      return result;
00343 }
00344 # endif
00345 
00346 // convert other cases into the case above
00347 CPPAD_FOLD_BOOL_VALUED_BINARY_OPERATOR(==)
00348 
00349 // -------------------------------- != -------------------------
00350 # ifdef NDEBUG
00351 
00352 template <class Base>
00353 CPPAD_INLINE_FRIEND_TEMPLATE_FUNCTION
00354 bool operator != (const AD<Base> &left , const AD<Base> &right)
00355 {    bool result =  (left.value_ != right.value_);
00356      return result;
00357 }
00358 
00359 # else
00360 template <class Base>
00361 CPPAD_INLINE_FRIEND_TEMPLATE_FUNCTION
00362 bool operator != (const AD<Base> &left , const AD<Base> &right)
00363 {    bool result =  (left.value_ != right.value_);
00364 
00365      ADTape<Base> *tape = CPPAD_NULL;
00366      if( Variable(left) )
00367           tape = left.tape_this();
00368      else if ( Variable(right) )
00369           tape = right.tape_this();
00370 
00371      if( tape != CPPAD_NULL )
00372           tape->RecordCompare(CompareNe, result, left, right);
00373 
00374      return result;
00375 }
00376 # endif
00377 
00378 // convert other cases into the case above
00379 CPPAD_FOLD_BOOL_VALUED_BINARY_OPERATOR(!=)
00380 
00381 } // END CppAD namespace
00382 
00383 # endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines