diff --git a/AutomaticDifferentiation.hpp b/AutomaticDifferentiation.hpp index 62afc19..153964f 100644 --- a/AutomaticDifferentiation.hpp +++ b/AutomaticDifferentiation.hpp @@ -119,6 +119,23 @@ class Dual Scalar b; /// Infinitesimal part }; +template +Dual operator+(A const& v, Dual const& x) { + return (Dual(v) + x); +} +template +Dual operator-(A const& v, Dual const& x) { + return (Dual(v) - x); +} +template +Dual operator*(A const& v, Dual const& x) { + return (Dual(v) * x); +} +template +Dual operator/(A const& v, Dual const& x) { + return (Dual(v) / x); +} + // Basic mathematical functions for Scalar numbers // Trigonometric functions diff --git a/AutomaticDifferentiationVector.hpp b/AutomaticDifferentiationVector.hpp index c94dfb4..c95d78c 100644 --- a/AutomaticDifferentiationVector.hpp +++ b/AutomaticDifferentiationVector.hpp @@ -42,8 +42,13 @@ class DualVector b = VectorT(_b, N); } + DualVector const& operator=(Scalar const& _a) + { + *this = DualVector(_a); + } + /// Use this function to set what variable is to be derived : x + DualVector::d(i) - static DualVector d(int i = 0) + static DualVector D(int i = 0) { assert(i >= 0); assert(i < N); @@ -62,6 +67,14 @@ class DualVector return *this; } + /// Returns the derivative value at index i + Scalar const& d(int i) const + { + assert(i >= 0); + assert(i < N); + return b[i]; + } + DualVector & operator+=(const DualVector & x) { a += x.a; @@ -127,6 +140,23 @@ class DualVector VectorT b; /// Infinitesimal parts }; +template +DualVector operator+(A const& v, DualVector const& x) { + return (DualVector(v) + x); +} +template +DualVector operator-(A const& v, DualVector const& x) { + return (DualVector(v) - x); +} +template +DualVector operator*(A const& v, DualVector const& x) { + return (DualVector(v) * x); +} +template +DualVector operator/(A const& v, DualVector const& x) { + return (DualVector(v) / x); +} + // Basic mathematical functions for Scalar numbers // Trigonometric functions diff --git a/examples/firstAndSecondDerivative.cpp b/examples/firstAndSecondDerivative.cpp new file mode 100644 index 0000000..af4aae5 --- /dev/null +++ b/examples/firstAndSecondDerivative.cpp @@ -0,0 +1,66 @@ +#include "../AutomaticDifferentiationVector.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 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); +} + +int main() +{ + double xdbl = 1.5; + + { + cout << "Analytical\n"; + cout << "f(x) = " << f(xdbl) << endl; + cout << "df(x)/dt = " << df(xdbl) << endl; + cout << "d²f(x)/dt = " << ddf(xdbl) << endl; + } + + // 1st derivative forward + { + using Fd = DualVector; + Fd x = xdbl; + x.diff(0); + Fd y = f(x); + cout << "\nForward\n"; + cout << "f(x) = " << y.a << endl; + cout << "df(x)/dt = " << y.d(0) << endl; + } + + // 2nd derivative forward + /* + { + using Fdd = DualVector,2>; + Fdd x(xdbl); + x.diff(0); + x.a.diff(1); + Fdd y = f(x); + cout << "\nForward 2nd der\n"; + cout << "f(x) = " << y.a.a << endl; + cout << "df(x)/dt = " << y.d(0).a << endl; + cout << "d²f(x)/dt = " << y.d(0).d(1) << endl; + }//*/ + + return 0; +}