\(\newcommand{\W}[1]{ \; #1 \; }\) \(\newcommand{\R}[1]{ {\rm #1} }\) \(\newcommand{\B}[1]{ {\bf #1} }\) \(\newcommand{\D}[2]{ \frac{\partial #1}{\partial #2} }\) \(\newcommand{\DD}[3]{ \frac{\partial^2 #1}{\partial #2 \partial #3} }\) \(\newcommand{\Dpow}[2]{ \frac{\partial^{#1}}{\partial {#2}^{#1}} }\) \(\newcommand{\dpow}[2]{ \frac{ {\rm d}^{#1}}{{\rm d}\, {#2}^{#1}} }\)
valvector_ad_split.cpp¶
View page sourceExample and Test of Splitting a valvector¶
# include <cppad/example/valvector/split_join.hpp>
# include <cppad/cppad.hpp>
bool ad_split(void)
{ // ok
bool ok = true;
//
// sparsity_type
typedef CppAD::sparse_rc< CPPAD_TESTVECTOR(size_t) > sparsity_type;
//
// scalar_type
typedef valvector::scalar_type scalar_type;
//
// ad_valvector
typedef CppAD::AD<valvector> ad_valvector;
//
// asplit
valvector_ad_split asplit;
//
// n, m
size_t n = 1;
size_t m = 10;
//
// ax
CPPAD_TESTVECTOR( ad_valvector ) ax(n);
ax[0] = valvector(0);
CppAD::Independent(ax);
//
// ax_sq
ad_valvector ax_sq = ax[0] * ax[0];
//
// f
CPPAD_TESTVECTOR( ad_valvector ) ay(m);
asplit(ax_sq, ay);
CppAD::ADFun<valvector> f(ax, ay);
//
// x
CPPAD_TESTVECTOR( valvector ) x(n);
x[0].resize(m);
for(size_t i = 0; i < m; ++i)
x[0][i] = scalar_type(i + 1);
//
// y
CPPAD_TESTVECTOR( valvector ) y(m);
y = f.Forward(0, x);
//
// ok
for(size_t i = 0; i < m; ++i)
ok &= y[i][0] == x[0][i] * x[0][i];
//
// dw
CPPAD_TESTVECTOR( valvector ) w(m), dw(n);
for(size_t i = 0; i < m; ++i)
w[i][0] = 1.0;
dw = f.Reverse(1, w);
//
// ok
for(size_t i = 0; i < m; ++i)
ok &= dw[0][i] == scalar_type(2) * x[0][i];
//
// jac_pattern
sparsity_type identity_pattern(n, n, n);
identity_pattern.set(0, 0, 0);
bool transpose = false;
bool dependency = false;
bool internal_bool = false;
sparsity_type jac_pattern;
f.for_jac_sparsity(
identity_pattern, transpose, dependency, internal_bool, jac_pattern
);
//
// ok
ok &= jac_pattern.nnz() == m;
ok &= jac_pattern.nr() == m;
ok &= jac_pattern.nc() == n;
CPPAD_TESTVECTOR(size_t) col_major = jac_pattern.col_major();
for(size_t k = 0; k < m; ++k)
{ ok &= jac_pattern.row()[k] == k;
ok &= jac_pattern.col()[k] == 0;
}
//
// hes_pattern
internal_bool = false;
CPPAD_TESTVECTOR(bool) select_domain(n);
CPPAD_TESTVECTOR(bool) select_range(m);
select_domain[0] = true;
for(size_t i = 0; i < m; ++i)
select_range[i] = false;
select_range[0] = true;
sparsity_type hes_pattern;
f.for_hes_sparsity (
select_domain , select_range , internal_bool , hes_pattern
);
//
// ok
ok &= hes_pattern.nnz() == 1;
ok &= hes_pattern.nr() == n;
ok &= hes_pattern.nc() == n;
ok &= hes_pattern.row()[0] == 0;
ok &= hes_pattern.col()[0] == 0;
//
// af
typedef CppAD::ADFun<ad_valvector, valvector> ad_fun_type;
ad_fun_type af = ad_fun_type( f.base2ad() );
//
// g
CPPAD_TESTVECTOR( ad_valvector ) adx(n), ady(m);
adx[0] = valvector( 1.0 );
CppAD::Independent(ax);
af.Forward(0, ax);
ady = af.Forward(1, adx);
CppAD::ADFun<valvector> g(ax, ady);
//
// ok
CPPAD_TESTVECTOR( valvector ) dy(m);
dy = g.Forward(0, x);
for(size_t i = 0; i < m; ++i)
ok &= dy[i][0] == 2.0 * x[0][i];
//
// h
CPPAD_TESTVECTOR( ad_valvector ) aw(m), adw(n);
for(size_t i = 0; i < m; ++i)
aw[i] = valvector( 1.0 );
CppAD::Independent(ax);
af.Forward(0, ax);
adw = af.Reverse(1, aw);
CppAD::ADFun<valvector> h(ax, adw);
//
// ok
dw = h.Forward(0, x);
for(size_t i = 0; i < m; ++i)
ok &= dw[0][i] == 2.0 * x[0][i];
//
// ok
f.optimize();
y = f.Forward(0, x);
for(size_t i = 0; i < m; ++i)
ok &= y[i][0] == x[0][i] * x[0][i];
//
return ok;
}