I am trying to fit a curve to X and Y data points using a rational function. It can be done in Matlab using the cftool (http://de.mathworks.com/help/curvefit/rational.html). However, I am looking to do the same in Python. I have tried to use scipy.optimize.curve_fit(), but it initially requires a function, which I don't have.
Asked
Active
Viewed 7,559 times
7
-
This isn't a recommendation question, it's asking how to do it in Python using scipy. – Jason S May 23 '17 at 22:38
-
4Voted to reopen: the stated reason for closing is a perversion of the spirit of "don't solicit a recommendation". If we used this perspective, we'd have to close all questions that ask for anything, because the answers might _recommend_ certain API etc. Even the "closed" blurb says "Instead, describe the problem and what has been done so far to solve it.", which has been done. The question is not of the form "tell me what's a good open-source CAS", it's of the form "here's a CAS, tell me how to do XYZ in it". – Evgeni Sergeev Jun 29 '17 at 09:26
-
Vote to reopen: it is a question: "How to use scipy.optimize.curve_fit() in this case?" – hynekcer Aug 20 '20 at 12:55
1 Answers
9
You have the function, it is the rational function. So you need to set up the function and perform the fitting. As curve_fit requires that you supply your arguments not as lists, I supplied an additional function which does the fitting on the specific case of third degree polynomial in both the numerator as well as the denominator.
def rational(x, p, q):
"""
The general rational function description.
p is a list with the polynomial coefficients in the numerator
q is a list with the polynomial coefficients (except the first one)
in the denominator
The zeroth order coefficient of the denominator polynomial is fixed at 1.
Numpy stores coefficients in [x**2 + x + 1] order, so the fixed
zeroth order denominator coefficent must comes last. (Edited.)
"""
return np.polyval(p, x) / np.polyval(q + [1.0], x)
def rational3_3(x, p0, p1, p2, q1, q2):
return rational(x, [p0, p1, p2], [q1, q2])
x = np.linspace(0, 10, 100)
y = rational(x, [-0.2, 0.3, 0.5], [-1.0, 2.0])
ynoise = y * (1.0 + np.random.normal(scale=0.1, size=x.shape))
popt, pcov = curve_fit(rational3_3, x, ynoise, p0=(0.2, 0.3, 0.5, -1.0, 2.0))
print popt
plt.plot(x, y, label='original')
plt.plot(x, ynoise, '.', label='data')
plt.plot(x, rational3_3(x, *popt), label='fit')

W. A. Coniglio
- 3
- 3

oschoudhury
- 1,086
- 12
- 17