! Determine a sparsity patterns for each function in a vector of functions. \param K is the number of functions that we are computing the sparsity pattern for. \param p is a vector with size K. For k = 0 , ... , K-1, p[k] is dimension of the range space for \f$ r_k (u) \f$; i.e., \f$ r_k (u) \in {\bf R}^{p(k)} \f$. \param q is a vector with size K. For k = 0 , ... , K-1, q[k]
| 75 | \f] |
| 76 | */ |
| 77 | void vec_fun_pattern( |
| 78 | size_t K , |
| 79 | const CppAD::vector<size_t>& p , |
| 80 | const CppAD::vector<size_t>& q , |
| 81 | const CppAD::vectorBool& retape , |
| 82 | CppAD::vector< CppAD::ADFun<Ipopt::Number> >& r_fun , |
| 83 | CppAD::vector<CppAD::vectorBool>& pattern_jac_r , |
| 84 | CppAD::vector<CppAD::vectorBool>& pattern_hes_r ) |
| 85 | { // check some assumptions |
| 86 | CPPAD_ASSERT_UNKNOWN( K == p.size() ); |
| 87 | CPPAD_ASSERT_UNKNOWN( K == q.size() ); |
| 88 | CPPAD_ASSERT_UNKNOWN( K == retape.size() ); |
| 89 | CPPAD_ASSERT_UNKNOWN( K == r_fun.size() ); |
| 90 | CPPAD_ASSERT_UNKNOWN( K == pattern_jac_r.size() ); |
| 91 | CPPAD_ASSERT_UNKNOWN( K == pattern_hes_r.size() ); |
| 92 | |
| 93 | using CppAD::vectorBool; |
| 94 | size_t i, j, k; |
| 95 | |
| 96 | for(k = 0; k < K; k++) |
| 97 | { // check some k specific assumptions |
| 98 | CPPAD_ASSERT_UNKNOWN( pattern_jac_r[k].size() == p[k] * q[k] ); |
| 99 | CPPAD_ASSERT_UNKNOWN( pattern_hes_r[k].size() == q[k] * q[k] ); |
| 100 | |
| 101 | if( retape[k] ) |
| 102 | { for(i = 0; i < p[k]; i++) |
| 103 | { for(j = 0; j < q[k]; j++) |
| 104 | pattern_jac_r[k][i*q[k] + j] = true; |
| 105 | } |
| 106 | for(i = 0; i < q[k]; i++) |
| 107 | { for(j = 0; j < q[k]; j++) |
| 108 | pattern_hes_r[k][i*q[k] + j] = true; |
| 109 | } |
| 110 | } |
| 111 | else |
| 112 | { // check assumptions about r_k |
| 113 | CPPAD_ASSERT_UNKNOWN( r_fun[k].Range() == p[k] ); |
| 114 | CPPAD_ASSERT_UNKNOWN( r_fun[k].Domain() == q[k] ); |
| 115 | |
| 116 | // pattern for the identity matrix |
| 117 | CppAD::vectorBool pattern_domain(q[k] * q[k]); |
| 118 | for(i = 0; i < q[k]; i++) |
| 119 | { for(j = 0; j < q[k]; j++) |
| 120 | pattern_domain[i*q[k] + j] = (i == j); |
| 121 | } |
| 122 | // use forward mode to compute Jacobian sparsity |
| 123 | pattern_jac_r[k] = |
| 124 | r_fun[k].ForSparseJac(q[k], pattern_domain); |
| 125 | // user reverse mode to compute Hessian sparsity |
| 126 | CppAD::vectorBool pattern_ones(p[k]); |
| 127 | for(i = 0; i < p[k]; i++) |
| 128 | pattern_ones[i] = true; |
| 129 | pattern_hes_r[k] = |
| 130 | r_fun[k].RevSparseHes(q[k], pattern_ones); |
| 131 | } |
| 132 | } |
| 133 | } |
| 134 | // --------------------------------------------------------------------------- |
no test coverage detected