CppAD::ADFun<T>* AtanTestTwoFunc(const std::vector<CppAD::AD<T> >& u) { using CppAD::atan; using CppAD::sin; using CppAD::cos; using namespace CppAD; assert(u.size() == 1); // a temporary values AD<T> x = sin(u[0]) / cos(u[0]); // dependent variable vector std::vector< AD<T> > Z(1); Z[0] = atan(x); // atan( tan(u) ) // create f: U -> Z and vectors used for derivative calculations return new ADFun<T > (u, Z); }
CppAD::ADFun<T>* AtanTestOneFunc(const std::vector<CppAD::AD<T> >& u) { using CppAD::atan; using namespace CppAD; assert(u.size() == 1); size_t s = 0; // some temporary values AD<T> x = cos(u[s]); AD<T> y = sin(u[s]); AD<T> z = y / x; // tan(s) // dependent variable vector and indices std::vector< AD<T> > Z(1); size_t a = 0; // dependent variable values Z[a] = atan(z); // atan( tan(s) ) // create f: U -> Z and vectors used for derivative calculations return new ADFun<T > (u, Z); }
bool VecUnary(void) { using namespace CppAD; using CppAD::abs; using CppAD::sin; using CppAD::atan; using CppAD::cos; using CppAD::exp; using CppAD::log; using CppAD::sqrt; bool ok = true; size_t n = 8; size_t i; CPPAD_TEST_VECTOR< AD<double> > X(n); VecAD<double> Y(n); CPPAD_TEST_VECTOR< AD<double> > Z(n); for(i = 0; i < n; i++) X[i] = int(i); // some compilers require the int here Independent(X); AD<double> j; j = 0.; Y[j] = X[0]; Z[0] = -Y[j]; j = 1.; Y[j] = X[1]; Z[1] = sin( Y[j] ); j = 2.; Y[j] = X[2]; Z[2] = abs( Y[j] ); j = 3.; Y[j] = X[3]; Z[3] = atan( Y[j] ); j = 4.; Y[j] = X[4]; Z[4] = cos( Y[j] ); j = 5.; Y[j] = X[5]; Z[5] = exp( Y[j] ); j = 6.; Y[j] = X[6]; Z[6] = log( Y[j] ); j = 7.; Y[j] = X[7]; Z[7] = sqrt( Y[j] ); ADFun<double> f(X, Z); CPPAD_TEST_VECTOR<double> x(n); CPPAD_TEST_VECTOR<double> z(n); for(i = 0; i < n; i++) x[i] = 2. / double(i + 1); x[7] = abs( x[7] ); z = f.Forward(0, x); ok &= NearEqual(z[0], - x[0], 1e-10, 1e-10); ok &= NearEqual(z[1], sin( x[1] ), 1e-10, 1e-10); ok &= NearEqual(z[2], abs( x[2] ), 1e-10, 1e-10); ok &= NearEqual(z[3], atan(x[3] ), 1e-10, 1e-10); ok &= NearEqual(z[4], cos( x[4] ), 1e-10, 1e-10); ok &= NearEqual(z[5], exp( x[5] ), 1e-10, 1e-10); ok &= NearEqual(z[6], log( x[6] ), 1e-10, 1e-10); ok &= NearEqual(z[7], sqrt(x[7] ), 1e-10, 1e-10); return ok; }
bool Cos(void) { bool ok = true; using CppAD::sin; using CppAD::cos; using namespace CppAD; // independent variable vector CPPAD_TESTVECTOR(AD<double>) U(1); U[0] = 1.; Independent(U); // dependent variable vector CPPAD_TESTVECTOR(AD<double>) Z(1); Z[0] = cos(U[0]); // create f: U -> Z and vectors used for derivative calculations ADFun<double> f(U, Z); CPPAD_TESTVECTOR(double) v(1); CPPAD_TESTVECTOR(double) w(1); // check value double sin_u = sin( Value(U[0]) ); double cos_u = cos( Value(U[0]) ); ok &= NearEqual(cos_u, Value(Z[0]), 1e-10 , 1e-10); // forward computation of partials w.r.t. u size_t j; size_t p = 5; double jfac = 1.; v[0] = 1.; for(j = 1; j < p; j++) { w = f.Forward(j, v); double value; if( j % 4 == 1 ) value = -sin_u; else if( j % 4 == 2 ) value = -cos_u; else if( j % 4 == 3 ) value = sin_u; else value = cos_u; jfac *= j; ok &= NearEqual(jfac*w[0], value, 1e-10 , 1e-10); // d^jz/du^j v[0] = 0.; } // reverse computation of partials of Taylor coefficients CPPAD_TESTVECTOR(double) r(p); w[0] = 1.; r = f.Reverse(p, w); jfac = 1.; for(j = 0; j < p; j++) { double value; if( j % 4 == 0 ) value = -sin_u; else if( j % 4 == 1 ) value = -cos_u; else if( j % 4 == 2 ) value = sin_u; else value = cos_u; ok &= NearEqual(jfac*r[j], value, 1e-10 , 1e-10); // d^jz/du^j jfac *= (j + 1); } return ok; }
bool ForHess(void) { bool ok = true; using namespace CppAD; using CppAD::exp; using CppAD::sin; using CppAD::cos; using CppAD::NearEqual; double eps99 = 99.0 * std::numeric_limits<double>::epsilon(); size_t i; // create independent variable vector with assigned values CPPAD_TESTVECTOR(double) u0(3); CPPAD_TESTVECTOR(AD<double>) U(3); for(i = 0; i < 3; i++) U[i] = u0[i] = double(i+1); Independent( U ); // define the function CPPAD_TESTVECTOR(AD<double>) Y(2); Y[0] = U[0] * exp( U[1] ); Y[1] = U[1] * sin( U[2] ); // create the function y = F(u) ADFun<double> F(U, Y); // formulas for the upper triangle of Hessian of F_0 CPPAD_TESTVECTOR(double) H0(9); H0[0] = 0.; // d^2 y[0] / d_u[0] d_u[0] H0[1] = exp( u0[1] ); // d^2 y[0] / d_u[0] d_u[1] H0[2] = 0.; // d^2 y[0] / d_u[0] d_u[2] H0[4] = u0[0] * exp( u0[1] ); // d^2 y[0] / d_u[1] d_u[1] H0[5] = 0.; // d^2 y[0] / d_u[1] d_u[2] H0[8] = 0.; // d^2 y[0] / d_u[2] d_u[2] // formulas for the upper triangle of Hessian of F_1 CPPAD_TESTVECTOR(double) H1(9); H1[0] = 0.; // d^2 Y[1] / d_U[0] d_U[0] H1[1] = 0.; // d^2 Y[1] / d_U[0] d_U[1] H1[2] = 0.; // d^2 Y[1] / d_U[0] d_U[2] H1[4] = 0.; // d^2 Y[1] / d_U[1] d_U[1] H1[5] = cos( u0[2] ); // d^2 Y[1] / d_U[1] d_U[2] H1[8] = - u0[1] * sin( u0[2] );// d^2 Y[1] / d_U[2] d_U[2] // Define U(t) = u0 + u1 t + u2 t^2 / 2 CPPAD_TESTVECTOR(double) u1(3); CPPAD_TESTVECTOR(double) u2(3); for(i = 0; i < 3; i++) u1[i] = u2[i] = 0.; size_t j; for(i = 0; i < 3; i++) { // diagonal of Hessians in i-th coordiante direction u1[i] = 1.; F.Forward(1, u1); CPPAD_TESTVECTOR(double) Di = F.Forward(2, u2); ok &= NearEqual( 2. * Di[0] , H0[ i + 3 * i], eps99, eps99); ok &= NearEqual( 2. * Di[1] , H1[ i + 3 * i], eps99, eps99); // for(j = i+1; j < 3; j++) { // cross term in i and j direction u1[j] = 1.; F.Forward(1, u1); CPPAD_TESTVECTOR(double) Cij = F.Forward(2, u2); // diagonal of Hessian in j-th coordinate direction u1[i] = 0.; F.Forward(1, u1); CPPAD_TESTVECTOR(double) Dj = F.Forward(2, u2); // (i, j) elements of the Hessians double H0ij = Cij[0] - Di[0] - Dj[0]; ok &= NearEqual( H0ij, H0[j + 3 * i], eps99, eps99); double H1ij = Cij[1] - Di[1] - Dj[1]; ok &= NearEqual( H1ij, H1[j + 3 * i], eps99, eps99); // reset all components of u1 to zero u1[j] = 0.; } } return ok; }