Exemplo n.º 1
0
def test_dxa():
    ls = LeastSquares(fn, x, y, dx=dx, dx_low=dxl)
    assert_almost_equal(0,
                        ls(1, 1),
                        err_msg="least squares dx asymmetric good parameters")
    assert_almost_equal(1 / 144,
                        ls(2, 1),
                        err_msg="least squares dx asymmetric bad parameters")
Exemplo n.º 2
0
def test_dxdy():
    ls = LeastSquares(fn, x, y, dy, dx)
    assert_almost_equal(0,
                        ls(1, 1),
                        err_msg="least squares dxdy good parameters")
    assert_almost_equal(1 / (64 + 4),
                        ls(2, 1),
                        err_msg="least squares dxdy bad parameters")
Exemplo n.º 3
0
def test_dx():
    ls = LeastSquares(fn, x, y, dx=dx)
    assert_almost_equal(0,
                        ls(1, 1),
                        err_msg="least squares dx good parameters")
    assert_almost_equal(1 / 64,
                        ls(2, 1),
                        err_msg="least squares dx bad parameters")
Exemplo n.º 4
0
def test_no_errors():
    ls = LeastSquares(fn, x, y)
    assert_almost_equal(0,
                        ls(1, 1),
                        err_msg="least squares no errors good parameters")
    assert_almost_equal(2,
                        ls(1, 2),
                        err_msg="least squares no errors bad parameters")
Exemplo n.º 5
0
def test_dxa_dy():
    ls = LeastSquares(fn, x, y, dy=dy, dx=dx, dx_low=dxl)
    assert_almost_equal(
        0,
        ls(1, 1),
        err_msg="least squares dx and dy asymmetric good parameters")
    assert_almost_equal(
        1 / (4 + 144),
        ls(2, 1),
        err_msg="least squares dy and dx asymmetric bad parameters")
Exemplo n.º 6
0
def test_dya():
    ls = LeastSquares(fn, x, y, dy, dy_low=dyl)
    assert_almost_equal(0,
                        ls(1, 1),
                        err_msg="least squares dy asymmetric good parameters")
    assert_almost_equal(1 / 100,
                        ls(0, 1),
                        err_msg="least squares dy asymmetric low parameters")
    assert_almost_equal(1 / 4,
                        ls(2, 1),
                        err_msg="least squares dy asymmetric high parameters")
Exemplo n.º 7
0
def test_dx_dya():
    ls = LeastSquares(fn, x, y, dy=dy, dx=dx, dy_low=dyl)
    assert_almost_equal(
        0,
        ls(1, 1),
        err_msg="least squares dx and dy asymmetric good parameters")
    assert_almost_equal(
        4 / (100 + 16),
        ls(-1, 1),
        err_msg="least squares dx and dy asymmetric low parameters")
    assert_almost_equal(
        1 / (4 + 64),
        ls(2, 1),
        err_msg="least squares dx and dy asymmetric high parameters")
Exemplo n.º 8
0
    def chi2(self):
        """
            Get chisquared / DOF for each fit function
        """
        self.chi = []
        for i in range(self.nsets):

            # get data
            x = self.x[i]
            y = self.y[i]
            p = self.par_runwise[i]
            f = self.fn[i]
            fx = self.fixed[i]
            m = self.metadata[i]

            dy = None if self.dy is None else self.dy[i]
            dx = None if self.dx is None else self.dx[i]
            dy_low = None if self.dy_low is None else self.dy_low[i]
            dx_low = None if self.dx_low is None else self.dx_low[i]

            # calc ls sum
            ls = LeastSquares(
                f,
                x,
                y,
                dy=dy,
                dx=dx,
                dx_low=dx_low,
                dy_low=dy_low,
            )
            # get dof
            dof = len(x) - self.npar + sum(fx)
            if dof == 0:
                warnings.warn(
                    "Zero degrees of freedom for data set %d, using len(x) as dof"
                    % i)
                dof = len(x)

            self.chi.append(ls(*np.concatenate((p, m))) / dof)

        self.chi = np.array(self.chi)

        return self.chi
Exemplo n.º 9
0
    def gchi2(self):
        """
            Get global chisquared / DOF
        """
        dof = len(self.xcat) - len(self.par)
        if dof <= 0:
            raise DivisionByZero("Zero degrees of freedom")

        if self.minimizer == 'migrad':
            self.chi_glbl = self.minuit.fval / dof
        else:

            ls = LeastSquares(self.master_fn,
                              self.xcat,
                              self.ycat,
                              dy=self.dycat,
                              dx=self.dxcat,
                              dy_low=self.dycat_low,
                              dx_low=self.dxcat_low,
                              fn_prime=self.master_fnprime)

            self.chi_glbl = ls(*self.par) / dof
        return self.chi_glbl
Exemplo n.º 10
0
    def __init__(self,
                 fn,
                 x,
                 y,
                 dy=None,
                 dx=None,
                 dy_low=None,
                 dx_low=None,
                 fn_prime=None,
                 fn_prime_dx=1e-6,
                 name=None,
                 start=None,
                 error=None,
                 limit=None,
                 fix=None,
                 print_level=1,
                 **kwargs):
        """
            fn: function handle. f(x, a, b, c, ...)
            x:              x data
            y:              y data
            dy:             error in y
            dx:             error in x
            dy_low:         Optional, if error in y is asymmetric. If not none, dy is upper error
            dx_low:         Optional, if error in y is asymmetric. If not none, dx is upper error
            fn_prime:       Optional, function handle for the first derivative of fn. f'(x, a, b, c, ...)
            fn_prime_dx:    Spacing in x to calculate the derivative for default calculation
            name:           Optional sequence of strings. If set, use this for setting parameter names
            start:          Optional sequence of numbers. Required if the 
                                function takes an array as input or if it has 
                                the form f(x, *pars), and name is not defined. 
                                Default: 1, broadcasted to all inputs
            error           Optional sequence of numbers. Initial step sizes. 
            limit           Optional sequence of limits that restrict the range 
                                format: [[low, high], [low, high], ...]
                                in which a parameter is varied by minuit. 
                                with None, +/- inf used to disable limit
            fix             Optional sequence of booleans. Default: False
            print_level Set the print_level
                            0 is quiet. 
                            1 print out at the end of MIGRAD/HESSE/MINOS. 
                            2 prints debug messages.
                
            kwargs:         passed to Minuit.from_array_func.
                
                To set for parameter "a" one can also assign the following 
                keywords instead of the array inputs
                    
                    a = initial_value
                    error_a = start_error
                    limit_a = (low, high)
                    fix_a = True
        """

        # construct least squares object
        ls = LeastSquares(fn=fn,
                          x=x,
                          y=y,
                          dy=dy,
                          dx=dx,
                          dy_low=dy_low,
                          dx_low=dx_low,
                          fn_prime=fn_prime,
                          fn_prime_dx=fn_prime_dx)
        self.ls = ls

        # get number of data points
        self.npts = len(x)

        # detect function names
        if name is None:

            # get names from code
            name = inspect.getfullargspec(fn).args

            # remove self
            if 'self' in name: name.remove('self')

            # remove data input
            name = name[1:]

            # check for starting parameters
            if start is not None:

                # if they don't match assume array input to function
                try:
                    if len(start) != len(name):
                        name = ['x%d' % d for d in range(len(start))]

                # start is a scalar to be broadcasted
                except TypeError:
                    pass

            # check for bad input
            else:
                for n in name:
                    if '*' in n:
                        raise RuntimeError(
                            "If array input must define name or start")

        # set starting values, limits, fixed, errors
        error, kwargs = self._set_start(array=error,
                                        namestr='error_',
                                        name=name,
                                        kwargs=kwargs,
                                        default=1)

        limit, kwargs = self._set_start(array=limit,
                                        namestr='limit_',
                                        name=name,
                                        kwargs=kwargs,
                                        default=[-np.inf, np.inf])

        fix, kwargs = self._set_start(array=fix,
                                      namestr='fix_',
                                      name=name,
                                      kwargs=kwargs,
                                      default=False)

        # are there starting values, limits, fixed, errors?
        is_start = start is not None
        is_error = error is not None
        is_limit = limit is not None
        is_fix = fix is not None

        keys = kwargs.keys()

        # check limit depth
        if is_start:
            broadcast_start = get_depth(start) < 1

        # iterate parameter names
        for n in name:

            # index of name
            nidx = list(name).index(n)

            # start
            if n not in keys:

                if is_start:

                    if broadcast_start: kwargs[n] = start
                    else: kwargs[n] = start[nidx]

                else:
                    kwargs[n] = 1

        # make minuit object
        super().__init__(ls, name=name, **kwargs)

        # set errors, limits, fix
        if is_error:
            self.errors = error
        if is_limit:
            self.limits = limit
        if is_fix:
            self.fixed = fix

        # set errordef for least squares minimization
        self.errordef = 1

        # set print level
        self.print_level = print_level