由于RuntimeWarning而导致solve_ivp发生ValueError:电源中遇到无效值

时间:2019-02-05 20:22:56

标签: python numpy scipy differential-equations

我正在开发一个进化模型,其中一个缩短的(因此生物学上毫无意义的)版本看起来像这样:

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行)!

0 个答案:

没有答案