valvector_ad_split.cpp

View page source

Example 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;
}