/*! Link from user_atomic to forward mode \copydetails atomic_base::forward */ virtual bool forward( size_t p , size_t q , const vector<bool>& vx , vector<bool>& vy , const vector<Base>& tx , vector<Base>& ty ) { CPPAD_ASSERT_UNKNOWN( f_.size_var() > 0 ); CPPAD_ASSERT_UNKNOWN( tx.size() % (q+1) == 0 ); CPPAD_ASSERT_UNKNOWN( ty.size() % (q+1) == 0 ); size_t n = tx.size() / (q+1); size_t m = ty.size() / (q+1); bool ok = true; size_t i, j; // 2DO: test both forward and reverse vy information if( vx.size() > 0 ) { //Compute Jacobian sparsity pattern. vector< std::set<size_t> > s(m); if( n <= m ) { vector< std::set<size_t> > r(n); for(j = 0; j < n; j++) r[j].insert(j); s = f_.ForSparseJac(n, r); } else { vector< std::set<size_t> > r(m); for(i = 0; i < m; i++) r[i].insert(i); s = f_.RevSparseJac(m, r); } std::set<size_t>::const_iterator itr; for(i = 0; i < m; i++) { vy[i] = false; for(itr = s[i].begin(); itr != s[i].end(); itr++) { j = *itr; assert( j < n ); // y[i] depends on the value of x[j] vy[i] |= vx[j]; } } } ty = f_.Forward(q, tx); // no longer need the Taylor coefficients in f_ // (have to reconstruct them every time) size_t c = 0; size_t r = 0; f_.capacity_order(c, r); return ok; }
/*! Link from user_atomic to reverse mode \copydetails atomic_base::reverse */ virtual bool reverse( size_t q , const vector<Base>& tx , const vector<Base>& ty , vector<Base>& px , const vector<Base>& py ) { CPPAD_ASSERT_UNKNOWN( f_.size_var() > 0 ); CPPAD_ASSERT_UNKNOWN( tx.size() % (q+1) == 0 ); CPPAD_ASSERT_UNKNOWN( ty.size() % (q+1) == 0 ); bool ok = true; // put proper forward mode coefficients in f_ # ifdef NDEBUG f_.Forward(q, tx); # else size_t n = tx.size() / (q+1); size_t m = ty.size() / (q+1); CPPAD_ASSERT_UNKNOWN( px.size() == n * (q+1) ); CPPAD_ASSERT_UNKNOWN( py.size() == m * (q+1) ); size_t i, j, k; // vector<Base> check_ty = f_.Forward(q, tx); for(i = 0; i < m; i++) { for(k = 0; k <= q; k++) { j = i * (q+1) + k; CPPAD_ASSERT_UNKNOWN( check_ty[j] == ty[j] ); } } # endif // now can run reverse mode px = f_.Reverse(q+1, py); // no longer need the Taylor coefficients in f_ // (have to reconstruct them every time) size_t c = 0; size_t r = 0; f_.capacity_order(c, r); return ok; }