在Python中,SciPY ode.int的多余工作已完成

时间:2018-11-22 15:48:57

标签: python scipy ode

我正在尝试对一个在二维平面中彼此追逐的bug进行追赶的问题,并且我正在使用SciPY.odeint来帮助我解决这个问题。使用以下代码,该模型可以正常工作,但是随着错误之间的距离越来越近,该模型崩溃并发出了对该调用(也许是错误的Dfun类型)错误所做的多余工作。

import numpy as np
from scipy.integrate import odeint

def split_list(a_list):
    half = len(a_list)//2
    return a_list[:half], a_list[half:]

def diff(w, t):
    x_points, y_points = split_list(w)
    def abso(f, s):
        return np.sqrt((x_points[f] - x_points[s])**2 + (y_points[f] - y_points[s])**2)
    x_funct = [(x_points[i+1] - x_points[i]) / abso(i+1, i) for i in range(len(x_points) - 1)]
    x_funct.append((x_points[0] - x_points[-1]) / abso(0,-1))

    y_funct = [(y_points[i+1] - y_points[i]) / abso(i+1,i) for i in range(len(x_points) - 1)]
    y_funct.append((y_points[0] - y_points[-1]) / abso(0,-1))
    funct = x_funct + y_funct
    return funct

def ode(tstart, tend, init_cond):

    t = np.linspace(tstart, tend, step_size)

    wsol = odeint(diff, init_cond, t)
    sols = [wsol[:,i] for i in range(len(init_cond))]
    x_sols, y_sols = split_list(sols)
    return x_sols, y_sols, t, tend

bug_init_cond = [[-0.5, 1],
                 [0.5, 1],
                 [0.5, -1],
                 [-0.5, -1],]

amount_of_bugs = 4
step_size = 10000

x_sols, y_sols, t, tend = ode(0, 5, [bug_init_cond[i][j] for j in range(2) for i in range(amount_of_bugs)])

由于我对使用Scipy.odeint函数还很陌生,所以我想知道是否有解决此多余工作的方法?谢谢您的时间。

1 个答案:

答案 0 :(得分:1)

您的问题是,在确切的解决方案中,路径在时间t=1.48t=1.5处相遇。在一个精确的解决方案中,您将得到零误差除以浮点噪声,该浮点噪声会“退化”为一种僵硬的情况,在这种情况下,步长会逐渐减小,直到输出时间步长需要超过mxstep=500个内部步长为止。

您可以添加条件,以便在仓位平仓时将右侧设置为零。要实现这一目标,一个快速的技巧是将距离函数abso修改为

  def abso(f, s):
    return np.sqrt(1e-12+(x_points[f] - x_points[s])**2 + (y_points[f] - y_points[s])**2)

这样您就永远不会除以零,并且对于可见距离,扰动可以忽略不计。