创建一个在特定斜率下改变方程的功能,可用于curve_fi。

2024-09-29 23:24:02 发布

您现在位置:Python中文网/ 问答频道 /正文

我目前正致力于将下降曲线拟合到实际生产数据中。我很幸运地创建了一个双曲型曲线并使用curve_fitfromscipy.optimize。我使用的当前函数:

def hyp_func(x,qi,b,di):
    return qi*(1.0-b*di*x)**(-1.0/b)

我现在要做的是,以一定的下降速度,过渡到指数函数。我怎样才能做到这一点,并且仍然能够在曲线拟合中使用(我认为下面的工作可以)?我正在尝试下面的代码,是这样做的吗?或者有更好的方法吗?在

^{pr2}$

hy是双曲方程
hdy是hy导数
ex是x在导数命中dlim后的部分
ey是指数方程

我还在解方程,我没有得到一个连续函数。在

编辑:数据here,并更新方程式


Tags: 数据函数def双曲曲线optimize方程导数
2条回答

假设qi>0斜率实际上是正的,所以我没有选择-0.003。而且我认为导数是错的。 可以精确计算坡度达到临界值的值。 根据我的经验,你有两个选择。如果您自己定义分段函数,通常会遇到使用numpy数组的函数调用问题。我通常将scipy.optimize.leastsq与自定义的残差函数一起使用。第二个选择是在两个功能之间进行连续转换。根据定义,只要值和斜率已经适合,就可以使其尽可能的锐利。 这两种解决方案如下所示

进口matplotlib.pyplot作为plt 将numpy作为np导入

def hy(x,b,qi,di):
    return qi*(1.0-b*di*x)**(-1.0/b)


def abshy(x,b,qi,di):#same as hy but defined for all x
    return qi*abs(1.0-b*di*x)**(-1.0/b)


def dhy(x,b,qi,di):#derivative of hy
    return qi*di*(1.0-b*di*x)**(-(b+1.0)/b)

def get_x_from_slope(s,b,qi,di):#self explaining
    return (1.0-(s/(qi*di))**(-b/(b+1.0)))/(b*di)


def exh(x,xlim,qlim,dlim):#exponential part (actually no free parameters)
    return qlim*np.exp(dlim*(x-xlim))

def trans(x,b,qi,di, s0):#piecewise function
    x0=get_x_from_slope(s0,b,qi,di)
    if x<x0:
        out= hy(x,b,qi,di)
    else:
        H0=hy(x0,b,qi,di)
        out=exh(x,x0,H0,s0/H0)
    return out


def no_if_trans(x,b,qi,di, s0,sharpness=10):#continuous transition between the two functions
    x0=get_x_from_slope(s0,b,qi,di)
    H0=hy(x0,b,qi,di)
    weight=0.5*(1+np.tanh(sharpness*(x-x0)))
    return weight*exh(x,x0,H0,s0/H0)+(1.0-weight)*abshy(x,b,qi,di)


xList=np.linspace(0,5.5,90)
hyList=np.fromiter(( hy(x,2.2,1.2,.1) for x in xList ) ,np.float)
t1List=np.fromiter(( trans(x,2.2,1.2,.1,3.59) for x in xList ) ,np.float)
nt1List=np.fromiter(( no_if_trans(x,2.2,1.2,.1,3.59) for x in xList ) ,np.float)


fig1=plt.figure(1)
ax=fig1.add_subplot(1,1,1)
ax.plot(xList,hyList)
ax.plot(xList,t1List,linestyle=' ')
ax.plot(xList,nt1List,linestyle=':')

ax.set_ylim([1,10])
ax.set_yscale('log')
plt.show()

Testfunctions

这两种解决方案几乎没有区别,但是使用scipy拟合函数的选项略有不同。第二个解决方案应该很容易与curve_fit配合使用

很抱歉我是坏消息的传递者,但是如果我理解您正在尝试做什么,我认为让scipy.optimize.curve_fit或来自{}的任何其他方法执行您希望的操作是非常困难的。在

大多数拟合算法都是设计用来处理连续的变量的,通常(而且curve_fit)通常是通过对参数值进行很小的更改来找到正确的方向和步长来改进结果的。在

但是你要找的是一个离散的变量,作为一个函数形式(大致上是“幂律”)到另一个函数形式(“指数”)之间的断点,算法通常不会对你的di参数进行足够大的更改,从而影响作为断点的值,并且可能认为di不会影响拟合度(您的模型也会以其他方式使用di,所以您可能会幸运,di可能会影响拟合度。在

相关问题 更多 >

    热门问题