Prev Next atomic_four_lin_ode_rev_depend.hpp

@(@\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}} }@)@This is cppad-20221105 documentation. Here is a link to its current documentation .
Atomic Linear ODE Forward Type Calculation: Example Implementation

Purpose
The rev_depend routine overrides the virtual functions used by the atomic_four base; see rev_depend .

Notation
We use the notation: call_id r pattern transpose nnz , row , col , x , n , A(x) , b(x) , y(x) , m , vk(x) , and the following additional notation:

wk(x)
Note that the factor @(@ r / k @)@, in the definition of @(@ v^k (x) @)@, is constant (with respect to the variables). Hence it suffices to compute the dependency for @[@ h (x) = \sum_{k=0}^4 w^k (x) @]@ where @(@ w^0 (x) = b(x) @)@ and for @(@ k = 1, 2, \ldots @)@, @(@ w^k (x) = A(x) w^{k-1} (x) @)@.

Source

# include <cppad/example/atomic_four/lin_ode/lin_ode.hpp>

namespace CppAD { // BEGIN_CPPAD_NAMESPACE
//
// rev_depend override
template <class Base>
bool atomic_lin_ode<Base>::rev_depend(
    size_t                                         call_id,
    CppAD::vector<bool>&                           ident_zero_x,
    CppAD::vector<bool>&                           depend_x,
    const CppAD::vector<bool>&                     depend_y
)
{
    // nnz
    Base      r;
    Base      step;
    sparse_rc pattern;
    bool      transpose;
    get(call_id, r, step, pattern, transpose);
    size_t nnz = pattern.nnz();
    //
    // m
    size_t m = depend_y.size();
    CPPAD_ASSERT_UNKNOWN( ident_zero_x.size() == depend_x.size() );
    CPPAD_ASSERT_UNKNOWN( pattern.nr() == m );
    CPPAD_ASSERT_UNKNOWN( pattern.nc() == m );
    //
    // depend_w
    CppAD::vector<bool> depend_w = depend_y;
    //
    // depend_x
    for(size_t p = 0; p < nnz; ++p)
        depend_x[p] = false;
    for(size_t i = 0; i < m; ++i)
        depend_x[nnz + i] = depend_y[i];
    //
    // change
    // Did depend_w change during the previous iteration of the while loop
    bool change = true;
    while(change)
    {   change = false;
        // we use k = 1, 2, ... to denote the pass through this loop
        //
        // depend_w, depend_x
        // include depenency for w^k (x)
        for(size_t p = 0; p < nnz; ++p) if( ! ident_zero_x[p] )
        {   size_t i = pattern.row()[p];
            size_t j = pattern.col()[p];
            if( transpose )
                std::swap(i, j);
            //
            // back propagate depenency on y
            if( depend_w[i] && ! depend_w[j] )
            {   change      = true;
                depend_w[j] = true;
            }
            //
            // depend_x
            // for propage dependency on A_{i,j}
            if( depend_w[i] & ! depend_x[p] )
            {   change      = true;
                depend_x[p] = true;
            }
        }
    }
    //
    // depend_x
    // terms corresponding to b(x)
    for(size_t i = 0; i < m; ++i)
        depend_x[nnz + i] = depend_w[i];
    //
    return true;
}
} // END_CPPAD_NAMESPACE

Input File: include/cppad/example/atomic_four/lin_ode/rev_depend.hpp