CppAD: A C++ Algorithmic Differentiation Package
20130918
|
00001 /* $Id$ */ 00002 # ifndef CPPAD_BASE_COND_EXP_INCLUDED 00003 # define CPPAD_BASE_COND_EXP_INCLUDED 00004 00005 /* -------------------------------------------------------------------------- 00006 CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-14 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 $begin base_cond_exp$$ 00018 $spell 00019 alloc 00020 Rel 00021 hpp 00022 enum 00023 namespace 00024 Op 00025 Lt 00026 Le 00027 Eq 00028 Ge 00029 Gt 00030 Ne 00031 cond 00032 exp 00033 const 00034 adolc 00035 CppAD 00036 inline 00037 $$ 00038 00039 $section Base Type Requirements for Conditional Expressions$$ 00040 $index CondExp, base require$$ 00041 $index base, CondExp require$$ 00042 $index require, base CondExp$$ 00043 00044 $head Purpose$$ 00045 These definitions are required by the user's code to support the 00046 $codei%AD<%Base%>%$$ type for $cref CondExp$$ operations: 00047 00048 $head CompareOp$$ 00049 The following $code enum$$ type is used in the specifications below: 00050 $codep 00051 namespace CppAD { 00052 // The conditional expression operator enum type 00053 enum CompareOp 00054 { CompareLt, // less than 00055 CompareLe, // less than or equal 00056 CompareEq, // equal 00057 CompareGe, // greater than or equal 00058 CompareGt, // greater than 00059 CompareNe // not equal 00060 }; 00061 } 00062 $$ 00063 00064 $head CondExpTemplate$$ 00065 The type $icode Base$$ must support the syntax 00066 $codei% 00067 %result% = CppAD::CondExpOp( 00068 %cop%, %left%, %right%, %exp_if_true%, %exp_if_false% 00069 ) 00070 %$$ 00071 which computes implements the corresponding $cref CondExp$$ 00072 function when the result has prototype 00073 $codei% 00074 %Base% %result% 00075 %$$ 00076 The argument $icode cop$$ has prototype 00077 $codei% 00078 enum CppAD::CompareOp %cop% 00079 %$$ 00080 The other arguments have the prototype 00081 $codei% 00082 const %Base%& %left% 00083 const %Base%& %right% 00084 const %Base%& %exp_if_true% 00085 const %Base%& %exp_if_false% 00086 %$$ 00087 00088 $subhead Ordered Type$$ 00089 If $icode Base$$ is a relatively simple type 00090 that supports 00091 $code <$$, $code <=$$, $code ==$$, $code >=$$, and $code >$$ operators 00092 its $code CondExpOp$$ function can be defined by 00093 $codei% 00094 namespace CppAD { 00095 inline %Base% CondExpOp( 00096 enum CppAD::CompareOp cop , 00097 const %Base% &left , 00098 const %Base% &right , 00099 const %Base% &exp_if_true , 00100 const %Base% &exp_if_false ) 00101 { return CondExpTemplate( 00102 cop, left, right, trueCase, falseCase); 00103 } 00104 } 00105 %$$ 00106 For example, see 00107 $cref/double CondExpOp/base_alloc.hpp/CondExpOp/$$. 00108 For an example of and implementation of $code CondExpOp$$ with 00109 a more involved $icode Base$$ type see 00110 $cref/adolc CondExpOp/base_adolc.hpp/CondExpOp/$$. 00111 00112 00113 $subhead Not Ordered$$ 00114 If the type $icode Base$$ does not support ordering, 00115 the $code CondExpOp$$ function does not make sense. 00116 In this case one might (but need not) define $code CondExpOp$$ as follows: 00117 $codei% 00118 namespace CppAD { 00119 inline %Base% CondExpOp( 00120 enum CompareOp cop , 00121 const %Base% &left , 00122 const %Base% &right , 00123 const %Base% &exp_if_true , 00124 const %Base% &exp_if_false ) 00125 { // attempt to use CondExp with a %Base% argument 00126 assert(0); 00127 return %Base%(0); 00128 } 00129 } 00130 %$$ 00131 For example, see 00132 $cref/complex CondExpOp/base_complex.hpp/CondExpOp/$$. 00133 00134 $head CondExpRel$$ 00135 $index CPPAD_COND_EXP_REL$$ 00136 The macro invocation 00137 $codei% 00138 CPPAD_COND_EXP_REL(%Base%) 00139 %$$ 00140 uses $code CondExpOp$$ above to define the following functions 00141 $codei% 00142 CondExpLt(%left%, %right%, %exp_if_true%, %exp_if_false%) 00143 CondExpLe(%left%, %right%, %exp_if_true%, %exp_if_false%) 00144 CondExpEq(%left%, %right%, %exp_if_true%, %exp_if_false%) 00145 CondExpGe(%left%, %right%, %exp_if_true%, %exp_if_false%) 00146 CondExpGt(%left%, %right%, %exp_if_true%, %exp_if_false%) 00147 %$$ 00148 where the arguments have type $icode Base$$. 00149 This should be done inside of the CppAD namespace. 00150 For example, see 00151 $cref/base_alloc/base_alloc.hpp/CondExpRel/$$. 00152 00153 $end 00154 */ 00155 00156 namespace CppAD { // BEGIN_CPPAD_NAMESPACE 00157 00158 /*! 00159 \file base_cond_exp.hpp 00160 CondExp operations that aid in meeting Base type requirements. 00161 */ 00162 00163 /*! 00164 \def CPPAD_COND_EXP_BASE_REL(Type, Rel, Op) 00165 This macro defines the operation 00166 \verbatim 00167 CondExpRel(left, right, exp_if_true, exp_if_false) 00168 \endverbatim 00169 The argument \c Type is the \c Base type for this base require operation. 00170 The argument \c Rel is one of \c Lt, \c Le, \c Eq, \c Ge, \c Gt. 00171 The argument \c Op is the corresponding \c CompareOp value. 00172 */ 00173 # define CPPAD_COND_EXP_BASE_REL(Type, Rel, Op) \ 00174 inline Type CondExp##Rel( \ 00175 const Type& left , \ 00176 const Type& right , \ 00177 const Type& exp_if_true , \ 00178 const Type& exp_if_false ) \ 00179 { return CondExpOp(Op, left, right, exp_if_true, exp_if_false); \ 00180 } 00181 00182 /*! 00183 \def CPPAD_COND_EXP_REL(Type) 00184 The macro defines the operations 00185 \verbatim 00186 CondExpLt(left, right, exp_if_true, exp_if_false) 00187 CondExpLe(left, right, exp_if_true, exp_if_false) 00188 CondExpEq(left, right, exp_if_true, exp_if_false) 00189 CondExpGe(left, right, exp_if_true, exp_if_false) 00190 CondExpGt(left, right, exp_if_true, exp_if_false) 00191 \endverbatim 00192 The argument \c Type is the \c Base type for this base require operation. 00193 */ 00194 # define CPPAD_COND_EXP_REL(Type) \ 00195 CPPAD_COND_EXP_BASE_REL(Type, Lt, CompareLt) \ 00196 CPPAD_COND_EXP_BASE_REL(Type, Le, CompareLe) \ 00197 CPPAD_COND_EXP_BASE_REL(Type, Eq, CompareEq) \ 00198 CPPAD_COND_EXP_BASE_REL(Type, Ge, CompareGe) \ 00199 CPPAD_COND_EXP_BASE_REL(Type, Gt, CompareGt) 00200 00201 /*! 00202 Template function to implement Conditional Expressions for simple types 00203 that have comparision operators. 00204 00205 \tparam CompareType 00206 is the type of the left and right operands to the comparision operator. 00207 00208 \tparam ResultType 00209 is the type of the result, which is the same as \c CompareType except 00210 during forward and reverse mode sparese calculations. 00211 00212 \param cop 00213 specifices which comparision to use; i.e., 00214 $code <$$, 00215 $code <=$$, 00216 $code ==$$, 00217 $code >=$$, 00218 $code >$$, or 00219 $code !=$$. 00220 00221 \param left 00222 is the left operand to the comparision operator. 00223 00224 \param right 00225 is the right operand to the comparision operator. 00226 00227 \param exp_if_true 00228 is the return value is the comparision results in true. 00229 00230 \param exp_if_false 00231 is the return value is the comparision results in false. 00232 00233 \return 00234 see \c exp_if_true and \c exp_if_false above. 00235 */ 00236 template <class CompareType, class ResultType> 00237 ResultType CondExpTemplate( 00238 enum CompareOp cop , 00239 const CompareType& left , 00240 const CompareType& right , 00241 const ResultType& exp_if_true , 00242 const ResultType& exp_if_false ) 00243 { ResultType returnValue; 00244 switch( cop ) 00245 { 00246 case CompareLt: 00247 if( left < right ) 00248 returnValue = exp_if_true; 00249 else returnValue = exp_if_false; 00250 break; 00251 00252 case CompareLe: 00253 if( left <= right ) 00254 returnValue = exp_if_true; 00255 else returnValue = exp_if_false; 00256 break; 00257 00258 case CompareEq: 00259 if( left == right ) 00260 returnValue = exp_if_true; 00261 else returnValue = exp_if_false; 00262 break; 00263 00264 case CompareGe: 00265 if( left >= right ) 00266 returnValue = exp_if_true; 00267 else returnValue = exp_if_false; 00268 break; 00269 00270 case CompareGt: 00271 if( left > right ) 00272 returnValue = exp_if_true; 00273 else returnValue = exp_if_false; 00274 break; 00275 00276 default: 00277 CPPAD_ASSERT_UNKNOWN(0); 00278 returnValue = exp_if_true; 00279 } 00280 return returnValue; 00281 } 00282 00283 } // END_CPPAD_NAMESPACE 00284 # endif