CppAD: A C++ Algorithmic Differentiation Package 20110419
|
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