I am trying to apply a 2D curve fit a data (arbitrary) set as given below:
# Data
T Z X 1 X 2 X 3 X 4 X 5
100.000 1.000 1.000 1.478 1.304 1.162 0.805
200.000 1.500 2.000 2.314 2.168 2.086 1.801
300.000 2.250 3.000 3.246 3.114 3.058 2.798
400.000 3.375 4.000 4.211 4.087 4.044 3.780
500.000 5.063 5.000 5.189 5.070 5.035 4.780
The ultimate aim is to develop a correlation of the form Z = f(X, T).
At first it is curve fit using a quadratic expression Z = a * x ^ 2 + b * x + c along a constant value of T i.e. along each rows, which gives as fit parameters for each T as given below (as an example):
T a b c
100.00 1.00 2.10 10.02
200.00 4.00 6.20 10.06
300.00 9.00 12.30 10.12
400.00 16.00 20.40 10.20
500.00 25.00 30.50 10.31
Now I would like to fit each fit parameters along T so that I get the equations of the form a = p * T ^ 2 + q * T + r, b = s * T ^ 2 + t * T + u, etc. I tried applying this using the code:
from __future__ import division
from scipy import optimize
import matplotlib.pyplot as plt
import numpy as np
data = open('data.dat', "r")
line = data.readline()
while line.startswith('#'):
line = data.readline()
data_header = line.split("\t")
data_header[-1] = data_header[-1].strip()
_data_ = np.genfromtxt('data.dat', skiprows=2, delimiter='\t', names = data_header, dtype = None, unpack = True).transpose()
data = np.array(_data_.tolist())
m = data.shape[0]
n = data.shape[1] - 2
print m, n
y_data = np.empty(shape=(m, n))
for i in range(0, m):
for j in range(0, n):
y_data[i, j] = (data[i, j+2])
x = _data_['X']
z = _data_['Z']
def quadratic_fit(x, a, b, c):
return a * x ** 2 + b * x + c
fit_a = np.empty(shape = (m, 1))
fit_b = np.empty(shape = (m, 1))
fit_c = np.empty(shape = (m, 1))
z_fit = np.empty(shape=(m, len(z)))
for j in range(m):
x_fit = y_data[j, :]
y_fit = z
fit_a[j], fit_b[j], fit_c[j] = optimize.curve_fit(quadratic_fit, x_fit, y_fit)[0]
fit_a_fit_a, fit_a_fit_b, fit_a_fit_c, = optimize.curve_fit(quadratic_fit, x, fit_a)[0]
fit_b_fit_a, fit_b_fit_b, fit_b_fit_c, = optimize.curve_fit(quadratic_fit, x, fit_b)[0]
fit_c_fit_a, fit_c_fit_b, fit_c_fit_c, = optimize.curve_fit(quadratic_fit, x, fit_c)[0]
fit_a = fit_a_fit_a * x ** 2 + fit_a_fit_b * x + fit_a_fit_c
fit_b = fit_b_fit_a * x ** 2 + fit_b_fit_b * x + fit_b_fit_c
fit_c = fit_c_fit_a * x ** 2 + fit_c_fit_b * x + fit_c_fit_c
for j in range(m):
z_fit[j, :] = (fit_a[j] * x_fit ** 2) + (fit_b[j] * x_fit) + fit_c[j]
But it gives me the following error:
ValueError: object too deep for desired array
Traceback (most recent call last):
fit_a_fit_a, fit_a_fit_b, fit_a_fit_c, = optimize.curve_fit(quadratic_fit, x, fit_a)[0]
File "scipy/optimize/minpack.py", line 533, in curve_fit
res = leastsq(func, p0, args=args, full_output=1, **kw)
File "scipy/optimize/minpack.py", line 378, in leastsq
gtol, maxfev, epsfcn, factor, diag)
minpack.error: Result from function call is not a proper array of floats.
How can this be done in Python?