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