将两个不同的方程拟合为一个函数 (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))
。其中 a
是 x
的值,您可以在其中从一条曲线更改为另一条曲线。我认为您应该使用 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()
我有一个问题:我有两个不同的方程,一个是线性方程,另一个是指数方程。然而,两个方程式不应同时有效,这意味着存在两种截然不同的制度。
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))
。其中 a
是 x
的值,您可以在其中从一条曲线更改为另一条曲线。我认为您应该使用 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()