我缺乏基本数学,并且想知道是否有比循环算法更有效的方法:
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。我忽略了vel
和dt
的起始值,因为它们只是乘法常数。最终结果是19*1000/60 = 316.66667。