Повышение класса odeint с производной и якобианом

Я намерен использовать библиотеку Boost odeint в подпрограмме MCMC для оценки параметров в модели ODE. Поскольку эти ОДУ могут быть жесткими, мне нужно иметь возможность передать якобиан в решатель с производной. Я хотел бы создать класс, который имеет параметры и начальные значения как частные члены, а затем производные, якобианские и методы для изменения параметров как общедоступные методы. Я попытался изменить жесткий пример с веб-сайта odeint, чтобы использовать один класс, содержащий оба, но получаю сообщение об ошибке: нет функции сопоставления для вызова Fitzhugh :: производного () при компиляции. Я не опытный программист на C ++, поэтому, скорее всего, это концептуальная ошибка. Вот код.

/* Fitzhugh Nagumo Equation in odeint */

#include <iostream>
#include <fstream>
#include <utility>
#include <cmath>

#include <boost/numeric/odeint.hpp>
#include <boost/phoenix/core.hpp>
#include <boost/phoenix/operator.hpp>

using namespace std;
using namespace boost::numeric::odeint;
namespace phoenix = boost::phoenix;

//[ stiff_system_definition
typedef boost::numeric::ublas::vector< double > vector_type;
typedef boost::numeric::ublas::matrix< double > matrix_type;

class Fitzhugh
{
    private:
        double a;
        double b;
        double c;

    public:
        Fitzhugh( double a_, double b_, double c_ ) : a(a_), b(b_), c(c_) { }

        void deriv ( const vector_type &x , vector_type &dxdt , double )
        {
            dxdt[ 0 ] = c*(x[0] - pow(x[0], 3.0)/3.0 + x[1]);
            dxdt[ 1 ] = -(x[0] - a + b*x[1])/c;
        }

        void jac ( const vector_type &x, matrix_type &J , const double &  , vector_type &dfdt )
        {
            J( 0 , 0 ) = c*(1 - pow(x[0], 2.0));
            J( 0 , 1 ) = c;
            J( 1 , 0 ) = -1/c;
            J( 1 , 1 ) = -b/c;
            dfdt[0] = 0.0;
            dfdt[1] = 0.0;
        }
};



int main( int argc , char **argv )
{
//    typedef rosenbrock4< double > stepper_type;
//    typedef rosenbrock4_controller< stepper_type > controlled_stepper_type;
//    typedef rosenbrock4_dense_output< controlled_stepper_type > dense_output_type;
    //[ integrate_stiff_system
    vector_type x( 2 , 1.0 );

    Fitzhugh fitzhugh(0.2, 0.2, 3.0);

    size_t num_of_steps = integrate_const( make_dense_output< rosenbrock4< double > >( 1.0e-6 , 1.0e-6 ) ,
            make_pair( fitzhugh.deriv() , fitzhugh.jac() ) ,
            x , 0.0 , 50.0 , 0.01 ,
            cout << phoenix::arg_names::arg2 << " " << phoenix::arg_names::arg1[0] << "\n" );
    //]
    clog << num_of_steps << endl;


    return 0;
}

Вот полный вывод

/home/chris/C++/examples/fitzhugh/main.cpp: In function ‘int main(int, char**)’:
/home/chris/C++/examples/fitzhugh/main.cpp:60:39: error: no matching function for call to ‘Fitzhugh::deriv()’
/home/chris/C++/examples/fitzhugh/main.cpp:60:39: note: candidate is:
/home/chris/C++/examples/fitzhugh/main.cpp:30:14: note: void Fitzhugh::deriv(const vector_type&, vector_type&, double)
/home/chris/C++/examples/fitzhugh/main.cpp:30:14: note:   candidate expects 3 arguments, 0 provided
/home/chris/C++/examples/fitzhugh/main.cpp:60:56: error: no matching function for call to ‘Fitzhugh::jac()’
/home/chris/C++/examples/fitzhugh/main.cpp:60:56: note: candidate is:
/home/chris/C++/examples/fitzhugh/main.cpp:36:14: note: void Fitzhugh::jac(const vector_type&, matrix_type&, const double&, vector_type&)
/home/chris/C++/examples/fitzhugh/main.cpp:36:14: note:   candidate expects 4 arguments, 0 provided

person caburke    schedule 21.09.2013    source источник


Ответы (1)


чтобы передать функцию-член, вам нужно использовать механизм привязки. если у вас есть компилятор C ++ 11, вы можете использовать std :: bind; включите пространство имен std :: placeholder: using namespace std::placeholders;, затем используйте std :: bind из <functional>:

make_pair( bind( &Fitzhugh::deriv , &fitzhugh , _1 , _2 , _3 ) , bind( &Fitzhugh::jac , &fitzhugh , _1 , _2 , _3, _4 ) )

person mariomulansky    schedule 21.09.2013
comment
Спасибо, после подключения вашего кода, обновления до компилятора GCC 4.7.3 и добавления соответствующих флагов, запускаемых моим кодом. - person caburke; 22.09.2013