CppAD: A C++ Algorithmic Differentiation Package 20110419
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-10 Bradley M. Bell
00006 
00007 CppAD is distributed under multiple licenses. This distribution is under
00008 the terms of the 
00009                     Common 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 \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 or \c sparse_set.
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 size_t*     arg           ,
00083         Vector_set&       sparsity      )
00084 {       
00085         // check assumptions
00086         CPPAD_ASSERT_UNKNOWN( arg[0] < i_z );
00087         CPPAD_ASSERT_UNKNOWN( 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 or \c sparse_set.
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 size_t*       arg           ,
00159         Vector_set&         sparsity      )
00160 {       
00161         // check assumptions
00162         CPPAD_ASSERT_UNKNOWN( arg[0] < i_z );
00163         CPPAD_ASSERT_UNKNOWN( 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 size_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( arg[0] < i_z );
00192         CPPAD_ASSERT_UNKNOWN( 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 size_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( arg[0] < i_z );
00224         CPPAD_ASSERT_UNKNOWN( 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 size_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( arg[0] < i_z );
00262         CPPAD_ASSERT_UNKNOWN( 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 size_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( arg[0] < i_z );
00302         CPPAD_ASSERT_UNKNOWN( 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 CPPAD_END_NAMESPACE
00328 # endif