zdouble: Example and Test
Keywords: zdouble: example test

| Prev | Next |  |  |  |  |  | zdouble.cpp | Headings

zdouble: Example and Test
`

    # include <cppad/cppad.hpp>

    namespace {
    	template <class Base> bool test(bool is_double)
    	{	bool ok = true;
    		Base eps = 10. * std::numeric_limits<double>::epsilon();

    		typedef CppAD::AD<Base>   a1type;
    		typedef CppAD::AD<a1type> a2type;

    		// value during taping
    		size_t n = 2;
    		CPPAD_TESTVECTOR(Base) x(n);
    		x[0] = 0.0;
    		x[1] = 0.0;

    		// declare independent variable
    		CPPAD_TESTVECTOR(a2type) a2x(n);
    		for (size_t j = 0; j < n; j++)
    			a2x[j] = a2type( a1type(x[j]) );
    		Independent(a2x);

    		// zero and one as a2type values
    		a2type a2zero = a2type(0.0);
    		a2type a2one  = a2type(1.0);

    		// h(x) = x[0] / x[1] if x[1] > x[0] else 1.0
    		a2type h_x = CondExpGt(a2x[1], a2x[0], a2x[0] / a2x[1], a2one);

    		// f(x) = h(x) if x[0] > 0.0 else 0.0
    		//      = x[0] / x[1] if x[1] > x[0]  and x[0] > 0.0
    		//      = 1.0         if x[0] >= x[1] and x[0] > 0.0
    		//      = 0.0         if x[0] <= 0.0
    		a2type f_x = CondExpGt(a2x[0], a2zero, h_x, a2one);

    		// define the function f(x)
    		size_t m = 1;
    		CPPAD_TESTVECTOR(a2type) a2y(m);
    		a2y[0] = f_x;
    		CppAD::ADFun<a1type> af1;
    		af1.Dependent(a2x, a2y);

    		// Define function g(x) = gradient of f(x)
    		CPPAD_TESTVECTOR(a1type) a1x(n), a1z(n), a1w(m);
    		for (size_t j = 0; j < n; j++)
    			a1x[j] = a1type(x[j]);
    		a1w[0] = a1type(1.0);
    		Independent(a1x);
    		af1.Forward(0, a1x);
    		a1z = af1.Reverse(1, a1w);
    		CppAD::ADFun<Base> g;
    		g.Dependent(a1x, a1z);

    		// check result for a case where f(x) = 0.0;
    		CPPAD_TESTVECTOR(Base) z(2);
    		x[0] = 0.0;
    		x[1] = 0.0;
    		z    = g.Forward(0, x);
    		ok &= z[0] == 0.0;
    		ok &= z[1] == 0.0;

    		// check result for a case where f(x) = 1.0;
    		x[0] = 1.0;
    		x[1] = 0.5;
    		z    = g.Forward(0, x);
    		ok &= z[0] == 0.0;
    		ok &= z[1] == 0.0;

    		// check result for a case where f(x) = x[0] / x[1];
    		x[0] = 1.0;
    		x[1] = 2.0;
    		z    = g.Forward(0, x);
    		ok &= CppAD::NearEqual(z[0], 1.0/x[1], eps, eps);
    		ok &= CppAD::NearEqual(z[1], - x[0]/(x[1]*x[1]), eps, eps);

    		return ok;
    	}
    }

    bool zdouble(void)
    {	bool ok = true;
    	using CppAD::AD;
    	using CppAD::NearEqual;
    	using CppAD::zdouble;
    	//
    	bool is_double = false;
    	ok &= test<zdouble>(is_double);
    	//
    	is_double = true;
    	ok &= test<double>(is_double);
    	//
    	return ok;
    }

`

Input File: test_more/zdouble.cpp