Dynamic Eigen vectors in Boost::odeint
Asked Answered
K

0

0

I am trying to use dynamic Eigen matrices and vectors with boost::odeint. The reason is that I want to solve a problem defined by user input of arbitrary size. The problem can be captured in a state space equation in the following form: x' = A*x + B*u (https://en.wikipedia.org/wiki/State-space_representation), which is basically the dxdt() function required for boost::odeint.

Following code is an example of what I am trying do:

#include <iostream>
#include <Eigen/Core>
#include <cstdlib>
#include <boost/numeric/odeint.hpp>
#include <boost/numeric/odeint/external/eigen/eigen_algebra.hpp>

typedef Eigen::VectorXd state_type;

state_type x;
Eigen::MatrixXd A;

void ODE_function (const state_type &x, state_type &dxdt, double)
{
    dxdt = A * x;
}

void write_states(const state_type &x, const double t)
{
    std::cout << t << "\t";
    for (int i = 0; i < x.size(); i++)
    {
        std::cout << *(x.data()+i) << "\t";
    }
    std::cout << std::endl;
}

int main()
{
    int nr_of_states;

    std::cout << "How many (random) states would you like to simulate?: ";
    std::cin >> nr_of_states;
    std::cout << std::endl;

    x = state_type(nr_of_states);
    A = Eigen::MatrixXd(nr_of_states, nr_of_states);

    srand(365);

    for (int i = 0; i < A.size(); i++)
    {
        *(A.data()+i) = ((double)rand()/(double)RAND_MAX);
    }

    for (int i = 0; i < x.size(); i++)
    {
        *(x.data()+i) = i;
    }

    typedef runge_kutta_dopri5<state_type, double, state_type, double, vector_space_algebra> stepper;
    integrate_adaptive(stepper(), ODE_function, x, 0.0, 25.0, 0.1, write_states);

    std::cout <<std::endl << "final state vector: " << std::endl << x << std::endl;

    return 0;
}

The user can input the amount of states in the system, accordingly the state matrix A and the initial state values are assigned arbitrary values for brevity of the example. Boost::odeint is then used to solve the state space equation. Compiling above code fails, returning the following error message:

cc1plus.exe: out of memory allocating 174479 bytes

Everything compiles fine when I exclude the following two blocks of code:

#include <boost/numeric/odeint.hpp>
#include <boost/numeric/odeint/external/eigen/eigen_algebra.hpp>

and

typedef runge_kutta_dopri5<state_type, double, state_type, double, vector_space_algebra> stepper;
integrate_adaptive(stepper(), ODE_function, x, 0.0, 100.0, 1.0, write_states);

If now only <boost/numeric/odeint.hpp> is included again, the same error message is returned by the compiler. I have tried to use UFT8 and UFT16 encoding on the source file, but to no avail.

I will be most gratefull to people that can help me with this problem with either suggestions or solutions

Knighthood answered 26/2, 2016 at 15:56 Comment(3)
Your compiler is running out of memory. Make sure you are running a 64 bits compiler and that you have enough free RAM (say 3 or 4 GB).Alvinaalvine
Yes, it seems that your compiler runs out of memory. I know that odeint might consume lots of memory if you are using boost.units within your state_type. It is strange that it happens with Eigen::matrixXd. Can you check how much memory your build is consuming? What kind of compiler are you using?Halt
I used the GNU GCC compiler, changed it to MinGW 64 bit, it now compiles fine. Only thing missing in my code was to put everything in its right namespace: 'using namespace boost::numeric::odeint;'. Thank you ggael and headmyshoulder for your responses.Knighthood

© 2022 - 2024 — McMap. All rights reserved.