ADFun Check and Re-Tape: Example and Test
Keywords: adfun check re-tape: example test Funcheck Dependent

| Prev | Next |  |  |  |  |  | fun_check.cpp | Headings

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;

    	// 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 = 1e-10;
    	double a = 1e-10;
    	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/fun_check.cpp