使用带有多个方程和输入的curve_fit进行联合拟合-甚至可能吗?

问题描述

我在JanuaryApril中问了类似的问题,即@MiłoszWieczór和@Joe足以引起人们的关注。现在,我面临一个相似但又不同的问题,因为我需要做与多个方程和输入共同拟合,以获得两个参数fcalpha的通用解。我的代码(基于先前问题的答案)如下:

import numpy as np
from numpy import linalg
import math
from scipy.optimize import curve_fit,least_squares,minimize

ya_exp  = np.array([1,1.3,1.7,2.1,2.7,3.5,4.5,5.8,7.5,9.7,12,16,21,27,34,44,57,73,94,120,156,250000])

yb_exp  = np.array([1,156])

xa1_exp = np.array([4.68,4.70,4.71,4.72,4.74,4.75,4.76,4.77,4.79,4.80,4.82,4.83,4.85,4.87,4.89,4.90,4.96,4.99,5.02,5.06,5.11,6.23])

xb1_exp = np.array([0.018,0.023,0.019,0.022,0.024,0.025,0.028,0.032,0.033,0.034,0.037,0.040,0.043,0.045,0.047,0.049])

xa2_exp = np.array([7.01,7.03,7.04,7.10,7.13,7.16,7.14,7.19,7.18,7.22,7.24,7.28,7.32,7.35,7.40,7.45,7.49,10.1])

xb2_exp = np.array([0.008,0.009,0.008,0.010,0.011,0.012,0.016,0.017,0.020,0.027,0.029,0.036,0.046,0.052])

xa3_exp = np.array([5.67,5.67,5.68,5.69,5.72,5.74,5.76,5.79,5.81,5.83,4.86,5.89,5.91,5.96,6.00,6.04,6.10,6.14,7.56])

xb3_exp = np.array([0.011,0.015,0.021,0.026,0.030,0.039,0.050,0.056,0.059,0.063])

xa1_zero = np.min(xa1_exp)
xa1_inf  = np.max(xa1_exp)

xa2_zero = np.min(xa2_exp)
xa2_inf  = np.min(xa2_exp)

xa3_zero = np.min(xa3_exp)
xa3_inf  = np.min(xa3_exp)

ig_fc    = 500
ig_alpha = 0.35

def CCXA(f_exp,fc,alpha):
    x  = np.log(f_exp/fc)
    R  = xa_zero + 1/2 * (xa_inf - xa_zero) * (1 + np.sinh((1 - alpha) * x) / (np.cosh((1 - alpha) * x) + np.sin(1/2 * alpha * math.pi)))
    I  = 1/2 * (xa_inf - xa_zero) * np.cos(alpha * math.pi / 2) / (np.cosh((1 - alpha) * x) + np.sin(alpha * math.pi / 2))
    RI = np.sqrt(R ** 2 + I ** 2)
    return RI

def CCXB(f_exp,alpha):
    x  = np.log(f_exp/fc)
    R  = xa_zero + 1/2 * (xa_inf - xa_zero) * (1 + np.sinh((1 - alpha) * x) / (np.cosh((1 - alpha) * x) + np.sin(1/2 * alpha * math.pi)))
    I  = 1/2 * (xa_inf - xa_zero) * np.cos(alpha * math.pi / 2) / (np.cosh((1 - alpha) * x) + np.sin(alpha * math.pi / 2))
    iQ = I / R
    return iQ

poptXA,pcovXA = curve_fit(CCXA,ya_exp,xa_exp,p0=(ig_fc,ig_alpha))

poptXB,pcovXB = curve_fit(CCXB,yb_exp,xb_exp,ig_alpha))

def objective(e_exp,f_exp):
    poptXA,ig_alpha))

    poptXB,ig_alpha))
    
    err_total = np.sum(np.sqrt(np.diag(pcovXA))) + np.sum(np.sqrt(np.diag(pcovXB)))

    delta = linalg.norm(poptXB - poptXA)
    
    return err_total,delta

test = objective(xa_exp,ya_exp)

我的第一个问题是我不确定如何定义CCXACCXB并从全局范围中查找xa_expxb_exp,因为定义了不同的变量其他名称:xa1_expxa2_expxa3_exp加上xb1_expxb2_expxb2_exp。同样,我对fcalpha作为可优化参数感兴趣。 curve_fit(CCXA,ig_alpha))可以针对fcalpha进行优化,但是依赖于全局范围内的xa_expxb_exp。当它们不同时,如何将它们传递给功能?另外,请注意ya_expxa1_expxa2_expxa3_exp的长度为22,而yb_exp,{{1 }},xb1_expxb2_expxb3_exp

我的第二个问题是我不知道如何编写将21用作包含所有值的全局联合拟合的function。换句话说,我想为所有所有值找到curve_fitfc的最佳通用拟合,以便获得一个全局(或通用?)拟合而不是六个独立的拟合。 alpha提供objective,而test[0]=poptXB[0]-poptXA[0]test[1]popXA的范数,但是poptXB都没有提供{{1} }和returns,这正是我所追求的。

这可能吗?


编辑26.08.2020(和30.08.2020)

我遇到了另一个关于question的适合度,并相应地调整了代码:

fc

alphafrom lmfit import minimize,Parameters,fit_report params = Parameters() params.add('fc',value=500) params.add('alpha',value=0.2) def CCXA(f_exp,xa_zero,xa_inf,alpha): x = np.log(f_exp/fc) R = xa_zero + 1/2 * (xa_inf - xa_zero) * (1 + np.sinh((1 - alpha) * x) / (np.cosh((1 - alpha) * x) + np.sin(1/2 * alpha * math.pi))) I = 1/2 * (xa_inf - xa_zero) * np.cos(alpha * math.pi / 2) / (np.cosh((1 - alpha) * x) + np.sin(alpha * math.pi / 2)) iQ = I / R return iQ def fit_function(params,ya_data=None,xa1_data=None,xa2_data=None,xa3_data=None,yb_data=None,xb1_data=None,xb2_data=None,xb3_data=None): xa_data = np.array([xa1_data,xa2_data,xa3_data]) modxa = np.array([CCXA(ya_data,np.min(i),np.max(i),params['fc'],params['alpha']) for i in xa_data]) #sigma = np.array([1 / np.sqrt(i+1) for i in xa_data]) #sigma = np.full((1,22),0.5) #resxa = np.array([(i - j)/k for i,j,k in zip(xa_data,modxa,sigma)]) resxa = np.array([i - j for i,j in zip(xa_data,modxa)]) xb_data = np.array([xb1_data,xb2_data,xb3_data]) modxb = np.array([CCXB(yb_data,params['alpha']) for i in xa_data]) #sigmb = np.array([1 / np.sqrt(i+1) for i in xb_data]) #sigmb = np.full((1,21),1) #resxb = np.array([(i - j)/k for i,k in zip(xb_data,modxb,sigmb)]) resxb = np.array([i - j for i,j in zip(xb_data,modxb)]) return np.concatenate((resxa.ravel(),resxb.ravel())) 的较小修改,以及使用CCXA解决的CCXB的引入,为fit_functionlmfit提供了值:

fc

由于我是alpha的新手,所以我想知道这是否应该被使用。我所做的是正确的还是完全错误的?

解决方法

直接使用minimum_squares可能会更容易。它采用残差向量,您只需在其中指定l.h.s。两个方程式中的一个

,

是的,您对lmfit和np.concatenate()的使用对我来说很合适,它可以找到一组参数值,以最大程度地减少(model1,dataset1)和(model2,dataset2)的残差。我不确定是否完全了解您的模型和3个x值。我认为这样做可能会更有效率,但这是关于装配技工是否按照您的预期工作的另一个问题-我认为他们在做。

下一个(棘手的)问题是您是否要强调一个数据集中的失配比另一个数据集中的失配。如所写,您的函数断言所有数据点的权重均相等-这是一种很好的默认方法,但并非总是如此。

相关问答

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