CppAD: A C++ Algorithmic Differentiation Package  20130102
base_cond_exp.hpp
Go to the documentation of this file.
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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines