在python中查找零交叉

在python中查找零交叉,python,ode,odeint,genfromtxt,Python,Ode,Odeint,Genfromtxt,我编写了以下代码,以查看tODE“指数衰减”穿过零线的地方。这是布伦特方法 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/(

我编写了以下代码,以查看
t
ODE“指数衰减”穿过零线的地方。这是布伦特方法

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))
在这段代码中,我们知道初始点,我们知道微分方程在过零点处的值,我们愿意找出在哪个点我们有这个答案。这是确定的,我们得到了这个代码的答案
ans
是零交叉处的
t

我的问题是,如果我们的ODE答案现在是
desired\u answer=odr[i]
不仅仅是一个数字,而且是一个
t
的值,我们该怎么办


我的意思是使用
odr[I]
我们正在读取数据文件,然后读取数字。现在考虑我们有一些类似于<代码> ODR=0.1*T,0.12×t,0.23*t,< /代码>,这不是一个数字,是一个函数,在<代码> t>代码>。

这不是最有效的使用<代码> SovivIVP接口。您可以使用
事件
机制自动获得结果

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;



如果你想得到可靠的结果,你应该明确控制公差
atol,rtol

你的代码的上半部分对我不起作用,充满了错误。如果您编写完整的代码,我将不胜感激,因为python对
event
solver等下面的部分没有任何影响。它是有效的,但我有一个问题,我想我忘了在问题中提到:代码只适用于
t_span=[0,1]
,我不能扩展它的范围,例如
-1,1
0,2
等。在某些值中,它表示
ValueError:f(a)和f(b)必须有不同的符号
您能给出两行示例参数吗?我纠正了参数名和布尔常量中的语法错误。对于误差,你可以使用括号法,如二分法、regula-falsi法、Dekker法、Müller法或Brent法,仅适用于观察到目标函数符号变化的区间。事件机制自动执行此操作,在内部步骤中检查符号更改,您必须显式执行此操作。
ans = brentq(lambda t: f_sol_ode(t) - 0.23*t, t_span[0], t_span[1])