CppAD: A C++ Algorithmic Differentiation Package  20130918
load_op.hpp
Go to the documentation of this file.
00001 /* $Id$ */
00002 # ifndef CPPAD_LOAD_OP_INCLUDED
00003 # define CPPAD_LOAD_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 load_op.hpp
00020 Setting a variable so that it corresponds to current value of a VecAD element.
00021 */
00022 
00023 /*!
00024 Shared documentation for zero order forward mode implementation of 
00025 op = LdpOp or LdvOp (not called).
00026 
00027 The C++ source code corresponding to this operation is
00028 \verbatim
00029      z = v[x]
00030 \endverbatim
00031 where v is a VecAD<Base> vector and x is an AD<Base> index. 
00032 We define the index corresponding to v[x] by
00033 \verbatim
00034      i_v_x = index_by_ind[ arg[0] + i_vec ]
00035 \endverbatim
00036 where i_vec is defined under the heading arg[1] below:
00037 
00038 \tparam Base
00039 base type for the operator; i.e., this operation was recorded
00040 using AD<Base> and computations by this routine are done using type Base.
00041 
00042 \param play
00043 is the tape that this operation appears in.
00044 This is for error detection and not used when NDEBUG is defined.
00045 
00046 \param i_z
00047 is the AD variable index corresponding to the variable z.
00048 
00049 \param arg
00050 \n
00051 arg[0]
00052 is the offset of this VecAD vector relative to the beginning 
00053 of the isvar_by_ind and index)_by_ind arrays.
00054 \n
00055 \n 
00056 arg[1] 
00057 \n
00058 If this is the LdpOp operation (if x is a parameter),
00059 i_vec is defined by
00060 \verbatim
00061      i_vec = arg[1]
00062 \endverbatim
00063 If this is the LdvOp operation (if x is a variable), 
00064 i_vec is defined by
00065 \verbatim
00066      i_vec = floor( taylor[ arg[1] * nc_taylor + 0 ] )
00067 \endverbatim
00068 where floor(c) is the greatest integer less that or equal c.
00069 \n
00070 \n
00071 arg[2]
00072 Is the index of this vecad load instruction in the
00073 var_by_load_op array.
00074 
00075 \param parameter
00076 If v[x] is a parameter, <code>parameter[ i_v_x ]</code> is its value.
00077 This vector has size play->num_par_rec().
00078 
00079 \param nc_taylor
00080 number of columns in the matrix containing the Taylor coefficients.
00081 
00082 \param taylor
00083 \n
00084 Input
00085 \n
00086 In LdvOp case, <code>taylor[ arg[1] * nc_taylor + 0 ]</code>
00087 is used to compute the index in the definition of i_vec above.
00088 If v[x] is a variable, <code>taylor[ i_v_x * nc_taylor + 0 ]</code>
00089 is the zero order Taylor coefficient for v[x].
00090 \n
00091 \n
00092 Output
00093 \n
00094 <code>taylor[ i_z * nc_taylor + 0 ]</code>
00095 is set to the zero order Taylor coefficient for the variable z.
00096 
00097 \param isvar_by_ind
00098 If <code>isvar_by_ind[ arg[0] + i_vec ] </code> is true,
00099 v[x] is a variable.  Otherwise it is a parameter.
00100 This vector has size play->num_vec_ind_rec().
00101 
00102 \param index_by_ind
00103 <code>index_by_ind[ arg[0] - 1 ]</code> 
00104 is the number of elements in the user vector containing this element.
00105 <code>index_by_ind[ arg[0] + i_vec ]</code> is the variable or 
00106 parameter index for this element,
00107 This array has size play->num_vec_ind_rec().
00108 
00109 \param var_by_load_op
00110 is a vector with size play->num_load_op_rec().
00111 The input value of its elements does not matter.
00112 Upon return,  it contains the variable index corresponding to each load 
00113 instruction.
00114 In the case where the index is zero,
00115 the instruction corresponds to a parameter (not variable).
00116 This array has size play->num_load_op_rec().
00117 
00118 \par Check User Errors
00119 \li In the LdvOp case check that the index is with in range; i.e.
00120 <code>i_vec < index_by_ind[ arg[0] - 1 ]</code>. 
00121 Note that, if x is a parameter, 
00122 the corresponding vector index and it does not change.
00123 In this case, the error above should be detected during tape recording.
00124 */
00125 template <class Base>
00126 inline void forward_load_op_0(
00127      player<Base>*  play        ,
00128      size_t         i_z         ,
00129      const addr_t*  arg         , 
00130      const Base*    parameter   ,
00131      size_t         nc_taylor   ,
00132      Base*          taylor      ,
00133      bool*          isvar_by_ind   ,
00134      size_t*        index_by_ind   ,
00135      addr_t*        var_by_load_op )
00136 {
00137      // This routine is only for documentaiton, it should not be used
00138      CPPAD_ASSERT_UNKNOWN( false );
00139 }
00140 /*!
00141 Shared documentation for sparsity operations corresponding to 
00142 op = LdpOp or LdvOp (not called).
00143 
00144 <!-- define sparse_load_op -->
00145 The C++ source code corresponding to this operation is
00146 \verbatim
00147      z = v[x]
00148 \endverbatim
00149 where v is a VecAD<Base> vector and x is an AD<Base> index. 
00150 
00151 \tparam Vector_set
00152 is the type used for vectors of sets. It can be either
00153 \c sparse_pack, \c sparse_set, or \c sparse_list.
00154 
00155 \param op
00156 is the code corresponding to this operator; i.e., LdpOp or LdvOp
00157 (only used for error checking).
00158 
00159 \param i_z
00160 is the AD variable index corresponding to the variable z; i.e.,
00161 the set with index \a i_z in \a var_sparsity is the sparsity pattern
00162 correpsonding to z.
00163 
00164 \param arg
00165 \n
00166 \a arg[0]
00167 is the offset corresponding to this VecAD vector in the VecAD combined array.
00168 
00169 \param num_combined
00170 is the total number of elements in the VecAD combinded array.
00171 
00172 \param combined
00173 is the VecAD combined array.
00174 \n
00175 \n
00176 \a combined[ \a arg[0] - 1 ]
00177 is the index of the set corresponding to the vector v  in \a vecad_sparsity.
00178 We use the notation i_v for this value; i.e.,
00179 \verbatim
00180      i_v = combined[ \a arg[0] - 1 ]
00181 \endverbatim
00182 
00183 \param var_sparsity
00184 The set with index \a i_z in \a var_sparsity is the sparsity pattern for z.
00185 This is an output for forward mode operations,
00186 and an input for reverse mode operations.
00187 
00188 \param vecad_sparsity
00189 The set with index \a i_v is the sparsity pattern for the vector v.
00190 This is an input for forward mode operations.
00191 For reverse mode operations,
00192 the sparsity pattern for z is added to the sparsity pattern for v.
00193 
00194 \par Checked Assertions 
00195 \li NumArg(op) == 3
00196 \li NumRes(op) == 1
00197 \li 0         <  \a arg[0]
00198 \li \a arg[0] < \a num_combined
00199 \li i_v       < \a vecad_sparsity.n_set()
00200 <!-- end sparse_load_op -->
00201 */
00202 template <class Vector_set>
00203 inline void sparse_load_op(
00204      OpCode              op             ,
00205      size_t              i_z            ,
00206      const addr_t*        arg           , 
00207      size_t              num_combined   ,
00208      const size_t*       combined       ,
00209      Vector_set&         var_sparsity   ,
00210      Vector_set&         vecad_sparsity )
00211 {
00212      // This routine is only for documentaiton, it should not be used
00213      CPPAD_ASSERT_UNKNOWN( false );
00214 }
00215 
00216 
00217 /*!
00218 Zero order forward mode implementation of op = LdpOp.
00219 
00220 \copydetails forward_load_op_0
00221 */
00222 template <class Base>
00223 inline void forward_load_p_op_0(
00224      player<Base>*  play        ,
00225      size_t         i_z         ,
00226      const addr_t*  arg         , 
00227      const Base*    parameter   ,
00228      size_t         nc_taylor   ,
00229      Base*          taylor      ,
00230      bool*          isvar_by_ind   ,
00231      size_t*        index_by_ind   ,
00232      addr_t*        var_by_load_op )
00233 {    CPPAD_ASSERT_UNKNOWN( NumArg(LdpOp) == 3 );
00234      CPPAD_ASSERT_UNKNOWN( NumRes(LdpOp) == 1 );
00235      CPPAD_ASSERT_UNKNOWN( 0 < arg[0] );
00236      CPPAD_ASSERT_UNKNOWN( arg[2] < play->num_load_op_rec() );
00237 
00238      // Because the index is a parameter, this indexing error should be
00239      // caught and reported to the user at an when the tape is recording.
00240      size_t i_vec = arg[1];
00241      CPPAD_ASSERT_UNKNOWN( i_vec < index_by_ind[ arg[0] - 1 ] );
00242      CPPAD_ASSERT_UNKNOWN( arg[0] + i_vec < play->num_vec_ind_rec() );
00243 
00244      size_t i_v_x  = index_by_ind[ arg[0] + i_vec ];
00245      Base* z       = taylor + i_z * nc_taylor;
00246      if( isvar_by_ind[ arg[0] + i_vec ]  )
00247      {    CPPAD_ASSERT_UNKNOWN( i_v_x < i_z );
00248           var_by_load_op[ arg[2] ] = i_v_x;
00249           Base* v_x = taylor + i_v_x * nc_taylor;
00250           z[0]      = v_x[0];
00251      }
00252      else
00253      {    CPPAD_ASSERT_UNKNOWN( i_v_x < play->num_par_rec()  );
00254           var_by_load_op[ arg[2] ] = 0;
00255           Base v_x  = parameter[i_v_x];
00256           z[0]      = v_x;
00257      }
00258 }
00259 
00260 /*!
00261 Zero order forward mode implementation of op = LdvOp.
00262 
00263 \copydetails forward_load_op_0
00264 */
00265 template <class Base>
00266 inline void forward_load_v_op_0(
00267      player<Base>*  play        ,
00268      size_t         i_z         ,
00269      const addr_t*  arg         , 
00270      const Base*    parameter   ,
00271      size_t         nc_taylor   ,
00272      Base*          taylor      ,
00273      bool*          isvar_by_ind   ,
00274      size_t*        index_by_ind   ,
00275      addr_t*        var_by_load_op )
00276 {    CPPAD_ASSERT_UNKNOWN( NumArg(LdvOp) == 3 );
00277      CPPAD_ASSERT_UNKNOWN( NumRes(LdvOp) == 1 );
00278      CPPAD_ASSERT_UNKNOWN( 0 < arg[0] );
00279      CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) < i_z );
00280      CPPAD_ASSERT_UNKNOWN( arg[2] < play->num_load_op_rec() );
00281 
00282      size_t i_vec = Integer( taylor[ arg[1] * nc_taylor + 0 ] );
00283      CPPAD_ASSERT_KNOWN( 
00284           i_vec < index_by_ind[ arg[0] - 1 ] ,
00285           "VecAD: index during zero order forward sweep is out of range"
00286      );
00287      CPPAD_ASSERT_UNKNOWN( arg[0] + i_vec < play->num_vec_ind_rec() );
00288 
00289      size_t i_v_x  = index_by_ind[ arg[0] + i_vec ];   
00290      Base* z       = taylor + i_z * nc_taylor;
00291      if( isvar_by_ind[ arg[0] + i_vec ]  )
00292      {    CPPAD_ASSERT_UNKNOWN( i_v_x < i_z );
00293           var_by_load_op[ arg[2] ] = i_v_x;
00294           Base* v_x = taylor + i_v_x * nc_taylor;
00295           z[0]      = v_x[0];
00296      }
00297      else
00298      {    CPPAD_ASSERT_UNKNOWN( i_v_x < play->num_par_rec() );
00299           var_by_load_op[ arg[2] ] = 0;
00300           Base v_x  = parameter[i_v_x];
00301           z[0]      = v_x;
00302      }
00303 }
00304 
00305 /*!
00306 Forward mode, except for zero order, for op = LdpOp or op = LdvOp
00307 
00308 The C++ source code corresponding to this operation is
00309 \verbatim
00310      z = v[x]
00311 \endverbatim
00312 where v is a VecAD<Base> vector and x is an AD<Base> or Base index. 
00313 
00314 \tparam Base
00315 base type for the operator; i.e., this operation was recorded
00316 using AD<Base> and computations by this routine are done using type Base.
00317 
00318 \param op
00319 is the code corresponding to this operator; i.e., LdpOp or LdvOp
00320 (only used for error checking).
00321 
00322 \param p
00323 is the lowest order of the Taylor coefficient that we are computing.
00324 
00325 \param q
00326 is the highest order of the Taylor coefficient that we are computing.
00327 
00328 \param i_z
00329 is the AD variable index corresponding to the variable z.
00330 
00331 \param arg
00332 arg[2]
00333 Is the index of this vecad load instruction in the
00334 var_by_load_op array.
00335 
00336 \param nc_taylor
00337 number of columns in the matrix containing the Taylor coefficients.
00338 
00339 \param taylor
00340 \n
00341 Input
00342 \n
00343 If v[x] is a variable, <code>taylor[ arg[2] * nc_taylor + k ]</code>
00344 for k = 0 , ... , q,
00345 is the k-order Taylor coefficient corresponding to v[x].
00346 \n
00347 \n
00348 Output
00349 \n
00350 <code>taylor[ i_z * nc_taylor + d ]</code>
00351 for k = p , ... , q,
00352 is set to the k-order Taylor coefficient for the variable z.
00353 
00354 \param var_by_load_op
00355 is a vector with size play->num_load_op_rec().
00356 It contains the variable index corresponding to each load instruction.
00357 In the case where the index is zero,
00358 the instruction corresponds to a parameter (not variable).
00359 */
00360 template <class Base>
00361 inline void forward_load_op(
00362      OpCode         op          ,
00363      size_t         p           ,
00364      size_t         q           ,
00365      size_t         i_z         ,
00366      const addr_t*  arg         , 
00367      size_t         nc_taylor   ,
00368      Base*          taylor      ,
00369      const addr_t*        var_by_load_op )
00370 {    size_t i_load = size_t( var_by_load_op[ arg[2] ] );
00371 
00372      CPPAD_ASSERT_UNKNOWN( NumArg(op) == 3 );
00373      CPPAD_ASSERT_UNKNOWN( NumRes(op) == 1 );
00374      CPPAD_ASSERT_UNKNOWN( q < nc_taylor );
00375      CPPAD_ASSERT_UNKNOWN( 0 < p && p <= q );
00376      CPPAD_ASSERT_UNKNOWN( i_load < i_z );
00377 
00378      Base* z      = taylor + i_z * nc_taylor;
00379      if( i_load > 0 )
00380      {    Base* v_x = taylor + i_load * nc_taylor;
00381           for(size_t d = p; d <= q; d++)
00382                z[d] = v_x[d];
00383      }
00384      else
00385      {    for(size_t d = p; d <= q; d++)
00386                z[d] = Base(0);
00387      }
00388 }
00389 
00390 /*!
00391 Reverse mode for op = LdpOp or LdvOp.
00392 
00393 The C++ source code corresponding to this operation is
00394 \verbatim
00395      z = y[x]
00396 \endverbatim
00397 where y is a VecAD<Base> vector and x is an AD<Base> or Base index. 
00398 
00399 This routine is given the partial derivatives of a function 
00400 G(z , y[x] , w , u ... )
00401 and it uses them to compute the partial derivatives of 
00402 \verbatim
00403      H( y[x] , w , u , ... ) = G[ z( y[x] ) , y[x] , w , u , ... ]
00404 \endverbatim
00405 
00406 \tparam Base
00407 base type for the operator; i.e., this operation was recorded
00408 using AD< \a Base > and computations by this routine are done using type 
00409 \a Base.
00410 
00411 \param op
00412 is the code corresponding to this operator; i.e., LdpOp or LdvOp
00413 (only used for error checking).
00414 
00415 \param d
00416 highest order the Taylor coefficient that we are computing the partial
00417 derivative with respect to.
00418 
00419 \param i_z
00420 is the AD variable index corresponding to the variable z.
00421 
00422 \param arg
00423 \a arg[2]
00424 Is the index of this vecad load instruction in the
00425 var_by_load_op array.
00426 
00427 \param nc_taylor
00428 number of columns in the matrix containing the Taylor coefficients
00429 (not used).
00430 
00431 \param taylor
00432 matrix of Taylor coefficients (not used).
00433 
00434 \param nc_partial
00435 number of colums in the matrix containing all the partial derivatives
00436 (not used if \a arg[2] is zero).
00437 
00438 \param partial
00439 If \a arg[2] is zero, y[x] is a parameter
00440 and no values need to be modified; i.e., \a partial is not used.
00441 Otherwise, y[x] is a variable and:
00442 \n
00443 \n
00444 \a partial [ \a i_z * \a nc_partial + k ] 
00445 for k = 0 , ... , \a d
00446 is the partial derivative of G
00447 with respect to the k-th order Taylor coefficient for z.
00448 \n
00449 \n
00450 If \a arg[2] is not zero,
00451 \a partial [ \a arg[2] * \a nc_partial + k ]
00452 for k = 0 , ... , \a d
00453 is the partial derivative with respect to 
00454 the k-th order Taylor coefficient for x.
00455 On input, it corresponds to the function G,
00456 and on output it corresponds to the the function H. 
00457 
00458 \param var_by_load_op
00459 is a vector with size play->num_load_op_rec().
00460 It contains the variable index corresponding to each load instruction.
00461 In the case where the index is zero,
00462 the instruction corresponds to a parameter (not variable).
00463 
00464 \par Checked Assertions 
00465 \li NumArg(op) == 3
00466 \li NumRes(op) == 1
00467 \li d < nc_taylor
00468 \li size_t(arg[2]) < i_z
00469 */
00470 template <class Base>
00471 inline void reverse_load_op(
00472      OpCode         op          ,
00473      size_t         d           ,
00474      size_t         i_z         ,
00475      const addr_t*  arg         , 
00476      size_t         nc_taylor   ,
00477      const Base*    taylor      ,
00478      size_t         nc_partial  ,
00479      Base*          partial     ,
00480      const addr_t*        var_by_load_op )
00481 {    size_t i_load = size_t( var_by_load_op[ arg[2] ] );
00482 
00483      CPPAD_ASSERT_UNKNOWN( NumArg(op) == 3 );
00484      CPPAD_ASSERT_UNKNOWN( NumRes(op) == 1 );
00485      CPPAD_ASSERT_UNKNOWN( d < nc_taylor );
00486      CPPAD_ASSERT_UNKNOWN( i_load < i_z );
00487 
00488      if( i_load > 0 )
00489      {
00490           Base* pz   = partial + i_z    * nc_partial;
00491           Base* py_x = partial + i_load * nc_partial;
00492           size_t j = d + 1;
00493           while(j--)
00494                py_x[j]   += pz[j];
00495      }
00496 }
00497 
00498 
00499 /*!
00500 Forward mode sparsity operations for LdpOp and LdvOp
00501 
00502 \copydetails sparse_load_op
00503 */
00504 template <class Vector_set>
00505 inline void forward_sparse_load_op(
00506      OpCode             op             ,
00507      size_t             i_z            ,
00508      const addr_t*      arg            , 
00509      size_t             num_combined   ,
00510      const size_t*      combined       ,
00511      Vector_set&        var_sparsity   ,
00512      Vector_set&        vecad_sparsity )
00513 {
00514      CPPAD_ASSERT_UNKNOWN( NumArg(op) == 3 );
00515      CPPAD_ASSERT_UNKNOWN( NumRes(op) == 1 );
00516      CPPAD_ASSERT_UNKNOWN( 0 < arg[0] );
00517      CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_combined );
00518      size_t i_v = combined[ arg[0] - 1 ];
00519      CPPAD_ASSERT_UNKNOWN( i_v < vecad_sparsity.n_set() );
00520 
00521      var_sparsity.assignment(i_z, i_v, vecad_sparsity);
00522 
00523      return;
00524 }
00525 
00526 
00527 /*!
00528 Reverse mode Jacobian sparsity operations for LdpOp and LdvOp
00529 
00530 \copydetails sparse_load_op
00531 */
00532 template <class Vector_set>
00533 inline void reverse_sparse_jacobian_load_op(
00534      OpCode             op             ,
00535      size_t             i_z            ,
00536      const addr_t*      arg            , 
00537      size_t             num_combined   ,
00538      const size_t*      combined       ,
00539      Vector_set&        var_sparsity   ,
00540      Vector_set&        vecad_sparsity )
00541 {
00542      CPPAD_ASSERT_UNKNOWN( NumArg(op) == 3 );
00543      CPPAD_ASSERT_UNKNOWN( NumRes(op) == 1 );
00544      CPPAD_ASSERT_UNKNOWN( 0 < arg[0] );
00545      CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_combined );
00546      size_t i_v = combined[ arg[0] - 1 ];
00547      CPPAD_ASSERT_UNKNOWN( i_v < vecad_sparsity.n_set() );
00548 
00549      vecad_sparsity.binary_union(i_v, i_v, i_z, var_sparsity);
00550 
00551      return;
00552 }
00553 
00554 
00555 /*!
00556 Reverse mode Hessian sparsity operations for LdpOp and LdvOp
00557 
00558 This routine is given the sparsity patterns for 
00559 G(z , v[x] , w , u ... )
00560 and it uses them to compute the sparsity patterns for
00561 \verbatim
00562      H( v[x] , w , u , ... ) = G[ z( v[x] ) , v[x] , w , u , ... ]
00563 \endverbatim
00564 
00565 <!-- replace sparse_load_op -->
00566 The C++ source code corresponding to this operation is
00567 \verbatim
00568      z = v[x]
00569 \endverbatim
00570 where v is a VecAD<Base> vector and x is an AD<Base> index. 
00571 
00572 \tparam Vector_set
00573 is the type used for vectors of sets. It can be either
00574 \c sparse_pack, \c sparse_set, or \c sparse_list.
00575 
00576 \param op
00577 is the code corresponding to this operator; i.e., LdpOp or LdvOp
00578 (only used for error checking).
00579 
00580 \param i_z
00581 is the AD variable index corresponding to the variable z; i.e.,
00582 the set with index \a i_z in \a var_sparsity is the sparsity pattern
00583 correpsonding to z.
00584 
00585 \param arg
00586 \n
00587 \a arg[0]
00588 is the offset corresponding to this VecAD vector in the VecAD combined array.
00589 
00590 \param num_combined
00591 is the total number of elements in the VecAD combinded array.
00592 
00593 \param combined
00594 is the VecAD combined array.
00595 \n
00596 \n
00597 \a combined[ \a arg[0] - 1 ]
00598 is the index of the set corresponding to the vector v  in \a vecad_sparsity.
00599 We use the notation i_v for this value; i.e.,
00600 \verbatim
00601      i_v = combined[ \a arg[0] - 1 ]
00602 \endverbatim
00603 
00604 \param var_sparsity
00605 The set with index \a i_z in \a var_sparsity is the sparsity pattern for z.
00606 This is an output for forward mode operations,
00607 and an input for reverse mode operations.
00608 
00609 \param vecad_sparsity
00610 The set with index \a i_v is the sparsity pattern for the vector v.
00611 This is an input for forward mode operations.
00612 For reverse mode operations,
00613 the sparsity pattern for z is added to the sparsity pattern for v.
00614 
00615 \par Checked Assertions 
00616 \li NumArg(op) == 3
00617 \li NumRes(op) == 1
00618 \li 0         <  \a arg[0]
00619 \li \a arg[0] < \a num_combined
00620 \li i_v       < \a vecad_sparsity.n_set()
00621 <!-- end sparse_load_op -->
00622 
00623 \param var_jacobian
00624 \a var_jacobian[i_z] 
00625 is false (true) if the Jacobian of G with respect to z is always zero 
00626 (many be non-zero).
00627 
00628 \param vecad_jacobian
00629 \a vecad_jacobian[i_v] 
00630 is false (true) if the Jacobian with respect to x is always zero 
00631 (may be non-zero).
00632 On input, it corresponds to the function G,
00633 and on output it corresponds to the function H.
00634 
00635 */
00636 template <class Vector_set>
00637 inline void reverse_sparse_hessian_load_op(
00638      OpCode             op             ,
00639      size_t             i_z            ,
00640      const addr_t*      arg            , 
00641      size_t             num_combined   ,
00642      const size_t*      combined       ,
00643      Vector_set&        var_sparsity   ,
00644      Vector_set&        vecad_sparsity ,
00645      bool*              var_jacobian   ,
00646      bool*              vecad_jacobian )
00647 {
00648      CPPAD_ASSERT_UNKNOWN( NumArg(op) == 3 );
00649      CPPAD_ASSERT_UNKNOWN( NumRes(op) == 1 );
00650      CPPAD_ASSERT_UNKNOWN( 0 < arg[0] );
00651      CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_combined );
00652      size_t i_v = combined[ arg[0] - 1 ];
00653      CPPAD_ASSERT_UNKNOWN( i_v < vecad_sparsity.n_set() );
00654 
00655      vecad_sparsity.binary_union(i_v, i_v, i_z, var_sparsity);
00656 
00657      vecad_jacobian[i_v] |= var_jacobian[i_z];
00658 
00659      return;
00660 }
00661 
00662 
00663 } // END_CPPAD_NAMESPACE
00664 # endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines