SciPyRK45(solve_ivp)函数计算次数是否准确?
Does SciPy RK45 (solve_ivp) count the number of function evaluations accurately?
我想根据 SciPy RK45 衡量我自己的 ODE 积分器的性能。因此,我需要确切地知道 RK45 使用的右侧函数计算的数量。
有谁知道sol.nfev这个数字是否准确,即没有重复?比如RK45拒绝一个步长,重复该步,那么该步的初始评价f(t,x)是不是算了多次?
此外,RK45 使用的 Dormand-Prince RK method 有 7 个阶段,但由于“First Same As Last”属性(最后一个阶段在与下一步的第一阶段)。 sol.nfev 中是否考虑到了这一点?
经过一些实验,我可以确认 RK45 计数准确,即不评估也不计算重复次数。对于任何想知道如何解释数字 sol.nfev 的人:
将 RK45 报告的 RK 步数表示为 num_steps = len(sol.t) - 1
,将拒绝的步数表示为 num_rej
。然后它成立
sol.nfev = (num_steps + num_rej) * 6 + 2
因为每一步都需要 6 次函数评估,除了第一个需要 7 次。此外,开始时有一个欧拉步来生成初始步长(因此 +2
)。感谢@LutzLehmann 指出这一点。
这是一个例子:
class Fun:
def __init__(self):
self.t = []
self.x = []
def __call__(self, t, x):
self.t.append(t)
self.x.append(x)
if t <= 1:
return - x ** 2
return 10 # discontinuity to provoke step rejection
t0 = 0
t1 = 1.01
x0 = [1]
sol = solve_ivp(Fun(), (t0, t1), x0)
print(sol.nfev)
print(len(f.t))
num_steps = len(sol.t) - 1
print(num_steps)
print(num_steps * 6 + 2)
从输出
56
56
7
44
我们可以看到最终解决方案中有 7 个 RK 步骤 sol
但由于函数的不连续性,也有 2 个被拒绝的步骤 (44 + 2 * 6 = 56)。
我想根据 SciPy RK45 衡量我自己的 ODE 积分器的性能。因此,我需要确切地知道 RK45 使用的右侧函数计算的数量。
有谁知道sol.nfev这个数字是否准确,即没有重复?比如RK45拒绝一个步长,重复该步,那么该步的初始评价f(t,x)是不是算了多次?
此外,RK45 使用的 Dormand-Prince RK method 有 7 个阶段,但由于“First Same As Last”属性(最后一个阶段在与下一步的第一阶段)。 sol.nfev 中是否考虑到了这一点?
经过一些实验,我可以确认 RK45 计数准确,即不评估也不计算重复次数。对于任何想知道如何解释数字 sol.nfev 的人:
将 RK45 报告的 RK 步数表示为 num_steps = len(sol.t) - 1
,将拒绝的步数表示为 num_rej
。然后它成立
sol.nfev = (num_steps + num_rej) * 6 + 2
因为每一步都需要 6 次函数评估,除了第一个需要 7 次。此外,开始时有一个欧拉步来生成初始步长(因此 +2
)。感谢@LutzLehmann 指出这一点。
这是一个例子:
class Fun:
def __init__(self):
self.t = []
self.x = []
def __call__(self, t, x):
self.t.append(t)
self.x.append(x)
if t <= 1:
return - x ** 2
return 10 # discontinuity to provoke step rejection
t0 = 0
t1 = 1.01
x0 = [1]
sol = solve_ivp(Fun(), (t0, t1), x0)
print(sol.nfev)
print(len(f.t))
num_steps = len(sol.t) - 1
print(num_steps)
print(num_steps * 6 + 2)
从输出
56
56
7
44
我们可以看到最终解决方案中有 7 个 RK 步骤 sol
但由于函数的不连续性,也有 2 个被拒绝的步骤 (44 + 2 * 6 = 56)。