Scipy odeint非负解决方案

时间:2014-01-26 17:35:58

标签: python numpy scipy scientific-computing differential-equations

显然,getting a non-negative solution from an ODE solver is non-trivial。在Matlab中,某些求解器有NonNegative option来获得非负解。 scipy中有类似的选项吗?

如果不是,强加非负面约束的“最佳”方式是什么?目前,我有以下内容:

def f(x, t, params):
     ... ... ...
     ... ... ...
     x_dot[(x <= 0) * (x_dot <= 0)] = 0.0
     return x_dot
... ... ...
x = odeint(f, x0, t, args=params)

然而,这会导致数值不稳定。我需要将mxstep设置为1e8,hmin = 1e-15。

1 个答案:

答案 0 :(得分:0)

问题不仅仅是你必须避免负x的平方根。问题在于施加约束的“最佳”方式仍取决于系统的应用程序是什么以及您认为“合理”的行为。如果你的系统在0处没有均衡,那么你的问题可能是不适当的。它以非零速度进入负x域的意义是什么?如果解释是解决方案应保持为零,那么您实际上不再具有ODE系统作为您的预期模型:您有一个具有非平滑分量的混合动力系统,即当轨迹x(t)达到0时t = t_1,对于所有t> t,它必须保持在x(t)。 T_1。这可以通过适当的动态系统包(例如PyDSTool)轻松实现。

或者,x = 0是稳定的平衡,并且您只需要防止f的评估为x <0。这也可以通过事件检测进行攻击。

在任何一种情况下,当x <0时未定义f时,x = 0处的事件检测很棘手。几乎没有标准的ODE求解器可以在所有情况下强制避免在子域中进行评估,并且大多数事件检测将涉及边界任一侧的评估。一个实用的解决方案是为x选择一个较小的数字,在这之下安全(在你的应用程序的上下文中)声明x = 0.然后在x到达时检测事件(假设你可以控制步长保持足够小)应该防止x被评估为负值。然后你会在这一点之后制定一个条件使x = 0,如果这是你想要的行为。再次,这在scipy / python中有点大惊小怪,但你可以做到。在PyDSTool中设置所需的行为也相当容易,如果你在帮助论坛发帖,我愿意为你提供建议。