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