CppAD: A C++ Algorithmic Differentiation Package  20130918
cond_op.hpp
Go to the documentation of this file.
00001 /* $Id$ */
00002 # ifndef CPPAD_COND_OP_INCLUDED
00003 # define CPPAD_COND_OP_INCLUDED
00004 /* --------------------------------------------------------------------------
00005 CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-14 Bradley M. Bell
00006 
00007 CppAD is distributed under multiple licenses. This distribution is under
00008 the terms of the 
00009                     Eclipse 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 namespace CppAD { // BEGIN_CPPAD_NAMESPACE
00016 /*!
00017 \file cond_op.hpp
00018 Forward, reverse, and sparse operations for conditional expressions.
00019 */
00020 
00021 /*!
00022 Shared documentation for conditional expressions (not called).
00023 
00024 <!-- define conditional_exp_op -->
00025 The C++ source code coresponding to this operation is
00026 \verbatim
00027      z = CondExpRel(y_0, y_1, y_2, y_3)
00028 \endverbatim
00029 where Rel is one of the following: Lt, Le, Eq, Ge, Gt. 
00030 
00031 \tparam Base
00032 base type for the operator; i.e., this operation was recorded
00033 using AD< \a Base > and computations by this routine are done using type 
00034 \a Base.
00035 
00036 \param i_z
00037 is the AD variable index corresponding to the variable z.
00038 
00039 \param arg
00040 \n
00041 \a arg[0]
00042 is static cast to size_t from the enum type
00043 \verbatim
00044      enum CompareOp {
00045           CompareLt, 
00046           CompareLe, 
00047           CompareEq, 
00048           CompareGe, 
00049           CompareGt, 
00050           CompareNe
00051      }
00052 \endverbatim
00053 for this operation.
00054 Note that arg[0] cannot be equal to CompareNe.
00055 \n
00056 \n
00057 \a arg[1] & 1
00058 \n
00059 If this is zero, y_0 is a parameter. Otherwise it is a variable.
00060 \n
00061 \n
00062 \a arg[1] & 2
00063 \n
00064 If this is zero, y_1 is a parameter. Otherwise it is a variable.
00065 \n
00066 \n
00067 \a arg[1] & 4
00068 \n
00069 If this is zero, y_2 is a parameter. Otherwise it is a variable.
00070 \n
00071 \n
00072 \a arg[1] & 8
00073 \n
00074 If this is zero, y_3 is a parameter. Otherwise it is a variable.
00075 \n
00076 \n
00077 \a arg[2 + j ] for j = 0, 1, 2, 3
00078 \n
00079 is the index corresponding to y_j.
00080 
00081 \param num_par
00082 is the total number of values in the vector \a parameter.
00083 
00084 \param parameter
00085 For j = 0, 1, 2, 3,
00086 if y_j is a parameter, \a parameter [ arg[2 + j] ] is its value.
00087 
00088 \param nc_taylor
00089 number of columns in the matrix containing the Taylor coefficients.
00090 
00091 \par Checked Assertions
00092 \li NumArg(CExpOp) == 6
00093 \li NumRes(CExpOp) == 1
00094 \li arg[0] < static_cast<size_t> ( CompareNe )
00095 \li arg[1] != 0; i.e., not all of y_0, y_1, y_2, y_3 are parameters.
00096 \li For j = 0, 1, 2, 3 if y_j is a parameter, arg[2+j] < num_par.
00097 \li For j = 0, 1, 2, 3 if y_j is a variable, arg[2+j] < iz.
00098 <!-- end conditional_exp_op -->
00099 */
00100 template <class Base>
00101 inline void conditional_exp_op(
00102      size_t         i_z         ,
00103      const addr_t*  arg         , 
00104      size_t         num_par     ,
00105      const Base*    parameter   ,
00106      size_t         nc_taylor   )
00107 {    // This routine is only for documentation, it should never be used
00108      CPPAD_ASSERT_UNKNOWN( false );
00109 }
00110 
00111 /*!
00112 Shared documentation for conditional expression sparse operations (not called).
00113 
00114 <!-- define sparse_conditional_exp_op -->
00115 The C++ source code coresponding to this operation is
00116 \verbatim
00117      z = CondExpRel(y_0, y_1, y_2, y_3)
00118 \endverbatim
00119 where Rel is one of the following: Lt, Le, Eq, Ge, Gt. 
00120 
00121 \tparam Vector_set
00122 is the type used for vectors of sets. It can be either
00123 \c sparse_pack, \c sparse_set, or \c sparse_list.
00124 
00125 \param i_z
00126 is the AD variable index corresponding to the variable z.
00127 
00128 \param arg
00129 \n
00130 \a arg[0]
00131 is static cast to size_t from the enum type
00132 \verbatim
00133      enum CompareOp {
00134           CompareLt, 
00135           CompareLe, 
00136           CompareEq, 
00137           CompareGe, 
00138           CompareGt, 
00139           CompareNe
00140      }
00141 \endverbatim
00142 for this operation.
00143 Note that arg[0] cannot be equal to CompareNe.
00144 \n
00145 \n
00146 \a arg[1] & 1
00147 \n
00148 If this is zero, y_0 is a parameter. Otherwise it is a variable.
00149 \n
00150 \n
00151 \a arg[1] & 2
00152 \n
00153 If this is zero, y_1 is a parameter. Otherwise it is a variable.
00154 \n
00155 \n
00156 \a arg[1] & 4
00157 \n
00158 If this is zero, y_2 is a parameter. Otherwise it is a variable.
00159 \n
00160 \n
00161 \a arg[1] & 8
00162 \n
00163 If this is zero, y_3 is a parameter. Otherwise it is a variable.
00164 \n
00165 \n
00166 \a arg[2 + j ] for j = 0, 1, 2, 3
00167 \n
00168 is the index corresponding to y_j.
00169 
00170 \param num_par
00171 is the total number of values in the vector \a parameter.
00172 
00173 \par Checked Assertions
00174 \li NumArg(CExpOp) == 6
00175 \li NumRes(CExpOp) == 1
00176 \li arg[0] < static_cast<size_t> ( CompareNe )
00177 \li arg[1] != 0; i.e., not all of y_0, y_1, y_2, y_3 are parameters.
00178 \li For j = 0, 1, 2, 3 if y_j is a parameter, arg[2+j] < num_par.
00179 \li For j = 0, 1, 2, 3 if y_j is a variable, arg[2+j] < iz.
00180 <!-- end sparse_conditional_exp_op -->
00181 */
00182 template <class Vector_set>
00183 inline void sparse_conditional_exp_op(
00184      size_t         i_z           ,
00185      const addr_t*  arg           , 
00186      size_t         num_par       )
00187 {    // This routine is only for documentation, it should never be used
00188      CPPAD_ASSERT_UNKNOWN( false );
00189 }
00190 
00191 /*!
00192 Compute forward mode Taylor coefficients for op = CExpOp.
00193 
00194 <!-- replace conditional_exp_op -->
00195 The C++ source code coresponding to this operation is
00196 \verbatim
00197      z = CondExpRel(y_0, y_1, y_2, y_3)
00198 \endverbatim
00199 where Rel is one of the following: Lt, Le, Eq, Ge, Gt. 
00200 
00201 \tparam Base
00202 base type for the operator; i.e., this operation was recorded
00203 using AD< \a Base > and computations by this routine are done using type 
00204 \a Base.
00205 
00206 \param i_z
00207 is the AD variable index corresponding to the variable z.
00208 
00209 \param arg
00210 \n
00211 \a arg[0]
00212 is static cast to size_t from the enum type
00213 \verbatim
00214      enum CompareOp {
00215           CompareLt, 
00216           CompareLe, 
00217           CompareEq, 
00218           CompareGe, 
00219           CompareGt, 
00220           CompareNe
00221      }
00222 \endverbatim
00223 for this operation.
00224 Note that arg[0] cannot be equal to CompareNe.
00225 \n
00226 \n
00227 \a arg[1] & 1
00228 \n
00229 If this is zero, y_0 is a parameter. Otherwise it is a variable.
00230 \n
00231 \n
00232 \a arg[1] & 2
00233 \n
00234 If this is zero, y_1 is a parameter. Otherwise it is a variable.
00235 \n
00236 \n
00237 \a arg[1] & 4
00238 \n
00239 If this is zero, y_2 is a parameter. Otherwise it is a variable.
00240 \n
00241 \n
00242 \a arg[1] & 8
00243 \n
00244 If this is zero, y_3 is a parameter. Otherwise it is a variable.
00245 \n
00246 \n
00247 \a arg[2 + j ] for j = 0, 1, 2, 3
00248 \n
00249 is the index corresponding to y_j.
00250 
00251 \param num_par
00252 is the total number of values in the vector \a parameter.
00253 
00254 \param parameter
00255 For j = 0, 1, 2, 3,
00256 if y_j is a parameter, \a parameter [ arg[2 + j] ] is its value.
00257 
00258 \param nc_taylor
00259 number of columns in the matrix containing the Taylor coefficients.
00260 
00261 \par Checked Assertions
00262 \li NumArg(CExpOp) == 6
00263 \li NumRes(CExpOp) == 1
00264 \li arg[0] < static_cast<size_t> ( CompareNe )
00265 \li arg[1] != 0; i.e., not all of y_0, y_1, y_2, y_3 are parameters.
00266 \li For j = 0, 1, 2, 3 if y_j is a parameter, arg[2+j] < num_par.
00267 \li For j = 0, 1, 2, 3 if y_j is a variable, arg[2+j] < iz.
00268 <!-- end conditional_exp_op -->
00269 
00270 \param p
00271 is the lowest order of the Taylor coefficient of z that we are computing.
00272 
00273 \param q
00274 is the highest order of the Taylor coefficient of z that we are computing.
00275 
00276 \param taylor
00277 \b Input:
00278 For j = 0, 1, 2, 3 and k = 0 , ... , q,
00279 if y_j is a variable then
00280 <code>taylor [ arg[2+j] * nc_taylor + k ]</code>
00281 is the k-th order Taylor coefficient corresponding to y_j.
00282 \n
00283 \b Input: <code>taylor [ i_z * nc_taylor + k ]</code> 
00284 for k = 0 , ... , p-1,
00285 is the k-th order Taylor coefficient corresponding to z.
00286 \n
00287 \b Output: <code>taylor [ i_z * nc_taylor + k ]</code>
00288 for k = p , ... , q, 
00289 is the k-th order Taylor coefficient corresponding to z. 
00290 
00291 */
00292 template <class Base>
00293 inline void forward_cond_op(
00294      size_t         p           ,
00295      size_t         q           ,
00296      size_t         i_z         ,
00297      const addr_t*  arg         , 
00298      size_t         num_par     ,
00299      const Base*    parameter   ,
00300      size_t         nc_taylor   ,
00301      Base*          taylor      )
00302 {    Base y_0, y_1, y_2, y_3;
00303      Base zero(0);
00304      Base* z = taylor + i_z * nc_taylor;
00305 
00306      CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < static_cast<size_t> (CompareNe) );
00307      CPPAD_ASSERT_UNKNOWN( NumArg(CExpOp) == 6 );
00308      CPPAD_ASSERT_UNKNOWN( NumRes(CExpOp) == 1 );
00309      CPPAD_ASSERT_UNKNOWN( arg[1] != 0 );
00310 
00311      if( arg[1] & 1 )
00312      {    CPPAD_ASSERT_UNKNOWN( size_t(arg[2]) < i_z );
00313           y_0 = taylor[ arg[2] * nc_taylor + 0 ];
00314      }
00315      else
00316      {    CPPAD_ASSERT_UNKNOWN( size_t(arg[2]) < num_par );
00317           y_0 = parameter[ arg[2] ];
00318      }
00319      if( arg[1] & 2 )
00320      {    CPPAD_ASSERT_UNKNOWN( size_t(arg[3]) < i_z );
00321           y_1 = taylor[ arg[3] * nc_taylor + 0 ];
00322      }
00323      else
00324      {    CPPAD_ASSERT_UNKNOWN( size_t(arg[3]) < num_par );
00325           y_1 = parameter[ arg[3] ];
00326      }
00327      if( p == 0 )
00328      {    if( arg[1] & 4 )
00329           {    CPPAD_ASSERT_UNKNOWN( size_t(arg[4]) < i_z );
00330                y_2 = taylor[ arg[4] * nc_taylor + 0 ];
00331           }
00332           else
00333           {    CPPAD_ASSERT_UNKNOWN( size_t(arg[4]) < num_par );
00334                y_2 = parameter[ arg[4] ];
00335           }
00336           if( arg[1] & 8 )
00337           {    CPPAD_ASSERT_UNKNOWN( size_t(arg[5]) < i_z );
00338                y_3 = taylor[ arg[5] * nc_taylor + 0 ];
00339           }
00340           else
00341           {    CPPAD_ASSERT_UNKNOWN( size_t(arg[5]) < num_par );
00342                y_3 = parameter[ arg[5] ];
00343           }
00344           z[0] = CondExpOp(
00345                CompareOp( arg[0] ),
00346                y_0,
00347                y_1,
00348                y_2,
00349                y_3
00350           );
00351           p++;
00352      }
00353      for(size_t d = p; d <= q; d++)
00354      {    if( arg[1] & 4 )
00355           {    CPPAD_ASSERT_UNKNOWN( size_t(arg[4]) < i_z );
00356                y_2 = taylor[ arg[4] * nc_taylor + d];
00357           }
00358           else y_2 = zero;
00359           if( arg[1] & 8 )
00360           {    CPPAD_ASSERT_UNKNOWN( size_t(arg[5]) < i_z );
00361                y_3 = taylor[ arg[5] * nc_taylor + d];
00362           }
00363           else y_3 = zero;
00364           z[d] = CondExpOp(
00365                CompareOp( arg[0] ),
00366                y_0,
00367                y_1,
00368                y_2,
00369                y_3
00370           );
00371      }
00372      return;
00373 }
00374 
00375 /*!
00376 Compute zero order forward mode Taylor coefficients for op = CExpOp.
00377 
00378 <!-- replace conditional_exp_op -->
00379 The C++ source code coresponding to this operation is
00380 \verbatim
00381      z = CondExpRel(y_0, y_1, y_2, y_3)
00382 \endverbatim
00383 where Rel is one of the following: Lt, Le, Eq, Ge, Gt. 
00384 
00385 \tparam Base
00386 base type for the operator; i.e., this operation was recorded
00387 using AD< \a Base > and computations by this routine are done using type 
00388 \a Base.
00389 
00390 \param i_z
00391 is the AD variable index corresponding to the variable z.
00392 
00393 \param arg
00394 \n
00395 \a arg[0]
00396 is static cast to size_t from the enum type
00397 \verbatim
00398      enum CompareOp {
00399           CompareLt, 
00400           CompareLe, 
00401           CompareEq, 
00402           CompareGe, 
00403           CompareGt, 
00404           CompareNe
00405      }
00406 \endverbatim
00407 for this operation.
00408 Note that arg[0] cannot be equal to CompareNe.
00409 \n
00410 \n
00411 \a arg[1] & 1
00412 \n
00413 If this is zero, y_0 is a parameter. Otherwise it is a variable.
00414 \n
00415 \n
00416 \a arg[1] & 2
00417 \n
00418 If this is zero, y_1 is a parameter. Otherwise it is a variable.
00419 \n
00420 \n
00421 \a arg[1] & 4
00422 \n
00423 If this is zero, y_2 is a parameter. Otherwise it is a variable.
00424 \n
00425 \n
00426 \a arg[1] & 8
00427 \n
00428 If this is zero, y_3 is a parameter. Otherwise it is a variable.
00429 \n
00430 \n
00431 \a arg[2 + j ] for j = 0, 1, 2, 3
00432 \n
00433 is the index corresponding to y_j.
00434 
00435 \param num_par
00436 is the total number of values in the vector \a parameter.
00437 
00438 \param parameter
00439 For j = 0, 1, 2, 3,
00440 if y_j is a parameter, \a parameter [ arg[2 + j] ] is its value.
00441 
00442 \param nc_taylor
00443 number of columns in the matrix containing the Taylor coefficients.
00444 
00445 \par Checked Assertions
00446 \li NumArg(CExpOp) == 6
00447 \li NumRes(CExpOp) == 1
00448 \li arg[0] < static_cast<size_t> ( CompareNe )
00449 \li arg[1] != 0; i.e., not all of y_0, y_1, y_2, y_3 are parameters.
00450 \li For j = 0, 1, 2, 3 if y_j is a parameter, arg[2+j] < num_par.
00451 \li For j = 0, 1, 2, 3 if y_j is a variable, arg[2+j] < iz.
00452 <!-- end conditional_exp_op -->
00453 
00454 \param taylor
00455 \b Input:
00456 For j = 0, 1, 2, 3,
00457 if y_j is a variable then
00458 \a taylor [ \a arg[2+j] * nc_taylor + 0 ]
00459 is the zero order Taylor coefficient corresponding to y_j.
00460 \n
00461 \b Output: \a taylor [ \a i_z * \a nc_taylor + 0 ] 
00462 is the zero order Taylor coefficient corresponding to z. 
00463 */
00464 template <class Base>
00465 inline void forward_cond_op_0(
00466      size_t         i_z         ,
00467      const addr_t*  arg         , 
00468      size_t         num_par     ,
00469      const Base*    parameter   ,
00470      size_t         nc_taylor   ,
00471      Base*          taylor      )
00472 {    Base y_0, y_1, y_2, y_3;
00473      Base* z;
00474 
00475      CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < static_cast<size_t> (CompareNe) );
00476      CPPAD_ASSERT_UNKNOWN( NumArg(CExpOp) == 6 );
00477      CPPAD_ASSERT_UNKNOWN( NumRes(CExpOp) == 1 );
00478      CPPAD_ASSERT_UNKNOWN( arg[1] != 0 );
00479 
00480      if( arg[1] & 1 )
00481      {    CPPAD_ASSERT_UNKNOWN( size_t(arg[2]) < i_z );
00482           y_0 = taylor[ arg[2] * nc_taylor + 0 ];
00483      }
00484      else
00485      {    CPPAD_ASSERT_UNKNOWN( size_t(arg[2]) < num_par );
00486           y_0 = parameter[ arg[2] ];
00487      }
00488      if( arg[1] & 2 )
00489      {    CPPAD_ASSERT_UNKNOWN( size_t(arg[3]) < i_z );
00490           y_1 = taylor[ arg[3] * nc_taylor + 0 ];
00491      }
00492      else
00493      {    CPPAD_ASSERT_UNKNOWN( size_t(arg[3]) < num_par );
00494           y_1 = parameter[ arg[3] ];
00495      }
00496      if( arg[1] & 4 )
00497      {    CPPAD_ASSERT_UNKNOWN( size_t(arg[4]) < i_z );
00498           y_2 = taylor[ arg[4] * nc_taylor + 0 ];
00499      }
00500      else
00501      {    CPPAD_ASSERT_UNKNOWN( size_t(arg[4]) < num_par );
00502           y_2 = parameter[ arg[4] ];
00503      }
00504      if( arg[1] & 8 )
00505      {    CPPAD_ASSERT_UNKNOWN( size_t(arg[5]) < i_z );
00506           y_3 = taylor[ arg[5] * nc_taylor + 0 ];
00507      }
00508      else
00509      {    CPPAD_ASSERT_UNKNOWN( size_t(arg[5]) < num_par );
00510           y_3 = parameter[ arg[5] ];
00511      }
00512      z = taylor + i_z * nc_taylor;
00513      z[0] = CondExpOp(
00514           CompareOp( arg[0] ),
00515           y_0,
00516           y_1,
00517           y_2,
00518           y_3
00519      );
00520      return;
00521 }
00522 
00523 /*!
00524 Compute reverse mode Taylor coefficients for op = CExpOp.
00525 
00526 This routine is given the partial derivatives of a function 
00527 G( z , y , x , w , ... )
00528 and it uses them to compute the partial derivatives of 
00529 \verbatim
00530      H( y , x , w , u , ... ) = G[ z(y) , y , x , w , u , ... ]
00531 \endverbatim
00532 where y above represents y_0, y_1, y_2, y_3.
00533 
00534 <!-- replace conditional_exp_op -->
00535 The C++ source code coresponding to this operation is
00536 \verbatim
00537      z = CondExpRel(y_0, y_1, y_2, y_3)
00538 \endverbatim
00539 where Rel is one of the following: Lt, Le, Eq, Ge, Gt. 
00540 
00541 \tparam Base
00542 base type for the operator; i.e., this operation was recorded
00543 using AD< \a Base > and computations by this routine are done using type 
00544 \a Base.
00545 
00546 \param i_z
00547 is the AD variable index corresponding to the variable z.
00548 
00549 \param arg
00550 \n
00551 \a arg[0]
00552 is static cast to size_t from the enum type
00553 \verbatim
00554      enum CompareOp {
00555           CompareLt, 
00556           CompareLe, 
00557           CompareEq, 
00558           CompareGe, 
00559           CompareGt, 
00560           CompareNe
00561      }
00562 \endverbatim
00563 for this operation.
00564 Note that arg[0] cannot be equal to CompareNe.
00565 \n
00566 \n
00567 \a arg[1] & 1
00568 \n
00569 If this is zero, y_0 is a parameter. Otherwise it is a variable.
00570 \n
00571 \n
00572 \a arg[1] & 2
00573 \n
00574 If this is zero, y_1 is a parameter. Otherwise it is a variable.
00575 \n
00576 \n
00577 \a arg[1] & 4
00578 \n
00579 If this is zero, y_2 is a parameter. Otherwise it is a variable.
00580 \n
00581 \n
00582 \a arg[1] & 8
00583 \n
00584 If this is zero, y_3 is a parameter. Otherwise it is a variable.
00585 \n
00586 \n
00587 \a arg[2 + j ] for j = 0, 1, 2, 3
00588 \n
00589 is the index corresponding to y_j.
00590 
00591 \param num_par
00592 is the total number of values in the vector \a parameter.
00593 
00594 \param parameter
00595 For j = 0, 1, 2, 3,
00596 if y_j is a parameter, \a parameter [ arg[2 + j] ] is its value.
00597 
00598 \param nc_taylor
00599 number of columns in the matrix containing the Taylor coefficients.
00600 
00601 \par Checked Assertions
00602 \li NumArg(CExpOp) == 6
00603 \li NumRes(CExpOp) == 1
00604 \li arg[0] < static_cast<size_t> ( CompareNe )
00605 \li arg[1] != 0; i.e., not all of y_0, y_1, y_2, y_3 are parameters.
00606 \li For j = 0, 1, 2, 3 if y_j is a parameter, arg[2+j] < num_par.
00607 \li For j = 0, 1, 2, 3 if y_j is a variable, arg[2+j] < iz.
00608 <!-- end conditional_exp_op -->
00609 
00610 \param d
00611 is the order of the Taylor coefficient of z that we are  computing.
00612 
00613 \param taylor
00614 \b Input:
00615 For j = 0, 1, 2, 3 and k = 0 , ... , \a d,
00616 if y_j is a variable then
00617 \a taylor [ \a arg[2+j] * nc_taylor + k ]
00618 is the k-th order Taylor coefficient corresponding to y_j.
00619 \n
00620 \a taylor [ \a i_z * \a nc_taylor + k ] 
00621 for k = 0 , ... , \a d
00622 is the k-th order Taylor coefficient corresponding to z.
00623 
00624 \param nc_partial
00625 number of columns in the matrix containing the Taylor coefficients.
00626 
00627 \param partial
00628 \b Input:
00629 For j = 0, 1, 2, 3 and k = 0 , ... , \a d,
00630 if y_j is a variable then
00631 \a partial [ \a arg[2+j] * nc_partial + k ]
00632 is the partial derivative of G( z , y , x , w , u , ... )
00633 with respect to the k-th order Taylor coefficient corresponding to y_j.
00634 \n
00635 \b Input: \a partial [ \a i_z * \a nc_taylor + k ] 
00636 for k = 0 , ... , \a d
00637 is the partial derivative of G( z , y , x , w , u , ... )
00638 with respect to the k-th order Taylor coefficient corresponding to z.
00639 \n
00640 \b Output:
00641 For j = 0, 1, 2, 3 and k = 0 , ... , \a d,
00642 if y_j is a variable then
00643 \a partial [ \a arg[2+j] * nc_partial + k ]
00644 is the partial derivative of H( y , x , w , u , ... )
00645 with respect to the k-th order Taylor coefficient corresponding to y_j.
00646 
00647 */
00648 template <class Base>
00649 inline void reverse_cond_op(
00650      size_t         d           ,
00651      size_t         i_z         ,
00652      const addr_t*  arg         , 
00653      size_t         num_par     ,
00654      const Base*    parameter   ,
00655      size_t         nc_taylor   ,
00656      const Base*    taylor      ,
00657      size_t         nc_partial  ,
00658      Base*          partial     )
00659 {    Base y_0, y_1;
00660      Base zero(0);
00661      Base* pz;
00662      Base* py_2;
00663      Base* py_3;
00664 
00665      CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < static_cast<size_t> (CompareNe) );
00666      CPPAD_ASSERT_UNKNOWN( NumArg(CExpOp) == 6 );
00667      CPPAD_ASSERT_UNKNOWN( NumRes(CExpOp) == 1 );
00668      CPPAD_ASSERT_UNKNOWN( arg[1] != 0 );
00669 
00670      pz = partial + i_z * nc_partial + 0;
00671      if( arg[1] & 1 )
00672      {    CPPAD_ASSERT_UNKNOWN( size_t(arg[2]) < i_z );
00673           y_0 = taylor[ arg[2] * nc_taylor + 0 ];
00674      }
00675      else
00676      {    CPPAD_ASSERT_UNKNOWN( size_t(arg[2]) < num_par );
00677           y_0 = parameter[ arg[2] ];
00678      }
00679      if( arg[1] & 2 )
00680      {    CPPAD_ASSERT_UNKNOWN( size_t(arg[3]) < i_z );
00681           y_1 = taylor[ arg[3] * nc_taylor + 0 ];
00682      }
00683      else
00684      {    CPPAD_ASSERT_UNKNOWN( size_t(arg[3]) < num_par );
00685           y_1 = parameter[ arg[3] ];
00686      }
00687      if( arg[1] & 4 )
00688      {    CPPAD_ASSERT_UNKNOWN( size_t(arg[4]) < i_z );
00689           py_2 = partial + arg[4] * nc_partial;
00690           size_t j = d + 1;
00691           while(j--)
00692           {    py_2[j] += CondExpOp(
00693                     CompareOp( arg[0] ),
00694                     y_0,
00695                     y_1,
00696                     pz[j],
00697                     zero
00698                );
00699           }
00700      }
00701      if( arg[1] & 8 )
00702      {    CPPAD_ASSERT_UNKNOWN( size_t(arg[5]) < i_z );
00703           py_3 = partial + arg[5] * nc_partial;
00704           size_t j = d + 1;
00705           while(j--)
00706           {    py_3[j] += CondExpOp(
00707                     CompareOp( arg[0] ),
00708                     y_0,
00709                     y_1,
00710                     zero,
00711                     pz[j]
00712                );
00713           }
00714      }
00715      return;
00716 }
00717 
00718 /*!
00719 Compute forward Jacobian sparsity patterns for op = CExpOp.
00720 
00721 <!-- replace sparse_conditional_exp_op -->
00722 The C++ source code coresponding to this operation is
00723 \verbatim
00724      z = CondExpRel(y_0, y_1, y_2, y_3)
00725 \endverbatim
00726 where Rel is one of the following: Lt, Le, Eq, Ge, Gt. 
00727 
00728 \tparam Vector_set
00729 is the type used for vectors of sets. It can be either
00730 \c sparse_pack, \c sparse_set, or \c sparse_list.
00731 
00732 \param i_z
00733 is the AD variable index corresponding to the variable z.
00734 
00735 \param arg
00736 \n
00737 \a arg[0]
00738 is static cast to size_t from the enum type
00739 \verbatim
00740      enum CompareOp {
00741           CompareLt, 
00742           CompareLe, 
00743           CompareEq, 
00744           CompareGe, 
00745           CompareGt, 
00746           CompareNe
00747      }
00748 \endverbatim
00749 for this operation.
00750 Note that arg[0] cannot be equal to CompareNe.
00751 \n
00752 \n
00753 \a arg[1] & 1
00754 \n
00755 If this is zero, y_0 is a parameter. Otherwise it is a variable.
00756 \n
00757 \n
00758 \a arg[1] & 2
00759 \n
00760 If this is zero, y_1 is a parameter. Otherwise it is a variable.
00761 \n
00762 \n
00763 \a arg[1] & 4
00764 \n
00765 If this is zero, y_2 is a parameter. Otherwise it is a variable.
00766 \n
00767 \n
00768 \a arg[1] & 8
00769 \n
00770 If this is zero, y_3 is a parameter. Otherwise it is a variable.
00771 \n
00772 \n
00773 \a arg[2 + j ] for j = 0, 1, 2, 3
00774 \n
00775 is the index corresponding to y_j.
00776 
00777 \param num_par
00778 is the total number of values in the vector \a parameter.
00779 
00780 \par Checked Assertions
00781 \li NumArg(CExpOp) == 6
00782 \li NumRes(CExpOp) == 1
00783 \li arg[0] < static_cast<size_t> ( CompareNe )
00784 \li arg[1] != 0; i.e., not all of y_0, y_1, y_2, y_3 are parameters.
00785 \li For j = 0, 1, 2, 3 if y_j is a parameter, arg[2+j] < num_par.
00786 \li For j = 0, 1, 2, 3 if y_j is a variable, arg[2+j] < iz.
00787 <!-- end sparse_conditional_exp_op -->
00788 
00789 \param sparsity
00790 \b Input:
00791 if y_2 is a variable, the set with index t is
00792 the sparsity pattern corresponding to y_2.
00793 This identifies which of the independent variables the variable y_2
00794 depends on.
00795 \n
00796 \b Input:
00797 if y_3 is a variable, the set with index t is
00798 the sparsity pattern corresponding to y_3.
00799 This identifies which of the independent variables the variable y_3
00800 depends on.
00801 \n
00802 \b Output: 
00803 The set with index T is
00804 the sparsity pattern corresponding to z.
00805 This identifies which of the independent variables the variable z
00806 depends on. 
00807 */
00808 template <class Vector_set>
00809 inline void forward_sparse_jacobian_cond_op(
00810      size_t             i_z           ,
00811      const addr_t*      arg           , 
00812      size_t             num_par       ,
00813      Vector_set&        sparsity      )
00814 {
00815      CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < static_cast<size_t> (CompareNe) );
00816      CPPAD_ASSERT_UNKNOWN( NumArg(CExpOp) == 6 );
00817      CPPAD_ASSERT_UNKNOWN( NumRes(CExpOp) == 1 );
00818      CPPAD_ASSERT_UNKNOWN( arg[1] != 0 );
00819 
00820 # ifndef NDEBUG
00821      if( arg[1] & 1 )
00822      {    CPPAD_ASSERT_UNKNOWN( size_t(arg[2]) < i_z );
00823      }
00824      else
00825      {    CPPAD_ASSERT_UNKNOWN( size_t(arg[2]) < num_par );
00826      }
00827      if( arg[1] & 2 )
00828      {    CPPAD_ASSERT_UNKNOWN( size_t(arg[3]) < i_z );
00829      }
00830      else
00831      {    CPPAD_ASSERT_UNKNOWN( size_t(arg[3]) < num_par );
00832      }
00833 # endif
00834      if( arg[1] & 4 )
00835      {    CPPAD_ASSERT_UNKNOWN( size_t(arg[4]) < i_z );
00836           if( arg[1] & 8 )
00837           {    CPPAD_ASSERT_UNKNOWN( size_t(arg[5]) < i_z );
00838                sparsity.binary_union(i_z, arg[4], arg[5], sparsity);
00839           }
00840           else
00841           {    CPPAD_ASSERT_UNKNOWN( size_t(arg[5]) < num_par );
00842                sparsity.assignment(i_z, arg[4], sparsity);
00843           }
00844      }    
00845      else
00846      {    CPPAD_ASSERT_UNKNOWN( size_t(arg[4]) < num_par );
00847           if( arg[1] & 8 )
00848           {    CPPAD_ASSERT_UNKNOWN( size_t(arg[5]) < i_z );
00849                sparsity.assignment(i_z, arg[5], sparsity);
00850           }
00851           else
00852           {    CPPAD_ASSERT_UNKNOWN( size_t(arg[5]) < num_par );
00853                sparsity.clear(i_z);
00854           }
00855      }
00856      return;
00857 }
00858 
00859 /*!
00860 Compute reverse Jacobian sparsity patterns for op = CExpOp.
00861 
00862 This routine is given the sparsity patterns
00863 for a function G(z, y, x, ... )
00864 and it uses them to compute the sparsity patterns for 
00865 \verbatim
00866      H( y, x, w , u , ... ) = G[ z(x,y) , y , x , w , u , ... ]
00867 \endverbatim
00868 where y represents the combination of y_0, y_1, y_2, and y_3.
00869 
00870 <!-- replace sparse_conditional_exp_op -->
00871 The C++ source code coresponding to this operation is
00872 \verbatim
00873      z = CondExpRel(y_0, y_1, y_2, y_3)
00874 \endverbatim
00875 where Rel is one of the following: Lt, Le, Eq, Ge, Gt. 
00876 
00877 \tparam Vector_set
00878 is the type used for vectors of sets. It can be either
00879 \c sparse_pack, \c sparse_set, or \c sparse_list.
00880 
00881 \param i_z
00882 is the AD variable index corresponding to the variable z.
00883 
00884 \param arg
00885 \n
00886 \a arg[0]
00887 is static cast to size_t from the enum type
00888 \verbatim
00889      enum CompareOp {
00890           CompareLt, 
00891           CompareLe, 
00892           CompareEq, 
00893           CompareGe, 
00894           CompareGt, 
00895           CompareNe
00896      }
00897 \endverbatim
00898 for this operation.
00899 Note that arg[0] cannot be equal to CompareNe.
00900 \n
00901 \n
00902 \a arg[1] & 1
00903 \n
00904 If this is zero, y_0 is a parameter. Otherwise it is a variable.
00905 \n
00906 \n
00907 \a arg[1] & 2
00908 \n
00909 If this is zero, y_1 is a parameter. Otherwise it is a variable.
00910 \n
00911 \n
00912 \a arg[1] & 4
00913 \n
00914 If this is zero, y_2 is a parameter. Otherwise it is a variable.
00915 \n
00916 \n
00917 \a arg[1] & 8
00918 \n
00919 If this is zero, y_3 is a parameter. Otherwise it is a variable.
00920 \n
00921 \n
00922 \a arg[2 + j ] for j = 0, 1, 2, 3
00923 \n
00924 is the index corresponding to y_j.
00925 
00926 \param num_par
00927 is the total number of values in the vector \a parameter.
00928 
00929 \par Checked Assertions
00930 \li NumArg(CExpOp) == 6
00931 \li NumRes(CExpOp) == 1
00932 \li arg[0] < static_cast<size_t> ( CompareNe )
00933 \li arg[1] != 0; i.e., not all of y_0, y_1, y_2, y_3 are parameters.
00934 \li For j = 0, 1, 2, 3 if y_j is a parameter, arg[2+j] < num_par.
00935 \li For j = 0, 1, 2, 3 if y_j is a variable, arg[2+j] < iz.
00936 <!-- end sparse_conditional_exp_op -->
00937 
00938 \param nz_compare
00939 Are the derivatives with respect to left and right of the expression below
00940 considered to be non-zero:
00941 \code
00942      CondExpRel(left, right, if_true, if_false)
00943 \endcode
00944 This is used by the optimizer to obtain the correct dependency relations.
00945 
00946 
00947 \param sparsity
00948 if y_2 is a variable, the set with index t is
00949 the sparsity pattern corresponding to y_2.
00950 This identifies which of the dependent variables depend on the variable y_2.
00951 On input, this pattern corresponds to the function G.
00952 On ouput, it corresponds to the function H.
00953 \n
00954 \n
00955 if y_3 is a variable, the set with index t is
00956 the sparsity pattern corresponding to y_3.
00957 This identifies which of the dependent variables depeond on the variable y_3.
00958 On input, this pattern corresponds to the function G.
00959 On ouput, it corresponds to the function H.
00960 \n
00961 \b Output: 
00962 The set with index T is
00963 the sparsity pattern corresponding to z.
00964 This identifies which of the dependent variables depend on the variable z.
00965 On input and output, this pattern corresponds to the function G.
00966 */
00967 template <class Vector_set>
00968 inline void reverse_sparse_jacobian_cond_op(
00969      bool                nz_compare    ,
00970      size_t              i_z           ,
00971      const addr_t*       arg           , 
00972      size_t              num_par       ,
00973      Vector_set&         sparsity      )
00974 {    
00975      CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < static_cast<size_t> (CompareNe) );
00976      CPPAD_ASSERT_UNKNOWN( NumArg(CExpOp) == 6 );
00977      CPPAD_ASSERT_UNKNOWN( NumRes(CExpOp) == 1 );
00978      CPPAD_ASSERT_UNKNOWN( arg[1] != 0 );
00979 
00980 # ifndef NDEBUG
00981      if( arg[1] & 1 )
00982      {    CPPAD_ASSERT_UNKNOWN( size_t(arg[2]) < i_z );
00983      }
00984      else
00985      {    CPPAD_ASSERT_UNKNOWN( size_t(arg[2]) < num_par );
00986      }
00987      if( arg[1] & 2 )
00988      {    CPPAD_ASSERT_UNKNOWN( size_t(arg[3]) < i_z );
00989      }
00990      else
00991      {    CPPAD_ASSERT_UNKNOWN( size_t(arg[3]) < num_par );
00992      }
00993      if( ! ( arg[1] & 4 ) )
00994      {    CPPAD_ASSERT_UNKNOWN( size_t(arg[4]) < num_par );
00995      }
00996      if( ! ( arg[1] & 8 ) )
00997      {    CPPAD_ASSERT_UNKNOWN( size_t(arg[5]) < num_par );
00998      }
00999 # endif
01000      if( nz_compare )
01001      {    if( arg[1] & 1 )
01002           {    CPPAD_ASSERT_UNKNOWN( size_t(arg[2]) < i_z );
01003                sparsity.binary_union(arg[2], arg[2], i_z, sparsity);
01004           }
01005           if( arg[1] & 2 )
01006           {    CPPAD_ASSERT_UNKNOWN( size_t(arg[3]) < i_z );
01007                sparsity.binary_union(arg[3], arg[3], i_z, sparsity);
01008           }
01009      }
01010      // --------------------------------------------------------------------
01011      if( arg[1] & 4 )
01012      {    CPPAD_ASSERT_UNKNOWN( size_t(arg[4]) < i_z );
01013           sparsity.binary_union(arg[4], arg[4], i_z, sparsity);
01014      }
01015      if( arg[1] & 8 )
01016      {    CPPAD_ASSERT_UNKNOWN( size_t(arg[5]) < i_z );
01017           sparsity.binary_union(arg[5], arg[5], i_z, sparsity);
01018      }
01019      return;
01020 }
01021 
01022 /*!
01023 Compute reverse Hessian sparsity patterns for op = CExpOp.
01024 
01025 This routine is given the sparsity patterns
01026 for a function G(z, y, x, ... )
01027 and it uses them to compute the sparsity patterns for 
01028 \verbatim
01029      H( y, x, w , u , ... ) = G[ z(x,y) , y , x , w , u , ... ]
01030 \endverbatim
01031 where y represents the combination of y_0, y_1, y_2, and y_3.
01032 
01033 <!-- replace sparse_conditional_exp_op -->
01034 The C++ source code coresponding to this operation is
01035 \verbatim
01036      z = CondExpRel(y_0, y_1, y_2, y_3)
01037 \endverbatim
01038 where Rel is one of the following: Lt, Le, Eq, Ge, Gt. 
01039 
01040 \tparam Vector_set
01041 is the type used for vectors of sets. It can be either
01042 \c sparse_pack, \c sparse_set, or \c sparse_list.
01043 
01044 \param i_z
01045 is the AD variable index corresponding to the variable z.
01046 
01047 \param arg
01048 \n
01049 \a arg[0]
01050 is static cast to size_t from the enum type
01051 \verbatim
01052      enum CompareOp {
01053           CompareLt, 
01054           CompareLe, 
01055           CompareEq, 
01056           CompareGe, 
01057           CompareGt, 
01058           CompareNe
01059      }
01060 \endverbatim
01061 for this operation.
01062 Note that arg[0] cannot be equal to CompareNe.
01063 \n
01064 \n
01065 \a arg[1] & 1
01066 \n
01067 If this is zero, y_0 is a parameter. Otherwise it is a variable.
01068 \n
01069 \n
01070 \a arg[1] & 2
01071 \n
01072 If this is zero, y_1 is a parameter. Otherwise it is a variable.
01073 \n
01074 \n
01075 \a arg[1] & 4
01076 \n
01077 If this is zero, y_2 is a parameter. Otherwise it is a variable.
01078 \n
01079 \n
01080 \a arg[1] & 8
01081 \n
01082 If this is zero, y_3 is a parameter. Otherwise it is a variable.
01083 \n
01084 \n
01085 \a arg[2 + j ] for j = 0, 1, 2, 3
01086 \n
01087 is the index corresponding to y_j.
01088 
01089 \param num_par
01090 is the total number of values in the vector \a parameter.
01091 
01092 \par Checked Assertions
01093 \li NumArg(CExpOp) == 6
01094 \li NumRes(CExpOp) == 1
01095 \li arg[0] < static_cast<size_t> ( CompareNe )
01096 \li arg[1] != 0; i.e., not all of y_0, y_1, y_2, y_3 are parameters.
01097 \li For j = 0, 1, 2, 3 if y_j is a parameter, arg[2+j] < num_par.
01098 \li For j = 0, 1, 2, 3 if y_j is a variable, arg[2+j] < iz.
01099 <!-- end sparse_conditional_exp_op -->
01100 
01101 
01102 \param jac_reverse
01103 \a jac_reverse[i_z] 
01104 is false (true) if the Jacobian of G with respect to z is always zero 
01105 (may be non-zero).
01106 \n
01107 \n
01108 \a jac_reverse[ arg[4] ] 
01109 If y_2 is a variable,
01110 \a jac_reverse[ arg[4] ] 
01111 is false (true) if the Jacobian with respect to y_2 is always zero 
01112 (may be non-zero).
01113 On input, it corresponds to the function G,
01114 and on output it corresponds to the function H.
01115 \n
01116 \n
01117 \a jac_reverse[ arg[5] ] 
01118 If y_3 is a variable,
01119 \a jac_reverse[ arg[5] ] 
01120 is false (true) if the Jacobian with respect to y_3 is always zero 
01121 (may be non-zero).
01122 On input, it corresponds to the function G,
01123 and on output it corresponds to the function H.
01124 
01125 \param hes_sparsity
01126 The set with index \a i_z in \a hes_sparsity 
01127 is the Hessian sparsity pattern for the function G
01128 where one of the partials is with respect to z.
01129 \n
01130 \n
01131 If y_2 is a variable,
01132 the set with index \a arg[4] in \a hes_sparsity 
01133 is the Hessian sparsity pattern 
01134 where one of the partials is with respect to y_2.
01135 On input, this pattern corresponds to the function G.
01136 On output, this pattern corresponds to the function H.
01137 \n
01138 \n
01139 If y_3 is a variable,
01140 the set with index \a arg[5] in \a hes_sparsity 
01141 is the Hessian sparsity pattern 
01142 where one of the partials is with respect to y_3.
01143 On input, this pattern corresponds to the function G.
01144 On output, this pattern corresponds to the function H.
01145 */
01146 template <class Vector_set>
01147 inline void reverse_sparse_hessian_cond_op(
01148      size_t               i_z           ,
01149      const addr_t*        arg           , 
01150      size_t               num_par       ,
01151      bool*                jac_reverse   ,
01152      Vector_set&          hes_sparsity  )
01153 {    
01154 
01155      CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < static_cast<size_t> (CompareNe) );
01156      CPPAD_ASSERT_UNKNOWN( NumArg(CExpOp) == 6 );
01157      CPPAD_ASSERT_UNKNOWN( NumRes(CExpOp) == 1 );
01158      CPPAD_ASSERT_UNKNOWN( arg[1] != 0 );
01159 
01160 # ifndef NDEBUG
01161      if( arg[1] & 1 )
01162      {    CPPAD_ASSERT_UNKNOWN( size_t(arg[2]) < i_z );
01163      }
01164      else
01165      {    CPPAD_ASSERT_UNKNOWN( size_t(arg[2]) < num_par );
01166      }
01167      if( arg[1] & 2 )
01168      {    CPPAD_ASSERT_UNKNOWN( size_t(arg[3]) < i_z );
01169      }
01170      else
01171      {    CPPAD_ASSERT_UNKNOWN( size_t(arg[3]) < num_par );
01172      }
01173      if( ! ( arg[1] & 4 ) )
01174      {    CPPAD_ASSERT_UNKNOWN( size_t(arg[4]) < num_par );
01175      }
01176      if( ! ( arg[1] & 8 ) )
01177      {    CPPAD_ASSERT_UNKNOWN( size_t(arg[5]) < num_par );
01178      }
01179 # endif
01180      if( arg[1] & 4 )
01181      {    CPPAD_ASSERT_UNKNOWN( size_t(arg[4]) < i_z );
01182 
01183           hes_sparsity.binary_union(arg[4], arg[4], i_z, hes_sparsity);
01184           jac_reverse[ arg[4] ] |= jac_reverse[i_z];
01185      }
01186      if( arg[1] & 8 )
01187      {    CPPAD_ASSERT_UNKNOWN( size_t(arg[5]) < i_z );
01188 
01189           hes_sparsity.binary_union(arg[5], arg[5], i_z, hes_sparsity);
01190           jac_reverse[ arg[5] ] |= jac_reverse[i_z];
01191      }
01192      return;
01193 }
01194 
01195 } // END_CPPAD_NAMESPACE
01196 # endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines