CppAD: A C++ Algorithmic Differentiation Package  20130102
cond_exp.hpp
Go to the documentation of this file.
00001 /* $Id$ */
00002 # ifndef CPPAD_COND_EXP_INCLUDED
00003 # define CPPAD_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 -------------------------------------------------------------------------------
00018 $begin CondExp$$
00019 $spell
00020      Atan2
00021      CondExp
00022      Taylor
00023      std
00024      Cpp
00025      namespace
00026      inline
00027      const
00028      abs
00029      Rel
00030      bool
00031      Lt
00032      Le
00033      Eq
00034      Ge
00035      Gt
00036 $$
00037 
00038 $index conditional, expression$$
00039 $index expression, conditional$$
00040 $index assign, conditional$$
00041 
00042 $section AD Conditional Expressions$$
00043 
00044 $head Syntax$$
00045 $icode%result% = CondExp%Rel%(%left%, %right%, %if_true%, %if_false%)%$$
00046 
00047 
00048 $head Purpose$$
00049 Record, 
00050 as part of an AD of $icode Base$$
00051 $cref/operation sequence/glossary/Operation/Sequence/$$,
00052 the conditional result 
00053 $codei%
00054      if( %left% %Cop% %right% )
00055           %result% = %if_true%
00056      else %result% = %if_false%
00057 %$$
00058 The relational $icode Rel$$ and comparison operator $icode Cop$$ 
00059 above have the following correspondence: 
00060 $codei%
00061      %Rel%   Lt   Le   Eq   Ge   Gt
00062      %Cop%    <   <=   ==   >=   >
00063 %$$
00064 If $icode f$$ is the $cref ADFun$$ object corresponding to the
00065 AD operation sequence,
00066 the assignment choice for $icode result$$
00067 in an AD conditional expression is made each time
00068 $cref/f.Forward/Forward/$$ is used to evaluate the zero order Taylor
00069 coefficients with new values for the 
00070 $cref/independent variables/glossary/Tape/Independent Variable/$$.
00071 This is in contrast to the $cref/AD comparison operators/Compare/$$
00072 which are boolean valued and not included in the AD operation sequence. 
00073 
00074 $head Rel$$
00075 In the syntax above, the relation $icode Rel$$ represents one of the following
00076 two characters: $code Lt$$, $code Le$$, $code Eq$$, $code Ge$$, $code Gt$$. 
00077 As in the table above,
00078 $icode Rel$$ determines which comparison operator $icode Cop$$ is used
00079 when comparing $icode left$$ and $icode right$$.
00080 
00081 $head Type$$
00082 These functions are defined in the CppAD namespace for arguments of
00083 $icode Type$$ is $code float$$ , $code double$$, or any type of the form
00084 $codei%AD<%Base%>%$$.
00085 (Note that all four arguments must have the same type.)
00086  
00087 $head left$$
00088 The argument $icode left$$ has prototype
00089 $codei%
00090      const %Type%& %left%
00091 %$$
00092 It specifies the value for the left side of the comparison operator.
00093  
00094 $head right$$
00095 The argument $icode right$$ has prototype
00096 $codei%
00097      const %Type%& %right%
00098 %$$
00099 It specifies the value for the right side of the comparison operator.
00100 
00101 $head if_true$$
00102 The argument $icode if_true$$ has prototype
00103 $codei%
00104      const %Type%& %if_true%
00105 %$$
00106 It specifies the return value if the result of the comparison is true.
00107 
00108 $head if_false$$
00109 The argument $icode if_false$$ has prototype
00110 $codei%
00111      const %Type%& %if_false%
00112 %$$
00113 It specifies the return value if the result of the comparison is false.
00114 
00115 $head result$$
00116 The $icode result$$ has prototype
00117 $codei%
00118      %Type%& %if_false%
00119 %$$
00120 
00121 
00122 $head CondExp$$
00123 Previous versions of CppAD used 
00124 $codei%
00125      CondExp(%flag%, %if_true%, %if_false%)
00126 %$$
00127 for the same meaning as 
00128 $codei%
00129      CondExpGt(%flag%, %Type%(0), %if_true%, %if_false%)
00130 %$$
00131 Use of $code CondExp$$ is deprecated, but continues to be supported.
00132 
00133 $head Operation Sequence$$
00134 This is an AD of $icode Base$$
00135 $cref/atomic operation/glossary/Operation/Atomic/$$
00136 and hence is part of the current
00137 AD of $icode Base$$
00138 $cref/operation sequence/glossary/Operation/Sequence/$$.
00139 
00140 
00141 $head Example$$
00142 
00143 $head Test$$
00144 $children%
00145      example/cond_exp.cpp
00146 %$$
00147 The file
00148 $cref cond_exp.cpp$$
00149 contains an example and test of this function.   
00150 It returns true if it succeeds and false otherwise.
00151 
00152 $head Atan2$$
00153 The following implementation of the
00154 AD $cref atan2$$ function is a more complex
00155 example of using conditional expressions:
00156 $code
00157 $verbatim%cppad/local/atan2.hpp%0%BEGIN CondExp%// END CondExp%$$
00158 $$
00159 
00160 
00161 $end
00162 -------------------------------------------------------------------------------
00163 */
00164 //  BEGIN CppAD namespace
00165 namespace CppAD {
00166 
00167 template <class Base>
00168 CPPAD_INLINE_FRIEND_TEMPLATE_FUNCTION
00169 AD<Base> CondExpOp(
00170      enum  CompareOp cop       ,
00171      const AD<Base> &left      , 
00172      const AD<Base> &right     , 
00173      const AD<Base> &if_true   , 
00174      const AD<Base> &if_false  )
00175 {
00176      AD<Base> returnValue;
00177      CPPAD_ASSERT_UNKNOWN( Parameter(returnValue) );
00178 
00179      // check first case where do not need to tape
00180      if( IdenticalPar(left) & IdenticalPar(right) )
00181      {    switch( cop )
00182           {
00183                case CompareLt:
00184                if( left.value_ < right.value_ )
00185                     returnValue = if_true;
00186                else returnValue = if_false;
00187                break;
00188 
00189                case CompareLe:
00190                if( left.value_ <= right.value_ )
00191                     returnValue = if_true;
00192                else returnValue = if_false;
00193                break;
00194 
00195                case CompareEq:
00196                if( left.value_ == right.value_ )
00197                     returnValue = if_true;
00198                else returnValue = if_false;
00199                break;
00200 
00201                case CompareGe:
00202                if( left.value_ >= right.value_ )
00203                     returnValue = if_true;
00204                else returnValue = if_false;
00205                break;
00206 
00207                case CompareGt:
00208                if( left.value_ > right.value_ )
00209                     returnValue = if_true;
00210                else returnValue = if_false;
00211                break;
00212 
00213                default:
00214                CPPAD_ASSERT_UNKNOWN(0);
00215                returnValue = if_true;
00216           }
00217           return returnValue;
00218      }
00219 
00220      // must use CondExp incase Base is an AD type and recording
00221      returnValue.value_ = CondExpOp(cop, 
00222           left.value_, right.value_, if_true.value_, if_false.value_);
00223 
00224      ADTape<Base> *tape = CPPAD_NULL;
00225      if( Variable(left) )
00226           tape = left.tape_this();
00227      if( Variable(right) )
00228           tape = right.tape_this();
00229      if( Variable(if_true) )
00230           tape = if_true.tape_this();
00231      if( Variable(if_false) )
00232           tape = if_false.tape_this();
00233 
00234      // add this operation to the tape
00235      if( tape != CPPAD_NULL ) 
00236           tape->RecordCondExp(cop, 
00237                returnValue, left, right, if_true, if_false);
00238 
00239      return returnValue;
00240 }
00241 
00242 // --- RecordCondExp(cop, returnValue, left, right, if_true, if_false) -----
00243 
00244 /// All these operations are done in \c Rec_, so we should move this
00245 /// routine to <tt>recorder<Base></tt>.
00246 template <class Base>
00247 void ADTape<Base>::RecordCondExp(
00248      enum CompareOp  cop         ,
00249      AD<Base>       &returnValue ,
00250      const AD<Base> &left        ,
00251      const AD<Base> &right       ,
00252      const AD<Base> &if_true     ,
00253      const AD<Base> &if_false    )
00254 {    size_t   ind0, ind1, ind2, ind3, ind4, ind5;
00255      size_t   returnValue_taddr;
00256 
00257      // taddr_ of this variable
00258      CPPAD_ASSERT_UNKNOWN( NumRes(CExpOp) == 1 );
00259      returnValue_taddr = Rec_.PutOp(CExpOp);
00260 
00261      // ind[0] = cop
00262      ind0 = addr_t( cop );
00263 
00264      // ind[1] = base 2 representaion of the value
00265      // [Var(left), Var(right), Var(if_true), Var(if_false)]
00266      ind1 = 0;
00267 
00268      // Make sure returnValue is in the list of variables and set its taddr
00269      if( Parameter(returnValue) )
00270           returnValue.make_variable(id_, returnValue_taddr );
00271      else returnValue.taddr_ = returnValue_taddr;
00272 
00273      // ind[2] = left address
00274      if( Parameter(left) )
00275           ind2 = Rec_.PutPar(left.value_);
00276      else
00277      {    ind1 += 1;
00278           ind2 = left.taddr_; 
00279      }
00280 
00281      // ind[3] = right address
00282      if( Parameter(right) )
00283           ind3 = Rec_.PutPar(right.value_);
00284      else
00285      {    ind1 += 2;
00286           ind3 = right.taddr_;     
00287      }
00288 
00289      // ind[4] = if_true address
00290      if( Parameter(if_true) )
00291           ind4 = Rec_.PutPar(if_true.value_);
00292      else
00293      {    ind1 += 4;
00294           ind4 = if_true.taddr_;   
00295      }
00296 
00297      // ind[5] =  if_false address
00298      if( Parameter(if_false) )
00299           ind5 = Rec_.PutPar(if_false.value_);
00300      else
00301      {    ind1 += 8;
00302           ind5 = if_false.taddr_;  
00303      }
00304 
00305      CPPAD_ASSERT_UNKNOWN( NumArg(CExpOp) == 6 );
00306      CPPAD_ASSERT_UNKNOWN( ind1 > 0 );
00307      Rec_.PutArg(ind0, ind1, ind2, ind3, ind4, ind5);
00308 
00309      // check that returnValue is a dependent variable
00310      CPPAD_ASSERT_UNKNOWN( Variable(returnValue) );
00311 }
00312 
00313 // ------------ CondExpOp(left, right, if_true, if_false) ----------------
00314 
00315 # define CPPAD_COND_EXP(Name)                                        \
00316      template <class Base>                                           \
00317      CPPAD_INLINE_FRIEND_TEMPLATE_FUNCTION                           \
00318      AD<Base> CondExp##Name(                                         \
00319           const AD<Base> &left      ,                                \
00320           const AD<Base> &right     ,                                \
00321           const AD<Base> &if_true   ,                                \
00322           const AD<Base> &if_false  )                                \
00323      {                                                               \
00324           return CondExpOp(Compare##Name,                            \
00325                left, right, if_true, if_false);                      \
00326      }
00327 
00328 // AD<Base>
00329 CPPAD_COND_EXP(Lt)
00330 CPPAD_COND_EXP(Le)
00331 CPPAD_COND_EXP(Eq)
00332 CPPAD_COND_EXP(Ge)
00333 CPPAD_COND_EXP(Gt)
00334 template <class Base>
00335 CPPAD_INLINE_FRIEND_TEMPLATE_FUNCTION
00336 AD<Base> CondExp(
00337      const AD<Base> &flag      , 
00338      const AD<Base> &if_true   ,
00339      const AD<Base> &if_false  )
00340 {    
00341      return CondExpOp(CompareGt, flag, AD<Base>(0), if_true, if_false);
00342 }
00343 
00344 # undef CPPAD_COND_EXP
00345 } // END CppAD namespace
00346 
00347 # endif 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines