Boost ODEINT:具有自定义类和向量空间代数的受控步进器
boost odeint: controlled stepper with custom class and vector space algebra
我正在使用boost odeint来演化微分方程。 时间和值由围绕纯数字的包装类给出(执行高斯误差传播)。
using Time = Number<double>;
using Value = Number<double>;
状态及其导数由带有声明的自定义类给出
class State : boost::addable<State>, boost::multipliable<State, Time>, boost::dividable<State>
{
public:
void Add(Group const& group, Value alpha);
Value Get(Group const& group) const;
State& operator*=(Time const& time);
State& operator+=(State const& state);
State& operator/=(State const& state);
State abs() const;
Value norm_inf() const;
private:
std::map<Group, Value> map_;
};
State abs(State const& state);
namespace boost
{
namespace numeric
{
namespace odeint
{
template<>
struct boost::numeric::odeint::vector_space_norm_inf<State> {
using result_type = Value;
result_type operator()(State const& state) const;
};
}
}
}
using Derivative = State;
我将 Runge-Kutta-Dopri-5 步进器与向量空间代数一起使用
using Stepper = boost::numeric::odeint::runge_kutta_dopri5<State, Value, Derivative, Time, boost::numeric::odeint::vector_space_algebra>;
我用整个想法像
auto start_state = GetStart();
auto system = GetSystem();
auto min = GetMin();
auto max = GetMax();
auto dt = GetDt;
auto observer = GetObserver();
auto stepper = boost::numeric::odeint::make_controlled<Stepper>(1e-6, 1e-6);
boost::numeric::odeint::integrate_adaptive(Stepper(), system, start_state, min, max, dt, observer);
这就像一个魅力。但正如您可能注意到的那样,我不使用倒数第二行中定义的受控步进器,而是使用默认步进器。当我尝试在最后一行中使用stepper
变量而不是默认Stepper()
时,我收到以下编译错误:
In file included from /home/me/Integrate.cpp:2:
In file included from /usr/include/boost/numeric/odeint.hpp:35:
/usr/include/boost/numeric/odeint/stepper/controlled_runge_kutta.hpp:85:17: error: no matching constructor for initialization of 'typename operations_type::rel_error<value_type>' (aka 'rel_error<me::Number<double> >')
typename operations_type::template rel_error< value_type >( m_eps_abs , m_eps_rel , m_a_x , m_a_dxdt * abs(get_unit_value( dt )) ) );
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/include/boost/numeric/odeint/stepper/controlled_runge_kutta.hpp:768:50: note: in instantiation of function template specialization 'odeint::default_error_checker<me::Number<double>, odeint::vector_space_algebra, odeint::default_operations>::error<me::State, me::State, me::State, me::Number<double> >' requested here
value_type max_rel_err = m_error_checker.error( m_stepper.algebra() , in , dxdt_in , m_xerr.m_v , dt );
^
/usr/include/boost/numeric/odeint/stepper/controlled_runge_kutta.hpp:716:38: note: in instantiation of function template specialization 'odeint::controlled_runge_kutta<odeint::runge_kutta_dopri5<me::State, me::Number<double>, me::State, me::Number<double>, odeint::vector_space_algebra, odeint::default_operations, odeint::initially_resizer>, odeint::default_error_checker<me::Number<double>, odeint::vector_space_algebra, odeint::default_operations>, odeint::default_step_adjuster<me::Number<double>, me::Number<double> >, odeint::initially_resizer, odeint::explicit_error_stepper_fsal_tag>::try_step<(lambda at /home/me/Integrate.cpp:28:19), me::State, me::State, me::State, me::State>' requested here
controlled_step_result res = try_step( system , x , dxdt , t , m_xnew.m_v , m_dxdtnew.m_v , dt );
^
/usr/include/boost/numeric/odeint/stepper/controlled_runge_kutta.hpp:899:16: note: in instantiation of function template specialization 'odeint::controlled_runge_kutta<odeint::runge_kutta_dopri5<me::State, me::Number<double>, me::State, me::Number<double>, odeint::vector_space_algebra, odeint::default_operations, odeint::initially_resizer>, odeint::default_error_checker<me::Number<double>, odeint::vector_space_algebra, odeint::default_operations>, odeint::default_step_adjuster<me::Number<double>, me::Number<double> >, odeint::initially_resizer, odeint::explicit_error_stepper_fsal_tag>::try_step<(lambda at /home/me/Integrate.cpp:28:19), me::State, me::State>' requested here
return try_step( system , x , m_dxdt.m_v , t , dt );
^
/usr/include/boost/numeric/odeint/stepper/controlled_runge_kutta.hpp:617:16: note: in instantiation of function template specialization 'odeint::controlled_runge_kutta<odeint::runge_kutta_dopri5<me::State, me::Number<double>, me::State, me::Number<double>, odeint::vector_space_algebra, odeint::default_operations, odeint::initially_resizer>, odeint::default_error_checker<me::Number<double>, odeint::vector_space_algebra, odeint::default_operations>, odeint::default_step_adjuster<me::Number<double>, me::Number<double> >, odeint::initially_resizer, odeint::explicit_error_stepper_fsal_tag>::try_step_v1<(lambda at /home/me/Integrate.cpp:28:19), me::State>' requested here
return try_step_v1( system , x , t , dt );
^
/usr/include/boost/numeric/odeint/integrate/detail/integrate_adaptive.hpp:103:22: note: in instantiation of function template specialization 'odeint::controlled_runge_kutta<odeint::runge_kutta_dopri5<me::State, me::Number<double>, me::State, me::Number<double>, odeint::vector_space_algebra, odeint::default_operations, odeint::initially_resizer>, odeint::default_error_checker<me::Number<double>, odeint::vector_space_algebra, odeint::default_operations>, odeint::default_step_adjuster<me::Number<double>, me::Number<double> >, odeint::initially_resizer, odeint::explicit_error_stepper_fsal_tag>::try_step<(lambda at /home/me/Integrate.cpp:28:19), me::State>' requested here
res = st.try_step( system , start_state , start_time , dt );
^
/usr/include/boost/numeric/odeint/integrate/integrate_adaptive.hpp:42:20: note: in instantiation of function template specialization 'odeint::detail::integrate_adaptive<odeint::controlled_runge_kutta<odeint::runge_kutta_dopri5<me::State, me::Number<double>, me::State, me::Number<double>, odeint::vector_space_algebra, odeint::default_operations, odeint::initially_resizer>, odeint::default_error_checker<me::Number<double>, odeint::vector_space_algebra, odeint::default_operations>, odeint::default_step_adjuster<me::Number<double>, me::Number<double> >, odeint::initially_resizer, odeint::explicit_error_stepper_fsal_tag>, (lambda at /home/me/Integrate.cpp:28:19), me::State, me::Number<double>, (lambda at /home/me/Integrate.cpp:48:21)>' requested here
return detail::integrate_adaptive(
^
/usr/include/boost/numeric/odeint/algebra/default_operations.hpp:435:9: note: candidate constructor not viable: no known conversion from 'me::State' to 'me::Number<double>' for 4th argument
rel_error( Fac1 eps_abs , Fac1 eps_rel , Fac1 a_x , Fac1 a_dxdt )
^
/usr/include/boost/numeric/odeint/algebra/default_operations.hpp:431:12: note: candidate constructor (the implicit move constructor) not viable: requires 1 argument, but 4 were provided
struct rel_error
^
/usr/include/boost/numeric/odeint/algebra/default_operations.hpp:431:12: note: candidate constructor (the implicit copy constructor) not viable: requires 1 argument, but 4 were provided
我可以看到odeint::rel_error<me::Number<double>>
应该是Number
类型,但是用作rel_error
构造函数的第 4 个参数的乘积m_a_dxdt * abs(get_unit_value( dt ))
是State
类型。 我假设我在为State
类实现向量空间代数时犯了一个错误,但我找不到我在哪里犯了错误。
如果我将时间和值类型替换为普通double
,则错误检查器将再次工作。
似乎 odeint 的指令包含了一个错误。 如果abs
函数的返回类型是Value
而不是State
,就像人们天真地期望的那样,编译错误就会消失。
相关文章:
- 需要反转音频步进公式
- Arduino Nano:A4988 使用串行输入时通过定时器进行步进控制不稳定
- 锁定步进pthread互斥
- 在 ODEINT 中通过 if 语句选择步进器
- boost odeint 中的受控误差步进器是否支持复杂的数据类型?
- 创建带有限幅器的步进器控件
- 班上的Arduino步进电动机指针不起作用
- 生成最多给定数字 N 的步进数字
- Boost ODEINT:具有自定义类和向量空间代数的受控步进器
- 我如何仅使用一个Arduino uno才能在同一时间和同一方向上旋转两个步进电动机
- 如何使步进电机运行,直到我按下 Arduino 上的特定键盘按钮
- Arduino Sonar和步进马达
- 这些步进回合是否等效
- 使用C++同步控制多个步进器
- 接口 C++ 以使用 Arduino 控制电机步进器
- 步骤程序?开始、结束、步进整数
- 如何使用ODEINT的标签系统为各种步进器类型做特定工作
- 通过替换模板<类步进器来要求>
- GDB 继续而不是步进
- cpp std::list 使用步进添加新元素