Source code for pypesto.profile.options

import warnings
from typing import Union

#: Deprecated ``ProfileOptions`` step-size names mapped to their replacements.
#: Kept for backward compatibility, both as constructor arguments and as
#: attributes.
_DEPRECATED_STEP_SIZE_NAMES = {
    "default_step_size": "default_step_size_absolute",
    "min_step_size": "min_step_size_absolute",
    "max_step_size": "max_step_size_absolute",
}


[docs] class ProfileOptions(dict): """ Options for optimization based profiling. Step sizes can be configured as absolute values or relative fractions of the parameter span. A family is disabled by setting its default step size to `0`. For each profiled parameter, pyPESTO uses either the full absolute family or the full relative family, whichever has the larger default step size, i.e. whichever of `default_step_size_absolute` and `default_step_size_relative * (ub - lb)` is larger. Attributes ---------- default_step_size_absolute: Default absolute profile step size. Set to `0` to disable. default_step_size_relative: Default relative profile step size, as fraction of `ub - lb`. Set to `0` to disable. min_step_size_absolute: Minimum absolute step size in adaptive methods. min_step_size_relative: Minimum relative step size, as fraction of `ub - lb`. max_step_size_absolute: Maximum absolute step size in adaptive methods. max_step_size_relative: Maximum relative step size, as fraction of `ub - lb`. step_size_factor: Adaptive methods recompute the likelihood at the predicted point and try to find a good step length by a sort of line search algorithm. This factor controls step handling in this line search. delta_ratio_max: Maximum allowed drop of the posterior ratio between two profile steps. ratio_min: Lower bound for likelihood ratio of the profile, based on inverse chi2-distribution. The default 0.145 is slightly lower than the 95% quantile 0.1465 of a chi2 distribution with one degree of freedom. reg_points: Number of profile points used for regression in regression based adaptive profile points proposal. reg_order: Maximum degree of regression polynomial used in regression based adaptive profile points proposal. adaptive_target_scaling_factor: The scaling factor of the next_obj_target in next guess generation. Larger values result in larger next_guess step size (must be > 1). whole_path: Whether to profile the whole bounds or only till we get below the ratio. step_size_precheck_mode: Controls the step-size precheck, which estimates how many profile steps the resolved step sizes imply and reports suspiciously small steps. One of ``"off"`` (disable the precheck), ``"warn"`` (only ever emit a warning), or ``"raise"`` (raise an error only for extreme, worst-case estimates, and warn otherwise). """
[docs] def __init__( self, default_step_size_absolute: float = 0.02, default_step_size_relative: float = 0.0025, min_step_size_absolute: float = 0.01, min_step_size_relative: float = 0.00125, max_step_size_absolute: float = 0.2, max_step_size_relative: float = 0.025, step_size_factor: float = 1.25, delta_ratio_max: float = 0.1, ratio_min: float = 0.145, reg_points: int = 10, reg_order: int = 4, adaptive_target_scaling_factor: float = 1.5, whole_path: bool = False, step_size_precheck_mode: str = "warn", default_step_size: float | None = None, min_step_size: float | None = None, max_step_size: float | None = None, ): super().__init__() # Backward compatibility: the absolute step-size arguments were # renamed. If an old name is passed, it overrides the new one. if default_step_size is not None: warnings.warn( "`default_step_size` is deprecated. Use " "`default_step_size_absolute` instead.", DeprecationWarning, stacklevel=2, ) default_step_size_absolute = default_step_size if min_step_size is not None: warnings.warn( "`min_step_size` is deprecated. Use " "`min_step_size_absolute` instead.", DeprecationWarning, stacklevel=2, ) min_step_size_absolute = min_step_size if max_step_size is not None: warnings.warn( "`max_step_size` is deprecated. Use " "`max_step_size_absolute` instead.", DeprecationWarning, stacklevel=2, ) max_step_size_absolute = max_step_size self.default_step_size_absolute = default_step_size_absolute self.default_step_size_relative = default_step_size_relative self.min_step_size_absolute = min_step_size_absolute self.min_step_size_relative = min_step_size_relative self.max_step_size_absolute = max_step_size_absolute self.max_step_size_relative = max_step_size_relative self.ratio_min = ratio_min self.step_size_factor = step_size_factor self.delta_ratio_max = delta_ratio_max self.reg_points = reg_points self.reg_order = reg_order self.adaptive_target_scaling_factor = adaptive_target_scaling_factor self.whole_path = whole_path self.step_size_precheck_mode = step_size_precheck_mode self.validate()
def __getattr__(self, key): """Allow usage of keys like attributes.""" if key in _DEPRECATED_STEP_SIZE_NAMES: new_key = _DEPRECATED_STEP_SIZE_NAMES[key] warnings.warn( f"`{key}` is deprecated. Use `{new_key}` instead.", DeprecationWarning, stacklevel=2, ) return self[new_key] try: return self[key] except KeyError: raise AttributeError(key) from None __setattr__ = dict.__setitem__ __delattr__ = dict.__delitem__
[docs] @staticmethod def create_instance( maybe_options: Union["ProfileOptions", dict], ) -> "ProfileOptions": """ Return a valid options object. Parameters ---------- maybe_options: ProfileOptions or dict """ if isinstance(maybe_options, ProfileOptions): return maybe_options options = ProfileOptions(**maybe_options) return options
[docs] def validate(self): """Check if options are valid. Raises ``ValueError`` if current settings aren't valid. """ def validate_step_size_family(family: str) -> bool: default_step_size = self[f"default_step_size_{family}"] min_step_size = self[f"min_step_size_{family}"] max_step_size = self[f"max_step_size_{family}"] if default_step_size < 0: raise ValueError(f"default_step_size_{family} must be >= 0.") if default_step_size == 0: return False if min_step_size <= 0: raise ValueError(f"min_step_size_{family} must be > 0.") if max_step_size <= 0: raise ValueError(f"max_step_size_{family} must be > 0.") if min_step_size > default_step_size: raise ValueError( f"min_step_size_{family} must be <= " f"default_step_size_{family}." ) if default_step_size > max_step_size: raise ValueError( f"default_step_size_{family} must be <= " f"max_step_size_{family}." ) return True absolute_enabled = validate_step_size_family("absolute") relative_enabled = validate_step_size_family("relative") if not absolute_enabled and not relative_enabled: raise ValueError( "At least one step-size family must be enabled by setting " "default_step_size_absolute > 0 or " "default_step_size_relative > 0." ) if self.adaptive_target_scaling_factor < 1: raise ValueError("adaptive_target_scaling_factor must be > 1.") if self.step_size_precheck_mode not in {"off", "warn", "raise"}: raise ValueError( "step_size_precheck_mode must be one of " "{'off', 'warn', 'raise'}." )