将两个不同的方程拟合为一个函数 (curve_fit)

Fitting two distinct equations to a function (curve_fit)

我有一个问题:我有两个不同的方程,一个是线性方程,另一个是指数方程。然而,两个方程式不应同时有效,这意味着存在两种截然不同的制度。

Equation 1 (x < a): E*x
Equation 2 (x >=a): a+b*x+c*(1-np.exp(-d*np.array(x)))

意味着数据的第一部分应该只用线性方程拟合,其余部分应该用前面提到的方程 2 拟合。

我尝试拟合的数据如下所示(我还添加了一些示例数据,如果人们想试一试的话):

我已经尝试了几件事,从只定义一个带有 heaviside 函数的拟合函数:

def fit_fun(x,a,b,c,d,E):
    
    funktion1=E*np.array(x)
    
    funktion2=a+b*x+c*(1-np.exp(-d*np.array(x)))
           
    return np.heaviside(x+a,0)*funktion2+(1-np.heaviside(x+a,0))*funktion1

定义分段函数:

def fit_fun(x,a,b,c,d,E):
    return np.piecewise(x, [x <= a, x > a], [lambda x: E*np.array(x), lambda x: a+b*x+c*(1-np.exp(-d*np.array(x)))])

最后(这不幸地给我带来了一些形式功能错误?):

def plast_fun(x,a,b,c,d,E):
   
    out = E*x
    out [np.where(x >= a)] = a+b*x+c*(1-np.exp(-d+x))
    
    return out

别误会我的意思,我确实得到了“一些”适合,但他们似乎要么采用一个或另一个方程式,而不是真正使用两者。我也尝试过使用几个边界和初始猜测,但它永远不会改变。

如有任何意见,我们将不胜感激!

数据:

0.000000     -1.570670 
0.000434     83.292677 
0.000867     108.909402 
0.001301     124.121676 
0.001734     138.187659 
0.002168     151.278839 
0.002601     163.160478 
0.003035     174.255626 
0.003468     185.035092 
0.003902     195.629820 
0.004336     205.887161 
0.004769     215.611995 
0.005203     224.752083 
0.005636     233.436680 
0.006070     241.897851 
0.006503     250.352697 
0.006937     258.915168 
0.007370     267.569337 
0.007804     276.199005 
0.008237     284.646778 
0.008671     292.772349 
0.009105     300.489611 
0.009538     307.776858 
0.009972     314.666291 
0.010405     321.224211 
0.010839     327.531594 
0.011272     333.669261 
0.011706     339.706420 
0.012139     345.689265 
0.012573     351.628362 
0.013007     357.488150 
0.013440     363.185771 
0.013874     368.606298 
0.014307     373.635696 
0.014741     378.203192 
0.015174     382.315634 
0.015608     386.064126 
0.016041     389.592120 
0.016475     393.033854 
0.016908     396.454226 
0.017342     399.831519 
0.017776     403.107084 
0.018209     406.277016 
0.018643     409.441119 
0.019076     412.710982 
0.019510     415.987331 
0.019943     418.873140 
0.020377     421.178098 
0.020810     423.756827 

到目前为止我找到了这两个问题,但我无法弄清楚: Fit of two different functions with boarder as fit parameter Fit a curve for data made up of two distinct regimes

我怀疑你在第二个等式中犯了错误,a+b*x+c*(1-np.exp(-d+x))。其中 ax 的值,您可以在其中从一条曲线更改为另一条曲线。我认为您应该使用 y 的值,而不是 a*E。定义拟合的初始参数也非常重要。我已经 运行 以下代码与您在 .txt 文件中的数据,并且看起来非常合适,如下所示:

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from scipy import optimize, stats

def fit_fun(x,a,b,c,d,E):
    return np.piecewise(x, [x <= a, x > a], [lambda x: E*x, lambda x: a*E+b*x+c*(1-np.exp(-d*x))])

df = pd.read_csv('teste.txt', delimiter='\s+', header=None)
df.columns = ['x','y']

xdata = df['x']
ydata = df['y']

p0 = [0.001,1,1,1,100000]
popt, pcov = optimize.curve_fit(fit_fun, xdata.values, ydata.values, p0=p0, maxfev=10000, absolute_sigma=True, method='trf')
print(popt)

plt.plot(xdata, ydata,'*')
plt.plot(xdata, fit_fun(xdata.values, *popt), 'r')
plt.show()