Пример #1
0
    def test_template_add_cov_mat(self):
        template = Template("test", self.var, self.num_bins, self.limits,
                            self.df)

        stat_cov_mat = np.diag(self.x_errors**2)
        cov_mat = np.array([[2, 1, 0], [1, 3, 0], [0, 0, 1]])
        expected_cov_mat = stat_cov_mat + cov_mat

        template.add_covariance_matrix(cov_mat)

        new_x_errors = np.sqrt(np.diag(expected_cov_mat))
        np.testing.assert_array_equal(template._relative_errors,
                                      new_x_errors / self.x_hist)
        np.testing.assert_array_almost_equal(template._cov, expected_cov_mat)
        np.testing.assert_array_almost_equal(template._corr,
                                             cov2corr(expected_cov_mat))
        np.testing.assert_array_almost_equal(
            template._inv_corr, np.linalg.inv(cov2corr(expected_cov_mat)))
Пример #2
0
    def _add_cov_mat(self, cov_mat):
        """Helper function. Calculates a covariance matrix from
        given histogram up and down variations.
        """

        self._cov_mats.append(np.copy(cov_mat))

        self._cov += cov_mat
        self._corr = cov2corr(self._cov)
        self._inv_corr = np.linalg.inv(self._corr)
        self._relative_errors = np.divide(
            np.sqrt(np.diag(self._cov)),
            self._flat_bin_counts,
            out=np.full(self._num_bins, 1e-7),
            where=self._flat_bin_counts != 0,
        )
Пример #3
0
    def add_covariance_matrix(self, covariance_matrix):
        """Add a covariance matrix for a systematic error to this template.
        This updates the total covariance matrix, the correlation matrix and
        the relative bin errors.

        Parameters
        ----------
        covariance_matrix : numpy.ndarray
            A covariance matrix. It is not checked if the matrix is
            valid (symmetric, positive semi-definite. Shape is
            (`num_bins`, `num_bins`).
        """
        self._cov += covariance_matrix
        self._corr = cov2corr(self._cov)
        self._inv_corr = np.linalg.inv(self._corr)
        self._relative_errors = np.divide(
            np.sqrt(np.diag(self._cov)),
            self._hist.bin_counts,
            out=np.full(self.num_bins, 1e-7),
            where=self._hist.bin_counts != 0,
        )
Пример #4
0
    def minimize(self,
                 initial_param_values: np.ndarray,
                 verbose: bool = False,
                 additional_args: Tuple[Any] = (),
                 get_hesse: bool = True) -> MinimizeResult:
        """
        Performs minimization of given objective function.

        Parameters
        ----------
        initial_param_values : np.ndarray or list of floats
            Initial values for the parameters used as starting values.
            Shape is (`num_params`,).
        additional_args : tuple
            Tuple of additional arguments for the objective function.
        get_hesse : bool
            If True, the Hesse matrix is estimated at the minimum
            of the objective function. This allows the calculation
            of parameter errors. Default is True.
        verbose: bool
            If True, a convergence message is printed. Default is False.

        Returns
        -------
        MinimizeResult
        """
        constraints = self._create_constraints(initial_param_values)

        opt_result = minimize(
            fun=self._fcn,
            x0=initial_param_values,
            args=additional_args,
            method="SLSQP",
            bounds=self._param_bounds,
            constraints=constraints,
            options={"disp": verbose},
        )

        self._success = opt_result.success
        self._status = opt_result.status
        self._message = opt_result.message

        if not opt_result.success:
            raise RuntimeError(f"Minimization was not successful.\n"
                               f"Status: {opt_result.status}\n"
                               f"Message: {opt_result.message}")

        self._params.values = opt_result.x
        self._fcn_min_val = opt_result.fun

        if get_hesse:
            hesse = ndt.Hessian(self._fcn)(self._params.values,
                                           *additional_args)
            self._params.covariance = np.linalg.inv(hesse)
            self._params.correlation = cov2corr(self._params.covariance)
            self._params.errors = np.sqrt(np.diag(self._params.covariance))

        if verbose:
            print(self._params)

        result = MinimizeResult(opt_result.fun, self._params, self._success)

        return result
Пример #5
0
    def minimize(
        self,
        initial_param_values: np.ndarray,
        verbose: bool = False,
        error_def: float = 0.5,
        additional_args: Optional[Tuple[Any, ...]] = None,
        get_hesse: bool = True,
        check_success: bool = True,
    ) -> MinimizeResult:
        """
        Performs minimization of given objective function.

        Parameters
        ----------
        initial_param_values : np.ndarray or list of floats
            Initial values for the parameters used as starting values.
            Shape is (`num_params`,).
        error_def : Not used for this implementation
        additional_args : tuple
            Tuple of additional arguments for the objective function.
        get_hesse : bool
            If True, the Hesse matrix is estimated at the minimum
            of the objective function. This allows the calculation
            of parameter errors. Default is True.
        verbose: bool
            If True, a convergence message is printed. Default is False.
        check_success: bool
            Check if fit was successful and raise if not! Default: True

        Returns
        -------
        MinimizeResult
        """
        constraints = self._create_constraints(initial_param_values)

        _additional_args = tuple([])  # type: Tuple[Any, ...]
        if additional_args is not None:
            _additional_args = additional_args

        logging.info(
            f"Starting SciPy minimization with {sum(~np.array(self.params.fixed_params))} floating and {sum(self.params.fixed_params)} fixed parameters."
        )
        opt_result = scipy_minimize(
            fun=self._fcn,
            x0=initial_param_values,
            args=additional_args,
            method="SLSQP",
            bounds=self._param_bounds,
            constraints=constraints,  # type: ignore
            options={"disp": verbose},
        )

        logging.info(
            f"Finished SciPy minimization with success = {opt_result.success}, status {opt_result.status} and message {opt_result.message}."
        )

        self._success = opt_result.success
        self._status = opt_result.status
        self._message = opt_result.message

        if not opt_result.success:
            raise RuntimeError(
                "Minimization was not successful.\n",
                f"Status: {opt_result.status}\n",
                f"Message: {opt_result.message}",
            )

        self._params.values = opt_result.x
        self._fcn_min_val = opt_result.fun

        if get_hesse:
            logging.info("Calculating Hesse Matrix for SciPy minimization.")
            hesse = ndt.Hessian(self._fcn)(self._params.values,
                                           *_additional_args)
            self._params.covariance = np.linalg.inv(hesse)
            self._params.correlation = cov2corr(self._params.covariance)
            self._params.errors = np.sqrt(np.diag(self._params.covariance))
            logging.info(
                "Finished calculation of Hesse Matrix for SciPy minimization.")

        if verbose:
            print(self._params)

        if check_success:
            pass  # TODO

        assert self._success is not None
        result = MinimizeResult(fcn_min_val=opt_result.fun,
                                params=self._params,
                                success=self._success)

        return result
Пример #6
0
    def bin_correlation_matrix(self) -> np.ndarray:
        if self._bin_correlation_matrix is not None:
            return self._bin_correlation_matrix

        self._bin_correlation_matrix = cov2corr(self.bin_covariance_matrix)
        return self._bin_correlation_matrix