Initial parameter estimation functions for curve fitting.
The fitting.estimators module provides functions to estimate initial parameter values for various mathematical models. These estimates are used as starting points for curve fitting algorithms to improve convergence and reduce the likelihood of finding local minima instead of the global optimum.
All estimation functions assume that input arrays x and y are finite and have been validated/cleaned by the caller. The functions are exported from the fitting package, so they can be imported as:
from fitting import estimate_linear_parameters, estimate_gaussian_parametersEstimate initial parameters for linear fit y = m*x + n.
Uses numpy.polyfit to compute the intercept (n) and slope (m) from the data.
Parameters:
x: Independent variable arrayy: Dependent variable array
Returns:
- Tuple
(n, m): intercept and slope
Example:
from fitting import estimate_linear_parameters
import numpy as np
x = np.array([1, 2, 3, 4, 5])
y = np.array([2.5, 5.1, 7.4, 10.2, 12.6])
n, m = estimate_linear_parameters(x, y)
print(f"Intercept: {n:.3f}, Slope: {m:.3f}")Estimate initial parameters for polynomial y = c0 + c1*x + ... + c_degree*x^degree.
Uses numpy.polyfit to compute coefficients. Returns coefficients in order from constant term to highest degree.
Parameters:
x: Independent variable arrayy: Dependent variable arraydegree: Polynomial degree
Returns:
- List of coefficients
[c0, c1, ..., c_degree](constant term first)
Example:
from fitting import estimate_polynomial_parameters
x = np.array([1, 2, 3, 4, 5])
y = np.array([1, 4, 9, 16, 25]) # Quadratic
coefs = estimate_polynomial_parameters(x, y, degree=2)
print(f"Coefficients: {coefs}")Estimate coefficient a for y = a * x^power (no constant term).
Uses least-squares: a = sum(y * x^power) / sum(x^(2*power)).
Parameters:
x: Independent variable arrayy: Dependent variable arraypower: Exponent (e.g., 2 for quadratic through origin)
Returns:
- Estimated coefficient
a
Example:
from fitting import estimate_single_power_parameter
x = np.array([1, 2, 3, 4, 5])
y = np.array([2, 8, 18, 32, 50]) # y = 2*x^2
a = estimate_single_power_parameter(x, y, power=2)
print(f"Coefficient: {a:.3f}")Estimate initial parameters for trigonometric functions y = a * sin(b*x) or y = a * cos(b*x).
Uses peak detection first, with autocorrelation fallback when peaks are insufficient. Estimates amplitude (a) and angular frequency (b).
Parameters:
x: Independent variable arrayy: Dependent variable array
Returns:
- Tuple
(amplitude, frequency)
Example:
from fitting import estimate_trigonometric_parameters
import numpy as np
x = np.linspace(0, 4*np.pi, 100)
y = 3.0 * np.sin(2.0 * x) # Amplitude=3, Frequency=2
amplitude, frequency = estimate_trigonometric_parameters(x, y)
print(f"Amplitude: {amplitude:.3f}, Frequency: {frequency:.3f}")Estimate initial phase shift for y = a * sin(b*x + c) or y = a * cos(b*x + c).
Parameters:
x: Independent variable arrayy: Dependent variable arrayamplitude: Estimated amplitude (a)frequency: Estimated angular frequency (b)
Returns:
- Estimated phase shift (c)
Example:
from fitting import estimate_trigonometric_parameters, estimate_phase_shift
amplitude, frequency = estimate_trigonometric_parameters(x, y)
phase = estimate_phase_shift(x, y, amplitude, frequency)
print(f"Phase shift: {phase:.3f}")Estimate initial parameters for hyperbolic functions y = a * sinh(b*x) or y = a * cosh(b*x).
- Amplitude (a) from half the y range
- Frequency (b) from the inverse of the x range
Parameters:
x: Independent variable arrayy: Dependent variable array
Returns:
- Tuple
(amplitude, frequency)
Example:
from fitting import estimate_hyperbolic_parameters
import numpy as np
x = np.linspace(0, 2, 50)
y = 2.0 * np.sinh(1.5 * x)
amplitude, frequency = estimate_hyperbolic_parameters(x, y)
print(f"Amplitude: {amplitude:.3f}, Frequency: {frequency:.3f}")Return parameter bounds for hyperbolic fits to avoid overflow in exp.
For y = a * sinh(b*x) or y = a * cosh(b*x): a can be any real; b is bounded so that b * max(|x|) does not cause overflow.
Parameters:
x: Independent variable array
Returns:
- Pair
(lower_bounds, upper_bounds), each of length 2 for(a, b)
Example:
from fitting import estimate_hyperbolic_parameters, estimate_hyperbolic_bounds
amplitude, frequency = estimate_hyperbolic_parameters(x, y)
(lower, upper) = estimate_hyperbolic_bounds(x)
# Use with merge_bounds when calling generic_fitEstimate initial parameter a for y = a * ln(x).
Uses least squares with no intercept. Requires positive x values.
Parameters:
x: Independent variable array (must be positive)y: Dependent variable array
Returns:
- Estimated coefficient
a
Example:
from fitting import estimate_ln_parameter
x = np.array([1, 2, 3, 4, 5])
y = 2.5 * np.log(x)
a = estimate_ln_parameter(x, y)
print(f"Coefficient: {a:.3f}")Estimate coefficient a for y = a / x^power.
Uses median of (y * x^power) for robustness to outliers.
Parameters:
x: Independent variable array (avoid zeros)y: Dependent variable arraypower: Power in denominator (1 or 2)
Returns:
- Estimated coefficient
a
Example:
from fitting import estimate_inverse_parameter
x = np.array([1, 2, 3, 4, 5])
y = 10.0 / x # y = 10/x
a = estimate_inverse_parameter(x, y, power=1)
print(f"Coefficient: {a:.3f}")Estimate initial (A, mu, sigma) for y = A * exp(-(x-mu)^2 / (2*sigma^2)).
Afrommax(y)mufromxat maximumsigmafrom FWHM (full width at half maximum) using half-max crossings
Parameters:
x: Independent variable arrayy: Dependent variable array
Returns:
- Tuple
(A, mu, sigma)
Example:
from fitting import estimate_gaussian_parameters
import numpy as np
x = np.linspace(-5, 5, 100)
y = 5.0 * np.exp(-(x - 1.0)**2 / (2 * 1.5**2)) # A=5, mu=1, sigma=1.5
A, mu, sigma = estimate_gaussian_parameters(x, y)
print(f"A: {A:.3f}, mu: {mu:.3f}, sigma: {sigma:.3f}")Estimate (a, b) for y = a * exp(b*x).
Uses log(y) = log(a) + b*x when y > 0; otherwise fallback from endpoints.
Parameters:
x: Independent variable arrayy: Dependent variable array
Returns:
- Tuple
(a, b)
Example:
from fitting import estimate_exponential_parameters
x = np.array([0, 1, 2, 3, 4])
y = 2.0 * np.exp(0.5 * x) # a=2, b=0.5
a, b = estimate_exponential_parameters(x, y)
print(f"a: {a:.3f}, b: {b:.3f}")Estimate (a, b, c) for logistic y = a / (1 + exp(-b*(x-c))).
a= range (y_max - y_min)c= midpoint of transitionbfrom inverse of transition width
Parameters:
x: Independent variable arrayy: Dependent variable array
Returns:
- Tuple
(a, b, c)
Example:
from fitting import estimate_binomial_parameters
x = np.linspace(-5, 5, 100)
y = 10.0 / (1 + np.exp(-2.0 * (x - 1.0))) # Logistic curve
a, b, c = estimate_binomial_parameters(x, y)
print(f"a: {a:.3f}, b: {b:.3f}, c: {c:.3f}")Estimate (A, t0, w) for a smooth square pulse: amplitude, center time, width.
Afrom peak-to-peakt0from center of mass ofy(absolute value)wfrom support of elevated region
Parameters:
x: Independent variable array (e.g., time)y: Dependent variable array
Returns:
- Tuple
(A, t0, w)
Example:
from fitting import estimate_square_pulse_parameters
x = np.linspace(0, 10, 100)
# Square pulse centered at t=5 with width=2
y = np.where((x >= 4) & (x <= 6), 5.0, 0.0)
A, t0, w = estimate_square_pulse_parameters(x, y)
print(f"A: {A:.3f}, t0: {t0:.3f}, w: {w:.3f}")Estimators are typically used internally by fitting functions to provide initial guesses, but you can also use them directly:
from fitting import estimate_gaussian_parameters, get_fitting_function
import numpy as np
# Generate sample data
x = np.linspace(-5, 5, 100)
y = 5.0 * np.exp(-(x - 1.0)**2 / (2 * 1.5**2)) + np.random.normal(0, 0.1, 100)
# Estimate initial parameters
A_0, mu_0, sigma_0 = estimate_gaussian_parameters(x, y)
print(f"Initial guess: A={A_0:.3f}, mu={mu_0:.3f}, sigma={sigma_0:.3f}")
# Use with fitting function (if it accepts initial_guess parameter)
# Note: Most fitting functions use estimators internallyAll estimator functions handle edge cases gracefully:
- Insufficient data: Returns sensible defaults (e.g., mean value, zero)
- Zero/negative values: Handles edge cases for logarithmic and inverse functions
- Numerical issues: Clips values to prevent overflow/underflow
- Peak detection failures: Falls back to alternative estimation methods
- Estimators are designed to be fast and robust
- They use vectorized NumPy operations
- Some functions (like trigonometric) use peak detection which can be slower for large datasets
- For very large datasets, consider subsampling before estimation
The estimators are automatically used by fitting functions in fitting.fitting_functions when initial guesses are needed. You typically don't need to call them directly unless you're:
- Debugging: Checking if initial guesses are reasonable
- Custom fitting: Creating your own fitting routines
- Visualization: Plotting initial guesses before fitting
- Validate inputs: Ensure
xandyare finite and have sufficient data points - Check domain: For logarithmic functions, ensure
x > 0 - Handle outliers: Some estimators use median for robustness
- Use appropriate estimators: Match the estimator to your model type
For more information about fitting functions, see fitting_functions and fitting_utils.