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