/home/coin/SVN-release/CoinAll-1.1.0/cppad/cppad/local/cond_exp.hpp

Go to the documentation of this file.
00001 # ifndef CPPAD_COND_EXP_INCLUDED
00002 # define CPPAD_COND_EXP_INCLUDED
00003 
00004 /* --------------------------------------------------------------------------
00005 CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-07 Bradley M. Bell
00006 
00007 CppAD is distributed under multiple licenses. This distribution is under
00008 the terms of the 
00009                     Common Public License Version 1.0.
00010 
00011 A copy of this license is included in the COPYING file of this distribution.
00012 Please visit http://www.coin-or.org/CppAD/ for information on other licenses.
00013 -------------------------------------------------------------------------- */
00014 
00015 /*
00016 -------------------------------------------------------------------------------
00017 $begin CondExp$$
00018 $spell
00019         Atan2
00020         CondExp
00021         Taylor
00022         std
00023         Cpp
00024         namespace
00025         inline
00026         const
00027         abs
00028         Op
00029         bool
00030         Lt
00031         Le
00032         Eq
00033         Ge
00034         Gt
00035 $$
00036 
00037 $index conditional, expression$$
00038 $index expression, conditional$$
00039 $index assign, conditional$$
00040 
00041 $section AD Conditional Expressions$$
00042 
00043 $head Syntax$$
00044 $syntax%%result% = CondExp%Op%(%left%, %right%, %trueCase%, %falseCase%)%$$
00045 
00046 
00047 $head Purpose$$
00048 Record, 
00049 as part of an AD of $italic Base$$
00050 $xref/glossary/Operation/Sequence/operation sequence/1/$$,
00051 a the conditional result of the form 
00052 $syntax%
00053         if( %left% %op% %right% )
00054                 %result% = %trueCase%
00055         else    %result% = %falseCase%
00056 %$$
00057 The notation $italic Op$$ and $italic op$$ 
00058 above have the following correspondence: 
00059 $table
00060 $italic Op$$ 
00061         $pre  $$ $cnext $code Lt$$
00062         $pre  $$ $cnext $code Le$$
00063         $pre  $$ $cnext $code Eq$$
00064         $pre  $$ $cnext $code Ge$$
00065         $pre  $$ $cnext $code Gt$$
00066 $rnext
00067 $italic op$$ 
00068         $cnext $code <$$
00069         $cnext $code <=$$
00070         $cnext $code ==$$
00071         $cnext $code >=$$
00072         $cnext $code >$$
00073 $tend
00074 If $italic f$$ is the $xref/ADFun/$$ object corresponding to the
00075 AD operation sequence,
00076 the choice in an AD conditional expression is made each time
00077 $xref/Forward//f.Forward/$$ is used to evaluate the zero order Taylor
00078 coefficients with new values for the 
00079 $cref/independent variables/glossary/Tape/Independent Variable/$$.
00080 This is in contrast to the $xref/Compare//AD comparison operators/$$
00081 which are boolean valued and not included in the AD operation sequence. 
00082 
00083 $head Type$$
00084 We use $italic Type$$ for the type of
00085 $italic left$$, $italic right$$, $italic trueCase$$, and $italic falseCase$$
00086 (which must all have the same type). 
00087 This type must be
00088 $code float$$, $code double$$, or in the 
00089 $cref/AD levels above/glossary/AD Levels Above Base/$$
00090 above $code float$$ or $code double$$.
00091 
00092 $head Op$$
00093 In the syntax above, $italic Op$$ represents one of the following
00094 two characters: $code Lt$$, $code Le$$, $code Eq$$, $code Ge$$, $code Gt$$. 
00095 As in the table above,
00096 $italic Op$$ determines the comparison operator $italic op$$.
00097  
00098 $head left$$
00099 The argument $italic left$$ has prototype
00100 $syntax%
00101         const %Type% &%left%
00102 %$$
00103 It specifies the value for the left side of the comparison operator.
00104  
00105 $head right$$
00106 The argument $italic right$$ has prototype
00107 $syntax%
00108         const %Type% &%right%
00109 %$$
00110 It specifies the value for the right side of the comparison operator.
00111 
00112 $head trueCase$$
00113 The argument $italic trueCase$$ has prototype
00114 $syntax%
00115         const %Type% &%trueCase%
00116 %$$
00117 It specifies the return value if the result of the comparison is true.
00118 
00119 $head falseCase$$
00120 The argument $italic falseCase$$ has prototype
00121 $syntax%
00122         const %Type% &%falseCase%
00123 %$$
00124 It specifies the return value if the result of the comparison is false.
00125 
00126 $head result$$
00127 The $italic result$$ has prototype
00128 $syntax%
00129         %Type% &%falseCase%
00130 %$$
00131 
00132 
00133 $head CondExp$$
00134 Previous versions of CppAD used 
00135 $syntax%
00136         CondExp(%flag%, %trueCase%, %falseCase%)
00137 %$$
00138 for the same meaning as 
00139 $syntax%
00140         CondExpGt(%flag%, %Type%(0), %trueCase%, %falseCase%)
00141 %$$
00142 Use of $code CondExp$$ is deprecated, but continues to be supported.
00143 
00144 $head Operation Sequence$$
00145 This is an AD of $italic Base$$
00146 $xref/glossary/Operation/Atomic/atomic operation/1/$$
00147 and hence is part of the current
00148 AD of $italic Base$$
00149 $xref/glossary/Operation/Sequence/operation sequence/1/$$.
00150 
00151 
00152 $head Example$$
00153 
00154 $head Test$$
00155 $children%
00156         example/cond_exp.cpp
00157 %$$
00158 The file
00159 $xref/CondExp.cpp/$$
00160 contains an example and test of this function.   
00161 It returns true if it succeeds and false otherwise.
00162 
00163 $head Atan2$$
00164 The following implementation of the
00165 AD $xref/atan2/$$ function is a more complex
00166 example of using conditional expressions:
00167 $code
00168 $verbatim%cppad/local/atan2.hpp%0%BEGIN CondExp%// END CondExp%$$
00169 $$
00170 
00171 
00172 $end
00173 -------------------------------------------------------------------------------
00174 */
00175 //  BEGIN CppAD namespace
00176 namespace CppAD {
00177 
00178 // ------------ CondExpOp(cop, left, right, trueCase, falseCase) --------------
00179 // CompareType and ResultType are different for the forward and reverse
00180 // sparese calculations.
00181 template <class CompareType, class ResultType>
00182 inline ResultType CondExpTemplate( 
00183         enum  CompareOp            cop ,
00184         const CompareType        &left ,
00185         const CompareType       &right , 
00186         const ResultType     &trueCase , 
00187         const ResultType    &falseCase )
00188 {       ResultType returnValue;
00189         switch( cop )
00190         {
00191                 case CompareLt:
00192                 if( left < right )
00193                         returnValue = trueCase;
00194                 else    returnValue = falseCase;
00195                 break;
00196 
00197                 case CompareLe:
00198                 if( left <= right )
00199                         returnValue = trueCase;
00200                 else    returnValue = falseCase;
00201                 break;
00202 
00203                 case CompareEq:
00204                 if( left == right )
00205                         returnValue = trueCase;
00206                 else    returnValue = falseCase;
00207                 break;
00208 
00209                 case CompareGe:
00210                 if( left >= right )
00211                         returnValue = trueCase;
00212                 else    returnValue = falseCase;
00213                 break;
00214 
00215                 case CompareGt:
00216                 if( left > right )
00217                         returnValue = trueCase;
00218                 else    returnValue = falseCase;
00219                 break;
00220 
00221                 default:
00222                 CPPAD_ASSERT_UNKNOWN(0);
00223                 returnValue = trueCase;
00224         }
00225         return returnValue;
00226 }
00227 
00228 inline float CondExpOp( 
00229         enum CompareOp     cop ,
00230         const float      &left ,
00231         const float     &right , 
00232         const float  &trueCase , 
00233         const float &falseCase )
00234 {       return CondExpTemplate(cop, left, right, trueCase, falseCase);
00235 }
00236 
00237 inline double CondExpOp( 
00238         enum CompareOp     cop ,
00239         const double      &left ,
00240         const double     &right , 
00241         const double  &trueCase , 
00242         const double &falseCase )
00243 {       return CondExpTemplate(cop, left, right, trueCase, falseCase);
00244 }
00245 
00246 template <class Base>
00247 inline AD<Base> CondExpOp(
00248         enum  CompareOp cop       ,
00249         const AD<Base> &left      , 
00250         const AD<Base> &right     , 
00251         const AD<Base> &trueCase  , 
00252         const AD<Base> &falseCase )
00253 {
00254         AD<Base> returnValue;
00255         CPPAD_ASSERT_UNKNOWN( Parameter(returnValue) );
00256 
00257         // check first case where do not need to tape
00258         if( IdenticalPar(left) & IdenticalPar(right) )
00259         {       switch( cop )
00260                 {
00261                         case CompareLt:
00262                         if( left.value_ < right.value_ )
00263                                 returnValue = trueCase;
00264                         else    returnValue = falseCase;
00265                         break;
00266 
00267                         case CompareLe:
00268                         if( left.value_ <= right.value_ )
00269                                 returnValue = trueCase;
00270                         else    returnValue = falseCase;
00271                         break;
00272 
00273                         case CompareEq:
00274                         if( left.value_ == right.value_ )
00275                                 returnValue = trueCase;
00276                         else    returnValue = falseCase;
00277                         break;
00278 
00279                         case CompareGe:
00280                         if( left.value_ >= right.value_ )
00281                                 returnValue = trueCase;
00282                         else    returnValue = falseCase;
00283                         break;
00284 
00285                         case CompareGt:
00286                         if( left.value_ > right.value_ )
00287                                 returnValue = trueCase;
00288                         else    returnValue = falseCase;
00289                         break;
00290 
00291                         default:
00292                         CPPAD_ASSERT_UNKNOWN(0);
00293                         returnValue = trueCase;
00294                 }
00295                 return returnValue;
00296         }
00297 
00298         // must use CondExp incase Base is an AD type and recording
00299         returnValue.value_ = CondExpOp(cop, 
00300                 left.value_, right.value_, trueCase.value_, falseCase.value_);
00301 
00302         ADTape<Base> *tape = CPPAD_NULL;
00303         if( Variable(left) )
00304                 tape = left.tape_this();
00305         if( Variable(right) )
00306                 tape = right.tape_this();
00307         if( Variable(trueCase) )
00308                 tape = trueCase.tape_this();
00309         if( Variable(falseCase) )
00310                 tape = falseCase.tape_this();
00311 
00312         // add this operation to the tape
00313         if( tape != CPPAD_NULL ) 
00314                 tape->RecordCondExp(cop, 
00315                         returnValue, left, right, trueCase, falseCase);
00316 
00317         return returnValue;
00318 }
00319 
00320 // --- RecordCondExp(cop, returnValue, left, right, trueCase, falseCase) -----
00321 
00322 template <class Base>
00323 void ADTape<Base>::RecordCondExp(
00324         enum CompareOp  cop         ,
00325         AD<Base>       &returnValue ,
00326         const AD<Base> &left        ,
00327         const AD<Base> &right       ,
00328         const AD<Base> &trueCase    ,
00329         const AD<Base> &falseCase   )
00330 {       size_t   ind0, ind1, ind2, ind3, ind4, ind5;
00331         size_t   returnValue_taddr;
00332 
00333         // taddr_ of this variable
00334         returnValue_taddr = Rec.PutOp(CExpOp);
00335 
00336         // ind[0] = cop
00337         ind0 = size_t( cop );
00338 
00339         // ind[1] = base 2 representaion of the value
00340         // [Var(left), Var(right), Var(trueCase), Var(falseCase)]
00341         ind1 = 0;
00342 
00343         // Make sure returnValue is in the list of variables and set its taddr
00344         if( Parameter(returnValue) )
00345                 returnValue.make_variable(id_, returnValue_taddr );
00346         else    returnValue.taddr_ = returnValue_taddr;
00347 
00348         // ind[2] = left address
00349         if( Parameter(left) )
00350                 ind2 = Rec.PutPar(left.value_);
00351         else
00352         {       ind1 += 1;
00353                 ind2 = left.taddr_;     
00354         }
00355 
00356         // ind[3] = right address
00357         if( Parameter(right) )
00358                 ind3 = Rec.PutPar(right.value_);
00359         else
00360         {       ind1 += 2;
00361                 ind3 = right.taddr_;    
00362         }
00363 
00364         // ind[4] = trueCase address
00365         if( Parameter(trueCase) )
00366                 ind4 = Rec.PutPar(trueCase.value_);
00367         else
00368         {       ind1 += 4;
00369                 ind4 = trueCase.taddr_; 
00370         }
00371 
00372         // ind[5] =  falseCase address
00373         if( Parameter(falseCase) )
00374                 ind5 = Rec.PutPar(falseCase.value_);
00375         else
00376         {       ind1 += 8;
00377                 ind5 = falseCase.taddr_;        
00378         }
00379 
00380         CPPAD_ASSERT_UNKNOWN( NumInd(CExpOp) == 6 );
00381         CPPAD_ASSERT_UNKNOWN( ind1 > 0 );
00382         Rec.PutInd(ind0, ind1, ind2, ind3, ind4, ind5);
00383 
00384         // check that returnValue is a dependent variable
00385         CPPAD_ASSERT_UNKNOWN( Variable(returnValue) );
00386 }
00387 
00388 // ------------ CondExpOp(left, right, trueCase, falseCase) ----------------
00389 
00390 # define CPPAD_COND_EXP(Name)                                              \
00391         template <class Base>                                              \
00392         inline AD<Base> CondExp##Name(                                     \
00393                 const AD<Base> &left      ,                                \
00394                 const AD<Base> &right     ,                                \
00395                 const AD<Base> &trueCase  ,                                \
00396                 const AD<Base> &falseCase )                                \
00397         {                                                                  \
00398                 return CondExpOp(Compare##Name,                            \
00399                         left, right, trueCase, falseCase);                 \
00400         }
00401 
00402 // AD<Base>
00403 CPPAD_COND_EXP(Lt)
00404 CPPAD_COND_EXP(Le)
00405 CPPAD_COND_EXP(Eq)
00406 CPPAD_COND_EXP(Ge)
00407 CPPAD_COND_EXP(Gt)
00408 template <class Base>
00409 inline AD<Base> CondExp(
00410         const AD<Base> &flag      , 
00411         const AD<Base> &trueCase  ,
00412         const AD<Base> &falseCase )
00413 {       
00414         return CondExpOp(CompareGt, flag, AD<Base>(0), trueCase, falseCase);
00415 }
00416 
00417 # undef CPPAD_COND_EXP
00418 # define CPPAD_COND_EXP(Name, Op, Type)                             \
00419         inline Type CondExp##Name(                                  \
00420                 const Type &left      ,                             \
00421                 const Type &right     ,                             \
00422                 const Type &trueCase  ,                             \
00423                 const Type &falseCase )                             \
00424         {       Type returnValue;                                   \
00425                 if( left Op right )                                 \
00426                         returnValue = trueCase;                     \
00427                 else    returnValue = falseCase;                    \
00428                 return returnValue;                                 \
00429         }
00430 
00431 // float
00432 CPPAD_COND_EXP(Lt,  <, float)
00433 CPPAD_COND_EXP(Le, <=, float)
00434 CPPAD_COND_EXP(Eq, ==, float)
00435 CPPAD_COND_EXP(Ge, >=, float)
00436 CPPAD_COND_EXP(Gt,  >, float)
00437 inline float CondExp(
00438         const float &flag      , 
00439         const float &trueCase  ,
00440         const float &falseCase )
00441 {       
00442         return CondExpGt(flag, float(0), trueCase, falseCase);
00443 }
00444 
00445 // double
00446 CPPAD_COND_EXP(Lt,  <, double)
00447 CPPAD_COND_EXP(Le, <=, double)
00448 CPPAD_COND_EXP(Eq, ==, double)
00449 CPPAD_COND_EXP(Ge, >=, double)
00450 CPPAD_COND_EXP(Gt,  >, double)
00451 inline double CondExp(
00452         const double &flag      , 
00453         const double &trueCase  ,
00454         const double &falseCase )
00455 {       
00456         return CondExpGt(flag, 0., trueCase, falseCase);
00457 }
00458 
00459 # undef CPPAD_COND_EXP
00460 
00461 } // END CppAD namespace
00462 
00463 # endif 

Generated on Sun Nov 14 14:06:33 2010 for Coin-All by  doxygen 1.4.7