简体   繁体   中英

Piecewise Exponential fit in Python

I am trying to make a piecewise fitting as shown in fig.1:

在此处输入图片说明

Here is the code:

import numpy as np
from matplotlib import pyplot as plt
from scipy import optimize

def piecewise_linear(x, x0, y0, k1, k2):
    return np.piecewise(x, [x < x0], [lambda x: k1*np.power(x,k2), lambda x: y0])

x=np.arange(0.0,100.0,1.0)
y=piecewise_linear( x, 45.0, 2025.0, 1.0, 2.0)

popt , pcov = optimize.curve_fit(piecewise_linear, x, y)
tau = np.linspace(x[0], x[-1], 200)
perr = np.sqrt(np.diag(pcov))
print popt
print perr
print pcov
plt.plot(x, y, 'b+')
plt.plot(tau, piecewise_linear(tau, *popt),'r')
plt.loglog()
plt.show()
plt.close()

But this gave me fitting as fig. 2: 在此处输入图片说明

The parameter x0 was fixed at 1, no matter how I changed the data set.

I don't know what's wrong with my code, and how can I correct this?

Within your optimize.curve_fit() you need to specify some initial guess for the fitting using p0 = [] where you input your initial guesses into p0 , the documentation of which can be found here .

In terms of the example you have given, you already have the values of x0, y0, k1, k2 as you used them to calculate y , therefore just input these into your curve_fit :

def piecewise_linear(x, x0, y0, k1, k2):
    return np.piecewise(x, [x < x0], [lambda x: k1*np.power(x,k2), lambda x: y0])

x=np.arange(0.0,100.0,1.0)
y=piecewise_linear( x, 45.0, 2025.0, 1.0, 2.0)

#insert the initial guesses into curve_fit below using p0 = [...]
popt , pcov = optimize.curve_fit(piecewise_linear, x, y, p0=[45, 2000, 1, 2])
tau = np.linspace(x[0], x[-1], 200)
perr = np.sqrt(np.diag(pcov))

print (popt)
print (perr)
print (pcov)

plt.plot(x, y, 'b+')
plt.plot(tau, piecewise_linear(tau, *popt),'r')
plt.loglog()
plt.show()

This give the following graph:

在此处输入图片说明

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM