Пример #1
0
    def _minimize(self, compute_covar=True):

        # Minimize with MIGRAD

        success = self.minimizer.Minimize()

        if not success:

            # Get status
            status = self.minimizer.Status()

            if status in _status_translation:

                msg = "MIGRAD did not converge. Reason: %s (status: %i)" % (
                    _status_translation[status], status)

            else:

                msg = "MIGRAD failed with status %i " \
                      "(see https://root.cern.ch/root/html/ROOT__Minuit2__Minuit2Minimizer.html)" % status

            raise FitFailed(msg)

        # Gather results

        minimum = self.minimizer.MinValue()

        best_fit_values = np.array(
            map(lambda x: x[0], zip(self.minimizer.X(), range(self.Npar))))

        return best_fit_values, minimum
Пример #2
0
    def _minimize(self):
        """
        Minimize the function using MIGRAD

        :param compute_covar: whether to compute the covariance (and error estimates) or not
        :return: best_fit: a dictionary containing the parameters at their best fit values
                 function_minimum : the value for the function at the minimum

                 NOTE: if the minimization fails, the dictionary will be empty and the function_minimum will be set
                 to minimization.FIT_FAILED
        """

        # Try a maximum of 10 times and break as soon as the fit is ok

        self.minuit.reset()
        self._last_migrad_results = self.minuit.migrad()

        for i in range(9):

            if self.minuit.valid:

                break

            else:

                # Try again
                self._last_migrad_results = self.minuit.migrad()

        if not self.minuit.valid:

            self._print_current_status()

            raise FitFailed(
                "MIGRAD call failed. This is usually due to unconstrained parameters."
            )

        else:

            # Gather the optimized values for all parameters from the internal
            # iminuit dictionary

            best_fit_values = []

            for k, par in self.parameters.items():

                minuit_name = self._parameter_name_to_minuit_name(k)

                best_fit_values.append(self.minuit.values[minuit_name])

            return best_fit_values, self.minuit.fval
Пример #3
0
    def _minimize(self):

        # Build initial point
        x0 = []
        bounds = []
        minima = []
        maxima = []

        for i, (par_name,
                (cur_value, cur_delta, cur_min,
                 cur_max)) in enumerate(self._internal_parameters.items()):

            x0.append(cur_value)

            # scipy's algorithms will always try to evaluate the function exactly at the boundaries, which will
            # fail because the Jacobian is not defined there... let's fix this by using a slightly larger or smaller
            # minimum and maximum within the scipy algorithm than the real boundaries (saved in minima and maxima)

            minima.append(cur_min)
            maxima.append(cur_max)

            if cur_min is not None:

                cur_min = cur_min + 0.00005 * abs(cur_min)

            if cur_max is not None:

                cur_max = cur_max - 0.00005 * abs(cur_max)

            bounds.append((cur_min, cur_max))

        def wrapper(x):

            if not self._check_bounds(x, minima, maxima):

                return np.inf

            return self.function(*x)

        def wrapper_2(*x):

            return wrapper(x)

        def jacobian(x):

            if not self._check_bounds(x, minima, maxima):

                return np.inf

            jacv = get_jacobian(wrapper_2, x, minima, maxima)

            return jacv

        res = scipy.optimize.minimize(
            wrapper,
            np.array(x0),
            method=self._setup_dict["algorithm"],
            bounds=bounds,
            jac=jacobian,
            tol=self._setup_dict["tol"],
        )

        # Make sure the optimization worked

        if not res.success:

            raise FitFailed(
                "Could not converge. Message from solver: %s (status: %i)" %
                (res.message, res.status))

        # Transform the result to numpy.array

        best_fit_values = np.array(res.x)

        return best_fit_values, float(res.fun)