【问题标题】:Integration of a complex function using Gauss-Kronrod quadrature from boost::math使用来自 boost::math 的 Gauss-Kronrod 求积对复杂函数进行积分
【发布时间】:2019-10-01 20:56:54
【问题描述】:

我正在尝试使用 Boost 提供的 Gauss-Kronrod 求积法在 C++ 中以数值方式在域 [0, 5] 上集成一个具有实参和复数返回值的函数,例如 f(x) = 1 + i。

我已经使用 boost 来解决真正有效的被积函数,因此该库已正确安装。 documentation 表示“Gauss-Kronrod 正交支持在实线上定义的被积函数并返回复数值。”

#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;
}

我的预期结果是 5 + 5i。我得到编译器错误

/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>')

意味着没有为 std::complex 定义一些运算符。我是否误读了文档并且无法进行复杂的集成?

编辑: 将我的代码更改为user14717 提供的版本会给我一个新的编译器错误:

/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;
                                        ^

【问题讨论】:

    标签: c++ boost numerical-integration


    【解决方案1】:

    解决方法如下:

    #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;
    }
    

    您的错误是您在复杂类型上进行了模板化。模板参数必须是真实类型。

    我注意到文档没有在此处提供示例,因此您确实无法知道这一点。我会为此提交一个补丁。 . .

    【讨论】:

    • 尝试这样做会给我一个新的编译器错误,如我的编辑中所列。
    • @Olaf:你用的是什么编译器?我用 g++-8 和 Apple clang 测试了我的答案。
    • clang++ -I/path/to/boost --std=c++17 reproduce_gk.cpp &amp;&amp; ./a.out
    • 我使用的是 gcc 版本 8.3.0 (Debian 8.3.0-6) 和 Boost 1.67.0。
    • @Olaf:你使用了 C++17 编译器标志吗?另外,boost 1.67 不支持这个;您需要升级到 Boost 1.70。
    猜你喜欢
    • 2016-12-13
    • 2016-12-13
    • 2021-01-31
    • 1970-01-01
    • 2021-10-24
    • 1970-01-01
    • 2017-03-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多