예제 #1
0
def test_errordef():
    m = Minuit(lambda x: x ** 2, 0)
    m.errordef = 4
    assert m.errordef == 4
    m.migrad()
    m.hesse()
    assert_allclose(m.errors["x"], 2)
    m.errordef = 1
    m.hesse()
    assert_allclose(m.errors["x"], 1)
    with pytest.raises(ValueError):
        m.errordef = 0
예제 #2
0
def test_parameter_at_limit(sign):
    m = Minuit(lambda x: (x - sign * 1.2) ** 2, x=0)
    m.errordef = 1
    m.limits["x"] = (-1, 1)
    m.migrad()
    assert m.values["x"] == approx(sign * 1.0, abs=1e-3)
    assert m.fmin.has_parameters_at_limit is True

    m = Minuit(lambda x: (x - sign * 1.2) ** 2, x=0)
    m.errordef = 1
    m.migrad()
    assert m.values["x"] == approx(sign * 1.2, abs=1e-3)
    assert m.fmin.has_parameters_at_limit is False
예제 #3
0
def test_hesse_without_migrad():
    m = Minuit(lambda x: x ** 2 + x ** 4, x=0)
    m.errordef = 0.5
    # second derivative: 12 x^2 + 2
    m.hesse()
    assert m.errors["x"] == approx(0.5 ** 0.5, abs=1e-4)
    m.values["x"] = 1
    m.hesse()
    assert m.errors["x"] == approx((1.0 / 14.0) ** 0.5, abs=1e-4)
    assert m.fmin is None

    m = Minuit(lambda x: 0, 0)
    m.errordef = 1
    with pytest.raises(RuntimeError):
        m.hesse()
예제 #4
0
def test_params():
    m = Minuit(func0, x=1, y=2)
    m.errordef = Minuit.LEAST_SQUARES
    m.errors = (3, 4)
    m.fixed["x"] = True
    m.limits["y"] = (None, 10)

    # these are the initial param states
    expected = (
        Param(0, "x", 1.0, 3.0, None, False, True, False, False, False, None, None),
        Param(1, "y", 2.0, 4.0, None, False, False, True, False, True, None, 10),
    )
    assert m.params == expected

    m.migrad()
    m.minos()
    assert m.init_params == expected

    expected = [
        Namespace(number=0, name="x", value=1.0, error=3.0, merror=(-3.0, 3.0)),
        Namespace(number=1, name="y", value=5.0, error=1.0, merror=(-1.0, 1.0)),
    ]

    params = m.params
    for i, exp in enumerate(expected):
        p = params[i]
        assert p.number == exp.number
        assert p.name == exp.name
        assert p.value == approx(exp.value, rel=1e-2)
        assert p.error == approx(exp.error, rel=1e-2)
        assert p.error == approx(exp.error, rel=1e-2)
예제 #5
0
    def fit(self, fit_params):
        """
        Performs the fitting procedure.

        Parameters
        ----------
        fit_params: array
            Parameters used to compute the likelihood but not fitted

        """
        def f(*args):
            return -2 * self.log_likelihood(*args, fit_params=fit_params)

        print_level = 2 if self.verbose in [1, 2, 3] else 0
        m = Minuit(f,
                   name=self.names_parameters,
                   *self.start_parameters.values())
        for key, val in self.bound_parameters.items():
            m.limits[key] = val
        m.print_level = print_level
        m.errordef = 0.5
        m.simplex().migrad()
        self.end_parameters = m.values.to_dict()
        self.fcn = m.fval
        self.error_parameters = m.errors.to_dict()
예제 #6
0
def test_bad_functions_np(func, expected):
    m = Minuit(lambda x: 0, (1, 1), grad=func)
    m.errordef = 1
    m.throw_nan = True
    with pytest.raises(type(expected)) as excinfo:
        m.migrad()
    assert str(expected) in str(excinfo.value)
예제 #7
0
def test_bad_functions(func, expected):
    m = Minuit(func, x=1)
    m.errordef = 1
    m.throw_nan = True
    with pytest.raises(type(expected)) as excinfo:
        m.migrad()
    assert str(expected) in str(excinfo.value)
예제 #8
0
def test_mncontour_with_fixed_var():
    m = Minuit(lambda x, y: 0, x=0, y=0)
    m.errordef = 1
    m.fixed["x"] = True
    m.migrad()
    with pytest.raises(ValueError):
        m.mncontour("x", "y")
예제 #9
0
def MinForReplica():
    global totalN,setDY,initialValues,initialErrors,searchLimits,parametersToMinimize
        
    def repchi_2(x):        
        global totalN
        startT=time.time()
        harpy.setNPparameters(x)
        print('np set =',["{:8.3f}".format(i) for i in x], end =" ")    
        
        ccDY2,cc2=DataProcessor.harpyInterface.ComputeChi2(repDataDY)
        if(usePenaltyTerm): ccDY2+=totalN*PenaltyTerm(x)
        
        cc=(ccDY2)/totalN
        endT=time.time()
        print(':->',cc,'       t=',endT-startT)
        return ccDY2
    
    repDataDY=setDY.GenerateReplica()
    
    localM = Minuit(repchi_2, initialValues)
    
    localM.errors=initialErrors
    localM.limits=searchLimits
    localM.fixed=parametersToMinimize
    localM.errordef=1    
    localM.tol=0.0001*totalN*10000 ### the last 0.0001 is to compensate MINUIT def
    localM.strategy=1

    localM.migrad()
    
    ### [chi^2, NP-parameters]
    return [localM.fval,list(localM.values)]
예제 #10
0
def _curve_fit_wrapper(
    func: Callable[..., Any],
    xdata: np.typing.NDArray[Any],
    ydata: np.typing.NDArray[Any],
    yerr: np.typing.NDArray[Any],
    likelihood: bool = False,
) -> tuple[tuple[float, ...], np.typing.NDArray[Any]]:
    """
    Wrapper around `scipy.optimize.curve_fit`. Initial parameters (`p0`)
    can be set in the function definition with defaults for kwargs
    (e.g., `func = lambda x,a=1.,b=2.: x+a+b`, will feed `p0 = [1.,2.]` to `curve_fit`)
    """
    try:
        from scipy.optimize import curve_fit, minimize
    except ModuleNotFoundError:
        print(_PLT_MISSING_MSG, file=sys.stderr)
        raise

    params = list(inspect.signature(func).parameters.values())
    p0 = [
        1 if arg.default is inspect.Parameter.empty else arg.default
        for arg in params[1:]
    ]

    mask = yerr != 0.0
    popt, pcov = curve_fit(
        func,
        xdata[mask],
        ydata[mask],
        sigma=yerr[mask],
        absolute_sigma=True,
        p0=p0,
    )
    if likelihood:
        try:
            from iminuit import Minuit
        except ModuleNotFoundError:
            print(_PLT_MISSING_MSG, file=sys.stderr)
            raise
        from scipy.special import gammaln

        def fnll(v: Iterable[np.typing.NDArray[Any]]) -> float:
            ypred = func(xdata, *v)
            if (ypred <= 0.0).any():
                return 1e6
            return (  # type: ignore[no-any-return]
                ypred.sum() - (ydata * np.log(ypred)).sum() +
                gammaln(ydata + 1).sum())

        # Seed likelihood fit with chi2 fit parameters
        res = minimize(fnll, popt, method="BFGS")
        popt = res.x

        # Better hessian from hesse, seeded with scipy popt
        m = Minuit(fnll, popt)
        m.errordef = 0.5
        m.hesse()
        pcov = np.array(m.covariance)
    return tuple(popt), pcov
def fit(least_squares):
    m = Minuit(least_squares, m1=1400, m2=300, m3=250, k=0, a=0, b=0, e=0, g=0)
    m.limits['m1'] = (1500, 1700)
    m.limits['m2'] = (300, 500)
    m.limits['m3'] = (250, 450)
    m.errordef = Minuit.LEAST_SQUARES
    m.migrad()
    return m
예제 #12
0
def test_inaccurate_fcn(iterate, valid):
    def f(x):
        return abs(x) ** 10 + 1e7

    m = Minuit(f, x=2)
    m.errordef = 1
    m.migrad(iterate=iterate)
    assert m.valid == valid
예제 #13
0
def test_function_with_maximum():
    def func(a):
        return -(a ** 2)

    m = Minuit(func, a=0)
    m.errordef = 1
    m.migrad()
    assert m.fmin.is_valid is False
예제 #14
0
def test_non_invertible():
    m = Minuit(lambda x, y: 0, 1, 2)
    m.errordef = 1
    m.strategy = 0
    m.migrad()
    assert m.fmin.is_valid
    m.hesse()
    assert not m.fmin.is_valid
    assert m.covariance is None
예제 #15
0
def test_errordef():
    m = Minuit(lambda x: x**2, pedantic=False, errordef=4)
    assert m.errordef == 4
    m.migrad()
    m.hesse()
    assert_allclose(m.errors["x"], 2)
    m.errordef = 1
    m.hesse()
    assert_allclose(m.errors["x"], 1)
예제 #16
0
파일: fit.py 프로젝트: ReynLieu/tf-pwa
def fit_minuit_v2(fcn, bounds_dict={}, hesse=True, minos=False, **kwargs):
    """

    :param fcn:
    :param bounds_dict:
    :param hesse:
    :param minos:
    :return:
    """
    from iminuit import Minuit

    var_args = {}
    var_names = fcn.vm.trainable_vars
    x0 = []
    for i in var_names:
        x0.append(fcn.vm.get(i))
        var_args[i] = fcn.vm.get(i)
        if i in bounds_dict:
            var_args["limit_{}".format(i)] = bounds_dict[i]
        # var_args["error_" + i] = 0.1

    f_g = Cached_FG(fcn.nll_grad)
    m = Minuit(
        f_g.fun,
        np.array(x0),
        name=var_names,
        grad=f_g.grad,
    )
    m.strategy = 0
    for i in var_names:
        if i in bounds_dict:
            m.limits[i] = bounds_dict[i]
    m.errordef = 0.5
    m.print_level = 2
    print("########## begin MIGRAD")
    now = time.time()
    m.migrad()  # (ncall=10000))#,precision=5e-7))
    print("MIGRAD Time", time.time() - now)
    if hesse:
        print("########## begin HESSE")
        now = time.time()
        m.hesse()
        print("HESSE Time", time.time() - now)
    if minos:
        print("########## begin MINOS")
        now = time.time()
        m.minos()  # (var="")
        print("MINOS Time", time.time() - now)
    ndf = len(var_names)
    ret = FitResult(dict(zip(var_names, m.values)),
                    fcn,
                    m.fval,
                    ndf=ndf,
                    success=m.valid)
    # print(m.errors)
    ret.set_error(dict(zip(var_names, m.errors)))
    return ret
예제 #17
0
def test_chi2_fit():
    def chi2(x, y):
        return (x - 1) ** 2 + ((y - 2) / 3) ** 2

    m = Minuit(chi2, x=0, y=0)
    m.errordef = 1
    m.migrad()
    assert_allclose(m.values, (1, 2))
    assert_allclose(m.errors, (1, 3))
예제 #18
0
def test_throw_nan():
    m = Minuit(returning_nan, x=1)
    m.errordef = 1
    assert not m.throw_nan
    m.migrad()
    m.throw_nan = True
    with pytest.raises(RuntimeError):
        m.migrad()
    assert m.throw_nan
예제 #19
0
파일: fit.py 프로젝트: aminnj/yahist
def curve_fit_wrapper(func,
                      xdata,
                      ydata,
                      sigma=None,
                      absolute_sigma=True,
                      likelihood=False,
                      **kwargs):
    """
    Wrapper around `scipy.optimize.curve_fit`. Initial parameters (`p0`)
    can be set in the function definition with defaults for kwargs
    (e.g., `func = lambda x,a=1.,b=2.: x+a+b`, will feed `p0 = [1.,2.]` to `curve_fit`)
    """
    from scipy.optimize import minimize, curve_fit

    xdata = xdata.astype(np.float64)  # need this for minuit hesse to converge
    if func.__defaults__ and len(
            func.__defaults__) + 1 == func.__code__.co_argcount:
        if "p0" not in kwargs:
            kwargs["p0"] = func.__defaults__
    tomask = (ydata == 0.0) | (~np.isfinite(ydata))
    if sigma is not None:
        tomask |= sigma == 0.0
    popt, pcov = curve_fit(
        func,
        xdata[~tomask],
        ydata[~tomask],
        sigma=sigma[~tomask],
        absolute_sigma=absolute_sigma,
        **kwargs,
    )
    if likelihood:
        from scipy.special import gammaln

        def fnll(v):
            ypred = func(xdata, *v)
            if (ypred <= 0.0).any():
                return 1e6
            return (ypred.sum() - (ydata * np.log(ypred)).sum() +
                    gammaln(ydata + 1).sum())

        res = minimize(fnll, popt, method="BFGS")
        popt = res.x
        pcov = res.hess_inv
        use_minuit = True
        if use_minuit:
            try:
                from iminuit import Minuit
            except ImportError:
                raise Exception(
                    "For likelihood minimization, the 'iminuit' module must be installed (`pip install --user iminuit`)."
                )
            m = Minuit(fnll, popt)
            m.errordef = 0.5
            m.hesse()
            pcov = np.array(m.covariance)
    return popt, pcov
예제 #20
0
def test_matrix():
    m = Minuit(lambda x, y: x**2 + (y / 2)**2 + 1, x=0, y=0)
    m.errordef = 1
    m.migrad()
    assert (framed(tab.tabulate(*m.covariance.to_table())) == """
         x       y
--  ------  ------
x    1      -0.643
y   -0.643   4
""")
예제 #21
0
def test_html_minuit():
    m = Minuit(lambda x, y: x**2 + 4 * y**2, x=0, y=0)
    m.errordef = 1
    assert m._repr_html_() == m.params._repr_html_()
    m.migrad()
    assert (m._repr_html_() == m.fmin._repr_html_() + m.params._repr_html_() +
            m.covariance._repr_html_())
    m.minos()
    assert (m._repr_html_() == m.fmin._repr_html_() + m.params._repr_html_() +
            m.merrors._repr_html_() + m.covariance._repr_html_())
예제 #22
0
def test_text_minuit():
    m = Minuit(lambda x, y: x**2 + 4 * y**2, x=0, y=0)
    m.errordef = 1
    assert str(m) == str(m.params)
    m.migrad()
    assert str(m) == str(m.fmin) + "\n" + str(m.params) + "\n" + str(
        m.covariance)
    m.minos()
    assert str(m) == str(m.fmin) + "\n" + str(m.params) + "\n" + str(
        m.merrors) + "\n" + str(m.covariance)
예제 #23
0
def test_perfect_correlation():
    def func(a, b):
        return (a - b) ** 2

    m = Minuit(func, a=1, b=2)
    m.errordef = 1
    m.migrad()
    assert m.fmin.is_valid is True
    assert m.fmin.has_accurate_covar is False
    assert m.fmin.has_posdef_covar is False
    assert m.fmin.has_made_posdef_covar is True
예제 #24
0
def test_fixing_long_variable_name(grad):
    m = Minuit(
        func5,
        grad=grad,
        long_variable_name_really_long_why_does_it_has_to_be_this_long=2,
        x=0,
        z=0,
    )
    m.errordef = 1
    m.fixed["long_variable_name_really_long_why_does_it_has_to_be_this_long"] = True
    m.migrad()
    assert_allclose(m.values, [1, 2, -1], atol=1e-3)
예제 #25
0
def optimize_1pz(w_in, a_baseline_in, t_beg_in, t_end_in, p0_in, val0_out):
    """
    Find the optimal, single pole-zero cancellation's parameter
    by minimizing the slope in the waveform's specified time range.
    
    Parameters
    ----------
    w_in         : array-like
                   The input waveform
    a_baseline_in: float
                   The resting baseline
    t_beg_in     : int
                   The lower bound's index for the time range over
                   which to optimize the pole-zero cancellation
    t_end_in     : int
                   The upper bound's index for the time range over
                   which to optimize the pole-zero cancellation
    p0_in        : float
                   The initial guess of the optimal time constant
    val0_out     : float
                   The output value of the best-fit time constant
              
    Processing Chain Example
    ------------------------
    "tau0": {
        "function": "optimize_1pz",
        "module": "pygama.dsp.processors",
        "args": ["waveform", "baseline", "0", "20*us", "500*us", "tau0"],
        "prereqs": ["waveform", "baseline"],
        "unit": "us"
    }
    """
    val0_out[0] = np.nan

    if np.isnan(w_in).any() or np.isnan(a_baseline_in) or np.isnan(t_beg_in) or np.isnan(t_end_in) or\
       np.isnan(p0_in):
        return

    if not np.floor(t_beg_in) == t_beg_in or\
       not np.floor(t_end_in) == t_end_in:
        raise DSPFatal('The waveform index is not an integer')

    if int(t_beg_in) < 0 or int(t_beg_in) > len(w_in) or\
       int(t_end_in) < 0 or int(t_end_in) > len(w_in):
        raise DSPFatal('The waveform index is out of range')

    m = Minuit(Model(pole_zero, w_in, a_baseline_in, int(t_beg_in), int(t_end_in)), [p0_in])
    m.print_level = -1
    m.strategy = 1
    m.errordef = Minuit.LEAST_SQUARES
    m.migrad()
    val0_out[0] = m.values[0]
예제 #26
0
def test_params():
    m = Minuit(lambda x, y: x**2 + (y / 2)**2 + 1, x=0, y=0)
    m.errordef = 1
    m.limits["y"] = (-1, 1)
    m.fixed["x"] = True
    m.migrad()
    m.minos()
    assert (framed(tab.tabulate(*m.params.to_table())) == """
  pos  name      value    error  error-    error+    limit-    limit+    fixed
-----  ------  -------  -------  --------  --------  --------  --------  -------
    0  x             0      0.1                                          yes
    1  y             0      1.5  -1.0      1.0       -1.0      1.0
""")
예제 #27
0
def test_issue_424():
    def lsq(x, y, z):
        return (x - 1) ** 2 + (y - 4) ** 2 / 2 + (z - 9) ** 2 / 3

    m = Minuit(lsq, x=0.0, y=0.0, z=0.0)
    m.errordef = 1
    m.migrad()

    m.fixed["x"] = True
    m.errors["x"] = 2
    m.hesse()
    assert m.fixed["x"] is True
    assert m.errors["x"] == 2
예제 #28
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:

        m = Minuit(
            self._fcn,
            initial_param_values,
            name=self.params.names,
        )

        m.errors = 0.05 * initial_param_values
        m.errordef = error_def
        m.limits = self._param_bounds

        for i in range(len(m.params)):
            m.fixed[i] = self._get_fixed_params()[i]

        m.print_level = 1 if verbose else 0

        # perform minimization twice!
        fmin = m.migrad(ncall=100000, iterate=2).fmin

        self._fcn_min_val = m.fval
        self._params.values = np.array(m.values)
        self._params.errors = np.array(m.errors)

        fixed_params = tuple(
            ~np.array(self._get_fixed_params()))  # type: Tuple[bool, ...]
        self._params.covariance = np.array(
            m.covariance)[fixed_params, :][:, fixed_params]
        self._params.correlation = np.array(
            m.covariance.correlation())[fixed_params, :][:, fixed_params]

        self._success = fmin.is_valid and fmin.has_valid_parameters and fmin.has_covariance

        if check_success and not self._success:
            raise RuntimeError(f"Minimization was not successful.\n"
                               f"{fmin}\n")

        assert self._success is not None
        return MinimizeResult(fcn_min_val=m.fval,
                              params=self._params,
                              success=self._success)
예제 #29
0
def test_fmin():
    m = Minuit(lambda x, s: (x * s) ** 2, x=1, s=1)
    m.fixed["s"] = True
    m.errordef = 1
    m.migrad()
    fm1 = m.fmin
    assert fm1.is_valid

    m.values["s"] = 0

    m.migrad()
    fm2 = m.fmin

    assert fm1.is_valid
    assert not fm2.is_valid
예제 #30
0
파일: fitting.py 프로젝트: watsonjj/ctapipe
def taubin_circle_fit(x, y, mask):
    """
    reference : Barcelona_Muons_TPA_final.pdf (slide 6)

    Parameters
    ----------
    x: array-like or astropy quantity
        x coordinates of the points
    y: array-like or astropy quantity
        y coordinates of the points
    mask: array-like boolean
        true for pixels surviving the cleaning
    """
    original_unit = x.unit
    x, y = all_to_value(x, y, unit=original_unit)

    x_masked = x[mask]
    y_masked = y[mask]

    R = x.max()  # x.max() just happens to be identical with R in many cases.

    taubin_r_initial = R / 2
    taubin_error = R * 0.1
    xc = 0
    yc = 0

    # minimization method
    fit = Minuit(make_taubin_loss_function(x_masked, y_masked),
                 xc=xc,
                 yc=yc,
                 r=taubin_r_initial)
    fit.errordef = Minuit.LEAST_SQUARES

    fit.errors["xc"] = taubin_error
    fit.errors["yc"] = taubin_error
    fit.errors["r"] = taubin_error

    fit.limits["xc"] = (-2 * R, 2 * R)
    fit.limits["yc"] = (-2 * R, 2 * R)
    fit.limits["r"] = (0, R)

    fit.migrad()

    radius = Quantity(fit.values["r"], original_unit)
    center_x = Quantity(fit.values["xc"], original_unit)
    center_y = Quantity(fit.values["yc"], original_unit)

    return radius, center_x, center_y