vec_fun_pattern.cpp 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. /* --------------------------------------------------------------------------
  2. CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-15 Bradley M. Bell
  3. CppAD is distributed under the terms of the
  4. Eclipse Public License Version 2.0.
  5. This Source Code may also be made available under the following
  6. Secondary License when the conditions for such availability set forth
  7. in the Eclipse Public License, Version 2.0 are satisfied:
  8. GNU General Public License, Version 2.0 or later.
  9. ---------------------------------------------------------------------------- */
  10. # include "cppad_ipopt_nlp.hpp"
  11. # include "vec_fun_pattern.hpp"
  12. // ---------------------------------------------------------------------------
  13. namespace cppad_ipopt {
  14. // ---------------------------------------------------------------------------
  15. /*!
  16. \{
  17. \file vec_fun_pattern.cpp
  18. \brief Determine a sparsity pattern for a vector of AD function objects.
  19. */
  20. /*!
  21. Determine a sparsity patterns for each function in a vector of functions.
  22. \param K
  23. is the number of functions that we are computing the sparsity pattern for.
  24. \param p
  25. is a vector with size K.
  26. For <tt>k = 0 , ... , K-1, p[k]</tt>
  27. is dimension of the range space for \f$ r_k (u) \f$; i.e.,
  28. \f$ r_k (u) \in {\bf R}^{p(k)} \f$.
  29. \param q
  30. is a vector with size K.
  31. For <tt>k = 0 , ... , K-1, q[k]</tt>
  32. is dimension of the domain space for \f$ r_k (u) \f$; i.e.,
  33. \f$ u \in {\bf R}^{q(k)} \f$.
  34. \param retape
  35. is a vector with size K.
  36. For <tt>k = 0 , ... , K-1</tt>,
  37. if <tt>retape[k]</tt> is true,
  38. the function object <tt>r[k]</tt> is a valid representation
  39. for \f$ r_k (u) \f$ for all \f$ u \in {\bf R}^{q(k)} \f$.
  40. Otherwise, the function object must be retaped for each
  41. value of \f$ u \f$.
  42. \param r_fun
  43. is the vector of AD function objects which has size size K.
  44. For <tt>k = 0 , ... , K-1</tt>,
  45. if <tt>retape[k]</tt> is true, <tt>r_fun[k]</tt> is not used.
  46. If <tt>retape[k]</tt> is false, <tt>r_fun[k]</tt> is not used.
  47. is a CppAD function object correspopnding to the function
  48. \f$ r_k : {\bf R}^{q[k]} \rightarrow {\bf R}^{p[k]} \f$.
  49. The following non-constant member functions will be called:
  50. \verbatim
  51. r_fun[k].ForSparseJac(q[k], pattern_domain)
  52. r_fun[k].RevSparseHes(p[k], pattern_range)
  53. \endverbatim
  54. The following const member functions <tt>r_fun[k].Range()</tt>
  55. and <tt>r_fun[k].Domain()</tt> may also be called.
  56. \param pattern_jac_r
  57. is a vector with size K.
  58. On input, For <tt>k = 0 , ... , K-1, pattern_jac_r[k]</tt>
  59. is a vector of length p[k] * q[k]
  60. and the value of its elements does not matter.
  61. On output it is a CppAD sparsity pattern for the Jacobian of
  62. \f$ r_k (u) \f$.
  63. \param pattern_hes_r
  64. is a vector with size K.
  65. On input, For <tt>k = 0 , ... , K-1, pattern_hes_r[k]</tt>
  66. is a vector of length q[k] * q[k]
  67. and the value of its elements does not matter.
  68. On output it is a CppAD sparsity pattern for the Hessian of
  69. \f$ R : {\bf R}^{q[k]} \rightarrow {\bf R} \f$ which is defined by
  70. \f[
  71. R(u) = \sum_{i=0}^{p[k]-1} r_k (u)_i
  72. \f]
  73. */
  74. void vec_fun_pattern(
  75. size_t K ,
  76. const CppAD::vector<size_t>& p ,
  77. const CppAD::vector<size_t>& q ,
  78. const CppAD::vectorBool& retape ,
  79. CppAD::vector< CppAD::ADFun<Ipopt::Number> >& r_fun ,
  80. CppAD::vector<CppAD::vectorBool>& pattern_jac_r ,
  81. CppAD::vector<CppAD::vectorBool>& pattern_hes_r )
  82. { // check some assumptions
  83. CPPAD_ASSERT_UNKNOWN( K == p.size() );
  84. CPPAD_ASSERT_UNKNOWN( K == q.size() );
  85. CPPAD_ASSERT_UNKNOWN( K == retape.size() );
  86. CPPAD_ASSERT_UNKNOWN( K == r_fun.size() );
  87. CPPAD_ASSERT_UNKNOWN( K == pattern_jac_r.size() );
  88. CPPAD_ASSERT_UNKNOWN( K == pattern_hes_r.size() );
  89. using CppAD::vectorBool;
  90. size_t i, j, k;
  91. for(k = 0; k < K; k++)
  92. { // check some k specific assumptions
  93. CPPAD_ASSERT_UNKNOWN( pattern_jac_r[k].size() == p[k] * q[k] );
  94. CPPAD_ASSERT_UNKNOWN( pattern_hes_r[k].size() == q[k] * q[k] );
  95. if( retape[k] )
  96. { for(i = 0; i < p[k]; i++)
  97. { for(j = 0; j < q[k]; j++)
  98. pattern_jac_r[k][i*q[k] + j] = true;
  99. }
  100. for(i = 0; i < q[k]; i++)
  101. { for(j = 0; j < q[k]; j++)
  102. pattern_hes_r[k][i*q[k] + j] = true;
  103. }
  104. }
  105. else
  106. { // check assumptions about r_k
  107. CPPAD_ASSERT_UNKNOWN( r_fun[k].Range() == p[k] );
  108. CPPAD_ASSERT_UNKNOWN( r_fun[k].Domain() == q[k] );
  109. // pattern for the identity matrix
  110. CppAD::vectorBool pattern_domain(q[k] * q[k]);
  111. for(i = 0; i < q[k]; i++)
  112. { for(j = 0; j < q[k]; j++)
  113. pattern_domain[i*q[k] + j] = (i == j);
  114. }
  115. // use forward mode to compute Jacobian sparsity
  116. pattern_jac_r[k] =
  117. r_fun[k].ForSparseJac(q[k], pattern_domain);
  118. // user reverse mode to compute Hessian sparsity
  119. CppAD::vectorBool pattern_ones(p[k]);
  120. for(i = 0; i < p[k]; i++)
  121. pattern_ones[i] = true;
  122. pattern_hes_r[k] =
  123. r_fun[k].RevSparseHes(q[k], pattern_ones);
  124. }
  125. }
  126. }
  127. // ---------------------------------------------------------------------------
  128. } // end namespace cppad_ipopt
  129. // ---------------------------------------------------------------------------