CppAD: A C++ Algorithmic Differentiation Package  20130918
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-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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines