Prev Next fun_check.cpp Headings

@(@\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 .
ADFun Check and Re-Tape: Example and Test
# include <cppad/cppad.hpp>

namespace { // -----------------------------------------------------------
// define the template function object Fun<Type,Vector> in empty namespace
template <class Type, class Vector>
class Fun {
private:
    size_t n;
public:
    // function constructor
    Fun(size_t n_) : n(n_)
    { }
    // function evaluator
    Vector operator() (const Vector &x)
    {   Vector y(n);
        size_t i;
        for(i = 0; i < n; i++)
        {   // This operaiton sequence depends on x
            if( x[i] >= 0 )
                y[i] = exp(x[i]);
            else
                y[i] = exp(-x[i]);
        }
        return y;
    }
};
// template function FunCheckCases<Vector, ADVector> in empty namespace
template <class Vector, class ADVector>
bool FunCheckCases(void)
{   bool ok = true;
    using CppAD::AD;
    using CppAD::ADFun;
    using CppAD::Independent;
    double eps99 = 99.0 * std::numeric_limits<double>::epsilon();

    // use the ADFun default constructor
    ADFun<double> f;

    // domain space vector
    size_t n = 2;
    ADVector X(n);
    X[0] = -1.;
    X[1] = 1.;

    // declare independent variables and starting recording
    Independent(X);

    // create function object to use with AD<double>
    Fun< AD<double>, ADVector > G(n);

    // range space vector
    size_t m = n;
    ADVector Y(m);
    Y = G(X);

    // stop tape and store operation sequence in f : X -> Y
    f.Dependent(X, Y);
    ok &= (f.size_order() == 0);  // no implicit forward operation

    // create function object to use with double
    Fun<double, Vector> g(n);

    // function values should agree when the independent variable
    // values are the same as during recording
    Vector x(n);
    size_t j;
    for(j = 0; j < n; j++)
        x[j] = Value(X[j]);
    double r = eps99;
    double a = eps99;
    ok      &= FunCheck(f, g, x, a, r);

    // function values should not agree when the independent variable
    // values are the negative of values during recording
    for(j = 0; j < n; j++)
        x[j] = - Value(X[j]);
    ok      &= ! FunCheck(f, g, x, a, r);

    // re-tape to obtain the new AD of double operation sequence
    for(j = 0; j < n; j++)
        X[j] = x[j];
    Independent(X);
    Y = G(X);

    // stop tape and store operation sequence in f : X -> Y
    f.Dependent(X, Y);
    ok &= (f.size_order() == 0);  // no implicit forward with this x

    // function values should agree now
    ok      &= FunCheck(f, g, x, a, r);

    return ok;
}
} // End empty namespace
# include <vector>
# include <valarray>
bool FunCheck(void)
{   bool ok = true;
    typedef CppAD::vector<double>                Vector1;
    typedef CppAD::vector< CppAD::AD<double> > ADVector1;
    typedef   std::vector<double>                Vector2;
    typedef   std::vector< CppAD::AD<double> > ADVector2;
    typedef std::valarray<double>                Vector3;
    typedef std::valarray< CppAD::AD<double> > ADVector3;
    // Run with Vector and ADVector equal to three different cases
    // all of which are Simple Vectors with elements of type
    // double and AD<double> respectively.
    ok &= FunCheckCases< Vector1, ADVector2 >();
    ok &= FunCheckCases< Vector2, ADVector3 >();
    ok &= FunCheckCases< Vector3, ADVector1 >();
    return ok;
}

Input File: example/general/fun_check.cpp