python - Curve fitting - monotonically increasing derivative -
i trying physical significant fit experimental data. know not y values increase monotonically x dy/dx increase monotonically. have tried number of fitting functions including polynomial fit , univariate spline neither of these has allowed me produce fit looking for.
so, i'm looking curve fitting function (in scipy?) allow me define known constraints of final curve. below example of data, fitted line not display monotonically increasing derivative.
import numpy np import matplotlib.pyplot plt data = np.array([[ 6.30991828, -10.22329935], [ 6.30991828, -10.2127338 ], [ 6.47697236, -10.01359361], [ 6.47697236, -9.89353722], [ 6.47697236, -9.81708052], [ 6.55108034, -9.42113403], [ 6.55108034, -9.21932801], [ 6.58617165, -8.40428977], [ 6.62007321, -7.6500927 ]]) interp = np.linspace(min(data[:,0]), max(data[:,0]), 20) f = np.polyfit(data[:,0], data[:,-1], 3) data_interp = np.polyval(f, interp) plt.plot(data[:,0], data[:,1], 'x', interp, data_interp, '-')
edit: believe can in matlab slmengine.
edit: attempt. posted half-baked answer before. , failed in reading too. hope better.
import numpy np import matplotlib.pyplot plt data = np.array([[ 6.30991828, -10.22329935], [ 6.30991828, -10.2127338 ], [ 6.47697236, -10.01359361], [ 6.47697236, -9.89353722], [ 6.47697236, -9.81708052], [ 6.55108034, -9.42113403], [ 6.55108034, -9.21932801], [ 6.58617165, -8.40428977], [ 6.62007321, -7.6500927 ]]) x = data[:, 0] def polynomial(p, x): return p[0]+p[1]*x+p[2]*x**2+p[3]*x**3 def constraint_2nd_der(p): return 2*p[2]+6*p[3]*x def constraint_1st_der(p): return p[1]+2*p[2]*x+3*p[3]*x**2 def objective(p): return ((polynomial(p, x)-data[:, 1])**2).sum() cons = (dict(type='ineq', fun=constraint_1st_der), dict(type='ineq', fun=constraint_2nd_der)) res = opt.minimize(objective, x0=np.array([0., 0., 0., 0.]), method='slsqp', constraints=cons) if res.success: pars = res.x x = np.linspace(data[:, 0].min(), data[:, 0].max(), 100) pol = polynomial(pars, x) plt.plot(data[:, 0], data[:, 1], 'x', x, pol, '-') plt.show() else: print 'failed'
Comments
Post a Comment