很抱歉,如果这是一个简单的问题 - 但是有一个“最佳实践”用于下采样odeint中状态变量的演变吗?
下面,我复制了一个很好的例子,用于构建"observer"以记录本文中提供的状态变量(http://www.codeproject.com/Articles/268589/odeint-v2-Solving-ordinary-differential-equations)
struct streaming_observer
{
std::ostream &m_out;
streaming_observer( std::ostream &out ) : m_out( out ) {}
void operator()( const state_type &x , double t ) const
{
m_out << t;
for( size_t i=0 ; i < x.size() ; ++i )
m_out << "\t" << x[i];
m_out << "\n";
}
};
// ...
integrate_const( runge_kutta4< state_type >() , lorenz , x , 0.0 , 10.0 , dt , streaming_observer( std::cout ) );
你如何改变观察者只能每10步记录一次状态(例如) . 我想知道是否有比使用if语句更优雅的解决方案:
struct streaming_observer
{
std::ostream &m_out;
int count;
streaming_observer( std::ostream &out ) : m_out( out ) {count = 10;}
void operator()( const state_type &x , double t ) const
{
if( count == 10 ) {
count = 1;
m_out << t;
for( size_t i=0 ; i < x.size() ; ++i )
m_out << "\t" << x[i];
m_out << "\n";
}
else {
count++;
}
}
};
2 回答
我有同样的问题,并像你一样完全解决了 . 但是,您也可以考虑使用具有步长控制的步进器,然后将integrate_const与dt一起使用,以便以所需的间隔调用观察器 . 当您使用具有步长控制的步进器(甚至更好:像dopri5这样的密集输出)时,integrate_const会根据您的容错来调整步长,但随后会确保在t0 n * dt时调用观察者 .
其实我会像你一样做 . 您还可以编写一个小适配器来进行跨步:
然后跨步是可选的和可组合的 . 然后,您可以将第一个示例编写为