curve_fit
Fit curve(s) to paired (x, y) data and report each fitted equation with its error.
Instructions
Fit curve(s) to paired (x, y) data and report each fitted equation with its error.
Reach for curve_fit when you have observations and want an EQUATION that describes
them; use calculate to evaluate an equation you already have, or solver to find the
input that drives a known equation to a target. For example, x=[1, 1.5, 2],
y=[2, 5.8, 8.9] comes back with the line 6.9*x - 4.78… ranked first by its residual
error, so you can paste that equation straight into calculate to predict new points.
curve_fit takes the observations as two equal-length lists — x and y — and estimates,
for every curve form it knows, the parameter values that best match the data in the
least-squares sense, reporting each form's fitted equation and the residual error
(the sum of squared residuals). The curve library holds the straight line a*x + b,
the quadratic a*x**2 + b*x + c, the cubic a*x**3 + b*x**2 + c*x + d, the power law
a*x**b, the exponential a*exp(b*x), the logarithm a + b*ln(x), the square root
a*sqrt(x) + b, the reciprocal a/x + b, the sinusoid a*sin(b*x + c) + d, the
gaussian a*exp(-(x-b)**2/(2*c**2)), the saturation x/(a*x + b) (Michaelis-Menten) and
the hyperbolic 1/(a*x + b) (44.2.1-44.2.12, the complete library). Every form but the
sinusoid is fitted in CLOSED FORM — the polynomials
and the affine logarithm/square-root/reciprocal forms by the exact normal equations, the
power and exponential laws by a log-linearisation (ln y = ln a + b·ln x for the power,
ln y = ln a + b·x for the exponential), the gaussian by Caruana's method (logs to
the quadratic ln y = p2·x**2 + p1·x + p0, fitted by the normal equations, then the
peak/centre/width are recovered from its coefficients), and the saturation and hyperbolic
by a reciprocal-line transform (the double-reciprocal Lineweaver-Burk line
1/y = a + b·(1/x) for the saturation, the line 1/y = a·x + b for the hyperbolic). The
sinusoid alone has no
closed-form solution, so it is fitted by an ITERATIVE frequency search: it is non-linear
only in the frequency b, so for each candidate b the best amplitude/phase/offset is a
linear sub-fit, and a coarse scan over a data-derived frequency range (then a
golden-section refinement) picks the b minimising the residual. A form that cannot fit
the data is dropped, not fatal: the power and logarithm need x > 0, the square root
x >= 0, the reciprocal x != 0, the exponential, power and gaussian y > 0 (and the
gaussian needs bell-shaped, downward-parabola data), the saturation x != 0 and y != 0,
the hyperbolic y != 0; the power, exponential, logarithm,
square-root, sinusoid and gaussian forms also drop in rational mode, which cannot represent
their irrational logs/roots/sines/exp (the saturation and hyperbolic, being pure
reciprocals, stay exact in rational); and a polynomial needs enough distinct x (the
sinusoid four). The forms that fit are ranked by their residual error — least error first —
and only the best three are returned (fewer when fewer forms fit).
mode and min_fixed_point_precision behave as in calculate — the whole fit runs
in that numeric type, so the parameters and error are exact in rational, rounded at
the scale in fixed-point, and native doubles in floating-point. As in the
solver, a fixed-point fit at scale 0 would round every fitted parameter to a whole
number, so when min_fixed_point_precision is omitted it DEFAULTS to 9 (sub-unit
resolution); pass an explicit value for more/fewer decimals. Complex mode is not
supported (the fit is real-valued).
Returns a dict: fits is the ranked list of fitted forms (best first, at most three),
each {form, equation, parameters, fit_error, fit_error_hex_dump, exact, precision} —
form names the curve, equation is the model with its parameters substituted (over
the variable x, so it can be pasted into calculate), parameters is a list of
{name, value, value_hex_dump} for each fitted coefficient (each value annotated
with its own precision verdict), and fit_error is the residual error annotated the
same way with its hex dump; that fit's own exact and precision describe its error.
mode is the resolved numeric type, and the top-level exact / precision describe
the BEST fit's error (the headline number), as in solver. On any failure — a bad
mode/precision, mismatched or too-short data, or data that cannot support the form
(every x equal, so a line has no slope) — fits/mode/exact/precision are null and
error carries the message; on success error is null.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| x | Yes | The x coordinates of the observations — a list of numbers, the same length as `y` and at least two points long. | |
| y | Yes | The y coordinates of the observations — a list of numbers paired with `x` (same length, at least two points). | |
| mode | No | Numeric type the fit runs in: 'fixed-point' (default), 'floating-point', or 'rational' — as in `calculate`. | fixed-point |
| min_fixed_point_precision | No | Floor on fixed-point fractional digits (non-negative integer). In fixed-point mode, omit it for a default floor of 9 so the fitted parameters keep sub-unit precision instead of rounding to whole numbers; pass an explicit value for more/fewer decimals. Leave null/omit in the other modes, which carry no decimal scale. |