CppAD: A C++ Algorithmic Differentiation Package
20130918
|
00001 /* $Id$ */ 00002 # ifndef CPPAD_COMP_OP_INCLUDED 00003 # define CPPAD_COMP_OP_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 namespace CppAD { // BEGIN_CPPAD_NAMESPACE 00018 /*! 00019 \file comp_op.hpp 00020 Zero order forward mode check how many 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 size_t(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 addr_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( size_t(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( size_t(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( size_t(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 } // END_CPPAD_NAMESPACE 00171 # endif