Accurate multidimensional integral using boost odeint

user3493721

What is the recommended way to calculate a multidimensional integral using boost odeint with high accuracy? The following code integrates f=x*y from -1 to 2 but the error relative to an analytic solution is over 1 % (gcc 4.8.2, -std=c++0x):

    #include "array"
    #include "boost/numeric/odeint.hpp"
    #include "iostream"
    using integral_type = std::array<double, 1>;
    int main() {
      integral_type outer_integral{0};

      double current_x = 0;
      boost::numeric::odeint::integrate(
        [&](
          const integral_type&,
          integral_type& dfdx,
          const double x
        ) {
          integral_type inner_integral{0};

          boost::numeric::odeint::integrate(
            [&current_x](
              const integral_type&,
              integral_type& dfdy,
              const double y
            ) {
              dfdy[0] = current_x * y;
            },
            inner_integral,
            -1.0,
            2.0,
            1e-3
          );

          dfdx[0] = inner_integral[0];
        },
        outer_integral,
        -1.0,
        2.0,
        1e-3,
        [&current_x](const integral_type&, const double x) {
          current_x = x; // update x in inner integrator
        }
      );
      std::cout
        << "Exact: 2.25, numerical: "
        << outer_integral[0]
        << std::endl;
      return 0;
    }

prints:

    Exact: 2.25, numerical: 2.19088

Should I just use more stringent stopping condition in the inner integrals or is there a faster/more accurate way to do this? Thanks!

mariomulansky

Firstly, there might be better numerical methods to compute high-dimensional integrals than an ODE scheme (http://en.wikipedia.org/wiki/Numerical_integration), but then I think this is a neat application of odeint, I find.

However, the problem with your code is that it assumes that you use an observer in the outer integrate to update the x-value for the inner integration. However, the integrate function uses a dense-output stepper internally which means that the actual time steps and the observer calls are not in synchrony. So the x for the inner integration is not updated at the right moments. A quick fix would be to use an integrate_const with a runge_kutta4 stepper, which uses constant step size and ensure that the observer calls, and thus x-updates, are called after each step of the outer loop. However, this is a bit of a hack relying on some internal details of the integrate routines. A better way would be to design the program in such a way that the state is indeed 2-dimensional, but where each integration works only on one of the two variables.

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

From Dev

DDE using boost odeint

From Dev

Boost lib error in using odeint

From Dev

Using Boost::odeint with Eigen::Matrix as state vector

From Dev

Using Boost::odeint with Eigen::Matrix as state vector

From Dev

using several eigen matrices as statetypes in boost/odeint

From Dev

Second order differential equation using C++ Boost odeint library

From Dev

Assertion error in a simple C++ program using boost:odeint

From Dev

returning derivatives with boost odeint

From Dev

returning derivatives with boost odeint

From Dev

Boost odeint class with derivative and jacobian

From Dev

error with installing odeint <boost/config.hpp>

From Dev

does boost odeint have a leapfrog algorithm?

From Dev

role of get_unit_value in boost ODEINT

From Dev

boost::odeint called within member class

From Dev

does boost odeint have a leapfrog algorithm?

From Dev

boost::odeint called within member class

From Dev

How to obtain integral from a multidimensional array in Matlab?

From Dev

How to obtain integral from a multidimensional array in Matlab?

From Dev

Using nquad for a double integral

From Dev

Using numpy arrays with scipy odeint

From Dev

Error C2309 in boost odeint package example code

From Dev

Can't get BOOST odeint to work with Adams-Bashforth-Moulton

From Dev

wrong output of boost::odeint with custom tensor data structure

From Dev

Segmentation fault in boost::odeint my_vector.cpp example

From Dev

how to control the order of bulirsch_stoer method in boost::odeint?

From Dev

Segmentation fault in boost::odeint my_vector.cpp example

From Dev

wrong output of boost::odeint with custom tensor data structure

From Dev

Armadillo's cx_mat and Boost's odeint compilation error

From Dev

Integral using importance sampling formula

Related Related

  1. 1

    DDE using boost odeint

  2. 2

    Boost lib error in using odeint

  3. 3

    Using Boost::odeint with Eigen::Matrix as state vector

  4. 4

    Using Boost::odeint with Eigen::Matrix as state vector

  5. 5

    using several eigen matrices as statetypes in boost/odeint

  6. 6

    Second order differential equation using C++ Boost odeint library

  7. 7

    Assertion error in a simple C++ program using boost:odeint

  8. 8

    returning derivatives with boost odeint

  9. 9

    returning derivatives with boost odeint

  10. 10

    Boost odeint class with derivative and jacobian

  11. 11

    error with installing odeint <boost/config.hpp>

  12. 12

    does boost odeint have a leapfrog algorithm?

  13. 13

    role of get_unit_value in boost ODEINT

  14. 14

    boost::odeint called within member class

  15. 15

    does boost odeint have a leapfrog algorithm?

  16. 16

    boost::odeint called within member class

  17. 17

    How to obtain integral from a multidimensional array in Matlab?

  18. 18

    How to obtain integral from a multidimensional array in Matlab?

  19. 19

    Using nquad for a double integral

  20. 20

    Using numpy arrays with scipy odeint

  21. 21

    Error C2309 in boost odeint package example code

  22. 22

    Can't get BOOST odeint to work with Adams-Bashforth-Moulton

  23. 23

    wrong output of boost::odeint with custom tensor data structure

  24. 24

    Segmentation fault in boost::odeint my_vector.cpp example

  25. 25

    how to control the order of bulirsch_stoer method in boost::odeint?

  26. 26

    Segmentation fault in boost::odeint my_vector.cpp example

  27. 27

    wrong output of boost::odeint with custom tensor data structure

  28. 28

    Armadillo's cx_mat and Boost's odeint compilation error

  29. 29

    Integral using importance sampling formula

HotTag

Archive