CppAD: A C++ Algorithmic Differentiation Package
20130102
|
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-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 $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 CPPAD_BEGIN_NAMESPACE 00157 00158 /*! 00159 \defgroup base_cond_exp_hpp base_cond_exp.hpp 00160 \{ 00161 \file base_cond_exp.hpp 00162 CondExp operations that aid in meeting Base type requirements. 00163 */ 00164 00165 /*! 00166 \def CPPAD_COND_EXP_BASE_REL(Type, Rel, Op) 00167 This macro defines the operation 00168 \verbatim 00169 CondExpRel(left, right, exp_if_true, exp_if_false) 00170 \endverbatim 00171 The argument \c Type is the \c Base type for this base require operation. 00172 The argument \c Rel is one of \c Lt, \c Le, \c Eq, \c Ge, \c Gt. 00173 The argument \c Op is the corresponding \c CompareOp value. 00174 */ 00175 # define CPPAD_COND_EXP_BASE_REL(Type, Rel, Op) \ 00176 inline Type CondExp##Rel( \ 00177 const Type& left , \ 00178 const Type& right , \ 00179 const Type& exp_if_true , \ 00180 const Type& exp_if_false ) \ 00181 { return CondExpOp(Op, left, right, exp_if_true, exp_if_false); \ 00182 } 00183 00184 /*! 00185 \def CPPAD_COND_EXP_REL(Type) 00186 The macro defines the operations 00187 \verbatim 00188 CondExpLt(left, right, exp_if_true, exp_if_false) 00189 CondExpLe(left, right, exp_if_true, exp_if_false) 00190 CondExpEq(left, right, exp_if_true, exp_if_false) 00191 CondExpGe(left, right, exp_if_true, exp_if_false) 00192 CondExpGt(left, right, exp_if_true, exp_if_false) 00193 \endverbatim 00194 The argument \c Type is the \c Base type for this base require operation. 00195 */ 00196 # define CPPAD_COND_EXP_REL(Type) \ 00197 CPPAD_COND_EXP_BASE_REL(Type, Lt, CompareLt) \ 00198 CPPAD_COND_EXP_BASE_REL(Type, Le, CompareLe) \ 00199 CPPAD_COND_EXP_BASE_REL(Type, Eq, CompareEq) \ 00200 CPPAD_COND_EXP_BASE_REL(Type, Ge, CompareGe) \ 00201 CPPAD_COND_EXP_BASE_REL(Type, Gt, CompareGt) 00202 00203 /*! 00204 Template function to implement Conditional Expressions for simple types 00205 that have comparision operators. 00206 00207 \tparam CompareType 00208 is the type of the left and right operands to the comparision operator. 00209 00210 \tparam ResultType 00211 is the type of the result, which is the same as \c CompareType except 00212 during forward and reverse mode sparese calculations. 00213 00214 \param cop 00215 specifices which comparision to use; i.e., 00216 $code <$$, 00217 $code <=$$, 00218 $code ==$$, 00219 $code >=$$, 00220 $code >$$, or 00221 $code !=$$. 00222 00223 \param left 00224 is the left operand to the comparision operator. 00225 00226 \param right 00227 is the right operand to the comparision operator. 00228 00229 \param exp_if_true 00230 is the return value is the comparision results in true. 00231 00232 \param exp_if_false 00233 is the return value is the comparision results in false. 00234 00235 \return 00236 see \c exp_if_true and \c exp_if_false above. 00237 */ 00238 template <class CompareType, class ResultType> 00239 ResultType CondExpTemplate( 00240 enum CompareOp cop , 00241 const CompareType& left , 00242 const CompareType& right , 00243 const ResultType& exp_if_true , 00244 const ResultType& exp_if_false ) 00245 { ResultType returnValue; 00246 switch( cop ) 00247 { 00248 case CompareLt: 00249 if( left < right ) 00250 returnValue = exp_if_true; 00251 else returnValue = exp_if_false; 00252 break; 00253 00254 case CompareLe: 00255 if( left <= right ) 00256 returnValue = exp_if_true; 00257 else returnValue = exp_if_false; 00258 break; 00259 00260 case CompareEq: 00261 if( left == right ) 00262 returnValue = exp_if_true; 00263 else returnValue = exp_if_false; 00264 break; 00265 00266 case CompareGe: 00267 if( left >= right ) 00268 returnValue = exp_if_true; 00269 else returnValue = exp_if_false; 00270 break; 00271 00272 case CompareGt: 00273 if( left > right ) 00274 returnValue = exp_if_true; 00275 else returnValue = exp_if_false; 00276 break; 00277 00278 default: 00279 CPPAD_ASSERT_UNKNOWN(0); 00280 returnValue = exp_if_true; 00281 } 00282 return returnValue; 00283 } 00284 00285 /*! \} */ 00286 CPPAD_END_NAMESPACE 00287 # endif