Ejemplo n.º 1
0
void ADFun<Base,RecBase>::ForSparseHesCase(
    const std::set<size_t>&   set_type         ,
    const SetVector&          r                ,
    const SetVector&          s                ,
    SetVector&                h                )
{
    // used to identify the RecBase type in calls to sweeps
    RecBase not_used_rec_base;
    //
    size_t n = Domain();
# ifndef NDEBUG
    size_t m = Range();
# endif
    std::set<size_t>::const_iterator itr_1;
    //
    // check SetVector is Simple Vector class with sets for elements
    CheckSimpleVector<std::set<size_t>, SetVector>(
        local::one_element_std_set<size_t>(), local::two_element_std_set<size_t>()
    );
    CPPAD_ASSERT_KNOWN(
        r.size() == 1,
        "ForSparseHes: size of s is not equal to one."
    );
    CPPAD_ASSERT_KNOWN(
        s.size() == 1,
        "ForSparseHes: size of s is not equal to one."
    );
    //
    // sparsity pattern corresponding to r
    local::sparse_list for_jac_pattern;
    for_jac_pattern.resize(num_var_tape_, n + 1);
    itr_1 = r[0].begin();
    while( itr_1 != r[0].end() )
    {   size_t i = *itr_1++;
        CPPAD_ASSERT_UNKNOWN( ind_taddr_[i] < n + 1 );
        // ind_taddr_[i] is operator taddr for i-th independent variable
        CPPAD_ASSERT_UNKNOWN( play_.GetOp( ind_taddr_[i] ) == local::InvOp );
        //
        // Use add_element when only adding one element per set is added.
        for_jac_pattern.add_element( ind_taddr_[i], ind_taddr_[i] );
    }
    // compute forward Jacobiain sparsity pattern
    bool dependency = false;
    local::sweep::for_jac<addr_t>(
        &play_,
        dependency,
        n,
        num_var_tape_,
        for_jac_pattern,
        not_used_rec_base

    );
    // sparsity pattern correspnding to s
    local::sparse_list rev_jac_pattern;
    rev_jac_pattern.resize(num_var_tape_, 1);
    itr_1 = s[0].begin();
    while( itr_1 != s[0].end() )
    {   size_t i = *itr_1++;
        CPPAD_ASSERT_KNOWN(
            i < m,
            "ForSparseHes: an element of the set s[0] has value "
            "greater than or equal m"
        );
        CPPAD_ASSERT_UNKNOWN( dep_taddr_[i] < num_var_tape_ );
        //
        // Use add_element when only adding one element per set is added.
        rev_jac_pattern.add_element( dep_taddr_[i], 0);
    }
    //
    // compute reverse sparsity pattern for dependency analysis
    // (note that we are only want non-zero derivatives not true dependency)
    local::sweep::rev_jac<addr_t>(
        &play_,
        dependency,
        n,
        num_var_tape_,
        rev_jac_pattern,
        not_used_rec_base

    );
    //
    // vector of sets that will hold reverse Hessain values
    local::sparse_list for_hes_pattern;
    for_hes_pattern.resize(n+1, n+1);
    //
    // compute the Hessian sparsity patterns
    local::sweep::for_hes<addr_t>(
        &play_,
        n,
        num_var_tape_,
        for_jac_pattern,
        rev_jac_pattern,
        for_hes_pattern,
        not_used_rec_base

    );
    // return values corresponding to independent variables
    // j is index corresponding to reverse mode partial
    h.resize(n);
    CPPAD_ASSERT_UNKNOWN( for_hes_pattern.end() == n+1 );
    for(size_t i = 0; i < n; i++)
    {   CPPAD_ASSERT_UNKNOWN( ind_taddr_[i] == i + 1 );
        CPPAD_ASSERT_UNKNOWN( play_.GetOp( ind_taddr_[i] ) == local::InvOp );

        // extract the result from for_hes_pattern
        local::sparse_list::const_iterator itr_2(for_hes_pattern, ind_taddr_[i] );
        size_t j = *itr_2;
        while( j < for_hes_pattern.end() )
        {   CPPAD_ASSERT_UNKNOWN( 0 < j )
                h[i].insert(j-1);
            j = *(++itr_2);
        }
    }
}
Ejemplo n.º 2
0
void ADFun<Base,RecBase>::ForSparseHesCase(
    bool              set_type         ,
    const SetVector&  r                ,
    const SetVector&  s                ,
    SetVector&        h                )
{
    // used to identify the RecBase type in calls to sweeps
    RecBase not_used_rec_base;
    //
    size_t n = Domain();
    size_t m = Range();
    //
    // check Vector is Simple SetVector class with bool elements
    CheckSimpleVector<bool, SetVector>();
    //
    CPPAD_ASSERT_KNOWN(
        size_t(r.size()) == n,
        "ForSparseHes: size of r is not equal to\n"
        "domain dimension for ADFun object."
    );
    CPPAD_ASSERT_KNOWN(
        size_t(s.size()) == m,
        "ForSparseHes: size of s is not equal to\n"
        "range dimension for ADFun object."
    );
    //
    // sparsity pattern corresponding to r
    local::sparse_pack for_jac_pattern;
    for_jac_pattern.resize(num_var_tape_, n + 1);
    for(size_t i = 0; i < n; i++)
    {   CPPAD_ASSERT_UNKNOWN( ind_taddr_[i] < n + 1 );
        // ind_taddr_[i] is operator taddr for i-th independent variable
        CPPAD_ASSERT_UNKNOWN( play_.GetOp( ind_taddr_[i] ) == local::InvOp );
        //
        // Use add_element when only adding one element per set is added.
        if( r[i] )
            for_jac_pattern.add_element( ind_taddr_[i], ind_taddr_[i] );
    }
    // compute forward Jacobiain sparsity pattern
    bool dependency = false;
    local::sweep::for_jac<addr_t>(
        &play_,
        dependency,
        n,
        num_var_tape_,
        for_jac_pattern,
        not_used_rec_base

    );
    // sparsity pattern correspnding to s
    local::sparse_pack rev_jac_pattern;
    rev_jac_pattern.resize(num_var_tape_, 1);
    for(size_t i = 0; i < m; i++)
    {   CPPAD_ASSERT_UNKNOWN( dep_taddr_[i] < num_var_tape_ );
        //
        // Use add_element when only adding one element per set is added.
        if( s[i] )
            rev_jac_pattern.add_element( dep_taddr_[i], 0);
    }
    // compute reverse sparsity pattern for dependency analysis
    // (note that we are only want non-zero derivatives not true dependency)
    local::sweep::rev_jac<addr_t>(
        &play_,
        dependency,
        n,
        num_var_tape_,
        rev_jac_pattern,
        not_used_rec_base

    );
    // vector of sets that will hold the forward Hessain values
    local::sparse_pack for_hes_pattern;
    for_hes_pattern.resize(n+1, n+1);
    //
    // compute the Hessian sparsity patterns
    local::sweep::for_hes<addr_t>(
        &play_,
        n,
        num_var_tape_,
        for_jac_pattern,
        rev_jac_pattern,
        for_hes_pattern,
        not_used_rec_base

    );
    // initialize return values corresponding to independent variables
    h.resize(n * n);
    for(size_t i = 0; i < n; i++)
    {   for(size_t j = 0; j < n; j++)
            h[ i * n + j ] = false;
    }
    // copy to result pattern
    CPPAD_ASSERT_UNKNOWN( for_hes_pattern.end() == n+1 );
    for(size_t i = 0; i < n; i++)
    {   // ind_taddr_[i] is operator taddr for i-th independent variable
        CPPAD_ASSERT_UNKNOWN( ind_taddr_[i] == i + 1 );
        CPPAD_ASSERT_UNKNOWN( play_.GetOp( ind_taddr_[i] ) == local::InvOp );

        // extract the result from for_hes_pattern
        local::sparse_pack::const_iterator itr(for_hes_pattern, ind_taddr_[i] );
        size_t j = *itr;
        while( j < for_hes_pattern.end() )
        {   CPPAD_ASSERT_UNKNOWN( 0 < j )
            h[ i * n + (j-1) ] = true;
            j = *(++itr);
        }
    }
}