Search code examples
c++boostderivative

Application of Boost Automatic Differentiation fails


I want to use the boost autodiff functionality to calculate the 2nd derivative of a complicated function.

At the boost help I can take a look on the following example:

#include <boost/math/differentiation/autodiff.hpp>
#include <iostream>

template <typename T>
T fourth_power(T const& x) {
    T x4 = x * x;  // retval in operator*() uses x4's memory via NRVO.
    x4 *= x4;      // No copies of x4 are made within operator*=() even when squaring.
    return x4;     // x4 uses y's memory in main() via NRVO.
}

int main() {
    using namespace boost::math::differentiation;

    constexpr unsigned Order = 5;                  // Highest order derivative to be calculated.
    auto const x = make_fvar<double, Order>(2.0);  // Find derivatives at x=2.
    auto const y = fourth_power(x);
    for (unsigned i = 0; i <= Order; ++i)
        std::cout << "y.derivative(" << i << ") = " << y.derivative(i) << std::endl;
    return 0;
}

I want to use this possibility to calculate a derivative in my class structure but I don't understand how. Here is a simplified code example of my .cxx file. I have a parametric equation which is seperated in two functions to get the x and y-coordinate. radius is a member variable. I want to calculate the second derivative of this parametric equation at a position phi.

#include <boost/math/differentiation/autodiff.hpp>

double
get_x_coordinate(const double phi) const {
    return (radius*cos(phi));
}

double
get_y_coordinate(const double phi) const {
    return (radius*sin(phi));
}

double
do_something(const double phi) const {
    auto const x = boost::math::differentiation::make_fvar<double, 2>(phi);
    auto fx = [this](auto x) { return get_x_coordinate(x); };
    auto fy = [this](auto x) { return get_y_coordinate(x); };
    auto const dx = fx(x);
    auto const dy = fy(x);
    return (dx.derivative(2)+dy.derivative(2));
}

This example fails because of the following error.

cannot convert argument 1 from boost::math::differentiation::autodiff_v1::detail::fvar<RealType,10>' to 'const double'

I cannot change that get_x_coordinate and get_y_coordinate receive a const double and return a double because I use them in my code at other positions. So I don't really know how to continue.

Also I'm using Visual studio 2017. I ask myself what is the difference between

#include <boost/math/differentiation/autodiff.hpp>

and

#include <boost/math/differentiation/autodiff_cpp11.hpp>

Do I have to use cpp11 if I use VS2017? Both are available in my boost version.


Solution

  • Functions of interest are to be converted into templates that may accept either double or boost fvar arguments. Note that boost provides custom implementations of trigonometric functions from standard library (such as sin, cos) suitable for fvar:

    #include <boost/math/differentiation/autodiff.hpp>
    #include <iostream>
    #include <math.h>
    
    constexpr double const radius{4.0};
    
    template <typename T>
    T get_x_coordinate(T const & phi)
    {
        return radius * cos(phi);
    }
    
    int main()
    {
        double const phi{2.0};
        auto const x{::boost::math::differentiation::make_fvar<double, 2>(phi)};
        auto const dx{get_x_coordinate(x)};
        ::std::cout << dx.derivative(2) << ::std::endl;
        return 0;
    }
    
    

    online compiler