3.1. Factory Functions¶
Factory functions enable runtime composition of optimization pipelines.
3.1.1. create_optimizer()¶
Creates a configured optimizer instance:
from nlsq.core.factories import create_optimizer
# Basic optimizer
optimizer = create_optimizer()
popt, pcov = optimizer.fit(model, x, y)
# With global optimization
optimizer = create_optimizer(global_optimization=True, n_starts=20)
# With full features
optimizer = create_optimizer(
global_optimization=True, diagnostics=True, recovery=True, n_starts=20
)
Parameters:
create_optimizer(
global_optimization=False, # Enable multi-start/CMA-ES
diagnostics=False, # Collect convergence metrics
recovery=False, # Auto-recovery from issues
n_starts=10, # Starts for global optimization
**kwargs # Passed to underlying fit
)
3.1.2. configure_curve_fit()¶
Returns a configured fit function with preset defaults:
from nlsq.core.factories import configure_curve_fit
# High-precision fit function
high_precision_fit = configure_curve_fit(
ftol=1e-12, xtol=1e-12, gtol=1e-12, enable_diagnostics=True
)
# Use like regular fit
popt, pcov = high_precision_fit(model, x, y, p0=[...])
# Fast fit function
fast_fit = configure_curve_fit(ftol=1e-6, xtol=1e-6, gtol=1e-6, max_nfev=100)
Parameters:
configure_curve_fit(
enable_diagnostics=False, # Collect metrics
enable_recovery=False, # Auto-recovery
enable_caching=True, # JIT caching
ftol=1e-8, # Function tolerance
xtol=1e-8, # Parameter tolerance
gtol=1e-8, # Gradient tolerance
**defaults # Merged into every call
)
3.1.3. Use Cases¶
Application-specific presets:
# Spectroscopy fitting
spectroscopy_fit = configure_curve_fit(
ftol=1e-10, enable_diagnostics=True, stability="strict"
)
# Quick exploratory fits
quick_fit = configure_curve_fit(ftol=1e-4, max_nfev=50)
Batch processing:
optimizer = create_optimizer(diagnostics=True)
results = []
for data_file in files:
x, y = load(data_file)
popt, pcov = optimizer.fit(model, x, y, p0=[...])
results.append(popt)
Testing configurations:
# Production config
prod_optimizer = create_optimizer(global_optimization=True, recovery=True)
# Test config (faster, no recovery)
test_optimizer = create_optimizer(global_optimization=False, recovery=False)
3.1.4. Complete Example¶
from nlsq.core.factories import create_optimizer, configure_curve_fit
import jax.numpy as jnp
import numpy as np
def model(x, a, b, c):
return a * jnp.exp(-b * x) + c
# Create test data
np.random.seed(42)
x = np.linspace(0, 10, 100)
y = 2.5 * np.exp(-0.5 * x) + 0.3 + 0.1 * np.random.randn(100)
# Configure different optimizers
fast = configure_curve_fit(ftol=1e-6, xtol=1e-6, gtol=1e-6)
precise = configure_curve_fit(ftol=1e-12, xtol=1e-12, gtol=1e-12)
global_opt = create_optimizer(global_optimization=True, n_starts=10)
# Compare
print("Fast fit:")
popt, _ = fast(model, x, y, p0=[2, 0.5, 0])
print(f" {popt}")
print("Precise fit:")
popt, _ = precise(model, x, y, p0=[2, 0.5, 0])
print(f" {popt}")
print("Global fit:")
popt, _ = global_opt.fit(model, x, y, p0=[2, 0.5, 0], bounds=([0, 0, -1], [10, 5, 1]))
print(f" {popt}")
3.1.5. Next Steps¶
Protocols - Interface definitions
Dependency Injection - DI patterns