:py:mod:`qsearch.persistent_aposmm` =================================== .. py:module:: qsearch.persistent_aposmm .. autoapi-nested-parse:: This module contains methods used our implementation of the Asynchronously Parallel Optimization Solver for finding Multiple Minima (APOSMM) method. `https://doi.org/10.1007/s12532-017-0131-4 `_ This implementation of APOSMM was developed by Kaushik Kulkarni and Jeffrey Larson in the summer of 2019. Module Contents --------------- Functions ~~~~~~~~~ .. autoapisummary:: qsearch.persistent_aposmm.aposmm qsearch.persistent_aposmm.update_history_dist qsearch.persistent_aposmm.decide_where_to_start_localopt qsearch.persistent_aposmm.initialize_APOSMM .. py:function:: aposmm(H, persis_info, gen_specs, libE_info) APOSMM coordinates multiple local optimization runs, starting from points which do not have a better point nearby (within a distance ``r_k``). This generation function uses a ``local_H`` (serving a similar purpose as ``H`` in libEnsemble) containing the fields: - ``'x' [n floats]``: Parameters being optimized over - ``'x_on_cube' [n floats]``: Parameters scaled to the unit cube - ``'f' [float]``: Objective function being minimized - ``'local_pt' [bool]``: True if point from a local optimization run - ``'dist_to_unit_bounds' [float]``: Distance to domain boundary - ``'dist_to_better_l' [float]``: Dist to closest better local opt point - ``'dist_to_better_s' [float]``: Dist to closest better sample point - ``'ind_of_better_l' [int]``: Index of point ``'dist_to_better_l``' away - ``'ind_of_better_s' [int]``: Index of point ``'dist_to_better_s``' away - ``'started_run' [bool]``: True if point has started a local opt run - ``'num_active_runs' [int]``: Number of active local runs point is in - ``'local_min' [float]``: True if point has been ruled a local minima - ``'sim_id' [int]``: Row number of entry in history and optionally - ``'fvec' [m floats]``: All objective components (if performing a least-squares calculation) - ``'grad' [n floats]``: The gradient (if available) of the objective with respect to `x`. Note: - If any of the above fields are desired after a libEnsemble run, name them in ``gen_specs['out']``. - If intitializing APOSMM with past function values, make sure to include ``'x'``, ``'x_on_cube'``, ``'f'``, ``'local_pt'``, etc. in ``gen_specs['in']`` (and, of course, include them in the H0 array given to libensemble). Necessary quantities in ``gen_specs['user']`` are: - ``'lb' [n floats]``: Lower bound on search domain - ``'ub' [n floats]``: Upper bound on search domain - ``'localopt_method' [str]``: Name of an NLopt, PETSc/TAO, or SciPy method (see 'advance_local_run' below for supported methods) - ``'initial_sample_size' [int]``: Number of uniformly sampled points must be returned (non-nan value) before a local opt run is started. Can be zero if no additional sampling is desired, but if zero there must be past sim_f values given to libEnsemble in H0. Optional ``gen_specs['user']`` entries are: - ``'sample_points' [numpy array]``: Points to be sampled (original domain). If more sample points are needed by APOSMM during the course of the optimization, points will be drawn uniformly over the domain - ``'components' [int]``: Number of objective components - ``'dist_to_bound_multiple' [float in (0,1]]``: What fraction of the distance to the nearest boundary should the initial step size be in localopt runs - ``'lhs_divisions' [int]``: Number of Latin hypercube sampling partitions (0 or 1 results in uniform sampling) - ``'mu' [float]``: Distance from the boundary that all localopt starting points must satisfy - ``'nu' [float]``: Distance from identified minima that all starting points must satisfy - ``'rk_const' [float]``: Multiplier in front of the r_k value - ``'max_active_runs' [int]``: Bound on number of runs APOSMM is advancing If the rules in ``decide_where_to_start_localopt`` produces more than ``'max_active_runs'`` in some iteration, then existing runs are prioritized. And ``gen_specs['user']`` must also contain fields for the given localopt_method's convergence tolerances (e.g., gatol/grtol for PETSC/TAO or ftol_rel for NLopt) .. seealso:: `test_persistent_aposmm_scipy `_ for basic APOSMM usage. .. seealso:: `test_persistent_aposmm_with_grad `_ for an example where past function values are given to libEnsemble/APOSMM. .. py:function:: update_history_dist(H, n) Updates distances/indices after new points that have been evaluated. .. seealso:: `start_persistent_local_opt_gens.py `_ .. py:function:: decide_where_to_start_localopt(H, n, n_s, rk_const, ld=0, mu=0, nu=0) APOSMM starts a local optimization runs from a point that: - is not in an active local optimization run, - is more than ``mu`` from the boundary (in the unit-cube domain), - is more than ``nu`` from identified minima (in the unit-cube domain), - does not have a better point within a distance ``r_k`` of it. For further details, see the conditions (S1-S5 and L1-L8) in Table 1 of the `APOSMM paper `_ This method first identifies sample points satisfying S2-S5, and then identifies all localopt points that satisfy L1-L7. We then start from any sample point also satisfying S1. We do not check condition L8 currently. We don't consider points in the history that have not returned from computation, or that have a ``nan`` value. As APOSMM works on the unit cube, note that ``mu`` and ``nu`` implicitly depend on the scaling of the original domain: adjusting the initial domain can make a run start (or not start) at a point that didn't (or did) previously. :param H: History array storing rows for each point. :type H: numpy structured array :param n: Problem dimension :type n: int :param n_s: Number of sample points in H :type n_s: int :param r_k_const: Radius for deciding when to start runs :type r_k_const: float :param ld: Number of Latin hypercube sampling divisions (0 or 1 means uniform random sampling over the domain) :type ld: integer :param mu: Distance from the boundary that all starting points must satisfy :type mu: nonnegative float :param nu: Distance from identified minima that all starting points must satisfy :type nu: nonnegative float :returns: **start_inds** -- Indices where a local opt run should be started, sorted by increasing function value. :rtype: list .. seealso:: `start_persistent_local_opt_gens.py `_ .. py:function:: initialize_APOSMM(H, user_specs, libE_info) Computes common values every time that APOSMM is reinvoked .. seealso:: `start_persistent_local_opt_gens.py `_