从数学上总和一个序列



我缺乏基本数学,并且想知道是否有比循环算法更有效的方法:

dt = 1 / 60.
vel = 1000.
fri = 0.05
result = 0
while vel > 0.5:
    vel -= vel * fri
    result += vel * dt
print(result)

编辑:您可以在此处看到一个VEL的示例,并在每次迭代中进行结果:https://www.desmos.com/calculator/1dfvxzgxvt

如果您只想在无限时间之后的答案,则Arndt Jonasson有答案。

加快代码

另外,如果您只想加快现有代码,那么对于这种数字代码,numba可能非常方便:

def fn():
    dt = 1 / 60.
    vel = 1000.
    fri = 0.05
    result = 0
    while vel > 0.5:
        vel -= vel * fri
        result += vel * dt
    return result
from numba import njit
numba_fn = njit(fn)

如果我们为两个时间,我们会看到一个很大的区别:

%timeit fn()
10.2 µs ± 12.6 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
%timeit numba_fn()
429 ns ± 5.86 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

集成以在任何时候获得距离

最后,如果您通常要在任何有限的时间内解决此问题,那么整合就是您的朋友。您显示的算法由以下等式描述

dv / dt = - 60 fri v(t)

换句话说,速度的变化与速度成正比(60仅是原始时间步骤的一个因素(。这被称为一阶微分方程,具有解决方案

from math import exp
def v(t):
    """Velocity at time ``t``.
    """
    return 950 * exp(-fri * 60 * t)

其中950是初始速度(当您在"移动"之前更改它时,不是1000(,因此我们通过求解上述方程式V(t(= 0.5:

来计算速度达到0.5的时间
from math import log
tf = log(0.5 / 1000) / (-fri * 60)  # approx(2.53)

然后,要使距离旅行直到时间tf,我们将v(t)0集成到tf

from scipy.integrate import quad
distance, err = quad(v, 0, tf)
print(distance)
316.50833333333327

或确认无限时间答案:

import numpy as np
print(quad(v, 0, np.inf)[0])
316.6666666666584

我假设vel的下限只是为了使迭代停止某个时间。

那么您正在做的是计算一个无限的所谓几何序列

k+k^2+k^3+k^4+...

其中 k = 1-fri = 0.95

结果是k/(1-k) =19。我忽略了veldt的起始值,因为它们只是乘法常数。最终结果是19*1000/60 = 316.66667。