问题描述
在@M Newville提出建设性意见后,我更改了最初的问题,以便提出一个最小的例子。
我在不同条件下进行了实验。在条件1中,我有比条件2更多的实验数据:
import numpy as np
from lmfit import minimize,Parameters,fit_report
# CONDITION 1.
x_data_1 = np.array([4.68,4.70,4.71,4.72,4.74])
y_data_1 = np.array([7.01,7.03,7.04,7.04])
z_data_1 = np.array([5.67,5.67,5.68,5.69,5.72])
n1_data_1 = np.array([0.374,0.371,0.369,0.376,0.375])
n2_data_1 = np.array([0.284,0.284,0.282,0.283])
n3_data_1 = np.array([0.284,0.283])
# CONDITION 2.
x_data_2 = np.array([10.72,10.68,10.77,10.76,10.79])
n1_data_2 = np.array([0.207,0.205,0.203,0.224,0.205])
但是,我需要Y>Z>X
才能同时满足这两个条件。由X
,Y
和Z
计算出的Function_X
,Function_Y
,Function_Z
取决于参数A
,{{1} },B
,C
和D
。与E
,N1
和N2
描述的N3
,Function_N1
和Function_N2
一样。
Function_N3
一方面,由于数据量较大,# FUNCTIONS.
def Function_X(A,B,C,E):
return C-B**2/(A-E)
def Function_Y(A,E):
return (4*E*((A-E)*C-B**2))/(A*C-B**2)
def Function_Z(A,D,E,X,Y):
return 4*(1/X+1/Y+1/D-B/((A-E)*C-B**2))**(-1)
def Function_N1(A,E):
return B/(2*(A-E))
def Function_N2(A,E):
return 2*E*B/(A*C-B**2)
def Function_N3(A,E):
return ((A-2*E)*C-B**2)/(A*C-B**2)
可以实现所需的FitFunction1
(Y>Z>X
),而无需使用任何数学约束。
y_computed_1>z_computed_1>x_computed_1
另一方面,由于数据量较小,# FIT FUNCTION (CONDITION 1).
def FitFunction1(params1,x_data_1=None,y_data_1=None,z_data_1=None,n1_data_1=None,n2_data_1=None,n3_data_1=None):
# MODEL.
x_mod = Function_X(params1['A'],params1['B'],params1['C'],params1['E'])
y_mod = Function_Y(params1['A'],params1['E'])
z_mod = Function_Z(params1['A'],params1['D'],params1['E'],x_mod,y_mod)
n1_mod = Function_N1(params1['A'],params1['E'])
n2_mod = Function_N2(params1['A'],params1['E'])
n3_mod = Function_N3(params1['A'],params1['E'])
# RESIDUALS.
x_res = x_data_1 - x_mod
y_res = y_data_1 - y_mod
z_res = z_data_1 - z_mod
n1_res = n1_data_1 - n1_mod
n2_res = n2_data_1 - n2_mod
n3_res = n3_data_1 - n3_mod
return np.concatenate((x_res.ravel(),y_res.ravel(),z_res.ravel(),n1_res.ravel(),n2_res.ravel(),n3_res.ravel()))
params1 = Parameters()
params1.add('fc',value= 1000,min=10,max=100000)
params1.add('alpha',value=0.4,min=0.2,max=0.8)
params1.add('A',value=20,max=30)
params1.add('B',value=10,min=1,max=15)
params1.add('C',value=15,max=20)
params1.add('D',value=2.5,max=5)
params1.add('E',value=5,min=2.5,max=7.5)
res1 = minimize(FitFunction1,params1,kws={'x_data_1': x_data_1,'y_data_1': y_data_1,'z_data_1': z_data_1,'n1_data_1': n1_data_1,'n2_data_1': n2_data_1,'n3_data_1': n3_data_1})
print(fit_report(res1))
for keys in res1.params:
exec(f'jf_{keys}_1 = res1.params[keys].value')
x_computed_1 = Function_X(jf_A_1,jf_B_1,jf_C_1,jf_E_1)
y_computed_1 = Function_Y(jf_A_1,jf_E_1)
z_computed_1 = Function_Z(jf_A_1,jf_D_1,jf_E_1,Function_X(jf_A_1,jf_E_1),Function_Y(jf_A_1,jf_E_1))
无法产生不受约束(没有数学约束)的相同FitFunction2
。
Y>Z>X
请注意,# FIT FUNCTION (CONDITION 2).
def FitFunction2(params2,x_data_2=None,n1_data_2=None):
# MODEL.
x_mod = Function_X(params2['A'],params2['B'],params2['C'],params2['E'])
n1_mod = Function_N1(params2['A'],params2['E'])
# RESIDUALS.
x_res = x_data_2 - x_mod
n1_res = n1_data_2 - n1_mod
return np.concatenate((x_res.ravel(),n1_res.ravel()))
params2 = Parameters()
params2.add('fc',max=100000)
params2.add('alpha',max=0.8)
params2.add('A',max=30)
params2.add('B',max=15)
params2.add('C',max=20)
params2.add('D',max=5)
params2.add('E',max=7.5)
params2.add('X',value=np.mean(x_data_2),min=0,expr='C-B**2/(A-E)')
params2.add('Z_minus_X',value=1,vary=True,min=0)
params2.add('Y_minus_Z',min=0)
params2.add('Z',expr='X + Z_minus_X',min=0)#,expr='(4*E*((A-E)*C-B**2))/(A*C-B**2)')
params2.add('Y',expr='Z + Y_minus_Z',expr='4*(1/X+1/Y+1/D-B/((A-E)*C-B**2))**(-1)')
res2 = minimize(FitFunction2,params2,kws={'x_data_2': x_data_2,'n1_data_2': n1_data_2})
print(fit_report(res2))
中没有参数D
。我试图引入另外五个约束来基于another question来强制FitFunction2
,但是它不起作用。我知道Y>Z>X
的结果不取决于当前配置中的参数FitFunction2
,X
和Y
。但是我不知道是否有一种方法可以使Z
的结果以某种方式依赖于它们的另一种配置。
- 是否可以在
FitFunction2
中排列参数A
,B
,C
,D
,E
,以便{{1} }使用数学约束(或其他任何方法)?
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)