CppAD: A C++ Algorithmic Differentiation Package
20130918
|
00001 // $Id$ 00002 # ifndef CPPAD_CSKIP_OP_INCLUDED 00003 # define CPPAD_CSKIP_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 namespace CppAD { // BEGIN_CPPAD_NAMESPACE 00017 /*! 00018 \file cskip_op.hpp 00019 Zero order forward mode set which operations to skip. 00020 */ 00021 00022 /*! 00023 Zero order forward mode execution of op = CSkipOp. 00024 00025 \tparam Base 00026 base type for the operator; i.e., this operation was recorded 00027 using AD< \a Base > and computations by this routine are done using type 00028 \a Base. 00029 00030 \param i_z 00031 variable index corresponding to the result of the previous operation. 00032 This is used for error checking. To be specific, 00033 the left and right operands for the CExpOp operation must have indexes 00034 less than or equal this value. 00035 00036 \param arg [in] 00037 \n 00038 \a arg[0] 00039 is static cast to size_t from the enum type 00040 \verbatim 00041 enum CompareOp { 00042 CompareLt, 00043 CompareLe, 00044 CompareEq, 00045 CompareGe, 00046 CompareGt, 00047 CompareNe 00048 } 00049 \endverbatim 00050 for this operation. 00051 Note that arg[0] cannot be equal to CompareNe. 00052 \n 00053 \n 00054 \a arg[1] & 1 00055 \n 00056 If this is zero, left is a a parameter. Otherwise it is a variable. 00057 \n 00058 \n 00059 \a arg[1] & 2 00060 \n 00061 If this is zero, right is a parameter. Otherwise it is a variable. 00062 \n 00063 \a arg[2] 00064 is the index corresponding to left in comparision. 00065 \n 00066 \a arg[3] 00067 is the index corresponding to right in comparision. 00068 \n 00069 \a arg[4] 00070 is the number of operations to skip if the comparision result is true. 00071 \n 00072 \a arg[5] 00073 is the number of operations to skip if the comparision result is false. 00074 \n 00075 <tt>arg[5+i]</tt> 00076 for <tt>i = 1 , ... , arg[4]</tt> are the operations to skip if the 00077 comparision result is true. 00078 \n 00079 <tt>arg[5+arg[4]+i]</tt> 00080 for <tt>i = 1 , ... , arg[5]</tt> are the operations to skip if the 00081 comparision result is false. 00082 00083 \param num_par [in] 00084 is the total number of values in the vector \a parameter. 00085 00086 \param parameter [in] 00087 If left is a parameter, 00088 <code>parameter [ arg[2] ]</code> is its value. 00089 If right is a parameter, 00090 <code>parameter [ arg[3] ]</code> is its value. 00091 00092 \param nc_taylor [in] 00093 number of columns in the matrix containing the Taylor coefficients. 00094 00095 \param taylor [in] 00096 If left is a variable, 00097 <code>taylor [ arg[2] * nc_taylor + 0 ]</code> 00098 is the zeroth order Taylor coefficient corresponding to left. 00099 If right is a variable, 00100 <code>taylor [ arg[3] * nc_taylor + 0 ]</code> 00101 is the zeroth order Taylor coefficient corresponding to right. 00102 00103 \param \cskip_op [in,out] 00104 is vector specifying which operations are at this point are know to be 00105 unecessary and can be skipped. 00106 This is both an input and an output. 00107 */ 00108 template <class Base> 00109 inline void forward_cskip_op_0( 00110 size_t i_z , 00111 const addr_t* arg , 00112 size_t num_par , 00113 const Base* parameter , 00114 size_t nc_taylor , 00115 Base* taylor , 00116 bool* cskip_op ) 00117 { 00118 CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < size_t(CompareNe) ); 00119 CPPAD_ASSERT_UNKNOWN( arg[1] != 0 ); 00120 00121 Base left, right; 00122 if( arg[1] & 1 ) 00123 { CPPAD_ASSERT_UNKNOWN( size_t(arg[2]) <= i_z ); 00124 left = taylor[ arg[2] * nc_taylor + 0 ]; 00125 CPPAD_ASSERT_UNKNOWN( IdenticalPar(left) ); 00126 } 00127 else 00128 { CPPAD_ASSERT_UNKNOWN( size_t(arg[2]) < num_par ); 00129 left = parameter[ arg[2] ]; 00130 CPPAD_ASSERT_UNKNOWN( IdenticalPar(left) ); 00131 } 00132 if( arg[1] & 2 ) 00133 { CPPAD_ASSERT_UNKNOWN( size_t(arg[3]) <= i_z ); 00134 right = taylor[ arg[3] * nc_taylor + 0 ]; 00135 CPPAD_ASSERT_UNKNOWN( IdenticalPar(right) ); 00136 } 00137 else 00138 { CPPAD_ASSERT_UNKNOWN( size_t(arg[3]) < num_par ); 00139 right = parameter[ arg[3] ]; 00140 CPPAD_ASSERT_UNKNOWN( IdenticalPar(right) ); 00141 } 00142 00143 00144 // initialize to avoid compiler warning 00145 bool true_case = false; 00146 Base diff = left - right; 00147 switch( CompareOp( arg[0] ) ) 00148 { 00149 case CompareLt: 00150 true_case = LessThanZero(diff); 00151 break; 00152 00153 case CompareLe: 00154 true_case = LessThanOrZero(diff); 00155 break; 00156 00157 case CompareEq: 00158 true_case = IdenticalZero(diff); 00159 break; 00160 00161 case CompareGe: 00162 true_case = GreaterThanOrZero(diff); 00163 break; 00164 00165 case CompareGt: 00166 true_case = GreaterThanZero(diff); 00167 break; 00168 00169 case CompareNe: 00170 true_case = ! IdenticalZero(diff); 00171 break; 00172 00173 default: 00174 CPPAD_ASSERT_UNKNOWN(false); 00175 } 00176 if( true_case ) 00177 { for(size_t i = 0; i < size_t(arg[4]); i++) 00178 cskip_op[ arg[6+i] ] = true; 00179 } 00180 else 00181 { for(size_t i = 0; i < size_t(arg[5]); i++) 00182 cskip_op[ arg[6+arg[4]+i] ] = true; 00183 } 00184 return; 00185 } 00186 } // END_CPPAD_NAMESPACE 00187 # endif 00188