Atomic Sparsity with Set Patterns: Example and Test
function
For this example, the atomic function
@(@
f : \B{R}^3 \rightarrow \B{R}^2
@)@ is defined by
@[@
f( x ) = \left( \begin{array}{c}
x_2 \\
x_0 * x_1
\end{array} \right)
@]@
# include <cppad/cppad.hpp>
namespace { // isolate items below to this fileusing CppAD::vector; // vectortypedef vector< std::set<size_t> > set_vector; // atomic_sparsity//// a utility to compute the union of two sets.using CppAD::set_union;
//class atomic_set_sparsity : public CppAD::atomic_base<double> {
virtual bool for_sparse_hes(
const vector<bool>& vx,
const vector<bool>& r ,
const vector<bool>& s ,
set_vector& h ,
const vector<double>& x )
{
size_t n = r.size();
# ifndef NDEBUG
size_t m = s.size();
# endifassert( x.size() == n );
assert( h.size() == n );
assert( n == 3 );
assert( m == 2 );
// initialize h as emptyfor(size_t i = 0; i < n; i++)
h[i].clear();
// only f_1 has a non-zero hessianif( ! s[1] )
returntrue;
// only the cross term between x[0] and x[1] is non-zeroif( ! ( r[0] & r[1] ) )
returntrue;
// set the possibly non-zero terms in the hessian
h[0].insert(1);
h[1].insert(0);
returntrue;
}
// correct Jacobian result
set_vector check_s(m);
check_s[0].insert(2);
check_s[1].insert(0);
check_s[1].insert(1);
// compute and test forward mode
{ set_vector r(n), s(m);
for(size_t i = 0; i < n; i++)
r[i].insert(i);
s = f.ForSparseJac(n, r);
for(size_t i = 0; i < m; i++)
ok &= s[i] == check_s[i];
}
// compute and test reverse mode
{ set_vector r(m), s(m);
for(size_t i = 0; i < m; i++)
r[i].insert(i);
s = f.RevSparseJac(m, r);
for(size_t i = 0; i < m; i++)
ok &= s[i] == check_s[i];
}
// correct Hessian result
set_vector check_h(n);
check_h[0].insert(1);
check_h[1].insert(0);
// compute and test forward mode
{ set_vector r(1), s(1), h(n);
for(size_t i = 0; i < m; i++)
s[0].insert(i);
for(size_t j = 0; j < n; j++)
r[0].insert(j);
h = f.ForSparseHes(r, s);
for(size_t i = 0; i < n; i++)
ok &= h[i] == check_h[i];
}
rev_sparse_hes
Note the previous call to ForSparseJac above
stored its results in
f
.
// compute and test reverse mode
{ set_vector s(1), h(n);
for(size_t i = 0; i < m; i++)
s[0].insert(i);
h = f.RevSparseHes(n, s);
for(size_t i = 0; i < n; i++)
ok &= h[i] == check_h[i];
}