如何使用有限数据的数学约束来约束lmfit?

问题描述

在@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才能同时满足这两个条件。由XYZ计算出的Function_XFunction_YFunction_Z取决于参数A,{{1} },BCD。与EN1N2描述的N3Function_N1Function_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) 可以实现所需的FitFunction1Y>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的结果不取决于当前配置中的参数FitFunction2XY。但是我不知道是否有一种方法可以使Z的结果以某种方式依赖于它们的另一种配置。

  • 是否可以在FitFunction2中排列参数ABCDE,以便{{1} }使用数学约束(或其他任何方法)?

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...