Python中如何更新参数和传递来解决_ivp

Python中如何更新参数和传递来解决_ivp,python,scipy,ode,Python,Scipy,Ode,在我的ODE函数中,我需要迭代求解一个参数方程,直到在每个时间步收敛。我想传递最新的参数值作为下一个时间步的初始值,这样当函数迭代更新参数时,所需的时间会更少。但我不知道该怎么做。ODE函数的代码结构如下所示: 来自scipy.integrate import solve\u ivp的 def运行(t,y): 如果t==0: a=1e-8 nn=0 而nn我认为你所寻找的是以下形式的东西: class test: a = 1e-8 def f(self, t, y):

在我的ODE函数中,我需要迭代求解一个参数方程,直到在每个时间步收敛。我想传递最新的参数值作为下一个时间步的初始值,这样当函数迭代更新参数时,所需的时间会更少。但我不知道该怎么做。ODE函数的代码结构如下所示:

来自scipy.integrate import solve\u ivp的

def运行(t,y):
如果t==0:
a=1e-8
nn=0

而nn我认为你所寻找的是以下形式的东西:

class test:
    a = 1e-8
    def f(self, t, y):
        ## do iter on self.a
        return self.a*y
        
t = test()
# solve_ivp(t.f, .....)

这样,您就可以始终使用
a
的最后一个值,因为它是
test
类实例的一部分。这并不完全是您所要求的,因为这将在每次
solve\u ivp
计算
f
时调用迭代,这将是每个时间步的多次。然而,我认为这是你能得到的最接近的,因为
solve_ivp
似乎没有一个
回调
函数在每个时间步后调用

不清楚你想要的是什么:你想在一系列参数值下为一个ODE获得一个解决方案吗(即,对于你求解整个ODE的每个参数值)或者随着ODE迭代更改参数(当然,您需要内部或外部迭代)


如果是前者,则只需在参数上执行for循环。如果是后者,那么使用实现特定解算器(DOPRI、Radau、RK、BDF等)的解算器类(solver class)可能会更容易、更干净,这些解算器类会将工作委托给ivp。它们提供了一个执行单个步骤的
步骤
方法。这样你就可以调整你的参数,控制收敛等等,以一种与这个特殊情况最相关的方式。

我想要的是后者。参数取决于状态。实际上,我不需要将参数值传递到下一个时间步,因为它可以在每个时间步迭代求解。但这会消耗时间。因此,如果我可以将当前值传递到下一个时间步,则收敛到新参数所需的迭代次数将更少。因此,关键的一点是,是否可以让ODE函数返回除导数以外的值,以及解算器是否可以使用返回的值。为了更清楚地了解您想要实现的目标,正如我之前所看到的:您想要解算一些隐式ODE,比如
y'=v,F(t,y,v)=0
。你已经有了一些相当于这个方程的定点迭代,它收敛得相当快。剩下的就是为定点迭代找到一个好的初始猜测,您想使用最后一个值或一个好的外推值吗?当然,如果scipy.integrate有DAE解算器,我建议将公式
y'=v,0=F(t,y,v)
视为半显式的索引1微分代数方程组。然后,隐式解和良好初始点的问题将自动/内部解决。完全正确!该参数满足一个非线性代数方程。它的解对初始猜测很敏感,因此最好使用当前时间步的值作为初始猜测,以开始下一时间步的非线性求解器迭代。我明白使用DAE的意义。但我觉得更一般的一点是,是否可以让ODE函数返回除导数以外的值,以及解算器是否可以使用非导数的返回值。我之前使用过R和Julia,它们都允许某种回调,让ODE函数返回不限于导数的值。您描述的更特殊的情况是
y'=a*y,0=F(t,y,a)
,带有自适应参数
a
a
可以有多个根,但您希望
a(t)
的曲线是连续的。当活动根接近另一个根时,会出现问题。有时它有助于迫使
a(t)
的导数也是连续的。