From 4412a768f618a4da6a4b75ccf2e8ca303bd15864 Mon Sep 17 00:00:00 2001 From: Giordon Stark Date: Wed, 26 Jun 2024 08:31:59 -0500 Subject: [PATCH 1/2] initial attempt to handle warnings at bounds --- src/pyhf/optimize/mixins.py | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/src/pyhf/optimize/mixins.py b/src/pyhf/optimize/mixins.py index 19e150f069..b43b8c13b8 100644 --- a/src/pyhf/optimize/mixins.py +++ b/src/pyhf/optimize/mixins.py @@ -67,15 +67,30 @@ def _internal_minimize( raise exceptions.FailedMinimization(result) return result - def _internal_postprocess(self, fitresult, stitch_pars, return_uncertainties=False): + def _internal_postprocess( + self, fitresult, stitch_pars, /, par_bounds, *, return_uncertainties=False + ): """ Post-process the fit result. + Args: + fitresult (scipy.optimize.OptimizeResult): Fit result from :func:`_internal_minimize` + stitch_pars (:obj:`func`): callable that stitches fixed parameters into the unfixed parameters + par_bounds (:obj:`list` of :obj:`list`/:obj:`tuple`): The extrema of values the model parameters + are allowed to reach in the fit. + The shape should be ``(n, 2)`` for ``n`` model parameters. + return_uncertainties (:obj:`bool`): Return uncertainties on the fitted parameters. Default is off (``False``). + Returns: fitresult (scipy.optimize.OptimizeResult): A modified version of the fit result. """ tensorlib, _ = get_backend() + # TODO: check how to handle this for batching + for par_index, (fitted_par, bound) in enumerate(zip(fitresult.x, par_bounds)): + if fitted_par in bound: + log.warning(f'parameter at index {par_index} is at the bounds') + # stitch in missing parameters (e.g. fixed parameters) fitted_pars = stitch_pars(tensorlib.astensor(fitresult.x)) @@ -195,7 +210,10 @@ def minimize( **minimizer_kwargs, options=kwargs, par_names=par_names ) result = self._internal_postprocess( - result, stitch_pars, return_uncertainties=return_uncertainties + result, + stitch_pars, + par_bounds=minimizer_kwargs['bounds'], + return_uncertainties=return_uncertainties, ) _returns = [result.x] From 071c32a711967781affc6d542c015216b91169a3 Mon Sep 17 00:00:00 2001 From: Giordon Stark Date: Wed, 26 Jun 2024 08:33:15 -0500 Subject: [PATCH 2/2] add additional todo comments --- src/pyhf/optimize/mixins.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/pyhf/optimize/mixins.py b/src/pyhf/optimize/mixins.py index b43b8c13b8..34f4155051 100644 --- a/src/pyhf/optimize/mixins.py +++ b/src/pyhf/optimize/mixins.py @@ -87,6 +87,8 @@ def _internal_postprocess( tensorlib, _ = get_backend() # TODO: check how to handle this for batching + # TODO: handle skipping fixed parameters + # TODO: handle various backends for par_index, (fitted_par, bound) in enumerate(zip(fitresult.x, par_bounds)): if fitted_par in bound: log.warning(f'parameter at index {par_index} is at the bounds')