我正在开发一个进化模型,其中一个缩短的(因此生物学上毫无意义的)版本看起来像这样:
n = 300 # population size
no_gens = 600 # total number of generations
R = 1000 # relative timescale of environmental variation
P = 0.9 # environmental predictability
def environment(t):
E = (np.sin(2 * np.pi * t / R) + 1) / 2
mu_env = 0.5 * (1 - P) + P * E
sigma_env = 0.5 * (1 - P) / 3
C = np.random.normal(mu_env, sigma_env)
return E, C
# initial population
def create_pop(n):
pop = np.zeros(n, dtype=[('E','<f8'), ('C','<f8'), ('hill','<f8'), ('phenotype','<f8'), ('fitness','<f8'),
('G','<f8'), ('basal','<f8'), ('b', '<f8'), ('alpha','<f8')])
pop['G'] = np.random.random(n)
pop['b'] = np.random.random(n)
pop['hill'] = 1
return pop
def phenotype(pop):
pop['basal'] = pop['G'] + pop['b'] * pop['C']
def phenotype_ode(t_ode, x):
dxdt = pop['basal'] - x + pop['alpha'] * (1 / (1 + x ** (-pop['hill'])))
return dxdt
t_end = 1e02
sol_lower = solve_ivp(phenotype_ode, [0, t_end], np.zeros(n), method='BDF')
lower_steady_states = sol_lower.y[:, -1]
return lower_steady_states
def mutation(pop):
if np.random.random() <= 0.001:
pop['G'] += np.random.normal(0, 0.05, n)
pop['G'][np.flatnonzero(pop['G'] < 0)] = 0
pop['G'][np.flatnonzero(pop['G'] > 1)] = 1
if np.random.random() <= 0.001:
pop['b'] += np.random.normal(0, 0.05, n)
pop['b'][np.flatnonzero(pop['b'] < 0)] = 0
pop['b'][np.flatnonzero(pop['b'] > 1)] = 1
if np.random.random() <= 0.001:
pop['hill'] += np.random.normal(0, 0.05, n)
pop['hill'][np.flatnonzero(pop['hill'] < 1)] = 1
if np.random.random() <= 0.001:
pop['alpha'] += np.random.normal(0, 0.05, n)
pop['alpha'][np.flatnonzero(pop['alpha'] < 0)] = 0
def reproduction(pop):
mutation(pop)
pop['phenotype'] = phenotype(pop)
return pop
# iteration
pop = create_pop(n)
for t in progressbar.progressbar(range(no_gens+1)):
enviro = environment(t)
pop['E'] = enviro[0]
pop['C'] = enviro[1]
pop = reproduction(pop)
如果世代数量足够多,可能会发生
RuntimeWarning: invalid value encountered in power
,最终导致
ValueError: array must not contain infs or NaNs
(如果我正确阅读了错误消息)。
在阅读Numpy error: invalid value encountered in power之前,我假设存在数据类型问题。 dtype
的{{1}}是pop['hill']
。如果我没记错的话,'<f8'
等效于np.dtype('f8')
(例如,参见https://jakevdp.github.io/PythonDataScienceHandbook/02.09-structured-data-numpy.html),即确切地说,在上述SO链接中所有数据都适用的数据类型。那么问题是否与“ little endian”(np.int64
)有关?
还是我在这里完全树错了树?
P.S。当然,如果有帮助,我可以发布完整的错误消息(> 30行)!