【问题标题】:Finding zero crossing in python在python中找到零交叉
【发布时间】:2019-05-09 18:23:11
【问题描述】:

我编写了以下代码来查看我的 ODE“exponential_decay”在哪个t 越过零线。这是Brent Method

odr, hr, dr, cr, m = np.genfromtxt('data.txt',unpack=True)
n=0
with open('RDE_nob_trans.txt', 'w') as d:
  for i in range(len(dr)):
      c = cr[i]
      initp = dr[i]
      exponential_decay = lambda t, y: -(1/(1+t)) * (2 *(1-y)* (-2 + (y/c)) + 3 - 3 * y)
      t_span = [0, 1] # Interval of integration
      y0 = [initp] # Initial state: y(t=t_span[0])=2
      desired_answer = odr[i]
      sol_ode = solve_ivp(exponential_decay, t_span, y0) # IVP solution

      f_sol_ode = interp1d(sol_ode.t, sol_ode.y) # Build interpolated function
      ans = brentq(lambda x: f_sol_ode(x) - desired_answer, t_span[0], t_span[1])
      d.write("{0} {1} {2} {3} {4}\n".format(hr[i], dr[i], cr[i], m[i], ans))

在这段代码中,我们知道了初始点initp = dr[i],我们知道了在零交叉处的微分方程的值desired_answer = odr[i],并且我们愿意在哪个t 中找到这个答案。没关系,我们通过这段代码得到答案。 ans 是零交叉处的t

我的问题是,如果我们对 ODE 的回答(现在是 desired_answer = odr[i])不仅仅是一个数字,而是一个以 t 表示的值,我们该怎么办。

我的意思是使用odr[i] 我们正在读取数据文件并随后读取数字。现在考虑我们有类似odr = 0.1 * t, 0.12 *t, 0.23 *t etc. 的东西,它不是数字,而是t 的函数。

【问题讨论】:

    标签: python ode odeint genfromtxt


    【解决方案1】:

    这不是solve_ivp 接口最有效的用法。您可以使用event 机制自动获取结果。

    def event(t,y): return y-desired_answer;
    event.terminal = True;
    
    sol_ode = solve_ivp(exponential_decay, t_span, y0, events=event) # IVP solution
    ans = sol_ode.t[-1]
    

    即使您想使用自己的求解器(或求解器调用),您也可以使用密集输出选项获得特定方法且准确的分段多项式插值,

    sol_ode = solve_ivp(exponential_decay, t_span, y0, dense_output=True) # IVP solution
    f_sol_ode = sol_ode.sol
    

    要获得依赖于时间的函数的根,您只需编写时间依赖的代码,例如

    def event(t,y): return y-0.23*t;
    

    ans = brentq(lambda t: f_sol_ode(t) - 0.23*t, t_span[0], t_span[1])
    

    如果您想要可靠的结果,您应该明确控制公差atol, rtol

    【讨论】:

    • 你代码的上半部分对我不起作用,充满了错误。如果您编写完整的代码,我将不胜感激,因为对于下部,python 对eventsolver 等几乎没有影响。它有效,但我有一个问题,我想我忘了在问题中提到的是:代码只适用于t_span = [0, 1],我无法扩展它的范围,例如-1,10,2 等在某些情况下它说的值ValueError: f(a) and f(b) must have different signs
    • 能否给出两行示例参数?我更正了参数名称和布尔常量中的语法错误。并且人们可能不能采用 sol 函数的第一个组件,只能采用它的值数组。
    • 对于错误,您可以仅对观察到目标函数符号变化的区间应用二分法、regula falsi、Dekker、Müller 或 Brent 等包围方法。事件机制会自动执行此操作,在内部步骤期间检查符号更改,您必须明确执行此操作。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-10-09
    • 2014-06-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-31
    • 1970-01-01
    相关资源
    最近更新 更多