Python scipy的Odeint和曲线拟合给出警告并给出错误结果

Python scipy的Odeint和曲线拟合给出警告并给出错误结果,python,scipy,curve-fitting,scipy-optimize,odeint,Python,Scipy,Curve Fitting,Scipy Optimize,Odeint,我被odeint和curve fit的警告所困扰。所以我想做的是: 我的第一个问题是,curve fit和odeint对3个数据集重复发出如下警告(总共6个警告),但与此同时,curve_fit确实给出了看似正确的结果 828:优化警告:无法估计参数的协方差 247:ODEintWarning:此调用上完成的工作过多(可能是错误的Dfun类型)。以full_output=1运行以获取定量信息 **第二个问题是积分曲线,使用完全相同的代码,只需多次执行,就会得到不同的结果。它似乎有一段时间的重复,

我被odeint和curve fit的警告所困扰。所以我想做的是:

我的第一个问题是,curve fit和odeint对3个数据集重复发出如下警告(总共6个警告),但与此同时,curve_fit确实给出了看似正确的结果

828:优化警告:无法估计参数的协方差

247:ODEintWarning:此调用上完成的工作过多(可能是错误的Dfun类型)。以full_output=1运行以获取定量信息

**第二个问题是积分曲线,使用完全相同的代码,只需多次执行,就会得到不同的结果。它似乎有一段时间的重复,在几次执行后,它给出了正确的曲线,但在下一次执行时,它再次变得不正确,等等。也许是不稳定的问题**

import math
import numpy as np
import pathlib as pl
import matplotlib.pyplot as plt
from scipy.optimize import curve_fit
from scipy.integrate import odeint

def loadData(path):    
    with open(path,"r") as fid:
        res=np.loadtxt(fid,comments="#")
    return res

def modeleeq(a,N,p,we,wp):
    res=(we*a/p[0])**p[1] + (wp*a/p[2])**p[3]
    return res

#get path
chemin=pl.Path(input("Paste the path to the directory containing data files\n"))

#get we and wp in array 3X2
wewp=loadData(chemin/'wewp.dat').transpose()

#plotting
plt.style.use('seaborn')
fig, (ax1,ax2) = plt.subplots(1,2)
colors = ['#79ccff', '#f78db4', '#a07ffb']

files = pl.Path(chemin).glob("a_dadN*")
para=[]
for i,f in enumerate(files):
    res=loadData(f)
    a=res[:,0]
    dadN=res[:,1]
    we=wewp[i,0]
    wp=wewp[i,1]
    
    #exp data    
    ax1.scatter(a,dadN,c=colors[i],marker="x", label = f"test {i+1}")
    
    #evaluation of parameters
    modele=lambda a, *p: (we*a/p[0])**p[1] + (wp*a/p[2])**p[3]  #p=[ge,me,gp,mp]
    p, pcov= curve_fit(modele,a,dadN, p0 = [2e5,0,1e5,0])
    para.append(p)
    ax1.plot(a,modele(a,*p),c=colors[i],label=f"test {i+1} identification")
    
    #intergration
    a0=a.min() #initial condition
    N = np.linspace(0, 4000)
    aitgr=odeint(modeleeq,a0,N,args=(p,we,wp))
    ax2.plot(N,aitgr,c=colors[i],label = f"test {i+1} integration")
#the following code is just for adding titles and print the identified paras
#so I won't put them here


非常感谢你们

我想这里有几个问题。首先,很明显这两个加数非常相似。因此,数据无法区分两者的情况可能发生,而且事实上确实发生了。缩放是第二个问题。使用跨越数量级的拟合参数通常不是一个好主意。事实上,gamma只是重新缩放了W。因此,可以很容易地将函数重写为
(f1*a)**e1
one拟合
f1
,并通过知道
f1=W/gamma
来计算
gamma
。另一个问题是出现负数的负幂的可能性。因此,应该使用
abs(f1)
f1**2
。考虑到这一点,我修改了代码,得到了下面的结果。从第二种和第三种情况下的拟合结果可以看出,
f1=0
或指数几乎相等。在这种情况下,无法确定协方差矩阵是正常的

最后,当涉及积分/绘图时,微分方程是某种类型的,所以我们有积分,积分将给出
a**(-k+1)=N+N0
a(N)=1/(N+N0)**(1/(k-1))。由于初始斜率为正
N0<0
,且函数在
N0
处发散。超出此值的数值积分没有意义

将numpy导入为np
将matplotlib.pyplot作为plt导入
从scipy.optimize导入曲线\u拟合
从scipy.integrate导入odeint
def loadData(路径):
打开(路径“r”)作为fid:
res=np.loadtxt(fid,comments=“#”)
返回res
def简化_模型(a、N、f1、e1、f2、e2):
dadN=(np.fabs(f1)*a)**e1+(np.fabs(f2)*a)**e2
返回数据
plt.style.use('seaborn')
图=plt.图()
ax1=图add_子批次(1,2,1)
ax2=图add_子批次(1、2、2)
颜色=['#79ccff'、'#f78db4'、'#a07ffb']
para=列表()
对于范围(3)中的i:
res=loadData(“a_dadN_{}.dat.format(i+1))
a=res[:,0]
dadN=res[:,1]
#~we=wewp[i,0]
#~wp=wewp[i,1]
def型号_包装(a、ge、me、gp、mp):
返回简化模型(a、0、ge、me、gp、mp)
#经验数据
ax1.散布(a,dadN,c=colors[i],marker=“x”,label=f“test{i+1}”)
印刷品(一)
al=np.linspace(最小(a),最大(a),50)
猜测=[.2+i,2.0,2,2.2]
dal=np.fromiter((对于al中的av,模型_包装(av,*猜测),np.float)
ax1.plot(al,dal,color=colors[i],ls=':')
p、 pcov=曲线拟合(模型包装,a,dadN,p0=猜测,最大FEV=100000)
印刷品(p)
dalf=np.fromiter((用于al中av的型号_包装(av,*p),np.float)
ax1.绘图(al、dalf、颜色=颜色[i])
#整合
a0=a.最小值()#初始条件
N=np.linspace(0,4000,100000)
aitgr=odeint(简化的_模型,a0,N,args=tuple(p))
ax2.plot(N,aitgr,c=colors[i],label=f“test{i+1}积分”)
ax2.set_ylim([1e-4,1e-2])
ax2.设置刻度(“日志”)
plt.show()
提供


有机会发布一些数据吗?这是指向3个数据文件的链接。谢谢!