生成线性间隔增长率的向量,知道开始、结束和总复合增长,带有 numpy 或类似



我正在寻找生物学应用的离散增长率模型。 我知道每小时的起始增长率(200%)和每小时的结束增长率(2%)。 增长率应每小时线性下降。 我也知道总增长应该是 200 倍。 我正在尝试计算所需的小时数并生成一个矢量数组,大小为小时数,包含增长率(每小时一个值)......类似 [200%, 180%, 160% ...4%, 2%]. 但我需要总复合增长率等于 200 倍。

我玩过np.linspace和np.geomspace,但我不够聪明,不知道在这种情况下如何让复合增长相匹配。

这是针对您的问题的代码。假设从第一个小时开始到第一个小时结束的增长率为 200%,这意味着它从一个值变为其值的 3 倍。然后,从第二个小时开始到结束的增长速度下降到较低的速度,依此类推。从最后一小时开始到结束的增长率为2%,并且增长率呈线性下降--即比率是一个递减的算术级数。

此代码查找最终金额的最小积分小时数,至少是初始金额的 200 倍。我不是 numpy 专家,所以我使用常规 Python 循环而不是使用 numpy 来计算整体增长。

import numpy as np
start_growth_rate = 2.00  # 200% as a decimal
stop_growth_rate = 0.02  # 2% as a decimal
target_total_growth = 200  # 200 times larger than the starting value
calced_total_growth = 0
num_hours = 2
while calced_total_growth < target_total_growth:
rates_array = np.linspace(start=start_growth_rate, stop=stop_growth_rate,
num=num_hours)
calced_total_growth = 1
for this_growth_rate in rates_array:
calced_total_growth *= 1 + this_growth_rate
num_hours += 1
print('Actual total growth rate = {} times over {} hours.'.format(
calced_total_growth, num_hours - 1))
print('Growths = {}'.format(rates_array))

打印输出为

Actual total growth rate = 324.01866418570273 times over 9 hours.
Growths = [ 2.      1.7525  1.505   1.2575  1.01    0.7625  0.515   0.2675  0.02  ]

最终结果是超过324,远远超过你的目标200。如果你把小时减少到只有8小时,你会得到

Actual total growth rate = 168.09849392178677 times over 8 hours.
Growths = [ 2.          1.71714286  1.43428571  1.15142857  0.86857143  0.58571429
0.30285714  0.02      ]

这低于您的目标 200,但比多用一个小时更接近。

使用 9 小时费率,在倒数第二个小时内实际上超过了 200 的目标。它被跨越的确切时间取决于你如何模拟从该小时开始到结束的增长模式 - 该小时内的增长与我的假设和我的代码无关。


另一组假设也是可能的——你给出的增长率是瞬时的,200倍的目标不会在整数小时内发生。这里的解决方案更数学化,但这里有一个大纲。

如果我们让 T 是达到人口规模所需的时间,则为初始值的 200 倍。然后从 2 线性下降到 0.02 的时间Tty的增长率公式为

y'/y = 2 - (1.98 / T) * t

这是一个可分微分方程,初始条件 y(0)=1。有解决方案的解决方案

y = exp(2 * t - (0.99 / T) * t**2)

在 Python 语法中。由于我们想在时间 T 处以目标 200 结束,因此我们得到

T = log(200) / 1.01 = 5.245858778760432

其中对数是自然对数,最后一个值是近似值。所以人口函数的最终解是

y = exp(2 * t - (0.9999 / log(200)) * t**2)

但是你想要在你的打印阵列中是增长率,由下式给出

y'/y = 2 - (1.9998 / log(200)) * t

在数组中大致显示

[2 - (1.9998 / log(200)) * t for t in range(6)]

其计算结果为

[2.0,
1.622559416197654,
1.2451188323953077,
0.8676782485929615,
0.4902376647906155,
0.11279708098826946]

最后一个值不是 0.02,因为增长在一小时 5 之后继续。(实际结束时间见上文时间T。

最新更新