Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Integration of a complex function using Gauss-Kronrod quadrature from boost::math

I am trying to integrate a function with real arguments and complex return value such as f(x) = 1 + i over the domain [0, 5] numerically in C++ using the Gauss-Kronrod quadrature as provided by Boost.

I have used boost to solve for real integrands which worked, so the library is installed correctly. The documentation says "The Gauss-Kronrod quadrature support integrands defined on the real line and returning complex values."

#include <iostream>
#include <cmath>
#include <complex>
#include <boost/math/quadrature/gauss_kronrod.hpp>

using namespace boost::math::quadrature;
using complex = std::complex<double>;


complex f(double t){
    return complex{1, 1};
};


int main() {
    complex error;
    complex a{0};
    complex b{5};
    unsigned int max_depth = 0;
    complex tolerance = 0;
    complex Q = gauss_kronrod<complex, 61>::integrate(f, a, b, max_depth, tolerance, &error);
    std::cout << Q << ", " << error << "\n";
    return 0;
}

My expected result would be 5 + 5i. I get the compiler error

/usr/include/boost/math/quadrature/gauss_kronrod.hpp:1871:17: error: no match for 'operator<=' (operand types are 'std::complex<double>' and 'std::complex<double>')

meaning some operators are not defined for std::complex. Am I misreading the documentation and complex integration is not possible?

edit: Changing my code to the version provided by user14717 gives me a new compiler error:

/usr/include/boost/math/quadrature/gauss_kronrod.hpp: In instantiation of 'static boost::math::quadrature::gauss_kronrod<Real, N, Policy>::value_type boost::math::quadrature::gauss_kronrod<Real, N, Policy>::integrate(F, Real, Real, unsigned int, Real, Real*, Real*) [with F = std::complex<double> (*)(double); Real = double; unsigned int N = 61; Policy = boost::math::policies::policy<boost::math::policies::default_policy, boost::math::policies::default_policy, boost::math::policies::default_policy, boost::math::policies::default_policy, boost::math::policies::default_policy, boost::math::policies::default_policy, boost::math::policies::default_policy, boost::math::policies::default_policy, boost::math::policies::default_policy, boost::math::policies::default_policy, boost::math::policies::default_policy>; boost::math::quadrature::gauss_kronrod<Real, N, Policy>::value_type = double]':
/home/olaf/testing numerical integration/boost/main.cpp:21:91:   required from here
/usr/include/boost/math/quadrature/gauss_kronrod.hpp:1877:47: error: cannot convert 'std::complex<double>' to 'double' in return
                return f(t*inv)*(1 + t_sq)*inv*inv;
                                               ^~~
/usr/include/boost/math/quadrature/gauss_kronrod.hpp:1890:32: error: cannot convert ?std::complex<double>? to 'double' in return
                return f(arg)*z*z;
                                ^
/usr/include/boost/math/quadrature/gauss_kronrod.hpp:1907:40: error: cannot convert 'std::complex<double>' to 'double' in return
                return f(b - arg) * z * z;
                                        ^
like image 813
Olaf Avatar asked Jan 26 '26 08:01

Olaf


1 Answers

Here's the fix:

#include <iostream>
#include <cmath>
#include <complex>
#include <boost/math/quadrature/gauss_kronrod.hpp>

using namespace boost::math::quadrature;
using complex = std::complex<double>;


complex f(double t){
    return complex{1, 1};
};


int main() {
    double error;
    double a{0};
    double b{5};
    unsigned int max_depth = 0;
    double tolerance = 0;
    complex Q = gauss_kronrod<double, 61>::integrate(f, a, b, max_depth, tolerance, &error);
    std::cout << Q << ", " << error << "\n";
    return 0;
}

Your mistake is that you templated on the complex type. The template argument must be the real type.

I note that the documentation does not provide an example here, so there was really no way for you to know this. I'll submit a patch for that . . .

like image 77
user14717 Avatar answered Jan 27 '26 23:01

user14717



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!