#include "../AutomaticDifferentiation.hpp" #include #include using std::cout; using std::endl; using std::setw; #define PRINT_VAR(x) std::cout << #x << "\t= " << std::setprecision(16) << (x) << std::endl #define PRINT_DUAL(x) std::cout << #x << "\t= " << std::fixed << std::setprecision(4) << std::setw(10) << (x).a << ", " << std::setw(10) << (x).b << std::endl template T f(const T & x) { // return T(1.) + x + x*x + T(1.)/x + log(x); return 1 + x + x*x + 1/x + log(x); } template T df(const T & x) { return 2*x + 1 + 1.0/x - 1/pow(x, 2); } template T ddf(const T & x) { return 2 - 1/pow(x, 2) + 2/pow(x, 3); } struct fFunctor { template Scalar operator()(Scalar const& x) {return f(x);} }; CREATE_GRAD_FUNCTION_OBJECT(f, GradF); CREATE_GRAD_FUNCTION_OBJECT_FUNCTOR(fFunctor, GradF_funct); CREATE_GRAD_FUNCTION_OBJECT_FUNCTOR(GradF_funct, Grad2F_funct); int main() { cout.precision(16); double xdbl = 1.5; { cout << "Analytical\n"; cout << "f(x) = " << f(xdbl) << endl; cout << "df(x)/dx = " << df(xdbl) << endl; cout << "d²f(x)/dx² = " << ddf(xdbl) << endl; } // 1st derivative forward { using Fd = Dual; Fd x = xdbl; x.diff(0); Fd y = f(x); cout << "\nForward\n"; cout << "f(x) = " << y.a << endl; cout << "df(x)/dx = " << y.d(0) << endl; } // first derivative using the gradient functor { GradFunc gradf(f>, xdbl); double fx, dfdx; gradf.get_f_grad(xdbl, fx, dfdx); cout << "\nForward using gradient function object\n"; cout << "f(x) = " << fx << endl; cout << "df(x)/dx = " << dfdx << endl; cout << "df(x)/dx = " << gradf(xdbl) << endl; } // first derivative using the gradient functor created through the macro { // GradF gradf; GradF gradf; // GradFunc gradf(f>, xdbl); double fx, dfdx; gradf.get_f_grad(xdbl, fx, dfdx); cout << "\nForward using gradient function object created using the macro\n"; cout << "f(x) = " << fx << endl; cout << "df(x)/dx = " << dfdx << endl; cout << "df(x)/dx = " << gradf(xdbl) << endl; { GradF_funct gradf_funct; Grad2F_funct grad2f_funct; PRINT_VAR(gradf(1.5f)); PRINT_VAR(gradf_funct(1.5)); // PRINT_VAR(grad2f_funct(1.5));// for this to work, the operator+-*/(A, Dual) must not be defined (conflict with operator from valarray) // third order does not work anyway (can't convert a double to Dual>>...) } } return 0; }