CppAD: A C++ Algorithmic Differentiation Package
20130102
|
00001 /* $Id$ */ 00002 /* -------------------------------------------------------------------------- 00003 CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-12 Bradley M. Bell 00004 00005 CppAD is distributed under multiple licenses. This distribution is under 00006 the terms of the 00007 Eclipse Public License Version 1.0. 00008 00009 A copy of this license is included in the COPYING file of this distribution. 00010 Please visit http://www.coin-or.org/CppAD/ for information on other licenses. 00011 -------------------------------------------------------------------------- */ 00012 # include "cppad_ipopt_nlp.hpp" 00013 # include "vec_fun_pattern.hpp" 00014 // --------------------------------------------------------------------------- 00015 namespace cppad_ipopt { 00016 // --------------------------------------------------------------------------- 00017 /*! 00018 \defgroup vec_fun_pattern_cpp vec_fun_pattern.cpp 00019 \{ 00020 \file vec_fun_pattern.cpp 00021 \brief Determine a sparsity pattern for a vector of AD function objects. 00022 */ 00023 00024 /*! 00025 Determine a sparsity patterns for each function in a vector of functions. 00026 00027 \param K 00028 is the number of functions that we are computing the sparsity pattern for. 00029 00030 \param p 00031 is a vector with size \c K. 00032 For <tt>k = 0 , ... , K-1, p[k]</tt> 00033 is dimension of the range space for \f$ r_k (u) \f$; i.e., 00034 \f$ r_k (u) \in {\bf R}^{p(k)} \f$. 00035 00036 \param q 00037 is a vector with size \c K. 00038 For <tt>k = 0 , ... , K-1, q[k]</tt> 00039 is dimension of the domain space for \f$ r_k (u) \f$; i.e., 00040 \f$ u \in {\bf R}^{q(k)} \f$. 00041 00042 \param retape 00043 is a vector with size \c K. 00044 For <tt>k = 0 , ... , K-1</tt>, 00045 if <tt>retape[k]</tt> is true, 00046 the function object <tt>r[k]</tt> is a valid representation 00047 for \f$ r_k (u) \f$ for all \f$ u \in {\bf R}^{q(k)} \f$. 00048 Otherwise, the function object must be retaped for each 00049 value of \f$ u \f$. 00050 00051 \param r_fun 00052 is the vector of AD function objects which has size size \c K. 00053 For <tt>k = 0 , ... , K-1</tt>, 00054 if <tt>retape[k]</tt> is true, <tt>r_fun[k]</tt> is not used. 00055 If <tt>retape[k]</tt> is false, <tt>r_fun[k]</tt> is not used. 00056 is a CppAD function object correspopnding to the function 00057 \f$ r_k : {\bf R}^{q[k]} \rightarrow {\bf R}^{p[k]} \f$. 00058 The following non-constant member functions will be called: 00059 \verbatim 00060 r_fun[k].ForSparseJac(q[k], pattern_domain) 00061 r_fun[k].RevSparseHes(p[k], pattern_range) 00062 \endverbatim 00063 The following \c const member functions <tt>r_fun[k].Range()</tt> 00064 and <tt>r_fun[k].Domain()</tt> may also be called. 00065 00066 \param pattern_jac_r 00067 is a vector with size \c K. 00068 On input, For <tt>k = 0 , ... , K-1, pattern_jac_r[k]</tt> 00069 is a vector of length p[k] * q[k] 00070 and the value of its elements does not matter. 00071 On output it is a CppAD sparsity pattern for the Jacobian of 00072 \f$ r_k (u) \f$. 00073 00074 \param pattern_hes_r 00075 is a vector with size \c K. 00076 On input, For <tt>k = 0 , ... , K-1, pattern_hes_r[k]</tt> 00077 is a vector of length q[k] * q[k] 00078 and the value of its elements does not matter. 00079 On output it is a CppAD sparsity pattern for the Hessian of 00080 \f$ R : {\bf R}^{q[k]} \rightarrow {\bf R} \f$ which is defined by 00081 \f[ 00082 R(u) = \sum_{i=0}^{p[k]-1} r_k (u)_i 00083 \f] 00084 */ 00085 void vec_fun_pattern( 00086 size_t K , 00087 const CppAD::vector<size_t>& p , 00088 const CppAD::vector<size_t>& q , 00089 const CppAD::vectorBool& retape , 00090 CppAD::vector< CppAD::ADFun<Ipopt::Number> >& r_fun , 00091 CppAD::vector<CppAD::vectorBool>& pattern_jac_r , 00092 CppAD::vector<CppAD::vectorBool>& pattern_hes_r ) 00093 { // check some assumptions 00094 CPPAD_ASSERT_UNKNOWN( K == p.size() ); 00095 CPPAD_ASSERT_UNKNOWN( K == q.size() ); 00096 CPPAD_ASSERT_UNKNOWN( K == retape.size() ); 00097 CPPAD_ASSERT_UNKNOWN( K == r_fun.size() ); 00098 CPPAD_ASSERT_UNKNOWN( K == pattern_jac_r.size() ); 00099 CPPAD_ASSERT_UNKNOWN( K == pattern_hes_r.size() ); 00100 00101 using CppAD::vectorBool; 00102 size_t i, j, k; 00103 00104 for(k = 0; k < K; k++) 00105 { // check some k specific assumptions 00106 CPPAD_ASSERT_UNKNOWN( pattern_jac_r[k].size() == p[k] * q[k] ); 00107 CPPAD_ASSERT_UNKNOWN( pattern_hes_r[k].size() == q[k] * q[k] ); 00108 00109 if( retape[k] ) 00110 { for(i = 0; i < p[k]; i++) 00111 { for(j = 0; j < q[k]; j++) 00112 pattern_jac_r[k][i*q[k] + j] = true; 00113 } 00114 for(i = 0; i < q[k]; i++) 00115 { for(j = 0; j < q[k]; j++) 00116 pattern_hes_r[k][i*q[k] + j] = true; 00117 } 00118 } 00119 else 00120 { // check assumptions about r_k 00121 CPPAD_ASSERT_UNKNOWN( r_fun[k].Range() == p[k] ); 00122 CPPAD_ASSERT_UNKNOWN( r_fun[k].Domain() == q[k] ); 00123 00124 // pattern for the identity matrix 00125 CppAD::vectorBool pattern_domain(q[k] * q[k]); 00126 for(i = 0; i < q[k]; i++) 00127 { for(j = 0; j < q[k]; j++) 00128 pattern_domain[i*q[k] + j] = (i == j); 00129 } 00130 // use forward mode to compute Jacobian sparsity 00131 pattern_jac_r[k] = 00132 r_fun[k].ForSparseJac(q[k], pattern_domain); 00133 // user reverse mode to compute Hessian sparsity 00134 CppAD::vectorBool pattern_ones(p[k]); 00135 for(i = 0; i < p[k]; i++) 00136 pattern_ones[i] = true; 00137 pattern_hes_r[k] = 00138 r_fun[k].RevSparseHes(q[k], pattern_ones); 00139 } 00140 } 00141 } 00142 // --------------------------------------------------------------------------- 00143 /*! \} */ 00144 } // end namespace cppad_ipopt 00145 // ---------------------------------------------------------------------------