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 "jac_g_map.hpp" 00014 // --------------------------------------------------------------------------- 00015 namespace cppad_ipopt { 00016 // --------------------------------------------------------------------------- 00017 /*! 00018 \{ 00019 \file jac_g_map.cpp 00020 \brief Creates a mapping between two representations for Jacobian of g. 00021 */ 00022 00023 00024 /*! 00025 Create mapping from CppAD to Ipopt sparse representations of Jacobian of g. 00026 00027 The functions 00028 \f$ f : {\bf R}^n \rightarrow {\bf R} \f$ and 00029 \f$ g : {\bf R}^n \rightarrow {\bf R}^m \f$ are defined by 00030 the \ref Users_Representation. 00031 00032 \param fg_info 00033 For <tt>k = 0 , ... , K-1</tt>, 00034 for <tt>ell = 0 , ... , L[k]</tt>, 00035 the function call 00036 \verbatim 00037 fg_info->index(k, ell, I, J); 00038 \endverbatim 00039 is made by \c jac_g_map. 00040 The values \c k and \c ell are inputs. 00041 The input size of \c I ( \c J ) 00042 is greater than or equal <tt>p[k] ( q[k] )</tt> 00043 and this size is not changed. 00044 The input values of the elements of \c I and \c J are not specified. 00045 The output value of the elements of \c I define 00046 \f[ 00047 I_{k, \ell} = ( {\rm I[0]} , \cdots , {\rm I[p[k]-1]} ) 00048 \f] 00049 The output value of the elements of \c J define 00050 \f[ 00051 J_{k, \ell} = ( {\rm J[0]} , \cdots , {\rm J[q[k]-1]} ) 00052 \f] 00053 00054 \param m 00055 is the dimension of the range space for \f$ g(x) \f$; i.e., 00056 \f$ g(x) \in {\bf R}^m \f$. 00057 00058 \param n 00059 is the dimension of the domain space for \f$ f(x) \f$ and \f$ g(x) \f$; 00060 i.e., \f$ x \in {\bf R}^n \f$. 00061 00062 \param K 00063 is the number of functions \f$ r_k ( u ) \f$ used for the representation of 00064 \f$ f(x) \f$ and \f$ g(x) \f$. 00065 00066 \param L 00067 is a vector with size \c K. 00068 For <tt>k = 0 , ... , K-1, L[k]</tt> 00069 is the number of terms that use \f$ r_k (u) \f$ 00070 in the representation of \f$ f(x) \f$ and \f$ g(x) \f$. 00071 00072 \param p 00073 is a vector with size \c K. 00074 For <tt>k = 0 , ... , K-1, p[k]</tt> 00075 is dimension of the range space for \f$ r_k (u) \f$; i.e., 00076 \f$ r_k (u) \in {\bf R}^{p(k)} \f$. 00077 00078 \param q 00079 is a vector with size \c K. 00080 For <tt>k = 0 , ... , K-1, q[k]</tt> 00081 is dimension of the domain space for \f$ r_k (u) \f$; i.e., 00082 \f$ u \in {\bf R}^{q(k)} \f$. 00083 00084 \param pattern_jac_r 00085 is a vector with size \c K. 00086 For <tt>k = 0 , ... , K-1, pattern_jac_r[k]</tt> 00087 is a CppAD sparsity pattern for the Jacobian of the function 00088 \f$ r_k : {\bf R}^{q(k)} \rightarrow {\bf R}^{p(k)} \f$. 00089 As such, <tt>pattern_jac_r[k].size() == p[k] * q[k]</tt>. 00090 00091 \param I 00092 is a work vector of length greater than or equal <tt>p[k]</tt> for all \c k. 00093 The input and output value of its elements are unspecified. 00094 The size of \c I is not changed. 00095 00096 \param J 00097 is a work vector of length greater than or equal <tt>q[k]</tt> for all \c k. 00098 The input and output value of its elements are unspecified. 00099 The size of \c J is not changed. 00100 00101 \param index_jac_g: 00102 On input, this is empty; i.e., <tt>index_jac_g.size() == 0</tt>. 00103 On output, it is the index mapping from \f$ (i, j) \f$ in the Jacobian of 00104 \f$ g(x) \f$ to the corresponding index value used by Ipopt to represent 00105 the Jacobian. 00106 Furthermore, if <tt>index_jac_g[i].find(j) == index_jac_g[i].end()</tt>, 00107 then the \f$ (i, j)\f$ entry in the Jacobian of \f$ g(x) \f$ is always zero. 00108 */ 00109 void jac_g_map( 00110 cppad_ipopt_fg_info* fg_info , 00111 size_t m , 00112 size_t n , 00113 size_t K , 00114 const CppAD::vector<size_t>& L , 00115 const CppAD::vector<size_t>& p , 00116 const CppAD::vector<size_t>& q , 00117 const CppAD::vector<CppAD::vectorBool>& pattern_jac_r , 00118 CppAD::vector<size_t>& I , 00119 CppAD::vector<size_t>& J , 00120 CppAD::vector< std::map<size_t,size_t> >& index_jac_g ) 00121 { 00122 using CppAD::vectorBool; 00123 size_t i, j, ij, k, ell; 00124 00125 CPPAD_ASSERT_UNKNOWN( K == L.size() ); 00126 CPPAD_ASSERT_UNKNOWN( K == p.size() ); 00127 CPPAD_ASSERT_UNKNOWN( K == q.size() ); 00128 CPPAD_ASSERT_UNKNOWN( K == pattern_jac_r.size() ); 00129 # ifndef NDEBUG 00130 for(k = 0; k < K; k++) 00131 { CPPAD_ASSERT_UNKNOWN( p[k] <= I.size() ); 00132 CPPAD_ASSERT_UNKNOWN( q[k] <= J.size() ); 00133 CPPAD_ASSERT_UNKNOWN( p[k]*q[k] == pattern_jac_r[k].size() ); 00134 } 00135 # endif 00136 // Now compute pattern for g 00137 // (use standard set representation because can be huge). 00138 CppAD::vector< std::set<size_t> > pattern_jac_g(m); 00139 for(k = 0; k < K; k++) for(ell = 0; ell < L[k]; ell++) 00140 { fg_info->index(k, ell, I, J); 00141 for(i = 0; i < p[k]; i++) if( I[i] != 0 ) 00142 { for(j = 0; j < q[k]; j++) 00143 { ij = i * q[k] + j; 00144 if( pattern_jac_r[k][ij] ) 00145 pattern_jac_g[I[i]-1].insert(J[j]); 00146 } 00147 } 00148 } 00149 00150 // Now compute the mapping from (i, j) in the Jacobian of g to the 00151 // corresponding index value used by Ipopt to represent the Jacobian. 00152 CPPAD_ASSERT_UNKNOWN( index_jac_g.size() == 0 ); 00153 index_jac_g.resize(m); 00154 std::set<size_t>::const_iterator itr; 00155 ell = 0; 00156 for(i = 0; i < m; i++) 00157 { for( itr = pattern_jac_g[i].begin(); 00158 itr != pattern_jac_g[i].end(); itr++) 00159 { 00160 index_jac_g[i][*itr] = ell++; 00161 } 00162 } 00163 return; 00164 } 00165 00166 // --------------------------------------------------------------------------- 00167 } // end namespace cppad_ipopt 00168 // ---------------------------------------------------------------------------