cotengra.hyperoptimizers.hyper_sbplx ==================================== .. py:module:: cotengra.hyperoptimizers.hyper_sbplx .. autoapi-nested-parse:: Hyper optimization using the Sbplx method (Rowan, 1990). Attributes ---------- .. autoapisummary:: cotengra.hyperoptimizers.hyper_sbplx._SBPLX_OMEGA Classes ------- .. autoapisummary:: cotengra.hyperoptimizers.hyper_sbplx.HyperSbplxSampler cotengra.hyperoptimizers.hyper_sbplx.SbplxOptLib Module Contents --------------- .. py:data:: _SBPLX_OMEGA :value: 0.1 .. py:class:: HyperSbplxSampler(space, seed=None, adaptive=False, alpha=1.0, gamma=2.0, rho=0.5, sigma=0.5, initial_scale=0.6, nsmin=2, nsmax=5, partition='greedy', psi=0.25, convergence_tol=0.01, filler_scale=0.3, n_initial=None, restart_patience='auto', explore_prob=0.05, inject_diameter_fraction=1.5, inject_restart_fraction=0.5, exponential_param_power=None) Sbplx optimizer in raw ``[-1, 1]`` parameter space. This is derived from Subplex (Rowan, 1990) which decomposes the full parameter space into low-dimensional subspaces (i.e. subsets of parameters) and runs Nelder-Mead (NM) on each in sequence. After all subspaces in a *cycle* are optimized, the overall convergence is checked; if the total displacement is negligible the search restarts with a jittered center. This is generally more robust that vanilla Nelder-Mead especially in higher dimensions. :param space: The search space for a single contraction method. :type space: dict[str, dict] :param seed: Random seed. :type seed: None or int, optional :param adaptive: Whether to use the adaptive NM coefficients recommended by Gao and Han (2010), which scale with problem dimension. If `True` then `alpha`, `gamma`, `rho`, and `sigma` are ignored. :type adaptive: bool, optional :param alpha: Reflection coefficient for each sub-NM. :type alpha: float, optional :param gamma: Expansion coefficient for each sub-NM. :type gamma: float, optional :param rho: Contraction coefficient for each sub-NM. :type rho: float, optional :param sigma: Shrink coefficient for each sub-NM. :type sigma: float, optional :param initial_scale: Initial step size in each dimension. :type initial_scale: float, optional :param nsmin: Minimum subspace size. Defaults to ``min(2, ndim)``. :type nsmin: int or None, optional :param nsmax: Maximum subspace size. Defaults to ``min(5, ndim)``. :type nsmax: int or None, optional :param psi: Step reduction factor applied when a subspace shows no movement, and used to scale the jitter on restart. :type psi: float, optional :param partition: Subspace partitioning strategy. ``"greedy"`` takes equal chunks of up to ``nsmax`` dimensions, shrinking only to avoid a remainder smaller than ``nsmin``. ``"goodness"`` uses Rowan's heuristic, favoring splits where average step magnitude drops sharply. Default ``"greedy"``. :type partition: str, optional :param convergence_tol: Relative convergence threshold for the overall cycle check. It is also passed as the absolute simplex diameter fallback for the inner Nelder-Mead cores. :type convergence_tol: float, optional :param filler_scale: Standard deviation of the gaussian noise used for filler points issued while the sub-NM is blocked. :type filler_scale: float, optional :param n_initial: Number of Latin Hypercube Sampled (LHS) warm-up points to evaluate before starting subplex cycling. The best result seeds the starting point. Default ``None`` means ``2 * ndim``. Set to ``0`` to disable. :type n_initial: int or None, optional :param restart_patience: Number of completed cycles without a new best score before triggering a restart. When ``"auto"`` it is chosen from the number of expected subspaces, with a minimum of 3. :type restart_patience: int or "auto", optional :param explore_prob: Probability of issuing a uniform random point instead of the NM-directed point during normal cycling. Maintains diversity throughout the search. :type explore_prob: float, optional :param inject_diameter_fraction: Passed to each sub-``_NMCore`` — controls the maximum allowed simplex diameter inflation when injecting an external vertex. :type inject_diameter_fraction: float, optional :param exponential_param_power: Passed through to the shared parameter mapping. :type exponential_param_power: float, optional .. py:attribute:: rng .. py:attribute:: params :value: [] .. py:attribute:: ndim .. py:attribute:: adaptive :value: False .. py:attribute:: alpha :value: 1.0 .. py:attribute:: gamma :value: 2.0 .. py:attribute:: rho :value: 0.5 .. py:attribute:: sigma :value: 0.5 .. py:attribute:: initial_scale :value: 0.6 .. py:attribute:: psi :value: 0.25 .. py:attribute:: convergence_tol :value: 0.01 .. py:attribute:: filler_scale :value: 0.3 .. py:attribute:: explore_prob :value: 0.05 .. py:attribute:: inject_diameter_fraction :value: 1.5 .. py:attribute:: inject_restart_fraction :value: 0.5 .. py:attribute:: nsmin .. py:attribute:: nsmax .. py:attribute:: partition :value: 'greedy' .. py:attribute:: n_initial :value: None .. py:attribute:: restart_patience :value: 'auto' .. py:attribute:: _trial_counter :value: 0 .. py:attribute:: _best_x :value: None .. py:attribute:: _best_score .. py:attribute:: _trial_map .. py:attribute:: _x .. py:attribute:: _step .. py:attribute:: _cycles_since_improvement :value: 0 .. py:attribute:: _restart_count :value: 0 .. py:attribute:: _stagnant_restart_count :value: 0 .. py:attribute:: _subspaces :value: None .. py:attribute:: _sub_idx :value: 0 .. py:attribute:: _sub_dims :value: None .. py:attribute:: _sub_nm :value: None .. py:attribute:: _sub_nm_id :value: None .. py:attribute:: _next_sub_nm_id :value: 0 .. py:attribute:: _x_at_cycle_start :value: None .. py:attribute:: _step_at_cycle_start :value: None .. py:attribute:: _best_score_at_cycle_start .. py:method:: _partition_dims() Partition dimensions into subspaces. Dimensions are first sorted by ``abs(step[d])`` descending. The partition strategy is selected by ``self.partition``: - ``"greedy"``: equal chunks of up to ``nsmax``, shrinking only to avoid a remainder smaller than ``nsmin``. - ``"goodness"``: Rowan's heuristic, favoring splits where the average step magnitude drops sharply. .. py:method:: _partition_greedy(order) Equal-chunk partitioning. .. py:method:: _partition_goodness(order, magnitudes) Rowan's goodness heuristic partitioning. .. py:method:: _clamp_scale_factor(factor) .. py:method:: _start_cycle() Snapshot the current point and begin a new cycle. .. py:method:: _start_sub_nm() Create a ``_NMCore`` for the current subspace. .. py:method:: _cycle_converged() .. py:method:: _embed_sub_vector(sub_x) Embed a subspace vector into a full-dimensional point, keeping non-subspace dimensions at their current values in ``_x``. .. py:method:: _ask_filler() .. py:method:: _rescale_step(step, factor, minimum=0.0) .. py:method:: _reset_cycle_state() .. py:method:: _restart(mode) Restart the search either locally around the best point or by re-expanding globally. :param mode: Restart mode. Local restarts jitter near the best known point while preserving step geometry. Global restarts jump to a random point and reset step sizes to ``initial_scale``. :type mode: {"local", "global"} .. py:method:: ask() Return the next candidate setting. During the LHS warm-up phase, pre-generated Latin Hypercube points are issued one at a time. Once all warm-up results have been collected, normal subplex cycling begins from the best warm-up point. During cycling, with probability ``explore_prob`` a uniform random point is returned to maintain diversity. If the active sub-NM is blocked waiting for results, a filler point is returned instead. .. py:method:: tell(trial_number, score) Record a completed trial result. .. py:method:: _finish_subspace() Extract the sub-NM result, update the full point and step vector, then advance to the next subspace or finish the cycle. .. py:method:: _update_steps_after_cycle() .. py:method:: _finish_cycle() Check overall convergence across all subspaces. Following the NLopt Sbplx logic, convergence is based on a relative per-dimension test using both the cycle displacement and the current step size. Repeated non-improving cycles still trigger restarts to preserve the asynchrcoonous wrapper behavior. .. py:class:: SbplxOptLib Bases: :py:obj:`cotengra.hyperoptimizers.hyper.HyperOptLib` Hyper-optimization backend using the 'Sbplx' method adapted from the Subplex method (Rowan, 1990). .. py:method:: setup(methods, space, optimizer=None, adaptive=False, alpha=1.0, gamma=2.0, rho=0.5, sigma=0.5, initial_scale=0.6, nsmin=2, nsmax=5, partition='greedy', psi=0.25, convergence_tol=0.01, filler_scale=0.3, n_initial=None, restart_patience='auto', explore_prob=0.05, inject_diameter_fraction=1.5, inject_restart_fraction=0.5, method_exploration=1.0, method_temperature=1.0, exponential_param_power=None, seed=None, **kwargs) Initialize Sbplx optimizers for each method. :param methods: The contraction methods to optimize over. :type methods: list[str] :param space: The per-method hyperparameter search space. :type space: dict[str, dict[str, dict]] :param optimizer: The parent optimizer. :type optimizer: HyperOptimizer, optional :param adaptive: Whether to use the adaptive NM coefficients recommended by Gao and Han (2010), which scale with problem dimension. If `True` then `alpha`, `gamma`, `rho`, and `sigma` are ignored. :type adaptive: bool, optional :param alpha: Reflection coefficient for each sub-NM. :type alpha: float, optional :param gamma: Expansion coefficient for each sub-NM. :type gamma: float, optional :param rho: Contraction coefficient for each sub-NM. :type rho: float, optional :param sigma: Shrink coefficient for each sub-NM. :type sigma: float, optional :param initial_scale: Scale of the initial simplex. :type initial_scale: float, optional :param nsmin: Minimum subspace size. :type nsmin: int or None, optional :param nsmax: Maximum subspace size. :type nsmax: int or None, optional :param partition: Subspace partitioning strategy. ``"greedy"`` or ``"goodness"``. Default ``"greedy"``. :type partition: str, optional :param psi: Step reduction factor. :type psi: float, optional :param convergence_tol: Convergence threshold for sub-NM and cycle check. :type convergence_tol: float, optional :param filler_scale: Gaussian noise scale for filler points. :type filler_scale: float, optional :param n_initial: Number of LHS warm-up points per method. Default ``None`` means ``2 * ndim``. Set to ``0`` to disable. :type n_initial: int or None, optional :param restart_patience: Number of completed non-improving cycles before restarting. When ``"auto"`` it is chosen from the expected number of subspaces, with a minimum of 3. :type restart_patience: int or "auto", optional :param explore_prob: Probability of issuing a uniform random exploration point during normal cycling. :type explore_prob: float, optional :param inject_diameter_fraction: Passed to each sub-``_NMCore`` — controls the maximum allowed simplex diameter inflation when injecting an external vertex. :type inject_diameter_fraction: float, optional :param inject_restart_fraction: Passed to each sub-``_NMCore`` — controls th XXX :type inject_restart_fraction: float, optional :param method_exploration: Exploration strength for the LCB method chooser. :type method_exploration: float, optional :param method_temperature: Noise temperature for the LCB method chooser. :type method_temperature: float, optional :param exponential_param_power: Passed to the shared parameter mapping. :type exponential_param_power: float, optional :param seed: Random seed. :type seed: None or int, optional .. py:method:: get_setting() Choose a method, then request its next setting. .. py:method:: report_result(setting, trial, score) Report a completed trial back to the method chooser and the per-method Sbplx sampler.