python:满足条件时中断odeint

时间:2014-12-03 14:56:04

标签: odeint

我正在使用scipy.integrate包中的odeint函数:

r0 = np.array([1,2,3,4])
t=np.linspace(0,1,20)
def drdt(r,t):
    return r # or whatever else
r = odeint(drdt,r0,t)

r0是一个numpy数组,包含一定数量点的初始位置。 在脚本结束时,正如预期的那样,我得到了20个时间点的位置。

现在我想在满足条件r时停止odeint求解器。特别是当这些点中的2个比某个阈值更接近时,我想停止odeint,对r向量进行一些更改,并使用新的初始位置继续odeint求解器。 有没有办法实现这个?

我一直在考虑的一个可能的解决方案是将odeint运行到最后,稍后检查是否满足条件,但这当然效率不高。

谢谢大家的帮助, 尼古拉

1 个答案:

答案 0 :(得分:1)

我有一个C ++的答案。它可能不是发布它的最佳位置,但它可能仍然有趣。 (我没有找到一个更好的地方,这是我在寻找C ++解决方案时登陆的地方)。

下面是一个C ++示例,当变量等于或低于零时停止集成。

#include <iostream>
#include <boost/range/algorithm.hpp>
#include <boost/numeric/odeint.hpp>

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


typedef double state_type;

typedef runge_kutta_cash_karp54< state_type > error_stepper_type;


class Myode{
public:
  void operator()(const state_type& x, state_type& dxdt, const double t){dxdt=-1-x;}
  static bool done(const state_type &x){return x<=0.0;}
};

int main(int argc, char* argv[]){
   Myode ode;
   state_type x=10.0;
   auto stepper =  make_controlled< error_stepper_type >( 1.0e-10 , 1.0e-6 );
   auto iter= boost::find_if(make_adaptive_range(stepper,ode,x, 0.0 , 20.0 , 0.01 ),
                 Myode::done);

   cout<<"integration stopped at"<<x<<endl;
  return 1;
}

积分在第一次达到小于或等于零的值x时停止(参见完成功能)。因此,根据您当前的步长,它可能远远低于零。

请注意,这使用了c ++ 11构造,因此您需要在编译器上启用此功能。在我的情况下(gcc 4.4),它是通过在编译命令中添加-std = gnu ++ 0x来实现的。