CppAD: A C++ Algorithmic Differentiation Package  20130918
sparse_binary_op.hpp
Go to the documentation of this file.
00001 /* $Id$ */
00002 # ifndef CPPAD_SPARSE_BINARY_OP_INCLUDED
00003 # define CPPAD_SPARSE_BINARY_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 sparse_binary_op.hpp
00018 Forward and reverse mode sparsity patterns for binary operators.
00019 */
00020 
00021 
00022 /*!
00023 Forward mode Jacobian sparsity pattern for all binary operators. 
00024 
00025 The C++ source code corresponding to a binary operation has the form
00026 \verbatim
00027      z = fun(x, y)
00028 \endverbatim
00029 where fun is a C++ binary function and both x and y are variables, 
00030 or it has the form
00031 \verbatim
00032      z = x op y
00033 \endverbatim
00034 where op is a C++ binary unary operator and both x and y are variables.
00035 
00036 \tparam Vector_set
00037 is the type used for vectors of sets. It can be either
00038 \c sparse_pack, \c sparse_set, or \c sparse_list.
00039 
00040 \param i_z
00041 variable index corresponding to the result for this operation; 
00042 i.e., z. 
00043 
00044 \param arg
00045 \a arg[0]
00046 variable index corresponding to the left operand for this operator;
00047 i.e., x.
00048 \n
00049 \n arg[1]
00050 variable index corresponding to the right operand for this operator;
00051 i.e., y.
00052 
00053 \param sparsity
00054 \b Input: 
00055 The set with index \a arg[0] in \a sparsity
00056 is the sparsity bit pattern for x.
00057 This identifies which of the independent variables the variable x
00058 depends on. 
00059 \n
00060 \n
00061 \b Input: 
00062 The set with index \a arg[1] in \a sparsity
00063 is the sparsity bit pattern for y.
00064 This identifies which of the independent variables the variable y
00065 depends on. 
00066 \n
00067 \n
00068 \b Output: 
00069 The set with index \a i_z in \a sparsity
00070 is the sparsity bit pattern for z.
00071 This identifies which of the independent variables the variable z
00072 depends on. 
00073 
00074 \par Checked Assertions:
00075 \li \a arg[0] < \a i_z 
00076 \li \a arg[1] < \a i_z 
00077 */
00078 
00079 template <class Vector_set>
00080 inline void forward_sparse_jacobian_binary_op(
00081      size_t            i_z           ,
00082      const addr_t*     arg           ,
00083      Vector_set&       sparsity      )
00084 {    
00085      // check assumptions
00086      CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < i_z );
00087      CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) < i_z );
00088 
00089      sparsity.binary_union(i_z, arg[0], arg[1], sparsity);
00090 
00091      return;
00092 }    
00093 
00094 /*!
00095 Reverse mode Jacobian sparsity pattern for all binary operators. 
00096 
00097 The C++ source code corresponding to a unary operation has the form
00098 \verbatim
00099      z = fun(x, y)
00100 \endverbatim
00101 where fun is a C++ unary function and x and y are variables, 
00102 or it has the form
00103 \verbatim
00104      z = x op y
00105 \endverbatim
00106 where op is a C++ bianry operator and x and y are variables.
00107 
00108 This routine is given the sparsity patterns
00109 for a function G(z, y, x, ... )
00110 and it uses them to compute the sparsity patterns for 
00111 \verbatim
00112      H( y, x, w , u , ... ) = G[ z(x,y) , y , x , w , u , ... ]
00113 \endverbatim
00114 
00115 \tparam Vector_set
00116 is the type used for vectors of sets. It can be either
00117 \c sparse_pack, \c sparse_set, or \c sparse_list.
00118 
00119 \param i_z
00120 variable index corresponding to the result for this operation; 
00121 i.e., z.
00122 
00123 \param arg
00124 \a arg[0]
00125 variable index corresponding to the left operand for this operator;
00126 i.e., x.
00127 
00128 \n
00129 \n arg[1]
00130 variable index corresponding to the right operand for this operator;
00131 i.e., y.
00132 
00133 \param sparsity
00134 The set with index \a i_z in \a sparsity 
00135 is the sparsity pattern for z corresponding ot the function G.
00136 \n
00137 \n
00138 The set with index \a arg[0] in \a sparsity 
00139 is the sparsity pattern for x.
00140 On input, it corresponds to the function G,
00141 and on output it corresponds to H.
00142 \n
00143 \n
00144 The set with index \a arg[1] in \a sparsity 
00145 is the sparsity pattern for y.
00146 On input, it corresponds to the function G,
00147 and on output it corresponds to H.
00148 \n
00149 \n
00150 
00151 \par Checked Assertions:
00152 \li \a arg[0] < \a i_z 
00153 \li \a arg[1] < \a i_z 
00154 */
00155 template <class Vector_set>
00156 inline void reverse_sparse_jacobian_binary_op(
00157      size_t              i_z           ,
00158      const addr_t*       arg           ,
00159      Vector_set&         sparsity      )
00160 {    
00161      // check assumptions
00162      CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < i_z );
00163      CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) < i_z );
00164 
00165      sparsity.binary_union(arg[0], arg[0], i_z, sparsity);
00166      sparsity.binary_union(arg[1], arg[1], i_z, sparsity);
00167 
00168      return;
00169 }    
00170 
00171 /*!
00172 Reverse mode Hessian sparsity pattern for add and subtract operators. 
00173 
00174 The C++ source code corresponding to a unary operation has the form
00175 \verbatim
00176      z = x op y
00177 \endverbatim
00178 where op is + or - and x, y are variables.
00179 
00180 \copydetails reverse_sparse_hessian_binary_op
00181 */
00182 template <class Vector_set>
00183 inline void reverse_sparse_hessian_addsub_op(
00184      size_t               i_z                ,
00185      const addr_t*        arg                ,
00186      bool*                jac_reverse        ,
00187      Vector_set&          for_jac_sparsity   ,
00188      Vector_set&          rev_hes_sparsity   )
00189 {    
00190      // check assumptions
00191      CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < i_z );
00192      CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) < i_z );
00193 
00194      rev_hes_sparsity.binary_union(arg[0], arg[0], i_z, rev_hes_sparsity);
00195      rev_hes_sparsity.binary_union(arg[1], arg[1], i_z, rev_hes_sparsity);
00196 
00197      jac_reverse[arg[0]] |= jac_reverse[i_z];
00198      jac_reverse[arg[1]] |= jac_reverse[i_z];
00199 
00200      return;
00201 }    
00202 
00203 /*!
00204 Reverse mode Hessian sparsity pattern for multiplication operator. 
00205 
00206 The C++ source code corresponding to a unary operation has the form
00207 \verbatim
00208      z = x * y
00209 \endverbatim
00210 where x and y are variables.
00211 
00212 \copydetails reverse_sparse_hessian_binary_op
00213 */
00214 template <class Vector_set>
00215 inline void reverse_sparse_hessian_mul_op(
00216      size_t               i_z                ,
00217      const addr_t*        arg                ,
00218      bool*                jac_reverse        ,
00219      Vector_set&          for_jac_sparsity   ,
00220      Vector_set&          rev_hes_sparsity   )
00221 {    
00222      // check assumptions
00223      CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < i_z );
00224      CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) < i_z );
00225 
00226      rev_hes_sparsity.binary_union(arg[0], arg[0], i_z, rev_hes_sparsity);
00227      rev_hes_sparsity.binary_union(arg[1], arg[1], i_z, rev_hes_sparsity);
00228 
00229      if( jac_reverse[i_z] )
00230      {    rev_hes_sparsity.binary_union(
00231                arg[0], arg[0], arg[1], for_jac_sparsity); 
00232           rev_hes_sparsity.binary_union(
00233                arg[1], arg[1], arg[0], for_jac_sparsity); 
00234      }
00235 
00236      jac_reverse[arg[0]] |= jac_reverse[i_z];
00237      jac_reverse[arg[1]] |= jac_reverse[i_z];
00238      return;
00239 }    
00240 
00241 /*!
00242 Reverse mode Hessian sparsity pattern for division operator. 
00243 
00244 The C++ source code corresponding to a unary operation has the form
00245 \verbatim
00246      z = x / y
00247 \endverbatim
00248 where x and y are variables.
00249 
00250 \copydetails reverse_sparse_hessian_binary_op
00251 */
00252 template <class Vector_set>
00253 inline void reverse_sparse_hessian_div_op(
00254      size_t               i_z                ,
00255      const addr_t*        arg                ,
00256      bool*                jac_reverse        ,
00257      Vector_set&          for_jac_sparsity   ,
00258      Vector_set&          rev_hes_sparsity   )
00259 {    
00260      // check assumptions
00261      CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < i_z );
00262      CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) < i_z );
00263 
00264      rev_hes_sparsity.binary_union(arg[0], arg[0], i_z, rev_hes_sparsity);
00265      rev_hes_sparsity.binary_union(arg[1], arg[1], i_z, rev_hes_sparsity);
00266 
00267      if( jac_reverse[i_z] )
00268      {    rev_hes_sparsity.binary_union(
00269                arg[0], arg[0], arg[1], for_jac_sparsity); 
00270           rev_hes_sparsity.binary_union(
00271                arg[1], arg[1], arg[0], for_jac_sparsity); 
00272           rev_hes_sparsity.binary_union(
00273                arg[1], arg[1], arg[1], for_jac_sparsity); 
00274      }
00275 
00276      jac_reverse[arg[0]] |= jac_reverse[i_z];
00277      jac_reverse[arg[1]] |= jac_reverse[i_z];
00278      return;
00279 }    
00280 
00281 /*!
00282 Reverse mode Hessian sparsity pattern for power function. 
00283 
00284 The C++ source code corresponding to a unary operation has the form
00285 \verbatim
00286      z = pow(x, y)
00287 \endverbatim
00288 where x and y are variables.
00289 
00290 \copydetails reverse_sparse_hessian_binary_op
00291 */
00292 template <class Vector_set>
00293 inline void reverse_sparse_hessian_pow_op(
00294      size_t               i_z                ,
00295      const addr_t*        arg                ,
00296      bool*                jac_reverse        ,
00297      Vector_set&          for_jac_sparsity   ,
00298      Vector_set&          rev_hes_sparsity   )
00299 {    
00300      // check assumptions
00301      CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < i_z );
00302      CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) < i_z );
00303 
00304      rev_hes_sparsity.binary_union(arg[0], arg[0], i_z, rev_hes_sparsity);
00305      rev_hes_sparsity.binary_union(arg[1], arg[1], i_z, rev_hes_sparsity);
00306 
00307      if( jac_reverse[i_z] )
00308      {
00309           rev_hes_sparsity.binary_union(
00310                arg[0], arg[0], arg[0], for_jac_sparsity); 
00311           rev_hes_sparsity.binary_union(
00312                arg[0], arg[0], arg[1], for_jac_sparsity); 
00313 
00314           rev_hes_sparsity.binary_union(
00315                arg[1], arg[1], arg[0], for_jac_sparsity); 
00316           rev_hes_sparsity.binary_union(
00317                arg[1], arg[1], arg[1], for_jac_sparsity); 
00318      }
00319 
00320      // I cannot think of a case where this is necessary, but it including
00321      // it makes it like the other cases.
00322      jac_reverse[arg[0]] |= jac_reverse[i_z];
00323      jac_reverse[arg[1]] |= jac_reverse[i_z];
00324      return;
00325 }    
00326 
00327 } // END_CPPAD_NAMESPACE
00328 # endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines