向量化/广播与使用resolve_ivp

时间:2018-10-15 15:47:38

标签: python numpy scipy

使用NumPy数组和向量化,我试图创建一组n个不同的个体,每个个体具有三个属性:alphabeta和{{1 }}(phenotype被计算为涉及phenotypealpha的微分方程的稳态)。所以,我希望每个人都有自己的表型。

但是,我的代码为每个人产生相同的表型。此外,只有在beta的{​​{1}}数组(这里是n)中恰好有solve_ivp个条目(这里是y0)时,才会发生这种有害行为-否则会出现广播错误产生:

[0, 1]

代码如下:

ValueError: operands could not be broadcast together with shapes (2,) (3,)

相比之下,如果通过“简单”等式从import numpy as np from scipy.integrate import solve_ivp def create_population(n): """creates a population of n individuals""" pop = np.zeros(n, dtype=[('alpha','<f8'),('beta','<f8'),('phenotype','<f8')]) pop['alpha'] = np.random.randn(n) pop['beta'] = np.random.randn(n) + 5 def phenotype(n): """creates the phenotype""" def pheno_ode(t_ode, y): """defines the ode for the phenotype""" dydt = 0.123 - y + pop['alpha'] * (y ** pop['beta'] / (1 + y ** pop['beta'])) return dydt t_end = 1e06 sol = solve_ivp(pheno_ode, [0, t_end], [0, 1], method='BDF') return sol.y[0][-1] # last entry is assumed to be the steady state pop['phenotype'] = phenotype(n) return pop popul = create_population(3) print(popul) alpha计算表型,则向量化可以正常工作:

beta

1 个答案:

答案 0 :(得分:0)

我可以看到两个问题:

首先,您将ODE的初始条件设置为[0, 1]。将solve_ivp的向量解的大小设置为2,而不考虑n的值。但是,数组pop['alpha']pop['beta']的长度为n,并且在脚本中,您将create_population设置为3的情况下调用了ndydt的公式中的数组形状中:y的长度为2,但是pop['alpha']pop['beta']的长度为3。这会导致您看到错误。

您可以通过使用np.ones(n)而不是[0, 1]作为对solve_ivp的调用的初始条件来解决此问题。

第二个问题是函数return sol.y[0][-1]中的语句phenotype(n)sol.y的形状为(n, num_points),其中num_pointssolve_ivp计算的点数。因此,sol.y[0]只是解决方案的第一个组成部分,sol.y[0][-1]是第一个组件的解决方案的最后一个值。这是一个标量,因此当执行pop['phenotype'] = phenotype(n)时,您将为所有表型分配相同的值(第一个组件的稳态)。

return语句应为return sol.y[:, -1]。返回结果数组的最后一个(即所有稳态表型)。