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

Python 生成线性间隔增长率的向量,知道开始、结束和总复合增长率,使用numpy或类似值,python,arrays,numpy,math,vector,Python,Arrays,Numpy,Math,Vector,我希望为生物应用程序建立离散增长率模型。我知道每小时的开始增长率(200%)和结束增长率(2%)。生长速率每小时应呈线性下降。我也知道总增长率应该是200倍。我试图计算所需的小时数,并生成一个向量数组,大小与小时数一致,包含增长率(每小时一个值)。。。大概是[200%,180%,160%…4%,2%]。但我需要总的复合增长等于200倍 我使用过np.linspace和np.geomspace,但我不够聪明,不知道如何使复合增长与这种情况相匹配。以下是解决问题的代码。假设从第一个小时开始到第一个小

我希望为生物应用程序建立离散增长率模型。我知道每小时的开始增长率(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))
最终结果超过了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的目标实际上是在下一个到最后一个小时内完成的。它跨越的确切时间取决于您如何对从一小时开始到结束的增长模式进行建模——一小时内的增长与我的假设和代码无关


另外一组假设也是可能的——你给出的增长率是瞬时的,200x的目标不是在整数小时内实现的。这里的解决方案更加数学化,但这里有一个提纲

如果我们让T为达到初始值200倍的种群规模所需的时间。然后在时间
T
上从2线性下降到0.02,在时间
T
上增长率
y
的公式为

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。)

来自学术界,“我不够聪明”和其他尊重通常是让别人为你做工作的一种方式。请说明您尝试了什么以及尝试中出现了什么问题。这些增长率是瞬时增长率,即导数值,还是离散的?这些增长率的时间单位是什么,例如,从每小时、每天、每年或其他时间的200%开始?它们是离散的。每小时200%。@roganjosh我试过以下方法。。。我计算出算术平均增长率为(200%+2%)/2=101%。然后,我计算了math.log(200,1+1.01)~=7.59的小时数。复合平均增长率必须为200^(1/7.59)-1=100.98%。这就是我被卡住的地方。。。我尝试了growth_rates=np.linspace(2,0.02,7),但当然,当我检查np.cumprod(1+growth_rates)时,答案并不需要更多的澄清。小时数是整数吗?如果是这样的话,你就不能精确地达到200倍的增长率,那么你希望增长率略低于200倍还是略高于200倍?离散增长率的含义是,在整个第一个小时内,增长率为200%,因此在第一个小时结束时,您现在有原来数量的3倍,然后在整个第二个小时内,增长率立即下降到101%(比如说),依此类推?最后2%的增长率是在一个小时内有效还是达到了,实验马上就完成了?非常感谢!我想我应该意识到积分约束的局限性。是的,我希望看到即时解决方案。是否有可能以离散形式表示瞬时解,其中最后一个时间数组值表示每小时的增长率,但在一小时内发生?这样,它仍然可以存储在离散的每小时数组中。因此,如果最后一个值是2%,我们知道小时数是8.42,例如,最后一次乘法将是累积的*1.02^(0.42)@bamboo77:请参阅我的上一次编辑以获得即时解决方案。再次感谢Rory。我可能没有正确理解这一点,但e^(2+1.62256+1.24512+0.86768+0.49024+0.02)是否应该等于200?好像要过去了that@bamboo77:我的答案中那一部分的增长率是瞬时的,因此增长率在任何时刻都接近指数,而你所写的不是如何找到值。总体的公式是
y=exp(2*t-(0.9999/log(200))*t**2)
如果用
5.245858778760432
代替t,则得到最终总体
199.99999999999991
,这是
200
,有轻微的舍入误差。如果你没有学习微积分,你就不会理解瞬时增长率。你通过积分得到总体值,而不是你写的。
[2.0,
 1.622559416197654,
 1.2451188323953077,
 0.8676782485929615,
 0.4902376647906155,
 0.11279708098826946]