1

What I am trying to do in this question is in line with what I was trying to do in: Dynamic Eigen vectors in Boost::odeint. However now I am trying to encapsulate it all in a class as follows:

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

namespace odeint = boost::numeric::odeint;
typedef odeint::runge_kutta_dopri5<Eigen::VectorXd, double, Eigen::VectorXd, double, odeint::vector_space_algebra> stepper;

class foo
{
private:
    Eigen::VectorXd m_x;
    Eigen::MatrixXd m_A;
    double m_t, m_dt;
public:
    foo(int nr_of_states){ //ctor
        m_t = 0;
        m_dt = 1.0;
        m_x = Eigen::VectorXd(nr_of_states);
        m_A = Eigen::MatrixXd(nr_of_states, nr_of_states);

        srand(365);

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

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

    void ODE_function(const Eigen::VectorXd &x, Eigen::VectorXd &dxdt, double){
        dxdt = m_A * x;}

    void next_step(){
        odeint::integrate_adaptive(stepper(), ODE_function, m_x, m_t, (m_t+(1*m_dt)), m_dt);}

    Eigen::VectorXd get_states(){
        return m_x;}
};

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;

    foo f1(nr_of_states);

    for (int i = 0; i < 100; i++){
        f1.next_step();}

    std::cout <<std::endl << "final state vector: " << std::endl << f1.get_states() << std::endl;

    return 0;
}

I am using the MinGW 64 bit compiler to compile above code when I get the following error message:

\boost\boost_1_59_0\boost\numeric\odeint\stepper\base\explicit_error_stepper_fsal_base.hpp|297|error: must use '.' or '->' to call pointer-to-member function in 'sys (...)', e.g. '(... ->* sys) (...)'|

Is what I am trying to do here in principle possible? If yes, how should above code be adapted?

Community
  • 1
  • 1
Sjonnie
  • 115
  • 1
  • 6
  • This sounds like the issue is with the compiler not understanding the boost header. (I looked up line 297 in the file listed in the error, and I see the definition and use of `sys`, which is what the error is complaining about.) – callyalater Mar 01 '16 at 14:20
  • 1
    you have to bind the member function, see e.g. http://stackoverflow.com/questions/18928733/boost-odeint-class-with-derivative-and-jacobian, if you have c++11 you can also simply use a lambda for that. – mariomulansky Mar 01 '16 at 16:07
  • 1
    It took me a while to wrap my head around it, but I think I've got it, I have changed the body of the `next_step()` function into: `odeint::integrate_adaptive(stepper(), std::bind(&foo::ODE_function, &(*this), std::placeholders::_1, std::placeholders::_2, std::placeholders::_3), m_x, m_t, (m_t+(1*m_dt)), m_dt);` It now compiles fine and the first output is correct. Thank you for your help Mario. – Sjonnie Mar 01 '16 at 19:02
  • Yes, this is a duplicate of http://stackoverflow.com/questions/18928733/boost-odeint-class-with-derivative-and-jacobian – headmyshoulder Mar 01 '16 at 23:06

0 Answers0