nlsq.parameter_estimation module¶
Automatic initial parameter estimation for curve fitting.
This module provides intelligent parameter estimation when users don’t provide initial guesses (p0). It uses heuristics based on data characteristics and function signatures to generate reasonable starting points.
Key Features¶
Automatic p0 estimation: No need to manually guess initial parameters
Pattern detection: Recognizes common function types (linear, exponential, gaussian, sigmoid)
Smart heuristics: Uses data statistics (range, mean, peaks) to estimate parameters
Library function support: Custom functions can provide their own .estimate_p0() method
Fallback strategies: Always provides reasonable defaults if pattern detection fails
Examples
Basic usage with automatic p0 estimation:
>>> from nlsq import curve_fit
>>> import jax.numpy as jnp
>>> import numpy as np
>>>
>>> # Define model (no p0 needed!)
>>> def exponential_decay(x, amplitude, rate, offset):
... return amplitude * jnp.exp(-rate * x) + offset
>>>
>>> # Generate data
>>> x = np.linspace(0, 5, 50)
>>> y = 3 * np.exp(-0.5 * x) + 1 + np.random.normal(0, 0.1, 50)
>>>
>>> # Use p0='auto' for automatic estimation
>>> popt, pcov = curve_fit(exponential_decay, x, y, p0='auto')
>>>
>>> # Note: p0=None (or omitting p0) uses default behavior [1.0, 1.0, ...]
>>> # for backward compatibility
>>> popt, pcov = curve_fit(exponential_decay, x, y) # Uses default p0
>>>
>>> print(f"Fitted: amplitude={popt[0]:.2f}, rate={popt[1]:.2f}, offset={popt[2]:.2f}")
>>> # Output: Fitted: amplitude=2.95, rate=0.51, offset=1.04
Notes
The automatic parameter estimation works as follows:
Custom estimation: Checks if function has .estimate_p0(xdata, ydata) method
Pattern detection: Analyzes data shape to detect function type
Heuristic estimation: Uses data statistics to estimate parameters:
First parameter (amplitude): y_range
Second parameter (rate/slope): 1/x_range
Third parameter (offset): y_mean
Fourth parameter (center): x_mean
Fallback: Returns sensible defaults if all else fails
See also
nlsq.minpack.curve_fitMain curve fitting function
nlsq.error_messagesEnhanced error messages
- nlsq.precision.parameter_estimation.estimate_initial_parameters(f, xdata, ydata, p0=None)[source]
Estimate initial parameters if p0 is None or ‘auto’.
This function attempts to intelligently guess initial parameter values based on the data characteristics when p0 is not provided.
The estimation strategy follows this order: 1. If p0 is provided (not None or ‘auto’), return it unchanged 2. If function has .estimate_p0() method, use it (for library functions) 3. Otherwise, use generic heuristics based on data statistics
- Parameters:
f (callable) – Model function f(x, p0, p1, …) → y
xdata (array_like) – Independent variable data
ydata (array_like) – Dependent variable data
p0 (array_like or None or 'auto', optional) – Initial guess. If None or ‘auto’, estimate from data.
- Returns:
p0_estimated – Initial parameter guess
- Return type:
ndarray
- Raises:
ValueError – If cannot determine number of parameters from function signature
Examples
Automatic estimation for exponential decay:
>>> import numpy as np >>> def exponential(x, a, b, c): ... return a * np.exp(-b * x) + c >>> xdata = np.linspace(0, 5, 50) >>> ydata = 3 * np.exp(-0.5 * xdata) + 1 >>> p0 = estimate_initial_parameters(exponential, xdata, ydata) >>> # p0 ≈ [2.0, 0.2, 1.5] (estimated from data statistics)
Estimation works with any number of parameters:
>>> def linear(x, a, b): ... return a * x + b >>> xdata = np.array([1, 2, 3, 4, 5]) >>> ydata = np.array([2, 4, 6, 8, 10]) >>> p0 = estimate_initial_parameters(linear, xdata, ydata) >>> # p0 ≈ [8.0, 0.25] (based on y_range and 1/x_range)
Custom functions can provide their own estimation:
>>> class GaussianModel: ... def __call__(self, x, amp, mu, sigma): ... return amp * np.exp(-(x - mu)**2 / (2 * sigma**2)) ... ... def estimate_p0(self, xdata, ydata): ... amp = np.max(ydata) - np.min(ydata) ... mu = xdata[np.argmax(ydata)] ... sigma = (np.max(xdata) - np.min(xdata)) / 4 ... return [amp, mu, sigma] >>> >>> model = GaussianModel() >>> xdata = np.linspace(-5, 5, 100) >>> ydata = 2 * np.exp(-(xdata - 1)**2 / 2) >>> p0 = estimate_initial_parameters(model, xdata, ydata) >>> # Uses custom estimate_p0 method
See also
detect_function_patternDetect likely function pattern from data
estimate_p0_for_patternPattern-specific estimation
- nlsq.precision.parameter_estimation.detect_function_pattern(ydata, xdata)[source]
Detect likely function pattern from data shape.
This function analyzes the shape of the data to identify common patterns. It uses simple heuristics like monotonicity, peak detection, and correlation.
- Parameters:
ydata (ndarray) – Dependent variable data
xdata (ndarray) – Independent variable data
- Returns:
pattern – Detected pattern: - ‘linear’: Strong linear correlation (|r| > 0.95) - ‘exponential_decay’: Monotonically decreasing - ‘exponential_growth’: Monotonically increasing - ‘gaussian’: Bell-shaped curve with peak in middle - ‘sigmoid’: S-shaped curve going from low to high (or vice versa) - ‘unknown’: No clear pattern detected
- Return type:
Notes
This is a simple heuristic detector, not a rigorous statistical test. It’s designed to be fast and provide reasonable guidance for initial parameter estimation, not to be 100% accurate.
Examples
Detect exponential decay:
>>> import numpy as np >>> xdata = np.linspace(0, 5, 50) >>> ydata = 3 * np.exp(-0.5 * xdata) >>> pattern = detect_function_pattern(ydata, xdata) >>> print(pattern) 'exponential_decay'
Detect Gaussian peak:
>>> xdata = np.linspace(-5, 5, 100) >>> ydata = 2 * np.exp(-(xdata - 1)**2 / 2) >>> pattern = detect_function_pattern(ydata, xdata) >>> print(pattern) 'gaussian'
See also
estimate_p0_for_patternEstimate parameters based on detected pattern
- nlsq.precision.parameter_estimation.estimate_p0_for_pattern(pattern, xdata, ydata, n_params)[source]
Estimate p0 based on detected pattern.
This function uses pattern-specific heuristics to estimate initial parameters. Each pattern has its own estimation strategy based on the mathematical properties of that function type.
- Parameters:
- Returns:
p0 – Estimated initial parameters (length n_params)
- Return type:
ndarray
Notes
Pattern-specific estimation strategies:
linear: Uses least squares to fit y = a*x + b
exponential_decay: Estimates amplitude from range, rate from half-life
gaussian: Estimates amplitude, mean from peak, sigma from FWHM
sigmoid: Estimates L, x0, k from data range and midpoint
unknown: Falls back to generic heuristics
Examples
Estimate parameters for exponential decay:
>>> import numpy as np >>> xdata = np.linspace(0, 5, 50) >>> ydata = 3 * np.exp(-0.5 * xdata) + 1 >>> p0 = estimate_p0_for_pattern('exponential_decay', xdata, ydata, 3) >>> print(p0) [2.0, 0.277..., 1.0] # [amplitude, rate, offset]
Estimate parameters for Gaussian:
>>> xdata = np.linspace(-5, 5, 100) >>> ydata = 2 * np.exp(-(xdata - 1)**2 / (2 * 0.5**2)) >>> p0 = estimate_p0_for_pattern('gaussian', xdata, ydata, 3) >>> print(p0) [2.0, 1.0, 0.5] # [amplitude, mean, sigma]
See also
detect_function_patternDetect pattern from data
estimate_initial_parametersMain parameter estimation function
Overview¶
The parameter_estimation module provides utilities for estimating initial parameter values from data.
Key Features¶
Automatic initial guess generation from data characteristics
Problem-specific heuristics for common model types
Bounds inference based on data range
Multi-start optimization with parameter space exploration
Functions¶
- nlsq.parameter_estimation.estimate_initial_parameters(f, xdata, ydata, p0=None)[source]
Estimate initial parameters if p0 is None or ‘auto’.
This function attempts to intelligently guess initial parameter values based on the data characteristics when p0 is not provided.
The estimation strategy follows this order: 1. If p0 is provided (not None or ‘auto’), return it unchanged 2. If function has .estimate_p0() method, use it (for library functions) 3. Otherwise, use generic heuristics based on data statistics
- Parameters:
f (callable) – Model function f(x, p0, p1, …) → y
xdata (array_like) – Independent variable data
ydata (array_like) – Dependent variable data
p0 (array_like or None or 'auto', optional) – Initial guess. If None or ‘auto’, estimate from data.
- Returns:
p0_estimated – Initial parameter guess
- Return type:
ndarray
- Raises:
ValueError – If cannot determine number of parameters from function signature
Examples
Automatic estimation for exponential decay:
>>> import numpy as np >>> def exponential(x, a, b, c): ... return a * np.exp(-b * x) + c >>> xdata = np.linspace(0, 5, 50) >>> ydata = 3 * np.exp(-0.5 * xdata) + 1 >>> p0 = estimate_initial_parameters(exponential, xdata, ydata) >>> # p0 ≈ [2.0, 0.2, 1.5] (estimated from data statistics)
Estimation works with any number of parameters:
>>> def linear(x, a, b): ... return a * x + b >>> xdata = np.array([1, 2, 3, 4, 5]) >>> ydata = np.array([2, 4, 6, 8, 10]) >>> p0 = estimate_initial_parameters(linear, xdata, ydata) >>> # p0 ≈ [8.0, 0.25] (based on y_range and 1/x_range)
Custom functions can provide their own estimation:
>>> class GaussianModel: ... def __call__(self, x, amp, mu, sigma): ... return amp * np.exp(-(x - mu)**2 / (2 * sigma**2)) ... ... def estimate_p0(self, xdata, ydata): ... amp = np.max(ydata) - np.min(ydata) ... mu = xdata[np.argmax(ydata)] ... sigma = (np.max(xdata) - np.min(xdata)) / 4 ... return [amp, mu, sigma] >>> >>> model = GaussianModel() >>> xdata = np.linspace(-5, 5, 100) >>> ydata = 2 * np.exp(-(xdata - 1)**2 / 2) >>> p0 = estimate_initial_parameters(model, xdata, ydata) >>> # Uses custom estimate_p0 method
See also
detect_function_patternDetect likely function pattern from data
estimate_p0_for_patternPattern-specific estimation
Example Usage¶
from nlsq.parameter_estimation import estimate_initial_parameters
import jax.numpy as jnp
# Define exponential model
def exponential(x, a, b):
return a * jnp.exp(-b * x)
# Generate data
x = jnp.linspace(0, 10, 100)
y = 2.5 * jnp.exp(-0.5 * x) + 0.1 * jnp.random.randn(100)
# Automatically estimate initial parameters
p0 = estimate_initial_parameters(exponential, x, y, n_params=2)
print(f"Estimated initial parameters: {p0}")
# Use in curve fitting
from nlsq import curve_fit
popt, pcov = curve_fit(exponential, x, y, p0=p0)
Supported Model Types¶
Automatic estimation for common model types:
Exponential decay:
y = a * exp(-b * x) + cGaussian:
y = a * exp(-((x-b)/c)^2)Linear:
y = a * x + bPolynomial:
y = sum(a_i * x^i)Logistic:
y = L / (1 + exp(-k*(x-x0)))
See Also¶
nlsq.bound_inference module - Bound inference utilities
nlsq.algorithm_selector module - Algorithm selection
Configuration Reference - Configuration reference