2013-09-12 2 views
1

Можете ли вы предоставить мне простой пример выполнения цифровой интеграции с odeint в C++?Как выполнить простую цифровую интеграцию с odeint в C++

Я хотел бы использовать функцию удобно интеграции, documented как:

integrate(system , x0 , t0 , t1 , dt) 

Кроме того, я не уверен, как передать его вместо функции или функтор, метод класса, если это возможно.

+0

Не интеграция в основном для цикла? – crush

+0

@crush Да, это так. Но Odeint автоматизирует этот процесс и позволяет вам позже интегрироваться с OpenMP, Cuda и Thrust, поэтому я решил использовать его. –

+4

@crush: интеграция - это больше, чем цикл for. Я также создаю шаговый элемент и выполняет интеграцию с плотным управлением выводом и шагом. – headmyshoulder

ответ

4

В C++ 11 вы можете использовать простую функцию лямбда оберточной вызов на метод члена

Class c; 
auto f = [&c](const state_type & x , state_type &dxdt , double t) { 
    c.system_func(x , dxdt , t); }; 
integrate(f , x0 , t0 , t1 , dt); 

std::bind может также работать, но тогда вы должны позаботиться, если значения передаются по ссылке из по стоимость.

В C++ 03 вы должны написать простую обертку вокруг вашего метода класса

struct wrapper 
{ 
    Class &c; 
    wrapper(Class &c_) : c(c_) { } 
    template< typename State , typename Time > 
    void operator()(State const &x , State &dxdt , Time t) const 
    { 
     c.system_func(x , dxdt , t); 
    } 
}; 

// ... 
integrate(wrapper(c) , x0 , t0 , t1 , dt); 

(Boost.Bind не будет правильно работать с более чем двумя аргументами).

+0

Возможно ли, чтобы этот метод был членом одного и того же экземпляра класса? –

+0

А также, что именно есть c, p1 :: _ 1 и т. Д. В вашем примере? –

+0

Я не понимаю ваш первый вопрос. Метод вызывается с экземпляром c. pl - пространство имен для std :: placeholders. Я отредактировал свой ответ. – headmyshoulder

2

Вы имеете в виду примеры в дополнение к ним provided online?

#include <iostream> 
#include <boost/array.hpp> 

#include <boost/numeric/odeint.hpp> 

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

const double sigma = 10.0; 
const double R = 28.0; 
const double b = 8.0/3.0; 

typedef boost::array< double , 3 > state_type; 

void lorenz(const state_type &x , state_type &dxdt , double t) 
{ 
    dxdt[0] = sigma * (x[1] - x[0]); 
    dxdt[1] = R * x[0] - x[1] - x[0] * x[2]; 
    dxdt[2] = -b * x[2] + x[0] * x[1]; 
} 

void write_lorenz(const state_type &x , const double t) 
{ 
    cout << t << '\t' << x[0] << '\t' << x[1] << '\t' << x[2] << endl; 
} 

int main(int argc, char **argv) 
{ 
    state_type x = { 10.0 , 1.0 , 1.0 }; // initial conditions 
    integrate(lorenz , x , 0.0 , 25.0 , 0.1 , write_lorenz); 
} 

Plot of the output from the example above

А что касается системы, вы можете предоставить что-либо, где следующее выражение справедливо:

sys(x , dxdt , t) // returning void 

Проверьте руководство пользователя (и другие примеры) online.