optimize¶
Parameter estimation and model validation. Four optimizer backends share one interface; see the parameter tuning guide for how to choose between them.
Optional dependencies
ScipyOptimizer works out of the box. The others need extras:
pip install "adtoolbox[blackbox]" (OpenBox), "adtoolbox[genetic]" (PyGAD), or
"adtoolbox[surrogate]" (PyTorch). Install all of them with "adtoolbox[optimize]".
Search space¶
ParameterSpec¶
ParameterSpec
dataclass
¶
Bounds and optional default value for one optimized parameter.
from_value
classmethod
¶
from_value(
name: str, value: "ParameterSpec | Sequence[float] | Mapping[str, float]"
) -> "ParameterSpec"
Source code in adtoolbox/optimize.py
OptimizationRecord¶
OptimizationRecord
dataclass
¶
Base interface¶
Shared machinery: input validation, parameter-name resolution, model preparation, objective evaluation, history bookkeeping, and JSON persistence.
Optimizer
¶
Optimizer(
base_model: Model,
train_data: Iterable[Experiment],
search_space: Mapping[str, ParameterSpec | Sequence[float] | Mapping[str, float]],
*,
parameter_target: ParameterTarget = "auto",
fitness_mode: str = "sum_squared_error",
ode_method: str = "BDF",
random_state: int | None = None,
logger: Logger | None = None
)
Bases: ABC
Common interface for ADToolbox parameter optimizers.
Source code in adtoolbox/optimize.py
search_space
instance-attribute
¶
parameter_names
property
¶
Optimized parameter names, in the order used by parameter vectors.
bounds
property
¶
Search-space bounds as an (n_parameters, 2) array of lower/upper pairs.
best_record
property
¶
The lowest-cost record seen so far, or None if nothing has been evaluated.
parameters_to_vector
¶
Convert a parameter mapping into a vector ordered by parameter_names.
Source code in adtoolbox/optimize.py
vector_to_parameters
¶
Convert a parameter vector back into a name-to-value mapping.
clip_vector
¶
Clip a parameter vector element-wise into the search-space bounds.
Source code in adtoolbox/optimize.py
default_vector
¶
Parameter vector of each spec's default, or its bound midpoint if unset.
Source code in adtoolbox/optimize.py
random_vector
¶
prepare_model
¶
prepare_model(
parameters: Mapping[str, float] | Sequence[float] | ndarray,
experiment: Experiment | None = None,
) -> adm.Model
Copy the base model and apply candidate parameters.
When an experiment is given, its feed, base parameters, and initial
concentrations are applied as well, the initial value of every measured
variable is set to its observed value at time zero, and any state listed
in the experiment's constants is pinned as a control state.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
parameters
|
Mapping[str, float] | Sequence[float] | ndarray
|
Candidate values, as a mapping or a vector. |
required |
experiment
|
Experiment | None
|
Optional experiment whose conditions should be applied. |
None
|
Returns:
| Type | Description |
|---|---|
Model
|
adm.Model: A new model instance ready to solve. The base model is never mutated. |
Source code in adtoolbox/optimize.py
evaluate
¶
Score one parameter set against every training experiment.
Each experiment is simulated at its own measurement time points and compared to the observed data. Calling this directly does not add to the optimizer history.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
parameters
|
Mapping[str, float] | Sequence[float] | ndarray
|
Candidate values, as a mapping or a vector. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
float |
float
|
Sum of squared residuals across all experiments, time points, and measured variables. Lower is better. |
Source code in adtoolbox/optimize.py
record
¶
record(
parameters: Mapping[str, float] | Sequence[float] | ndarray,
cost: float,
*,
metadata: Mapping[str, Any] | None = None
) -> OptimizationRecord
Append an evaluated point to the history.
If the cost improves on the current best, best_cost,
optimized_parameters, and optimized_model are updated.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
parameters
|
Mapping[str, float] | Sequence[float] | ndarray
|
The evaluated values, as a mapping or a vector. |
required |
cost
|
float
|
The objective value for those parameters. |
required |
metadata
|
Mapping[str, Any] | None
|
Optional free-form annotations, such as which backend produced the point. |
None
|
Returns:
| Name | Type | Description |
|---|---|---|
OptimizationRecord |
OptimizationRecord
|
The record that was appended. |
Source code in adtoolbox/optimize.py
clear_history
¶
Discard all recorded evaluations and the current best result.
to_dict
¶
Serialize the search space, best result, and full history to a dict.
Source code in adtoolbox/optimize.py
save
¶
Write the optimizer state to a JSON file, creating parent directories.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
path
|
str | Path
|
Destination file path. |
required |
Returns:
| Type | Description |
|---|---|
Path
|
pathlib.Path: The path that was written. |
Source code in adtoolbox/optimize.py
load
¶
Restore optimizer state by replaying a saved history.
The current history is cleared first, so best_cost,
optimized_parameters, and optimized_model end up reflecting the
saved run.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
path
|
str | Path
|
A JSON file previously written by |
required |
Returns:
| Name | Type | Description |
|---|---|---|
Optimizer |
'Optimizer'
|
This optimizer, to allow chaining. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If the saved parameter names do not match this optimizer's search space. |
Source code in adtoolbox/optimize.py
optimize
abstractmethod
¶
Optimizer backends¶
ScipyOptimizer¶
ScipyOptimizer
¶
ScipyOptimizer(
base_model: Model,
train_data: Iterable[Experiment],
search_space: Mapping[str, ParameterSpec | Sequence[float] | Mapping[str, float]],
*,
parameter_target: ParameterTarget = "auto",
fitness_mode: str = "sum_squared_error",
ode_method: str = "BDF",
random_state: int | None = None,
logger: Logger | None = None
)
Bases: Optimizer
Differential-evolution optimizer using SciPy only.
Source code in adtoolbox/optimize.py
optimize
¶
optimize(
*,
maxiter: int = 100,
popsize: int = 15,
polish: bool = True,
workers: int = 1,
**kwargs
)
Source code in adtoolbox/optimize.py
BlackBoxOptimizer¶
BlackBoxOptimizer
¶
BlackBoxOptimizer(
base_model: Model,
train_data: Iterable[Experiment],
search_space: Mapping[str, ParameterSpec | Sequence[float] | Mapping[str, float]],
*,
parameter_target: ParameterTarget = "auto",
fitness_mode: str = "sum_squared_error",
ode_method: str = "BDF",
random_state: int | None = None,
logger: Logger | None = None
)
Bases: Optimizer
OpenBox-backed optimizer with the shared ADToolbox optimizer interface.
Source code in adtoolbox/optimize.py
optimize
¶
Source code in adtoolbox/optimize.py
GeneticOptimizer¶
GeneticOptimizer
¶
GeneticOptimizer(
base_model: Model,
train_data: Iterable[Experiment],
search_space: Mapping[str, ParameterSpec | Sequence[float] | Mapping[str, float]],
*,
parameter_target: ParameterTarget = "auto",
fitness_mode: str = "sum_squared_error",
ode_method: str = "BDF",
random_state: int | None = None,
logger: Logger | None = None
)
Bases: Optimizer
PyGAD-backed genetic optimizer with the shared ADToolbox optimizer interface.
Source code in adtoolbox/optimize.py
optimize
¶
Source code in adtoolbox/optimize.py
SurrogateOptimizer¶
SurrogateOptimizer
¶
SurrogateOptimizer(
*args,
hidden_size: int = 30,
hidden_layers: int = 4,
learning_rate: float = 0.001,
input_learning_rate: float = 0.001,
train_epochs: int = 500,
**kwargs
)
Bases: Optimizer
Small neural surrogate optimizer for expensive ODE model evaluations.
Source code in adtoolbox/optimize.py
optimize
¶
optimize(
*,
n_steps: int = 100,
initial_points: int = 8,
grad_steps: int = 20,
perturbation_scale: float = 0.05,
save_every: int | None = None,
history_path: str | Path | None = None
) -> list[OptimizationRecord]
Source code in adtoolbox/optimize.py
Validation¶
validate_model¶
validate_model
¶
validate_model(
model: Model,
data: Experiment | Iterable[Experiment],
plot: bool = False,
show_extra_states: Iterable[str] | None = None,
ode_solver: str = "Radau",
) -> tuple[dict[str, pl.DataFrame], plotly.graph_objs.Figure | None]
Compare model predictions against one or more experiments.
Source code in adtoolbox/optimize.py
648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 | |
calculate_fit_stats¶
calculate_fit_stats
¶
Calculate RMSE and R-squared metrics for a set of experiments.