ValueError с solve_ivp из-за RuntimeWarning: недопустимое значение, обнаруженное в power - PullRequest
0 голосов
/ 05 февраля 2019

Я разрабатываю эволюционную модель, укороченная (и, следовательно, биологически бессмысленная) версия выглядит так:

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 (если я правильно читаю сообщение об ошибке).

Прочитав Ошибка с ошибкой: недопустимое значение при обнаружении питания, я предполагал проблему с типом данных.dtype из pop['hill'] - это '<f8'.Если я не ошибаюсь, np.dtype('f8') эквивалентно np.int64 (см., Например, https://jakevdp.github.io/PythonDataScienceHandbook/02.09-structured-data-numpy.html),, т. Е. Именно тот тип данных, для которого все прошло хорошо в приведенной выше ссылке SO.делать с "little endian" (<)?

или я тут совсем не то лаю дерево ??

PS Конечно, могу выложить полное сообщение об ошибке (> 30 строк), если это поможет!

...