CppAD: A C++ Algorithmic Differentiation Package 20110419
comp_op.hpp
Go to the documentation of this file.
00001 /* $Id$ */
00002 # ifndef CPPAD_COMP_OP_INCLUDED
00003 # define CPPAD_COMP_OP_INCLUDED
00004 
00005 /* --------------------------------------------------------------------------
00006 CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-10 Bradley M. Bell
00007 
00008 CppAD is distributed under multiple licenses. This distribution is under
00009 the terms of the 
00010                     Common 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 CPPAD_BEGIN_NAMESPACE
00018 /*!
00019 \file comp_op.hpp
00020 Zero order forward mode check how man comparisons changed.
00021 */
00022 
00023 /*!
00024 Zero order forward mode execution of op = CompOp.
00025 
00026 The C++ source code corresponding to this operation is
00027 \verbatim
00028         left Cop right
00029 \endverbatim
00030 where Cop is one of the following:
00031 <, <=, == , >=, >, !=.
00032 
00033 \tparam Base
00034 base type for the operator; i.e., this operation was recorded
00035 using AD< \a Base > and computations by this routine are done using type 
00036 \a Base.
00037 
00038 \param count
00039 If the comparision has the same result as when t operation seqeunce was
00040 recorded, \a count is not affected.
00041 Otherwise it is incremented by one.
00042 
00043 \param arg
00044 \n
00045 \a arg[0]
00046 is static cast to size_t from the enum type
00047 \verbatim
00048         enum CompareOp {
00049                 CompareLt, 
00050                 CompareLe, 
00051                 CompareEq, 
00052                 CompareGe, 
00053                 CompareGt, 
00054                 CompareNe
00055         }
00056 \endverbatim
00057 for this operation.
00058 \n
00059 \n 
00060 \a arg[1] & 1 
00061 \n
00062 If this expression is true, 
00063 the result of the comparison during taping it true.
00064 Othwise the result if false.
00065 \n
00066 \n
00067 \a arg[1] & 2
00068 \n
00069 if this expression is true, left is a variable, otherwise it is a parameter.
00070 \n
00071 \n
00072 \a arg[1] & 4
00073 \n
00074 if this expression is true, right is a variable, otherwise it is a parameter.
00075 \n
00076 
00077 \param num_par
00078 is the lenght of the \a parameter vector.
00079 This value is only used for checking assumptions mentioned below
00080 (and is not used at all when NDEBUG is defined).
00081 
00082 \param parameter
00083 Vector of parameters corresponding to the tape.
00084 If left is a parameter, \a parameter[ arg[2] ] is its value.
00085 If right is a parameter, \a parameter[ arg[3] ] is its value.
00086 
00087 \param nc_taylor
00088 number of columns in the matrix containing the Taylor coefficients.
00089 
00090 \param taylor
00091 Matrix of Taylor coefficients.
00092 If left is a variable, \a taylor[ arg[2] * nc_taylor + 0 ] is its value.
00093 If right is a variable, \a taylor[ arg[3] * nc_taylor + 0 ] is its value.
00094 
00095 
00096 \par Checked Assertions where op is a binary operator:
00097 \li NumArg(ComOp) == 4
00098 \li NumRes(ComOp) == 0
00099 \li arg[0] <= static_cast<size_t>( CompareNe )
00100 \li arg[1] != 0 (either left or right is a variable)
00101 \li if left is a parameter, \a arg[2] < \a num_par
00102 \li if right is a parameter, \a arg[3] < \a num_par
00103 
00104 */
00105 template <class Base>
00106 inline void forward_comp_op_0(
00107         size_t&        count       ,
00108         const size_t*  arg         , 
00109         size_t         num_par     ,
00110         const Base*    parameter   ,
00111         size_t         nc_taylor   ,
00112         Base*          taylor      )
00113 {       bool result;
00114         Base left;
00115         Base right;
00116 
00117         CPPAD_ASSERT_UNKNOWN( NumArg(ComOp) == 4 );
00118         CPPAD_ASSERT_UNKNOWN( NumRes(ComOp) == 0 );
00119         CPPAD_ASSERT_UNKNOWN( arg[0] <= static_cast<size_t> (CompareNe) );
00120         CPPAD_ASSERT_UNKNOWN( arg[1] != 0 );
00121 
00122         // result of comparision during recording
00123         result = (arg[1] & 1) == 1;
00124 
00125         // value of left operand for this forward sweep
00126         if( arg[1] & 2 )
00127                 left = taylor[ arg[2] * nc_taylor + 0 ];
00128         else
00129         {       CPPAD_ASSERT_UNKNOWN( arg[2] < num_par );
00130                 left = parameter[ arg[2] ];
00131         }
00132 
00133         // value of right operand for this forward sweep.
00134         if( arg[1] & 4 )
00135                 right = taylor[ arg[3] * nc_taylor + 0 ];
00136         else
00137         {       CPPAD_ASSERT_UNKNOWN( arg[3] < num_par );
00138                 right = parameter[ arg[3] ];
00139         }
00140         switch( CompareOp( arg[0] ) )
00141         {       case CompareLt:
00142                 count += ( result != LessThanZero(left - right) );
00143                 break;
00144 
00145                 case CompareLe:
00146                 count += ( result != LessThanOrZero(left - right) );
00147                 break;
00148 
00149                 case CompareEq:
00150                 count += ( result != (left == right) );
00151                 break;
00152 
00153                 case CompareGe:
00154                 count += ( result != GreaterThanOrZero(left - right) );
00155                 break;
00156 
00157                 case CompareGt:
00158                 count += ( result != GreaterThanZero(left - right) );
00159                 break;
00160 
00161                 case CompareNe:
00162                 count += ( result != (left != right) );
00163                 break;
00164 
00165                 default:
00166                 CPPAD_ASSERT_UNKNOWN(0);
00167         }
00168         return;
00169 }
00170 CPPAD_END_NAMESPACE
00171 # endif