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