Exemple #1
0
bool opt_val_hes(void)
{	bool ok = true;
	using CppAD::AD;
	using CppAD::NearEqual;

	// temporary indices
	size_t j, k;

	// x space vector
	size_t n = 1;
	BaseVector x(n);
	x[0] = 2. * 3.141592653;

	// y space vector
	size_t m = 1;
	BaseVector y(m);
	y[0] = 1.;

	// t and z vectors
	size_t ell = 10;
	BaseVector t(ell);
	BaseVector z(ell);
	for(k = 0; k < ell; k++)
	{	t[k] = double(k) / double(ell);       // time of measurement
		z[k] = y[0] * sin( x[0] * t[k] );     // data without noise
	}

	// construct the function object
	Fun fun(t, z);

	// evaluate the Jacobian and Hessian
	BaseVector jac(n), hes(n * n);
	int signdet = CppAD::opt_val_hes(x, y, fun, jac, hes);

	// we know that F_yy is positive definate for this case
	assert( signdet == 1 );

	// create ADFun object g corresponding to V(x)
	ADVector a_x(n), a_v(1);
	for(j = 0; j < n; j++)
		a_x[j] = x[j];
	Independent(a_x);
	a_v[0] = V(a_x, t, z);
	CppAD::ADFun<double> g(a_x, a_v);

	// accuracy for checks
	double eps = 10. * CppAD::numeric_limits<double>::epsilon();

	// check Jacobian
	BaseVector check_jac = g.Jacobian(x);
	for(j = 0; j < n; j++)
		ok &= NearEqual(jac[j], check_jac[j], eps, eps);

	// check Hessian
	BaseVector check_hes = g.Hessian(x, 0);
	for(j = 0; j < n*n; j++)
		ok &= NearEqual(hes[j], check_hes[j], eps, eps);

	return ok;
}
Exemple #2
0
bool interp_retape(void)
{	bool ok = true;

	using CppAD::AD;
	using CppAD::NearEqual;

	// domain space vector
	size_t n = 1;
	CPPAD_TESTVECTOR(AD<double>) X(n);

	// loop over argument values
	size_t k;
	for(k = 0; k < TableLength - 1; k++)
	{
		X[0] = .4 * ArgumentValue[k] + .6 * ArgumentValue[k+1];

		// declare independent variables and start tape recording
		// (use a different tape for each argument value)
		CppAD::Independent(X);

		// evaluate piecewise linear interpolant at X[0]
		AD<double> A = Argument(X[0]);
		AD<double> F = Function(X[0]);
		AD<double> S = Slope(X[0]);
		AD<double> I = F + (X[0] - A) * S;

		// range space vector
		size_t m = 1;
		CPPAD_TESTVECTOR(AD<double>) Y(m);
		Y[0] = I;

		// create f: X -> Y and stop tape recording
		CppAD::ADFun<double> f(X, Y);

		// vectors for arguments to the function object f
		CPPAD_TESTVECTOR(double) x(n);   // argument values
		CPPAD_TESTVECTOR(double) y(m);   // function values
		CPPAD_TESTVECTOR(double) dx(n);  // differentials in x space
		CPPAD_TESTVECTOR(double) dy(m);  // differentials in y space

		// to check function value we use the fact that X[0] is between
		// ArgumentValue[k] and ArgumentValue[k+1]
		double delta, check;
		x[0]   = Value(X[0]);
		delta  = ArgumentValue[k+1] - ArgumentValue[k];
		check  = FunctionValue[k+1] * (x[0]-ArgumentValue[k]) / delta
	               + FunctionValue[k] * (ArgumentValue[k+1]-x[0]) / delta;
		ok    &= NearEqual(Y[0], check, 1e-10, 1e-10);

		// evaluate partials w.r.t. x[0]
		dx[0] = 1.;
		dy    = f.Forward(1, dx);

		// check that the derivative is the slope
		check = (FunctionValue[k+1] - FunctionValue[k])
		      / (ArgumentValue[k+1] - ArgumentValue[k]);
		ok   &= NearEqual(dy[0], check, 1e-10, 1e-10);
	}
	return ok;
}
Exemple #3
0
bool BenderQuad(void)
{	bool ok = true;
	using CppAD::AD;
	using CppAD::NearEqual;

	// temporary indices
	size_t i, j;

	// x space vector
	size_t n = 1;
	BAvector x(n);
	x[0] = 2. * 3.141592653;

	// y space vector
	size_t m = 1;
	BAvector y(m);
	y[0] = 1.;

	// t and z vectors
	size_t N = 10;
	BAvector t(N);
	BAvector z(N);
	for(i = 0; i < N; i++)
	{	t[i] = double(i) / double(N);       // time of measurement
		z[i] = y[0] * sin( x[0] * t[i] );   // data without noise
	}

	// construct the function object
	Fun fun(t, z);

	// evaluate the G(x), G'(x) and G''(x)
	BAvector g(1), gx(n), gxx(n * n);
	CppAD::BenderQuad(x, y, fun, g, gx, gxx);


	// create ADFun object Gfun corresponding to G(x)
	ADvector a_x(n), a_g(1);
	for(j = 0; j < n; j++)
		a_x[j] = x[j];
	Independent(a_x);
	a_g[0] = G(a_x, t, z);
	CppAD::ADFun<double> Gfun(a_x, a_g);

	// accuracy for checks
	double eps = 10. * CppAD::numeric_limits<double>::epsilon();

	// check Jacobian
	BAvector check_gx = Gfun.Jacobian(x);
	for(j = 0; j < n; j++)
		ok &= NearEqual(gx[j], check_gx[j], eps, eps);

	// check Hessian
	BAvector check_gxx = Gfun.Hessian(x, 0);
	for(j = 0; j < n*n; j++)
		ok &= NearEqual(gxx[j], check_gxx[j], eps, eps);

	return ok;
}
Exemple #4
0
bool forward_order(void)
{	bool ok = true;
	using CppAD::AD;
	using CppAD::NearEqual;
	double eps = 10. * std::numeric_limits<double>::epsilon();

	// domain space vector
	size_t n = 2;
	CPPAD_TESTVECTOR(AD<double>) ax(n);
	ax[0] = 0.;
	ax[1] = 1.;

	// declare independent variables and starting recording
	CppAD::Independent(ax);

	// range space vector
	size_t m = 1;
	CPPAD_TESTVECTOR(AD<double>) ay(m);
	ay[0] = ax[0] * ax[0] * ax[1];

	// create f: x -> y and stop tape recording
	CppAD::ADFun<double> f(ax, ay);

	// initially, the variable values during taping are stored in f
	ok &= f.size_order() == 1;

	// Compute three forward orders at one
	size_t q = 2, q1 = q+1;
	CPPAD_TESTVECTOR(double) xq(n*q1), yq;
	xq[q1*0 + 0] = 3.;    xq[q1*1 + 0] = 4.; // x^0 (order zero)
	xq[q1*0 + 1] = 1.;    xq[q1*1 + 1] = 0.; // x^1 (order one)
	xq[q1*0 + 2] = 0.;    xq[q1*1 + 2] = 0.; // x^2 (order two)
	// X(t) =   x^0 + x^1 * t + x^2 * t^2
	//      = [ 3 + t, 4 ]
	yq  = f.Forward(q, xq);
	ok &= size_t( yq.size() ) == m*q1;
	// Y(t) = F[X(t)]
	//      = (3 + t) * (3 + t) * 4
	//      = y^0 + y^1 * t + y^2 * t^2 + o(t^3)
	//
	// check y^0 (order zero)
	CPPAD_TESTVECTOR(double) x0(n);
	x0[0] = xq[q1*0 + 0];
	x0[1] = xq[q1*1 + 0];
	ok  &= NearEqual(yq[q1*0 + 0] , x0[0]*x0[0]*x0[1], eps, eps);
	//
	// check y^1 (order one)
	ok  &= NearEqual(yq[q1*0 + 1] , 2.*x0[0]*x0[1], eps, eps);
	//
	// check y^2 (order two)
	double F_00 = 2. * yq[q1*0 + 2]; // second partial F w.r.t. x_0, x_0
	ok   &= NearEqual(F_00, 2.*x0[1], eps, eps);

	// check number of orders per variable
	ok   &= f.size_order() == 3;

	return ok;
}
Exemple #5
0
bool atanh(void)
{   bool ok = true;

    using CppAD::AD;
    using CppAD::NearEqual;

    // 10 times machine epsilon
    double eps = 10. * std::numeric_limits<double>::epsilon();

    // domain space vector
    size_t n  = 1;
    double x0 = 0.5;
    CPPAD_TESTVECTOR(AD<double>) ax(n);
    ax[0]     = x0;

    // declare independent variables and start tape recording
    CppAD::Independent(ax);

    // a temporary value
    AD<double> tanh_of_x0 = CppAD::tanh(ax[0]);

    // range space vector
    size_t m = 1;
    CPPAD_TESTVECTOR(AD<double>) ay(m);
    ay[0] = CppAD::atanh(tanh_of_x0);

    // create f: x -> y and stop tape recording
    CppAD::ADFun<double> f(ax, ay);

    // check value
    ok &= NearEqual(ay[0] , x0,  eps, eps);

    // forward computation of first partial w.r.t. x[0]
    CPPAD_TESTVECTOR(double) dx(n);
    CPPAD_TESTVECTOR(double) dy(m);
    dx[0] = 1.;
    dy    = f.Forward(1, dx);
    ok   &= NearEqual(dy[0], 1., eps, eps);

    // forward computation of higher order partials w.r.t. x[0]
    size_t n_order = 5;
    for(size_t order = 2; order < n_order; order++)
    {   dx[0] = 0.;
        dy    = f.Forward(order, dx);
        ok   &= NearEqual(dy[0], 0., eps, eps);
    }
    // reverse computation of derivatives
    CPPAD_TESTVECTOR(double)  w(m);
    CPPAD_TESTVECTOR(double) dw(n_order * n);
    w[0]  = 1.;
    dw    = f.Reverse(n_order, w);
    ok   &= NearEqual(dw[0], 1., eps, eps);
    for(size_t order = 1; order < n_order; order++)
        ok   &= NearEqual(dw[order * n + 0], 0., eps, eps);

    return ok;
}
Exemple #6
0
bool Div(void)
{	bool ok = true;
	using CppAD::AD;
	using CppAD::NearEqual;
	double eps99 = 99.0 * std::numeric_limits<double>::epsilon();


	// domain space vector
	size_t n  = 1;
	double x0 = 0.5;
	CPPAD_TESTVECTOR(AD<double>) x(n);
	x[0]      = x0;

	// declare independent variables and start tape recording
	CppAD::Independent(x);

	// some binary division operations
	AD<double> a = x[0] / 1.; // AD<double> / double
	AD<double> b = a  / 2;    // AD<double> / int
	AD<double> c = 3. / b;    // double     / AD<double>
	AD<double> d = 4  / c;    // int        / AD<double>

	// range space vector
	size_t m = 1;
	CPPAD_TESTVECTOR(AD<double>) y(m);
	y[0] = (x[0] * x[0]) / d;   // AD<double> / AD<double>

	// create f: x -> y and stop tape recording
	CppAD::ADFun<double> f(x, y);

	// check value
	ok &= NearEqual(y[0], x0*x0*3.*2.*1./(4.*x0), eps99, eps99);

	// forward computation of partials w.r.t. x[0]
	CPPAD_TESTVECTOR(double) dx(n);
	CPPAD_TESTVECTOR(double) dy(m);
	dx[0] = 1.;
	dy    = f.Forward(1, dx);
	ok   &= NearEqual(dy[0], 3.*2.*1./4., eps99, eps99);

	// reverse computation of derivative of y[0]
	CPPAD_TESTVECTOR(double)  w(m);
	CPPAD_TESTVECTOR(double) dw(n);
	w[0]  = 1.;
	dw    = f.Reverse(1, w);
	ok   &= NearEqual(dw[0], 3.*2.*1./4., eps99, eps99);

	// use a VecAD<Base>::reference object with division
	CppAD::VecAD<double> v(1);
	AD<double> zero(0);
	v[zero] = d;
	AD<double> result = (x[0] * x[0]) / v[zero];
	ok     &= (result == y[0]);

	return ok;
}
Exemple #7
0
bool atan2(void)
{	bool ok = true;

	using CppAD::AD;
	using CppAD::NearEqual;
	double eps99 = 99.0 * std::numeric_limits<double>::epsilon();

	// domain space vector
	size_t n  = 1;
	double x0 = 0.5;
	CPPAD_TESTVECTOR(AD<double>) x(n);
	x[0]      = x0;

	// declare independent variables and start tape recording
	CppAD::Independent(x);

	// a temporary value
	AD<double> sin_of_x0 = CppAD::sin(x[0]);
	AD<double> cos_of_x0 = CppAD::cos(x[0]);

	// range space vector
	size_t m = 1;
	CPPAD_TESTVECTOR(AD<double>) y(m);
	y[0] = CppAD::atan2(sin_of_x0, cos_of_x0);

	// create f: x -> y and stop tape recording
	CppAD::ADFun<double> f(x, y);

	// check value
	ok &= NearEqual(y[0] , x0, eps99, eps99);

	// forward computation of first partial w.r.t. x[0]
	CPPAD_TESTVECTOR(double) dx(n);
	CPPAD_TESTVECTOR(double) dy(m);
	dx[0] = 1.;
	dy    = f.Forward(1, dx);
	ok   &= NearEqual(dy[0], 1., eps99, eps99);

	// reverse computation of derivative of y[0]
	CPPAD_TESTVECTOR(double)  w(m);
	CPPAD_TESTVECTOR(double) dw(n);
	w[0]  = 1.;
	dw    = f.Reverse(1, w);
	ok   &= NearEqual(dw[0], 1., eps99, eps99);

	// use a VecAD<Base>::reference object with atan2
	CppAD::VecAD<double> v(2);
	AD<double> zero(0);
	AD<double> one(1);
	v[zero]           = sin_of_x0;
	v[one]            = cos_of_x0;
	AD<double> result = CppAD::atan2(v[zero], v[one]);
	ok               &= NearEqual(result, x0, eps99, eps99);

	return ok;
}
Exemple #8
0
bool AddEq(void)
{   bool ok = true;
    using CppAD::AD;
    using CppAD::NearEqual;
    double eps99 = 99.0 * std::numeric_limits<double>::epsilon();

    // domain space vector
    size_t  n = 1;
    double x0 = .5;
    CPPAD_TESTVECTOR(AD<double>) x(n);
    x[0]      = x0;

    // declare independent variables and start tape recording
    CppAD::Independent(x);

    // range space vector
    size_t m = 2;
    CPPAD_TESTVECTOR(AD<double>) y(m);
    y[0] = x[0];         // initial value
    y[0] += 2;           // AD<double> += int
    y[0] += 4.;          // AD<double> += double
    y[1] = y[0] += x[0]; // use the result of a compound assignment

    // create f: x -> y and stop tape recording
    CppAD::ADFun<double> f(x, y);

    // check value
    ok &= NearEqual(y[0] , x0+2.+4.+x0, eps99, eps99);
    ok &= NearEqual(y[1] ,        y[0], eps99, eps99);

    // forward computation of partials w.r.t. x[0]
    CPPAD_TESTVECTOR(double) dx(n);
    CPPAD_TESTVECTOR(double) dy(m);
    dx[0] = 1.;
    dy    = f.Forward(1, dx);
    ok   &= NearEqual(dy[0], 2., eps99, eps99);
    ok   &= NearEqual(dy[1], 2., eps99, eps99);

    // reverse computation of derivative of y[0]
    CPPAD_TESTVECTOR(double)  w(m);
    CPPAD_TESTVECTOR(double) dw(n);
    w[0]  = 1.;
    w[1]  = 0.;
    dw    = f.Reverse(1, w);
    ok   &= NearEqual(dw[0], 2., eps99, eps99);

    // use a VecAD<Base>::reference object with computed addition
    CppAD::VecAD<double> v(1);
    AD<double> zero(0);
    AD<double> result = 1;
    v[zero] = 2;
    result += v[zero];
    ok     &= (result == 3);

    return ok;
}
Exemple #9
0
bool pow_int(void)
{	bool ok = true;

	using CppAD::AD;
	using CppAD::NearEqual;

	// declare independent variables and start tape recording
	size_t n  = 1;
	double x0 = -0.5;
	CPPAD_TESTVECTOR(AD<double>) x(n);
	x[0]      = x0;
	CppAD::Independent(x);

	// dependent variable vector
	size_t m = 7;
	CPPAD_TESTVECTOR(AD<double>) y(m);
	int i;
	for(i = 0; i < int(m); i++)
		y[i] = CppAD::pow(x[0], i - 3);

	// create f: x -> y and stop tape recording
	CppAD::ADFun<double> f(x, y);

	// check value
	double check;
	for(i = 0; i < int(m); i++)
	{	check = std::pow(x0, double(i - 3));
		ok &= NearEqual(y[i] , check,  1e-10 , 1e-10);
	}

	// forward computation of first partial w.r.t. x[0]
	CPPAD_TESTVECTOR(double) dx(n);
	CPPAD_TESTVECTOR(double) dy(m);
	dx[0] = 1.;
	dy    = f.Forward(1, dx);
	for(i = 0; i < int(m); i++)
	{	check = double(i-3) * std::pow(x0, double(i - 4));
		ok &= NearEqual(dy[i] , check,  1e-10 , 1e-10);
	}

	// reverse computation of derivative of y[i]
	CPPAD_TESTVECTOR(double)  w(m);
	CPPAD_TESTVECTOR(double) dw(n);
	for(i = 0; i < int(m); i++)
		w[i] = 0.;
	for(i = 0; i < int(m); i++)
	{	w[i] = 1.;
		dw    = f.Reverse(1, w);
		check = double(i-3) * std::pow(x0, double(i - 4));
		ok &= NearEqual(dw[0] , check,  1e-10 , 1e-10);
		w[i] = 0.;
	}

	return ok;
}
/* $$
$head Use Atomic Function$$
$codep */
bool get_started(void)
{	bool ok = true;
	using CppAD::AD;
	using CppAD::NearEqual;
	double eps = 10. * CppAD::numeric_limits<double>::epsilon();
/* $$
$subhead Constructor$$
$codep */
	// Create the atomic get_started object
	atomic_get_started afun("atomic_get_started");
/* $$
$subhead Recording$$
$codep */
	// Create the function f(x)
	//
	// domain space vector
	size_t n  = 1;
	double  x0 = 0.5;
	vector< AD<double> > ax(n);
	ax[0]     = x0;

	// declare independent variables and start tape recording
	CppAD::Independent(ax);

	// range space vector 
	size_t m = 1;
	vector< AD<double> > ay(m);

	// call user function and store get_started(x) in au[0] 
	vector< AD<double> > au(m);
	afun(ax, au);        // u = 1 / x

	// now use AD division to invert to invert the operation
	ay[0] = 1.0 / au[0]; // y = 1 / u = x

	// create f: x -> y and stop tape recording
	CppAD::ADFun<double> f;
	f.Dependent (ax, ay);  // f(x) = x
/* $$
$subhead forward$$
$codep */
	// check function value 
	double check = x0;
	ok &= NearEqual( Value(ay[0]) , check,  eps, eps);

	// check zero order forward mode
	size_t p;
	vector<double> x_p(n), y_p(m);
	p      = 0;
	x_p[0] = x0;
	y_p    = f.Forward(p, x_p);
	ok &= NearEqual(y_p[0] , check,  eps, eps);

	return ok;
}
Exemple #11
0
bool Add(void)
{	bool ok = true;
	using CppAD::AD;
	using CppAD::NearEqual;
	double eps99 = 99.0 * std::numeric_limits<double>::epsilon();

	// domain space vector
	size_t n  = 1;
	double x0 = 0.5;
	CPPAD_TESTVECTOR(AD<double>) x(n);
	x[0]      = x0;

	// declare independent variables and start tape recording
	CppAD::Independent(x);

	// some binary addition operations
	AD<double> a = x[0] + 1.; // AD<double> + double
	AD<double> b = a    + 2;  // AD<double> + int
	AD<double> c = 3.   + b;  // double     + AD<double>
	AD<double> d = 4    + c;  // int        + AD<double>

	// range space vector
	size_t m = 1;
	CPPAD_TESTVECTOR(AD<double>) y(m);
	y[0] = d + x[0];          // AD<double> + AD<double>

	// create f: x -> y and stop tape recording
	CppAD::ADFun<double> f(x, y);

	// check value
	ok &= NearEqual(y[0] , 2. * x0 + 10, eps99, eps99);

	// forward computation of partials w.r.t. x[0]
	CPPAD_TESTVECTOR(double) dx(n);
	CPPAD_TESTVECTOR(double) dy(m);
	dx[0] = 1.;
	dy    = f.Forward(1, dx);
	ok   &= NearEqual(dy[0], 2., eps99, eps99);

	// reverse computation of derivative of y[0]
	CPPAD_TESTVECTOR(double)  w(m);
	CPPAD_TESTVECTOR(double) dw(n);
	w[0]  = 1.;
	dw    = f.Reverse(1, w);
	ok   &= NearEqual(dw[0], 2., eps99, eps99);

	// use a VecAD<Base>::reference object with addition
	CppAD::VecAD<double> v(1);
	AD<double> zero(0);
	v[zero] = a;
	AD<double> result = v[zero] + 2;
	ok     &= (result == b);

	return ok;
}
Exemple #12
0
bool SubEq(void)
{	bool ok = true;
	using CppAD::AD;
	using CppAD::NearEqual;

	// domain space vector
	size_t  n = 1;
	double x0 = .5;
	CPPAD_TEST_VECTOR< AD<double> > x(n);
	x[0]      = x0; 

	// declare independent variables and start tape recording
	CppAD::Independent(x);

	// range space vector 
	size_t m = 2;
	CPPAD_TEST_VECTOR< AD<double> > y(m);
	y[0] = 3. * x[0];    // initial value
	y[0] -= 2;           // AD<double> -= int
	y[0] -= 4.;          // AD<double> -= double
	y[1] = y[0] -= x[0]; // use the result of a computed assignment

	// create f: x -> y and stop tape recording
	CppAD::ADFun<double> f(x, y); 

	// check value 
	ok &= NearEqual(y[0] , 3.*x0-(2.+4.+x0),  1e-10 , 1e-10);
	ok &= NearEqual(y[1] ,             y[0],  1e-10 , 1e-10);

	// forward computation of partials w.r.t. x[0]
	CPPAD_TEST_VECTOR<double> dx(n);
	CPPAD_TEST_VECTOR<double> dy(m);
	dx[0] = 1.;
	dy    = f.Forward(1, dx);
	ok   &= NearEqual(dy[0], 2., 1e-10, 1e-10);
	ok   &= NearEqual(dy[1], 2., 1e-10, 1e-10);

	// reverse computation of derivative of y[0]
	CPPAD_TEST_VECTOR<double>  w(m);
	CPPAD_TEST_VECTOR<double> dw(n);
	w[0]  = 1.;
	w[1]  = 0.;
	dw    = f.Reverse(1, w);
	ok   &= NearEqual(dw[0], 2., 1e-10, 1e-10);

	// use a VecAD<Base>::reference object with computed subtraction
	CppAD::VecAD<double> v(1);
	AD<double> zero(0);
	AD<double> result = 1;
	v[zero] = 2;
	result -= v[zero];
	ok     &= (result == -1);

	return ok;
}
Exemple #13
0
bool MulEq(void)
{   bool ok = true;
    using CppAD::AD;
    using CppAD::NearEqual;

    // domain space vector
    size_t  n = 1;
    double x0 = .5;
    CPPAD_TESTVECTOR(AD<double>) x(n);
    x[0]      = x0;

    // declare independent variables and start tape recording
    CppAD::Independent(x);

    // range space vector
    size_t m = 2;
    CPPAD_TESTVECTOR(AD<double>) y(m);
    y[0] = x[0];         // initial value
    y[0] *= 2;           // AD<double> *= int
    y[0] *= 4.;          // AD<double> *= double
    y[1] = y[0] *= x[0]; // use the result of a computed assignment

    // create f: x -> y and stop tape recording
    CppAD::ADFun<double> f(x, y);

    // check value
    ok &= NearEqual(y[0] , x0*2.*4.*x0,  1e-10 , 1e-10);
    ok &= NearEqual(y[1] ,        y[0],  1e-10 , 1e-10);

    // forward computation of partials w.r.t. x[0]
    CPPAD_TESTVECTOR(double) dx(n);
    CPPAD_TESTVECTOR(double) dy(m);
    dx[0] = 1.;
    dy    = f.Forward(1, dx);
    ok   &= NearEqual(dy[0], 8.*2.*x0, 1e-10, 1e-10);
    ok   &= NearEqual(dy[1], 8.*2.*x0, 1e-10, 1e-10);

    // reverse computation of derivative of y[0]
    CPPAD_TESTVECTOR(double)  w(m);
    CPPAD_TESTVECTOR(double) dw(n);
    w[0]  = 1.;
    w[1]  = 0.;
    dw    = f.Reverse(1, w);
    ok   &= NearEqual(dw[0], 8.*2.*x0, 1e-10, 1e-10);

    // use a VecAD<Base>::reference object with computed multiplication
    CppAD::VecAD<double> v(1);
    AD<double> zero(0);
    AD<double> result = 1;
    v[zero] = 2;
    result *= v[zero];
    ok     &= (result == 2);

    return ok;
}
Exemple #14
0
bool Mul(void)
{	bool ok = true;
	using CppAD::AD;
	using CppAD::NearEqual;

	// domain space vector
	size_t n  = 1;
	double x0 = .5;
	CPPAD_TEST_VECTOR< AD<double> > x(n);
	x[0]      = x0;

	// declare independent variables and start tape recording
	CppAD::Independent(x);

	// some binary multiplication operations
	AD<double> a = x[0] * 1.; // AD<double> * double
	AD<double> b = a    * 2;  // AD<double> * int
	AD<double> c = 3.   * b;  // double     * AD<double> 
	AD<double> d = 4    * c;  // int        * AD<double> 

	// range space vector 
	size_t m = 1;
	CPPAD_TEST_VECTOR< AD<double> > y(m);
	y[0] = x[0] * d;          // AD<double> * AD<double>

	// create f: x -> y and stop tape recording
	CppAD::ADFun<double> f(x, y); 

	// check value 
	ok &= NearEqual(y[0] , x0*(4.*3.*2.*1.)*x0,  1e-10 , 1e-10);

	// forward computation of partials w.r.t. x[0]
	CPPAD_TEST_VECTOR<double> dx(n);
	CPPAD_TEST_VECTOR<double> dy(m);
	dx[0] = 1.;
	dy    = f.Forward(1, dx);
	ok   &= NearEqual(dy[0], (4.*3.*2.*1.)*2.*x0, 1e-10 , 1e-10); 

	// reverse computation of derivative of y[0]
	CPPAD_TEST_VECTOR<double>  w(m);
	CPPAD_TEST_VECTOR<double> dw(n); 
	w[0]  = 1.;
	dw    = f.Reverse(1, w);
	ok   &= NearEqual(dw[0], (4.*3.*2.*1.)*2.*x0, 1e-10 , 1e-10); 

	// use a VecAD<Base>::reference object with multiplication
	CppAD::VecAD<double> v(1);
	AD<double> zero(0);
	v[zero] = c;
	AD<double> result = 4 * v[zero];
	ok     &= (result == d);

	return ok;
}
Exemple #15
0
bool Sub(void)
{   bool ok = true;
    using CppAD::AD;
    using CppAD::NearEqual;
    double eps99 = 99.0 * std::numeric_limits<double>::epsilon();

    // domain space vector
    size_t  n =  1;
    double x0 = .5;
    CPPAD_TESTVECTOR(AD<double>) x(1);
    x[0]      = x0;

    // declare independent variables and start tape recording
    CppAD::Independent(x);

    AD<double> a = 2. * x[0] - 1.; // AD<double> - double
    AD<double> b = a  - 2;         // AD<double> - int
    AD<double> c = 3. - b;         // double     - AD<double>
    AD<double> d = 4  - c;         // int        - AD<double>

    // range space vector
    size_t m = 1;
    CPPAD_TESTVECTOR(AD<double>) y(m);
    y[0] = x[0] - d;              // AD<double> - AD<double>

    // create f: x -> y and stop tape recording
    CppAD::ADFun<double> f(x, y);

    // check value
    ok &= NearEqual(y[0], x0-4.+3.+2.-2.*x0+1., eps99, eps99);

    // forward computation of partials w.r.t. x[0]
    CPPAD_TESTVECTOR(double) dx(n);
    CPPAD_TESTVECTOR(double) dy(m);
    dx[0] = 1.;
    dy    = f.Forward(1, dx);
    ok   &= NearEqual(dy[0], -1., eps99, eps99);

    // reverse computation of derivative of y[0]
    CPPAD_TESTVECTOR(double)  w(m);
    CPPAD_TESTVECTOR(double) dw(n);
    w[0]  = 1.;
    dw    = f.Reverse(1, w);
    ok   &= NearEqual(dw[0], -1., eps99, eps99);

    // use a VecAD<Base>::reference object with subtraction
    CppAD::VecAD<double> v(1);
    AD<double> zero(0);
    v[zero] = b;
    AD<double> result = 3. - v[zero];
    ok     &= (result == c);

    return ok;
}
Exemple #16
0
bool Tanh(void)
{	bool ok = true;

	using CppAD::AD;
	using CppAD::NearEqual;
	double eps = 10. * CppAD::numeric_limits<double>::epsilon();

	// domain space vector
	size_t n  = 1;
	double x0 = 0.5;
	CPPAD_TESTVECTOR(AD<double>) x(n);
	x[0]      = x0;

	// declare independent variables and start tape recording
	CppAD::Independent(x);

	// range space vector
	size_t m = 1;
	CPPAD_TESTVECTOR(AD<double>) y(m);
	y[0] = CppAD::tanh(x[0]);

	// create f: x -> y and stop tape recording
	CppAD::ADFun<double> f(x, y);

	// check value
	double check = std::tanh(x0);
	ok &= NearEqual(y[0] , check,  eps, eps);

	// forward computation of first partial w.r.t. x[0]
	CPPAD_TESTVECTOR(double) dx(n);
	CPPAD_TESTVECTOR(double) dy(m);
	dx[0] = 1.;
	dy    = f.Forward(1, dx);
	check = 1. - std::tanh(x0) * std::tanh(x0);
	ok   &= NearEqual(dy[0], check, eps, eps);

	// reverse computation of derivative of y[0]
	CPPAD_TESTVECTOR(double)  w(m);
	CPPAD_TESTVECTOR(double) dw(n);
	w[0]  = 1.;
	dw    = f.Reverse(1, w);
	ok   &= NearEqual(dw[0], check, eps, eps);

	// use a VecAD<Base>::reference object with tan
	CppAD::VecAD<double> v(1);
	AD<double> zero(0);
	v[zero]           = x0;
	AD<double> result = CppAD::tanh(v[zero]);
	check = std::tanh(x0);
	ok   &= NearEqual(result, check, eps, eps);

	return ok;
}
Exemple #17
0
bool log10(void)
{	bool ok = true;

	using CppAD::AD;
	using CppAD::NearEqual;

	// domain space vector
	size_t n  = 1;
	double x0 = 0.5;
	CPPAD_TESTVECTOR(AD<double>) x(n);
	x[0]      = x0;

	// declare independent variables and start tape recording
	CppAD::Independent(x);

	// ten raised to the x0 power
	AD<double> ten = 10.;
	AD<double> pow_10_x0 = CppAD::pow(ten, x[0]);

	// range space vector
	size_t m = 1;
	CPPAD_TESTVECTOR(AD<double>) y(m);
	y[0] = CppAD::log10(pow_10_x0);

	// create f: x -> y and stop tape recording
	CppAD::ADFun<double> f(x, y);

	// check value
	ok &= NearEqual(y[0] , x0,  1e-10 , 1e-10);

	// forward computation of first partial w.r.t. x[0]
	CPPAD_TESTVECTOR(double) dx(n);
	CPPAD_TESTVECTOR(double) dy(m);
	dx[0] = 1.;
	dy    = f.Forward(1, dx);
	ok   &= NearEqual(dy[0], 1., 1e-10, 1e-10);

	// reverse computation of derivative of y[0]
	CPPAD_TESTVECTOR(double)  w(m);
	CPPAD_TESTVECTOR(double) dw(n);
	w[0]  = 1.;
	dw    = f.Reverse(1, w);
	ok   &= NearEqual(dw[0], 1., 1e-10, 1e-10);

	// use a VecAD<Base>::reference object with log10
	CppAD::VecAD<double> v(1);
	AD<double> zero(0);
	v[zero]           = pow_10_x0;
	AD<double> result = CppAD::log10(v[zero]);
	ok   &= NearEqual(result, x0, 1e-10, 1e-10);

	return ok;
}
Exemple #18
0
bool mul_level(void) 
{	bool ok = true;                          // initialize test result
	using CppAD::NearEqual;
	double eps = 10. * std::numeric_limits<double>::epsilon();


	typedef CppAD::AD<double>   ADdouble;    // for one level of taping
	typedef CppAD::AD<ADdouble> ADDdouble;   // for two levels of taping
	size_t n = 2;                            // dimension for example

	CPPAD_TEST_VECTOR<ADdouble>   a_x(n);
	CPPAD_TEST_VECTOR<ADDdouble> aa_x(n);

	// value of the independent variables
	a_x[0] = 2.; a_x[1] = 3.;
	Independent(a_x);
	aa_x[0] = a_x[0]; aa_x[1] = a_x[1];
	CppAD::Independent(aa_x);

	// compute the function f(x) = 2 * x[0] * x[1]
	CPPAD_TEST_VECTOR<ADDdouble> aa_f(1);
	aa_f[0] = 2. * aa_x[0] * aa_x[1];
	CppAD::ADFun<ADdouble> F(aa_x, aa_f);

	// re-evaluate f(2, 3) (must get proper deepedence on a_x).
	size_t p = 0;
	CPPAD_TEST_VECTOR<ADdouble> a_fp(1);
	a_fp    = F.Forward(p, a_x);
	ok     &= NearEqual(a_fp[0], 2. * a_x[0] * a_x[1], eps, eps);

	// compute the function g(x) = 2 * partial_x[0] f(x) = 4 * x[1]
	p = 1;
	CPPAD_TEST_VECTOR<ADdouble> a_dx(n), a_g(1);
	a_dx[0] = 1.; a_dx[1] = 0.;
	a_fp    = F.Forward(p, a_dx);
	a_g[0]  = 2. * a_fp[0];
	CppAD::ADFun<double> G(a_x, a_g);

	// compute partial_x[1] g(x)
	CPPAD_TEST_VECTOR<double>  xp(n), gp(1);
	p = 0;
	xp[0] = 4.; xp[1] = 5.;
	gp    = G.Forward(p, xp);
	ok   &= NearEqual(gp[0], 4. * xp[1], eps, eps);

	p = 1;
	xp[0] = 0.; xp[1] = 1.;
	gp    = G.Forward(p, xp);
	ok   &= NearEqual(gp[0], 4., eps, eps);

	return ok;
}
Exemple #19
0
bool Asin(void)
{	bool ok = true;

	using CppAD::AD;
	using CppAD::NearEqual;

	// domain space vector
	size_t n  = 1;
	double x0 = 0.5;
	CPPAD_TEST_VECTOR< AD<double> > x(n);
	x[0]      = x0;

	// declare independent variables and start tape recording
	CppAD::Independent(x);

	// a temporary value
	AD<double> sin_of_x0 = CppAD::sin(x[0]);

	// range space vector 
	size_t m = 1;
	CPPAD_TEST_VECTOR< AD<double> > y(m);
	y[0] = CppAD::asin(sin_of_x0);

	// create f: x -> y and stop tape recording
	CppAD::ADFun<double> f(x, y); 

	// check value 
	ok &= NearEqual(y[0] , x0,  1e-10 , 1e-10);

	// forward computation of first partial w.r.t. x[0]
	CPPAD_TEST_VECTOR<double> dx(n);
	CPPAD_TEST_VECTOR<double> dy(m);
	dx[0] = 1.;
	dy    = f.Forward(1, dx);
	ok   &= NearEqual(dy[0], 1., 1e-10, 1e-10);

	// reverse computation of derivative of y[0]
	CPPAD_TEST_VECTOR<double>  w(m);
	CPPAD_TEST_VECTOR<double> dw(n);
	w[0]  = 1.;
	dw    = f.Reverse(1, w);
	ok   &= NearEqual(dw[0], 1., 1e-10, 1e-10);

	// use a VecAD<Base>::reference object with asin
	CppAD::VecAD<double> v(1);
	AD<double> zero(0);
	v[zero] = sin_of_x0;
	AD<double> result = CppAD::asin(v[zero]);
	ok     &= NearEqual(result, x0, 1e-10, 1e-10);

	return ok;
}
Exemple #20
0
bool OdeErrControl_three(void)
{   bool ok = true;     // initial return value
    using CppAD::NearEqual;

    double alpha = 10.;
    Method_three method(alpha);

    CppAD::vector<double> xi(2);
    xi[0] = 1.;
    xi[1] = 0.;

    CppAD::vector<double> eabs(2);
    eabs[0] = 1e-4;
    eabs[1] = 1e-4;

    // inputs
    double ti   = 0.;
    double tf   = 1.;
    double smin = 1e-4;
    double smax = 1.;
    double scur = 1.;
    double erel = 0.;

    // outputs
    CppAD::vector<double> ef(2);
    CppAD::vector<double> xf(2);
    CppAD::vector<double> maxabs(2);
    size_t nstep;


    xf = OdeErrControl(method,
        ti, tf, xi, smin, smax, scur, eabs, erel, ef, maxabs, nstep);


    double x0       = exp( alpha * tf * tf );
    ok &= NearEqual(x0, xf[0], 1e-4, 1e-4);
    ok &= NearEqual(0., ef[0], 1e-4, 1e-4);

    double root_pi    = sqrt( 4. * atan(1.));
    double root_alpha = sqrt( alpha );
    double x1 = CppAD::erf(alpha * tf) * root_pi / (2 * root_alpha);
    ok &= NearEqual(x1, xf[1], 1e-4, 1e-4);
    ok &= NearEqual(0., ef[1], 1e-4, 1e-4);

    ok &= method.F.was_negative();

    return ok;
}
Exemple #21
0
bool compare_op(void)
{   bool ok = true;
    using CppAD::AD;
    using CppAD::NearEqual;
    double eps10 = 10.0 * std::numeric_limits<double>::epsilon();

    // domain space vector
    size_t n  = 1;
    CPPAD_TESTVECTOR(AD<double>) ax(n);
    ax[0] = 0.5;

    // range space vector
    size_t m = 1;
    CPPAD_TESTVECTOR(AD<double>) ay(m);

    for(size_t k = 0; k < 2; k++)
    {   // optimization options
        std::string options = "";
        if( k == 0 )
            options = "no_compare_op";

        // declare independent variables and start tape recording
        CppAD::Independent(ax);

        // compute function value
        tape_size before, after;
        fun(options, ax, ay, before, after);

        // create f: x -> y and stop tape recording
        CppAD::ADFun<double> f(ax, ay);
        ok &= f.size_var() == before.n_var;
        ok &= f.size_op() == before.n_op;

        // Optimize the operation sequence
        f.optimize(options);
        ok &= f.size_var() == after.n_var;
        ok &= f.size_op() == after.n_op;

        // Check result for a zero order calculation for a different x,
        // where the result of the comparison is he same.
        CPPAD_TESTVECTOR(double) x(n), y(m), check(m);
        x[0] = 0.75;
        y    = f.Forward(0, x);
        if ( options == "" )
            ok  &= f.compare_change_number() == 0;
        fun(options, x, check, before, after);
        ok &= NearEqual(y[0], check[0], eps10, eps10);

        // Check case where result of the comparision is differnent
        // (hence one needs to re-tape to get correct result)
        x[0] = 2.0;
        y    = f.Forward(0, x);
        if ( options == "" )
            ok  &= f.compare_change_number() == 1;
        fun(options, x, check, before, after);
        ok  &= std::fabs(y[0] - check[0]) > 0.5;
    }
    return ok;
}
Exemple #22
0
bool OdeErrControl_two(void)
{   bool ok = true;     // initial return value
    using CppAD::NearEqual;

    CppAD::vector<double> w(2);
    w[0] = 10.;
    w[1] = 1.;
    Method_two method(w);

    CppAD::vector<double> xi(2);
    xi[0] = 1.;
    xi[1] = 0.;

    CppAD::vector<double> eabs(2);
    eabs[0] = 1e-4;
    eabs[1] = 1e-4;

    // inputs
    double ti   = 0.;
    double tf   = 1.;
    double smin = 1e-4;
    double smax = 1.;
    double scur = .5;
    double erel = 0.;

    // outputs
    CppAD::vector<double> ef(2);
    CppAD::vector<double> xf(2);
    CppAD::vector<double> maxabs(2);
    size_t nstep;


    xf = OdeErrControl(method,
        ti, tf, xi, smin, smax, scur, eabs, erel, ef, maxabs, nstep);

    double x0 = exp(-w[0]*tf);
    ok &= NearEqual(x0, xf[0], 1e-4, 1e-4);
    ok &= NearEqual(0., ef[0], 1e-4, 1e-4);

    double x1 = w[0] * (exp(-w[0]*tf) - exp(-w[1]*tf))/(w[1] - w[0]);
    ok &= NearEqual(x1, xf[1], 1e-4, 1e-4);
    ok &= NearEqual(0., ef[1], 1e-4, 1e-4);

    return ok;
}
Exemple #23
0
bool std_math(void)
{	using CppAD::NearEqual;	
	bool ok = true;
	ADDdouble half   = .5;
	ADDdouble one    = 1.;
	ADDdouble two    = 2.;
	ADDdouble ten    = 10.;
	ADDdouble small  = 1e-6;
	ADDdouble pi_4   = 3.141592653 / 4.;
	ADDdouble root_2 =  sqrt(two);

	ADDdouble y = acos(one / root_2);
	ok &= NearEqual( pi_4, y, small, small );

	y = cos(pi_4);
	ok &= NearEqual( one / root_2, y, small, small );

	y = asin(one / root_2);
	ok &= NearEqual( pi_4, y, small, small );

	y = sin(pi_4);
	ok &= NearEqual( one / root_2, y, small, small );

	y = atan(one);
	ok &= NearEqual( pi_4, y, small, small );

	y = tan(pi_4);
	ok &= NearEqual( one, y, small, small );

	y = two * cosh(one);
	ok &= NearEqual( exp(one) + exp(-one), y, small, small );

	y = two * sinh(one);
	ok &= NearEqual( exp(one) - exp(-one), y, small, small );

	y = log( exp(one) );
	ok &= NearEqual( one, y, small, small );

	y = log10( exp( log(ten) ) );
	ok &= NearEqual( one, y, small, small );

	return ok;
}
Exemple #24
0
bool RevTwo()
{	bool ok = true;
	using CppAD::AD;
	using CppAD::vector;
	using CppAD::NearEqual;


	size_t n = 2;
   	vector< AD<double> > X(n);
	X[0] = 1.;
	X[1] = 1.;
	Independent(X);

	size_t m = 1;
   	vector< AD<double> > Y(m);
	Y[0] = X[0] * X[0] + X[0] * X[1] + 2. * X[1] * X[1];
	CppAD::ADFun<double> F(X,Y);

	vector<double> x(n);
	x[0] = .5;
	x[1] = 1.5;

	size_t L = 1;
	vector<size_t> I(L);
	vector<size_t> J(L);
	vector<double> H(n);
	I[0] = 0;
	J[0] = 0;
	H    = F.RevTwo(x, I, J);
	ok  &= NearEqual(H[0], 2., 1e-10, 1e-10);
	ok  &= NearEqual(H[1], 1., 1e-10, 1e-10);
	J[0] = 1;
	H    = F.RevTwo(x, I, J);
	ok  &= NearEqual(H[0], 1., 1e-10, 1e-10);
	ok  &= NearEqual(H[1], 4., 1e-10, 1e-10);

	return ok;
}
Exemple #25
0
bool sparse_jac_fun(void)
{	using CppAD::NearEqual;
	using CppAD::AD;

	bool ok = true;

	size_t j, k;
	double eps = CppAD::numeric_limits<double>::epsilon();
	size_t n   = 3;
	size_t m   = 4;
	size_t K   = 5;
	CppAD::vector<size_t>       row(K), col(K);
	CppAD::vector<double>       x(n),   yp(K);
	CppAD::vector< AD<double> > a_x(n), a_y(m);

	// choose x
	for(j = 0; j < n; j++)
		a_x[j] = x[j] = double(j + 1);

	// choose row, col
	for(k = 0; k < K; k++)
	{	row[k] = k % m;
		col[k] = (K - k) % n;
	}

	// declare independent variables
	Independent(a_x);

	// evaluate function
	size_t order = 0;
	CppAD::sparse_jac_fun< AD<double> >(m, n, a_x, row, col, order, a_y);

	// evaluate derivative
	order = 1;
	CppAD::sparse_jac_fun<double>(m, n, x, row, col, order, yp);

	// use AD to evaluate derivative
	CppAD::ADFun<double>   f(a_x, a_y);
	CppAD::vector<double>  jac(m * n);
	jac = f.Jacobian(x);

	for(k = 0; k < K; k++)
	{	size_t index = row[k] * n + col[k];
		ok &= NearEqual(jac[index], yp[k] , eps, eps);
	}
	return ok;
}
Exemple #26
0
bool eigen_array(void)
{	bool ok = true;
	using CppAD::AD;
	using CppAD::NearEqual;
	using Eigen::Matrix;
	using Eigen::Dynamic;
	//
	typedef Matrix< AD<double> , Dynamic, 1 > a_vector;
	//
	// some temporary indices
	size_t i, j;

	// domain and range space vectors
	size_t n  = 10, m = n;
	a_vector a_x(n), a_y(m);

	// set and declare independent variables and start tape recording
	for(j = 0; j < n; j++)
		a_x[j] = double(1 + j);
	CppAD::Independent(a_x);

	// evaluate a component wise function
	a_y = a_x.array() + a_x.array().sin();

	// create f: x -> y and stop tape recording
	CppAD::ADFun<double> f(a_x, a_y);

	// compute the derivative of y w.r.t x using CppAD
	CPPAD_TESTVECTOR(double) x(n);
	for(j = 0; j < n; j++)
		x[j] = double(j) + 1.0 / double(j+1);
	CPPAD_TESTVECTOR(double) jac = f.Jacobian(x);

	// check Jacobian
	double eps = 100. * CppAD::numeric_limits<double>::epsilon();
	for(i = 0; i < m; i++)
	{	for(j = 0; j < n; j++)
		{	double check = 1.0 + cos(x[i]);
			if( i != j )
				check = 0.0;
			ok &= NearEqual(jac[i * n + j], check, eps, eps);
		}
	}

	return ok;
}
Exemple #27
0
bool OdeErrControl_one(void)
{   bool   ok = true;     // initial return value

    using CppAD::NearEqual;

    // Runge45 should yield exact results for x_i (t) = t^(i+1), i < 4
    size_t  n = 6;

    // construct method for n component solution
    Method_one method(n);

    // inputs to OdeErrControl

    double ti   = 0.;
    double tf   = .9;
    double smin = 1e-2;
    double smax = 1.;
    double scur = .5;
    double erel = 1e-7;

    CppAD::vector<double> xi(n);
    CppAD::vector<double> eabs(n);
    size_t i;
    for(i = 0; i < n; i++)
    {   xi[i]   = 0.;
        eabs[i] = 0.;
    }

    // outputs from OdeErrControl

    CppAD::vector<double> ef(n);
    CppAD::vector<double> xf(n);

    xf = OdeErrControl(method,
        ti, tf, xi, smin, smax, scur, eabs, erel, ef);

    double check = 1.;
    for(i = 0; i < n; i++)
    {   check *= tf;
        ok &= NearEqual(check, xf[i], erel, 0.);
    }

    return ok;
}
Exemple #28
0
bool ode_evaluate(void)
{   using CppAD::NearEqual;
    using CppAD::AD;

    bool ok = true;

    size_t n = 3;
    CppAD::vector<double>       x(n);
    CppAD::vector<double>       ym(n * n);
    CppAD::vector< AD<double> > X(n);
    CppAD::vector< AD<double> > Ym(n);

    // choose x
    size_t j;
    for(j = 0; j < n; j++)
    {   x[j] = double(j + 1);
        X[j] = x[j];
    }

    // declare independent variables
    Independent(X);

    // evaluate function
    size_t m = 0;
    CppAD::ode_evaluate(X, m, Ym);

    // evaluate derivative
    m = 1;
    CppAD::ode_evaluate(x, m, ym);

    // use AD to evaluate derivative
    CppAD::ADFun<double>   F(X, Ym);
    CppAD::vector<double>  dy(n * n);
    dy = F.Jacobian(x);

    size_t k;
    for(k = 0; k < n * n; k++)
        ok &= NearEqual(ym[k], dy[k] , 1e-7, 1e-7);

    return ok;
}
bool NearEqualExt(void)
{	bool ok = true;
	using CppAD::AD;
	using CppAD::NearEqual;

	// double 
	double x    = 1.00000;
	double y    = 1.00001;
	double a    =  .00005;
	double r    =  .00005;
	double zero = 0.; 

	// AD<double> 
	AD<double> ax(x);
	AD<double> ay(y);

	ok &= NearEqual(ax, ay, zero, a);
	ok &= NearEqual(ax, y,  r, zero);
	ok &= NearEqual(x, ay,  r,    a);

	// std::complex<double> 
	AD<double> cx(x);
	AD<double> cy(y);

	// AD< std::complex<double> > 
	AD<double> acx(x);
	AD<double> acy(y);

	ok &= NearEqual(acx, acy, zero, a);
	ok &= NearEqual(acx,  cy, r, zero);
	ok &= NearEqual(acx,   y, r,    a);
	ok &= NearEqual( cx, acy, r,    a);
	ok &= NearEqual(  x, acy, r,    a);

	return ok;
}
Exemple #30
0
bool StackMachine(void)
{	bool ok = true;

	using std::string;
	using std::stack;

	using CppAD::AD;
	using CppAD::NearEqual;
	using CppAD::vector;

	// The users program in that stack machine language
	const char *program[] = {
		"1.0", "a", "+", "=", "b",  // b = a + 1
		"2.0", "b", "*", "=", "c",  // c = b * 2
		"3.0", "c", "-", "=", "d",  // d = c - 3
		"4.0", "d", "/", "=", "e"   // e = d / 4
	};
	size_t n_program = sizeof( program ) / sizeof( program[0] );

	// put the program in the token stack
	stack< string > token_stack;
	size_t i = n_program;
	while(i--)
		token_stack.push( program[i] );

	// domain space vector
	size_t n = 1;
	vector< AD<double> > X(n);
	X[0] = 0.;

	// declare independent variables and start tape recording
	CppAD::Independent(X);

	// x[0] corresponds to a in the stack machine
	vector< AD<double> > variable(26);
	variable[0] = X[0];

	// calculate the resutls of the program
	StackMachine( token_stack , variable);

	// range space vector
	size_t m = 4;
	vector< AD<double> > Y(m);
	Y[0] = variable[1];   // b = a + 1
	Y[1] = variable[2];   // c = (a + 1) * 2
	Y[2] = variable[3];   // d = (a + 1) * 2 - 3
	Y[3] = variable[4];   // e = ( (a + 1) * 2 - 3 ) / 4

	// create f : X -> Y and stop tape recording
	CppAD::ADFun<double> f(X, Y);

	// use forward mode to evaluate function at different argument value
	size_t p = 0;
	vector<double> x(n);
	vector<double> y(m);
	x[0] = 1.;
	y    = f.Forward(p, x);

	// check function values
	ok &= (y[0] == x[0] + 1.);
	ok &= (y[1] == (x[0] + 1.) * 2.);
	ok &= (y[2] == (x[0] + 1.) * 2. - 3.);
	ok &= (y[3] == ( (x[0] + 1.) * 2. - 3.) / 4.);

	// Use forward mode (because x is shorter than y) to calculate Jacobian
	p = 1;
	vector<double> dx(n);
	vector<double> dy(m);
	dx[0] = 1.;
	dy    = f.Forward(p, dx);
	ok   &= NearEqual(dy[0], 1., 1e-10, 1e-10);
	ok   &= NearEqual(dy[1], 2., 1e-10, 1e-10);
	ok   &= NearEqual(dy[2], 2., 1e-10, 1e-10);
	ok   &= NearEqual(dy[3], .5, 1e-10, 1e-10);

	// Use Jacobian routine (which automatically decides which mode to use)
	dy = f.Jacobian(x);
	ok   &= NearEqual(dy[0], 1., 1e-10, 1e-10);
	ok   &= NearEqual(dy[1], 2., 1e-10, 1e-10);
	ok   &= NearEqual(dy[2], 2., 1e-10, 1e-10);
	ok   &= NearEqual(dy[3], .5, 1e-10, 1e-10);

	return ok;
}