我试图用python解决一个模型,并将模型的未知参数与实验数据相匹配。该模型由2个ODE组成,我使用scipy.integrate.solve_ivp进行求解。模型的参数是未知的,所以,我想用大量的方法来拟合它们。我的第一个选择是差分进化,因为它可以为更复杂的模型提供非常好的结果(早些时候作为另一个包的一部分使用)。然而,问题是,当我给出微分进化时,我的模型(我希望它找到计算点和实验点之间最小二乘的全局最小值),它找到了模型变得不稳定的参数(由于内部步长为0,LSODA无法对其进行积分)。我试图捕捉LSODA在这些情况下抛出的运行时警告,但没有帮助。解决这个问题的最佳方式是什么
我的型号和代码如下:
def aggregation_model(time, z, k1, k2, k3, k_1, k_2):
GPVI_0 = 55.5
GPVI, GPVI_Clust = z
dGPVIdt = - k1 * GPVI_Clust * GPVI + k_1 * (GPVI_0 - GPVI) - 2 * k2 * GPVI * GPVI
dGPVI_Clustdt = - (k_2 * GPVI_Clust + k3) * GPVI_Clust + k2 * GPVI * GPVI
return [dGPVIdt, dGPVI_Clustdt]
def res_squares(parameters):
time = np.linspace(0, 300, 1000)
timepoints = [0, 25, 50, 75, 100, 125, 150, 300]
val = [0, 2, 5, 10, 15, 20, 20, 18]
model_calc = solve_ivp(aggregation_model, [0, 300], [55.5, 0], args=parameters, max_step=100000,
dense_output=True, method='LSODA', rtol=1e-12, atol=1e-6)
solution = model_calc.sol(time)
transposed = list(map(list, zip(*solution.T)))
size = [0, ]
for i in range(1, len(transposed[0])):
size.append((55.5 - transposed[0][i]) / transposed[1][i])
diff = []
for i in range(len(timepoints)):
indexval = min(range(len(time)), key=lambda j: abs(time[j] - timepoints[i]))
diff.append((val[i] - size[indexval])**2)
# print(np.sqrt(np.sum(diff)))
output = np.sum(diff)
return output
if __name__ == '__main__':
from scipy.integrate import solve_ivp
from scipy.optimize import differential_evolution
import numpy as np
parameterBounds = []
parameterBounds.append([-1000000, 1000000]) # parameter bounds for a
parameterBounds.append([-1000000, 1000000]) # parameter bounds for a
parameterBounds.append([-1000000, 1000000]) # parameter bounds for a
parameterBounds.append([-1000000, 1000000]) # parameter bounds for a
parameterBounds.append([-1000000, 1000000]) # parameter bounds for a
result = differential_evolution(res_squares, parameterBounds, seed=3, disp=True, init='random')
print(result.x)
sol = solve_ivp(aggregation_model, [0, 300], [55.5, 0], args=parvalues,
dense_output=True, method='LSODA', rtol=1e-6, atol=1e-12)
有几种方法可以实现这一点,可能需要将它们结合起来才能获得稳定的解决方案:
dy/dt = f(y)
,而是求解dx/dt = exp(-x) f(exp(x))
,其中x = log(y)
。(这可以通过对dlog(y)/dt
应用微分链规则得出。)minstep
参数可能有助于解决这个问题。设置min_step=1e-14
至少可以让优化器通过差分进化算法的前11个阶段。之后,解算器和优化器都不会打印任何消息,因此我不确定发生了什么李>顺便说一下,您可能希望将
t_eval=timepoints
传递给solve_ivp
,这样解算器就可以在您需要的时间点返回解。这将节省您当前执行的插值相关问题 更多 >
编程相关推荐