pycma Documentation

repository·development·Indexed 23 days ago

https://github.com/cma-es/pycma

A Python implementation of the Covariance Matrix Adaptation Evolution Strategy (CMA-ES) for derivative-free numerical optimization of non-convex, ill-conditioned, multi-modal, rugged, or noisy functions. It provides tools for constrained optimization via fmin_con and fmin_con2, bound handling through BoundDomainTransform and BoundPenalty, and a comprehensive suite of Black-Box Optimization Benchmarking (BBOB) test functions.

Tokens
20.5K
Snippets
34
Records
119
Agent score
79%

What's inside pycma

  1. Overview of pycma capabilities

    development

    pycma is a Python implementation of the Covariance Matrix Adaptation Evolution Strategy (CMA-ES), a randomized derivative-free numerical optimization algorithm designed for difficult optimization problems (non-convex, ill-conditioned, multi-modal, rugged, or noisy) in continuous and mixed-integer search spaces.

    Key features include:

    • Bound constraints: Handled via the 'bounds' = [lower, upper] option or the cma.BoundDomainTransform wrapper.
    • Linear and nonlinear constraints: Handled via the constraints argument in fmin2 or fmin_con2.
    • Noise handling: Enabled via noise_handler=True in fmin2.
    • Mixed-integer problems: Handled for integer variables via the 'integer_variables'=index_list option.
  2. Install pycma from PyPI

    development

    To install the latest release of pycma from the Python Package Index (PyPI), use the following command in your system shell:

    python -m pip install cma

    To upgrade an existing installation to the latest release, use install -U instead of install.

  3. Install pycma from GitHub

    development

    You can install the development branch directly from GitHub using pip:

    pip install git+https://github.com/CMA-ES/pycma.git@development

    Alternatively, you can perform a manual installation:

    1. Clone the repository: git clone https://github.com/CMA-ES/pycma.git.
    2. Install the package in editable mode within the pycma folder:
    pip install -e .

    Note: You may need to use python -m pip or prefix commands with sudo depending on your environment permissions.

  4. Use cma.s for interactive shell shortcuts

    development

    The cma.s module provides versatile shortcuts and aliases designed for quick typing in (i)python shells. It is intended for interactive use and experimentation rather than stable code development. It includes aliases for various submodules like evolution_strategy, fitness_transformations, and transformations, as well as utility functions for plotting and inspecting objects.

    Warning: Do not use this module for stable code developments! It is not actively maintained.

  5. Use GenoPheno for genotype-phenotype transformations

    development

    The GenoPheno class manages the transformation between the optimizer's internal representation (genotype) and the representation used by the objective function (phenotype).

    By default, the transformation is the identity. The transformation process follows this order:

    1. Insertion of fixed variables.
    2. Affine linear transformation (scaling then shifting).
    3. User-defined transformation (tf[0]).
    4. Repair (e.g., boundary constraints).
    5. Re-assignment of fixed variables to their original phenotypic values.

    Use pheno(x) to map a genotype to a phenotype, and geno(y) to map a phenotype back to a genotype (the inverse).

  6. How GaussSampler eigenspectrum works

    development
    The eigenspectrum property of a GaussSampler returns the eigenvalues of the matrix $H^{1/2} C H^{1/2}$, where $H$ is the reference Hessian set via set_H. If no Hessian is set, it falls back to the eigenvalues of the covariance matrix (or variances if diagonal).
  7. How constraints are handled via Augmented Lagrangian

    development

    In pycma, constraints are typically handled by transforming a constrained problem into an unconstrained one using the AugmentedLagrangian class.

    A vector-valued constraint function $g$ defines a solution $x$ as feasible if $g_i(x) \le 0$ for all $i$. The AugmentedLagrangian constructs an objective function $L(x)$:

    $$L(x) = f(x) + \sum_i (\lambda_i g_i + \frac{\mu_i}{2}g_i^2)$$

    where $g_i := \max(g_i(x), -\lambda_i/\mu_i)$.

    Key concepts:

    • Active Constraints: Constraints where $g_i(x) = 0$. The Lagrange multipliers $\lambda_i$ for these must converge to correct values to reach the true optimum.
    • Update Mechanism: The AugmentedLagrangian.update method is used to adjust the multipliers $\lambda_i$ during optimization.
    • Feasibility: A solution is feasible if all $g_i(x) \le 0$.
  8. How CMA-ES and purecma implementations differ

    development

    The cma package provides two independent implementations of the CMA-ES algorithm:

    1. cma.CMAEvolutionStrategy (and cma.CMA): The primary implementation. It relies heavily on numpy and optionally matplotlib.pyplot for plotting. It is recommended for most users.
    2. cma.purecma.CMAES: A pure Python implementation. It can be used if numpy is not available, but it lacks the advanced features and performance of the main implementation.

    If numpy is not installed, only purecma will be available.

  9. How Mahalanobis norm is computed in samplers

    development

    The norm(x) method in both GaussFullSampler and GaussDiagonalSampler computes the Mahalanobis norm induced by the current covariance matrix $C$.

    For a GaussFullSampler, the norm is calculated as: $$\text{norm}(x) = \sqrt{\sum (B^T x / D)^2}$$ where $B$ and $D$ are the eigenvectors and square root of eigenvalues of $C$.

    For a GaussDiagonalSampler, it is: $$\text{norm}(x) = \sqrt{\sum x_i^2 / C_{ii}}$$

    The expected Mahalanobis norm for a sample drawn from the distribution is approximately $\sqrt{\text{dimension}}$.

  10. How the `Logger` class works for custom data logging

    development

    The Logger class allows you to log arbitrary data (scalars or iterables) at every timestep of an optimization run.

    Workflow:

    1. Initialization: Pass an object (like a CMAEvolutionStrategy instance) and a list of callables (functions that take the object as an argument and return a value) and labels (strings describing the values).
    2. Logging: During the optimization loop, call logger.push() as a callback. This executes the callables, logs the results, and dumps the data to disk.
    3. Loading: Use logger.load() to read previously logged data back into memory.

    Note: If you want to run without logging (silent mode), use LoggerDummy instead.

    import numpy as np
    import cma
    
    # Example: Logging best f and sigma
    for lg in [cma.logger.Logger, cma.logger.LoggerDummy]:
        es = cma.CMAEvolutionStrategy(3 * [1], 2, dict(maxiter=9, verbose=-9))
        lg = Logger(es, 
                    callables=[lambda s: s.best.f, 
                               lambda s: np.log10(np.abs(s.best.f)),
                               lambda s: np.log10(s.sigma)],
                    labels=['best f', 'lg(best f)', r'lg($\sigma$)'])
        
        # Use lg.push as the callback
        _ = es.optimize(cma.ff.sphere, callback=lg.push)
  11. Understand BBOB function noise models

    development

    The BBOB testbed includes functions with different noise characteristics. These are implemented via specific subclasses of BBOBFunction:

    • BBOBNfreeFunction: Returns the deterministic, noise-free value.
    • BBOBGaussFunction: Adds Gaussian noise (controlled by gaussbeta).
    • BBOBUniformFunction: Adds uniform noise (controlled by unifalphafac and unifbeta).
    • BBOBCauchyFunction: Adds Cauchy noise (controlled by cauchyalpha and cauchyp).

    When calling a noisy function, the evaluate(x) method returns the noisy value, while the internal _evalfull(x) method returns both the noisy and the noise-free values.

  12. How Augmented Lagrangian coefficients are updated

    development

    The ConstrainedFitnessAL class manages the transition from a constrained problem to an unconstrained one by adjusting Lagrange multipliers ($\lambda$) and penalty parameters ($\mu$).

    When update(es) is called:

    1. It retrieves the current best solution (based on the which parameter).
    2. It calculates the difference in objective and constraint values.
    3. It updates the internal AugmentedLagrangian instance, which adjusts $\lambda_i$ and $\mu_i$ for each constraint $i$.

    This process ensures that as the optimization progresses, the penalty for violating constraints increases, pushing the search towards the feasible region.