Search code examples
c++boost

Automatic Differentiation of functions of complex variables


I was wondering if it is possible to apply boost's automatic differentiation library:

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

to functions which return std::complex<double> values?


For instance, consider the multivariate complex valued function:

 #include <complex>

 std::complex<double> complex_function(double a, double c){
     // Assuming a < 0
     return exp(sqrt(std::complex(a, 0.0))) + sin(c);
 }

How can I take the derivative wrt to a or c using Boost's autodiff? Is that even possible?


Solution

  • is [it] possible to apply boost's automatic differentiation library to functions which return std::complex<double> values?

    Not at the present time.

    A version that did might look something like this:

    // THIS DOES NOT COMPILE - FOR DISCUSSION ONLY
    #include <boost/math/differentiation/autodiff.hpp>
    
    #include <iostream>
    #include <complex>
    
    namespace ad = boost::math::differentiation;
    
    template <typename T0, typename T1>
    auto complex_function(T0 a, T1 c){
      // Assuming a < 0
      return exp(sqrt(complex(a, 0.0))) + sin(c);  // DOES NOT COMPILE
    }
    
    int main() {
      auto const a = ad::make_fvar<double, 2>(-3);
      auto const c = 0.0;
      auto const answer = complex_function(a, c);
      return 0;
    }
    

    This requires complex to be defined specific to autodiff::fvar template types, similar to how other mathematical functions (exp, sqrt, etc.) have overloads in the autodiff library, and are called via ADL.

    As @user14717 pointed out in the comments, it is a special case of vector-valued autodiff since the return value isn't a single truncated Taylor polynomial, but rather a tuple of them.