CMAES optimizer (evopt.cma_optimizer)

Warning

This module is part of the internal implementation of evopt and is not intended for direct use by end users. Its API may change without notice.

CMA-ES (Covariance Matrix Adaptation Evolution Strategy) implementation for optimization.

This module provides an implementation of the CMA-ES algorithm for black-box optimization of non-linear or non-convex continuous optimization problems. CMA-ES is particularly effective for problems that are ill-conditioned, have multiple local optima, or where gradient information is not available.

The implementation extends the BaseOptimizer class and leverages the pycma library for core CMA-ES functionality while handling parameter management, parallel evaluation, convergence detection, and result logging.

Example

Basic usage with a simple objective function:

>>> from evopt import CmaesOptimizer, DirectoryManager
>>> parameters = {'x': (-10, 10), 'y': (-5, 5)}
>>> def evaluator(params):
>>>     return params['x']**2 + params['y']**2  # Simple quadratic function
>>> dir_manager = DirectoryManager('./optimization_results')
>>> optimizer = CmaesOptimizer(
...     parameters=parameters,
...     evaluator=evaluator,
...     batch_size=10,
...     directory_manager=dir_manager,
...     n_epochs=50
... )
>>> results = optimizer.optimize()
>>> print(f"Best parameters: {results.best_parameters}")
>>> print(f"Final error: {results.final_error}")
class evopt.cma_optimizer.CmaesOptimizer(parameters: dict, evaluator, batch_size: int, directory_manager: DirectoryManager, sigma_threshold: float = 0.1, rand_seed: int = 1, start_epoch: int | None = None, verbose: bool = True, n_epochs: int | None = None, target_dict: dict | None = None, max_workers: int = 1, cores_per_worker: int = 1, **kwargs)[source]

Bases: BaseOptimizer

Optimization using the CMA-ES (Covariance Matrix Adaptation Evolution Strategy) algorithm.

This class implements the CMA-ES algorithm for black-box optimization of non-linear, non-convex continuous optimization problems. CMA-ES adapts a multivariate normal distribution to sample increasingly optimal solutions, using the covariance matrix to capture parameter dependencies and step-size adaptation for efficient convergence.

The implementation uses the pycma library for core functionality while adding support for parallel evaluation, checkpoint management, and comprehensive result tracking.

es

The underlying CMA-ES optimizer instance.

Type:

cma.CMAEvolutionStrategy

Note

This class inherits from BaseOptimizer and implements the required abstract methods. See BaseOptimizer for inherited attributes and methods.

Example

>>> from evopt import CmaesOptimizer, DirectoryManager
>>> # Define parameter space with bounds
>>> parameters = {'length': (10, 100), 'width': (5, 50), 'height': (1, 10)}
>>> # Define evaluator function (lower is better)
>>> def evaluator(params):
...     volume = params['length'] * params['width'] * params['height']
...     return 1000 - volume  # Maximize volume by minimizing this value
>>>
>>> # Set up optimizer
>>> dir_manager = DirectoryManager('./cmaes_results')
>>> optimizer = CmaesOptimizer(
...     parameters=parameters,
...     evaluator=evaluator,
...     batch_size=16,
...     directory_manager=dir_manager,
...     sigma_threshold=0.05,  # Convergence threshold
...     max_workers=4,  # Parallel evaluation
...     n_epochs=100  # Maximum epochs
... )
>>>
>>> # Run optimization
>>> results = optimizer.optimize()
>>>
>>> # Access results
>>> print(f"Best parameters: {results.best_parameters}")
>>> print(f"Best fitness: {results.final_error}")
check_termination() bool[source]

Check if optimization termination criteria are met.

Determines whether the optimization should terminate based on either:

  1. Convergence: All parameters’ normalized standard deviations have fallen below the threshold, indicating the algorithm has converged

  2. Maximum epochs: The specified maximum number of epochs has been reached

The method uses the standard deviations from the CMA-ES covariance matrix as a direct measure of search space exploration.

Returns:

True if termination criteria are met (either convergence or

maximum epochs reached), False otherwise.

Return type:

bool

Example

>>> while not optimizer.check_termination():
...     # Run one iteration
...     solutions = optimizer.es.ask(optimizer.batch_size)
...     errors = optimizer.process_batch(solutions)
...     optimizer.es.tell(solutions, errors)
optimize() OptimizationResults[source]

Run the CMA-ES optimization process until termination.

Executes the complete CMA-ES optimization loop, handling:

  1. Setup/initialization of the optimizer

  2. Generation of candidate solutions

  3. Evaluation of solutions (potentially in parallel)

  4. Updating the internal state of the algorithm

  5. Checkpointing for resumability

  6. Termination detection

  7. Results compilation

The method continues until either convergence criteria are met or the maximum number of epochs is reached.

Returns:

A comprehensive results object containing the best

parameters found, optimization history, and algorithm-specific data.

Return type:

OptimizationResults

Example

>>> # Run the full optimization process
>>> results = optimizer.optimize()
>>>
>>> # Extract best results
>>> best_params = results.best_parameters
>>> error = results.final_error
>>>
>>> # Analyze convergence behavior
>>> import matplotlib.pyplot as plt
>>> plt.plot(results.mean_error_history)
>>> plt.title("Error Convergence")
>>> plt.xlabel("Epoch")
>>> plt.ylabel("Error")
>>> plt.show()
setup_opt(epoch: int | None = None) None[source]

Set up the CMA-ES optimizer instance.

Initializes or restores the CMA-ES optimizer either by creating a new instance or loading a checkpoint from a previous run. This method configures the CMA-ES algorithm with appropriate parameters and bounds.

Parameters:

epoch – The epoch number to resume from if restoring from a checkpoint. If None, starts a new optimization run. Default is None.

Returns:

None

Note

This method stores the CMA-ES instance in self.es and updates the current_epoch counter.

Example

>>> # Start a new optimization
>>> optimizer.setup_opt()
>>>
>>> # Resume from epoch 10
>>> optimizer.setup_opt(epoch=10)
class evopt.cma_optimizer.OptimizationResults(best_parameters: Dict[str, float], final_error: float, mean_error_history: List[float], sigma_error_history: List[float], mean_params_history: Dict[str, List[float]], sigma_params_history: Dict[str, List[float]], norm_sigmas_history: Dict[str, List[float]], mean_target_history: Dict[str, List[float]] | None = None, sigma_target_history: Dict[str, List[float]] | None = None, epochs_completed: int | None = None, terminated_reason: str | None = None, cmaes_sigma: float | None = None, cmaes_C: ndarray | None = None)[source]

Bases: object

Container for comprehensive optimization results.

This dataclass stores all results from a completed optimization run, including the best parameters found, error values, complete optimization history, and algorithm-specific data. All numeric values are stored as native Python types for better serialization compatibility.

best_parameters

Dictionary of the best parameter values found, with parameter names as keys and their optimized values as values.

Type:

Dict[str, float]

final_error

The error/fitness value of the best solution.

Type:

float

mean_error_history

List of mean error values for each epoch.

Type:

List[float]

sigma_error_history

List of error standard deviations for each epoch.

Type:

List[float]

mean_params_history

Dictionary of parameter means over time, with parameter names as keys and lists of their mean values as values.

Type:

Dict[str, List[float]]

sigma_params_history

Dictionary of parameter standard deviations over time.

Type:

Dict[str, List[float]]

norm_sigmas_history

Dictionary of normalized sigma values over time.

Type:

Dict[str, List[float]]

mean_target_history

Dictionary of mean target values over time (for multi-objective optimization). None if no targets were specified.

Type:

Dict[str, List[float]] | None

sigma_target_history

Dictionary of target standard deviations over time.

Type:

Dict[str, List[float]] | None

epochs_completed

Total number of epochs/generations completed.

Type:

int

terminated_reason

String describing why optimization terminated.

Type:

str

cmaes_sigma

Final step size of the CMA-ES algorithm.

Type:

float

cmaes_C

Final covariance matrix of the CMA-ES algorithm.

Type:

numpy.ndarray | None

Example

>>> # Accessing optimization results
>>> results = optimizer.optimize()
>>>
>>> # Get best parameters and error
>>> print(f"Best parameters: {results.best_parameters}")
>>> print(f"Best fitness: {results.final_error}")
>>>
>>> # Plot convergence history
>>> import matplotlib.pyplot as plt
>>> plt.figure(figsize=(12, 6))
>>> plt.plot(results.mean_error_history)
>>> plt.title(f"Optimization Convergence ({results.terminated_reason})")
>>> plt.xlabel("Epoch")
>>> plt.ylabel("Error")
>>> plt.grid(True)
>>> plt.show()
best_parameters: Dict[str, float]
cmaes_C: ndarray | None = None
cmaes_sigma: float = None
epochs_completed: int = None
final_error: float
mean_error_history: List[float]
mean_params_history: Dict[str, List[float]]
mean_target_history: Dict[str, List[float]] | None = None
norm_sigmas_history: Dict[str, List[float]]
sigma_error_history: List[float]
sigma_params_history: Dict[str, List[float]]
sigma_target_history: Dict[str, List[float]] | None = None
terminated_reason: str = None