/*! Link from user_atomic to forward sparse Jacobian \copydetails atomic_base::rev_sparse_hes */ virtual bool rev_sparse_hes( const vector<bool>& vx , const vector<bool>& s , vector<bool>& t , size_t q , const vector< std::set<size_t> >& r , const vector< std::set<size_t> >& u , vector< std::set<size_t> >& v ) { size_t n = v.size(); size_t m = u.size(); CPPAD_ASSERT_UNKNOWN( r.size() == v.size() ); CPPAD_ASSERT_UNKNOWN( s.size() == m ); CPPAD_ASSERT_UNKNOWN( t.size() == n ); bool ok = true; bool transpose = true; std::set<size_t>::const_iterator itr; // compute sparsity pattern for T(x) = S(x) * f'(x) t = f_.RevSparseJac(1, s); # ifndef NDEBUG for(size_t j = 0; j < n; j++) CPPAD_ASSERT_UNKNOWN( vx[j] || ! t[j] ) # endif // V(x) = f'(x)^T * g''(y) * f'(x) * R + g'(y) * f''(x) * R // U(x) = g''(y) * f'(x) * R // S(x) = g'(y) // compute sparsity pattern for A(x) = f'(x)^T * U(x) vector< std::set<size_t> > a(n); a = f_.RevSparseJac(q, u, transpose); // set version of s vector< std::set<size_t> > set_s(1); CPPAD_ASSERT_UNKNOWN( set_s[0].empty() ); size_t i; for(i = 0; i < m; i++) if( s[i] ) set_s[0].insert(i); // compute sparsity pattern for H(x) = (S(x) * F)''(x) * R // (store it in v) f_.ForSparseJac(q, r); v = f_.RevSparseHes(q, set_s, transpose); // compute sparsity pattern for V(x) = A(x) + H(x) for(i = 0; i < n; i++) { for(itr = a[i].begin(); itr != a[i].end(); itr++) { size_t j = *itr; CPPAD_ASSERT_UNKNOWN( j < q ); v[i].insert(j); } } // no longer need the forward mode sparsity pattern // (have to reconstruct them every time) f_.size_forward_set(0); return ok; }
/*! Link from user_atomic to forward sparse Jacobian \copydetails atomic_base::rev_sparse_hes */ virtual bool rev_sparse_hes( const vector<bool>& vx , const vector<bool>& s , vector<bool>& t , size_t q , const vector<bool>& r , const vector<bool>& u , vector<bool>& v ) { CPPAD_ASSERT_UNKNOWN( r.size() == v.size() ); CPPAD_ASSERT_UNKNOWN( s.size() == u.size() / q ); CPPAD_ASSERT_UNKNOWN( t.size() == v.size() / q ); size_t n = t.size(); bool ok = true; bool transpose = true; std::set<size_t>::const_iterator itr; size_t i, j; // compute sparsity pattern for T(x) = S(x) * f'(x) t = f_.RevSparseJac(1, s); # ifndef NDEBUG for(j = 0; j < n; j++) CPPAD_ASSERT_UNKNOWN( vx[j] || ! t[j] ) # endif // V(x) = f'(x)^T * g''(y) * f'(x) * R + g'(y) * f''(x) * R // U(x) = g''(y) * f'(x) * R // S(x) = g'(y) // compute sparsity pattern for A(x) = f'(x)^T * U(x) vector<bool> a(n * q); a = f_.RevSparseJac(q, u, transpose); // compute sparsity pattern for H(x) =(S(x) * F)''(x) * R // (store it in v) f_.ForSparseJac(q, r); v = f_.RevSparseHes(q, s, transpose); // compute sparsity pattern for V(x) = A(x) + H(x) for(i = 0; i < n; i++) { for(j = 0; j < q; j++) v[ i * q + j ] |= a[ i * q + j]; } // no longer need the forward mode sparsity pattern // (have to reconstruct them every time) f_.size_forward_set(0); return ok; }
/*! Link from user_atomic to forward sparse Jacobian \copydetails atomic_base::for_sparse_jac */ virtual bool for_sparse_jac( size_t q , const vector< std::set<size_t> >& r , vector< std::set<size_t> >& s ) { bool ok = true; s = f_.ForSparseJac(q, r); // no longer need the forward mode sparsity pattern // (have to reconstruct them every time) f_.size_forward_set(0); return ok; }