问题描述
我有一些适合模型的数据点.我的模型不是定义为方程,而是定义为3个方程的数值解.我的模型定义如下:
I have some data points to fit with a model. My model is not defined as an equation but as a numerical solution of 3 equations.My model is defined as below:
def eq(q):
z1=q[0]
z2=q[1]
H=q[2]
F=empty((3))
F[0] = ((J*(1-(D*(1-(1-8*a*T/D**3)**(1/3)))**(b)/Lx))*sin(z1-z2))+(H*sin(z1-pi/4))+(((3.6*10**5)/2)*sin(2*z1))
F[1] = ((-J*(1-(D*(1-(1-8*a*T/D**3)**(1/3)))**(b)/Lx))*sin(z1-z2))+(H*sin(z2-pi/4))+(((3.6*10**5)/2)*sin(2*z2))
F[2] = cos(z1-pi/4)
return F
guess1=array([2.35,0.2,125000])
z=fsolve(eq,guess1)
Hc=z[2]*(1-(T/Tb)**(1/2))
那个
D=10**(-8)
a=2.2*10**(-28)
Lx=4.28*10**(-9)
和 J
, b
, Tb
是参数,而 z1
, z2
, H
是变量
and J
, b
, Tb
are parameters and z1
, z2
, H
are variables
我的数据点是:
T=[10, 60, 110, 160, 210, 260, 300]
Hc=[0.58933, 0.5783, 0.57938, 0.58884, 0.60588, 0.62788, 0.6474]
如何根据具有数据点的拟合模型找到 J
, b
, Tb
?
how can I find J
, b
, Tb
according to fitting model with data points?
推荐答案
您可以使用 scipy.optimize.curve_fit
.您需要了解,curve_fit只关心函数的输入和输出,因此您需要使用以下方式进行定义:
You can use scipy.optimize.curve_fit
. You need to understand that curve_fit will only care about the input and the output of your function, such that you need to define it this way :
def func(x, *params):
....
return y
然后,您可以应用 curve_fit
( https://docs.scipy.org/doc/scipy/reference/generation/scipy.optimize.curve_fit.html ):
Then you can apply curve_fit
(https://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.curve_fit.html):
popt, pcov = curve_fit(func, x, y_data)
我写信并举例说明您的情况.有100种方法可以更有效地编写它.但是,我试图弄清楚这一点,以便您可以理解您所给与我所提议之间的联系.
I wrote and example taking your case. There is 100 ways to write it more efficiently. However, I tried to make it clear so you can understand the link between what you gave and what I propose.
import numpy as np
from scipy.optimize import fsolve, curve_fit
def eq(q, T, J, b):
z1 = q[0]
z2 = q[1]
H = q[2]
D=10**(-8)
a=2.2*10**(-28)
Lx=4.28*10**(-9)
F = np.empty((3))
F[0] = ((J*(1-(D*(1-(1-8*a*T/D**3)**(1/3)))**(b)/Lx))*np.sin(z1-z2))+(H*np.sin(z1-np.pi/4))+(((3.6*10**5)/2)*np.sin(2*z1))
F[1] = ((-J*(1-(D*(1-(1-8*a*T/D**3)**(1/3)))**(b)/Lx))*np.sin(z1-z2))+(H*np.sin(z2-np.pi/4))+(((3.6*10**5)/2)*np.sin(2*z2))
F[2] = np.cos(z1-np.pi/4)
return F
def func(T,J,b,Tb):
Hc = []
guess1 = np.array([2.35,0.2,125000])
for t in T :
z = fsolve(eq, guess1, args = (t, J, b))
Hc.append(z[2]*(1-(t/Tb)**(1/2)))
return Hc
T = [10, 60, 110, 160, 210, 260, 300]
Hc_exp = [0.58933, 0.5783, 0.57938, 0.58884, 0.60588, 0.62788, 0.6474]
p0 = (1,1,100)
popt, pcov = curve_fit(func, T, Hc_exp, p0)
J = popt[0]
b = popt[1]
Tb = popt[2]
似乎很难做到合适.为了改善这一点,您可以通过 p0
向参数添加初始猜测,或为参数添加界限(请参见 curve_fit
文档).收敛后,您可能会在估计的参数上出现错误.
It seems that the fit is hard to be done. To improve that, you can add an initial guess to the parameters through p0
, or adding bounds to the parameters (see curve_fit
documentation). Once it converges, you can have the error on the estimated parameters.
这篇关于用python中的数值模型进行曲线拟合的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!