原发性 HIV 感染期间血浆病毒浓度建模(待修改)

原作者日期2022-12:目前不能运行

TypeError: diffeqs() missing 4 required positional arguments: 'd', 'k', 'delta', and 'p'

#原发性 HIV 感染期间血浆病毒浓度建模
# from:https://stackoverflow.com/questions/74791991/ode-fitting-with-python-least-squares-takes-to-long-to-compute

import numpy as np
from scipy.optimize import least_squares
from scipy.integrate import solve_ivp

c = 3 #global constant 
v0= 10e-6

#dados
timeDataPatient1=np.array([0,22,43,78,106,146,183,230,268,358,435,489,519,534,584,610,687,778])
VirDataPatient1=10e3*np.array([v0*10e-3,27.2,210,85.9,81.1,46.2,60.1,82.8,103,72.1,79.4,70.4,207,42.6,10.8,54.2,22.3,40.8])


xdata = timeDataPatient1
ydata = VirDataPatient1

#inicial condition and max time of data set
IC = [10,0,10e-6]
t_max = max(xdata)

def diffeqs(t,y,d,k,delta,p):
    '''Model of the differencial equation'''
    global lam, c
    
    T=y[0]
    I=y[1]
    V=y[2]
    
    dT = 10*d - d*T-k*T*V
    dI = k*T*V - delta*I
    dV = p*I-c*V
    
    return [dT,dI,dV]

def Vtime(theta):
    '''solves the differencial equation, and returns the values of the model on the time points corresponding to the data set'''

    global t_max, IC, xdata
    
    sol = solve_ivp(diffeqs, (0,t_max), IC, args = (theta),t_eval=xdata)
    
    return sol.y[2]

#now I define the objetive function to minimize. For a parameter theta, that corresponds to d,k,delta,p in the ODE model,it calculates the difference between the log of the data given and the predicts by the ODE model.
  
def calcErrorHIV(theta):
    '''objetive function given in the paper'''
    global ydata
    
    dif = np.log(ydata)-np.log(Vtime(theta))
    
    return sum(dif**2)

#should return theta parameters that best fits the data, but It doesn't compute.
res = least_squares(calcErrorHIV,[0.013,0.46e-2,0.40,980],gtol=1e-2,xtol=1e-2,ftol=1e-2)
print(res)

为了能够运行目前最新版本需要进行修改:

GPT修改

这个问题出在solve_ivp函数可能没有正确求解出微分方程,从而使整个模型预测失败。问题可能源于函数solve_ivpt_eval参数。solve_ivp在寻找微分方程的解时有一个自适应的步长控制机制,当在某些情况下,它可能跳过了你的t_eval中的某些时间点,从而使最后的解的维度与ydata不匹配。尝试使用较小的时间间隔,并将t_eval的时间点包括进去,这或许可以解决你的问题:

t_eval = np.arange(0,t_max,0.1)  # set time points with smaller interval
t_eval = np.sort(np.append(t_eval, xdata))  # include xdata points
sol = solve_ivp(diffeqs, (0,t_max), IC, args = (theta), t_eval = t_eval)

这样,solve_ivp会在较小的时间间隔内寻找解,并确定包含了你的数据时间点。

再一个可能的错误来源是:你的模型在初期可能就已经发散或者趋近于0,导致在对数运算中出现无穷大或者NaN的结果。你可能需要检查是否你的初始参数,包括IC和[0.013,0.46e-2,0.40,980],已经被正确设置,如果需要的话,可能要对它们进行调整。

你也需要注意least_squares默认是求解残差平方和最小的问题,这个函数的返回值是每次计算的残差形成的向量,而不是一个标量,如果需要求解一个标量目标,比如你代码中的总平方和,应该使用scipy.optimize.minimize或者其它能够接受标量目标的优化方法。如果你需要保持使用least_squares但是希望最小化总平方和,你可以更改目标函数将每个观测点的残差返回,像这样:

def calcErrorHIV(theta):
    '''objetive function given in the paper'''
    global ydata

    dif = np.log(ydata)-np.log(Vtime(theta))   
    return dif

这样就会返回一个向量,每个元素为对应观测点的残差,然后least_squares会对这个向量求解欧式范数最小,也就是残差平方和最小。

你可能感兴趣的:(python,开发语言)