예제 #1
0
def phasespace3(M, m1, m2, m3):
    """Calculate the full three body phase space:
    >>> M, m1  , m2 , m3 = ...
    >>> ps3 = phasespace3 ( M , m1  , m2 , m3 ) 
    - The algorithm includes two embedded numerical integration -> could be slow 
    """
    assert 0 <= M and 0 <= m1 and 0 <= m2 and 0 <= m3, 'Invalid setting of masses!'

    ##
    if m1 + m2 + m3 >= M: return 0  ## RETURN!

    s = M * M
    m1_2 = m1 * m1
    m2_2 = m2 * m2
    m3_2 = m3 * m3

    high = (M - m1)**2
    low = (m2 + m3)**2

    import math
    func = lambda x: math.sqrt(kallen(x, s, m1_2) * kallen(x, m2_2, m3_2)) / x

    from ostap.math.integral import integral

    r = integral(func, low, high, err=False)

    return (math.pi**2) * r / (4.0 * s)
예제 #2
0
파일: moments.py 프로젝트: Pro100Tema/ostap
    def __call__(self, func, *args):

        ## additional arguments
        args = args if args else self.args

        #
        ## define integration rules
        #
        if hasattr(func, 'integral'):
            _integral_ = lambda f, low, high: f.integral(low, high, *args)
        else:
            from ostap.math.integral import integral
            _integral_ = lambda f, low, high: integral(f, low, high, *args)

        #
        ## xmin/max
        #
        xmin, xmax = self.xmin, self.xmax

        #
        ## calculate x0 as "mean"-value
        #
        x0 = self.x0
        if x0 is None:
            if hasattr(func, 'mean'): x0 = func.mean()
            else:
                m = Mean(xmin, xmax, False)
                x0 = m(func, *args)

        #
        ## check validity of x0
        #
        if not xmin <= x0 <= xmax:
            raise AttributeError("Invalid x0 value %s<=%s<=%s" %
                                 (xmin, x0, xmax))

        #
        ## get the normalization
        #
        norm = _integral_(func, xmin, xmax)
        if 0 >= norm:
            raise AttributeError("Normalization integral is not positive %s" %
                                 norm)

        #
        ## Equation:  ifun(x) \equiv \int_{x0-x}^{x0+x}f(t)dt - N*prob = 0
        #
        yval = self.prob * norm

        def ifun(x):
            if 0 >= x: return -yval
            return _integral_(func, max(xmin, x0 - x), min(xmax,
                                                           x0 + x)) - yval

        from ostap.math.rootfinder import findroot
        s = findroot(ifun, 0, max(xmax - x0, x0 - xmin))

        from ostap.math.ve import VE
        return VE(x0, s * s)
예제 #3
0
def distance(fun1, fun2, low, high):
    """calculate ``distance'' between two functions"""

    df = lambda x: abs(fun1(x) - fun2(x))

    from ostap.math.integral import integral
    di = integral(df, low, high)

    return di / (high - low)
예제 #4
0
def phasespace4(M, m1, m2, m3, m4):
    """Calculate the full four body phase space
    >>> M, m1  , m2 , m3 , m4 = ...
    >>> ps4 = phasespace4 ( M , m1  , m2 , m3 , m4 ) 
    - The algorithm includes two embedded numerical integration -> could be relatively slow 
    """
    assert 0 <= M and 0 <= m1 and 0 <= m2 and 0 <= m3 and 0 <= m4, 'Invalid setting of masses!'

    ##
    if m1 + m2 + m3 + m4 >= M: return 0  ## RETURN!

    low = m1 + m2
    high = M - m3 - m4

    func = lambda x: 2.0 * x * phasespace3(M, x, m3, m4) * phasespace2(
        x, m1, m2)

    from ostap.math.integral import integral

    return integral(func, low, high, err=False)
예제 #5
0
파일: funcs.py 프로젝트: Pro100Tema/ostap
def _tf2_integrate_X_(tf2, y, xlow=None, xhigh=None):
    r"""Integrate TF2 over range in X
    f = \int_{x_{low}}^{x_{high}} f(x,y) dx 
    
    >>> func = ROOT.TF2( ... )
    >>> a = func.integrate_X ( y , xlow , xhigh )
    """
    ## check Y
    ymin, ymax = tf2.yminmax()
    if not ymin <= y <= ymax: return 0
    ## check X
    xmin, xmax = tf2.yminmax()
    if None is xlow: xlow = xmin
    if None is xhigh: xhigh = xmax
    xmin = max(xmin, xlow)
    xmax = min(xmax, xhigh)
    ##
    func_x = lambda x: tf2(x, y)
    from ostap.math.integral import integral
    return integral(func_x, xmin, xmax)
예제 #6
0
파일: funcs.py 프로젝트: Pro100Tema/ostap
def _tf2_integrate_Y_(tf2, x, ylow=None, yhigh=None):
    r"""Integrate TF2 over range in Y
    f = \int_{y_{low}}^{y_{high}} f(x,y) dy
    
    >>> func = ROOT.TF2( ... )
    >>> a = func.integrate_Y ( x , ylow , yhigh )
    """
    ## check X
    xmin, xmax = tf2.xminmax()
    if not xmin <= x <= xmax: return 0
    ## check Y
    ymin, ymax = tf2.yminmax()
    if None is ylow: ylow = ymin
    if None is yhigh: yhigh = ymax
    ymin = max(ymin, ylow)
    ymax = min(ymax, yhigh)
    ##
    func_y = lambda y: tf2(x, y)
    from ostap.math.integral import integral
    return integral(func_y, ymin, ymax)
예제 #7
0
def test_integral():

    from math import sin, cos, exp, log, pi, e

    from ostap.math.integral import integral, romberg
    funcs = [(sin, 0, pi, 2), (cos, 0, pi, 0), (exp, 0, 1, e - 1),
             (log, 1.e-50, 1, -1)]

    for entry in funcs:

        args = entry[:3]
        vi = integral(*entry[:3], err=True)
        vr = romberg(*entry[:3], err=True, maxdepth=100)

        value = entry[3]
        func = 'int(%s,%g,%g)' % (entry[0].__name__, entry[1], entry[2])
        logger.info('%20s: I        %-20s %-20s' % (func, vi, vr))
        logger.info('%20s: Delta    %-20s %-20s' %
                    (func, vi - value, vr - value))
        logger.info('%20s: Delta/I  %-20s %-20s' % (func,
                                                    (vi - value) / vi.error(),
                                                    (vr - value) / vr.error()))
예제 #8
0
def phasespace(M, *args):
    """Calculate full  N-body phase space
    >>> M, m1 , m2 , ... , mn = ...
    >>> ps = phasespace ( M , m1 , m2 , ... , mn )
    - The algorithm includes embedded numerical integrations -> could be relatively slow 
    """

    assert 0 <= M and 2 <= len(args), 'Invalid setting of masses!'

    summ = 0.0
    for m in args:
        assert 0 <= m, 'Invalid setting of masses'
        summ += m

    if summ >= M: return 0

    N = len(args)
    if 2 == N: return phasespace2(M, *args)
    elif 3 == N: return phasespace3(M, *args)
    elif 4 == N: return phasespace4(M, *args)

    ## split particles into two groups & (recursively) apply the splitting formula

    k = N / 2

    args1 = args[k:]
    args2 = args[:k]

    low = sum(args1)
    high = M - sum(args2)

    func = lambda x: 2.0 * x * phasespace(M, x, *args2) * phasespace(x, *args1)

    from ostap.math.integral import integral

    return integral(func, low, high, err=False)
예제 #9
0
파일: moments.py 프로젝트: Pro100Tema/ostap
    def __call__(self, func, *args):

        ## additional arguments
        args = args if args else self.args

        #
        ## define integration rules
        #
        if hasattr(func, 'integral'):
            _integral_ = lambda f, low, high: f.integral(low, high, *args)
        else:
            from ostap.math.integral import integral
            _integral_ = lambda f, low, high: integral(f, low, high, *args)

        #
        ## xmin/max
        #
        xmin, xmax = self.xmin, self.xmax

        #
        # calculate mode
        if hasattr(func, 'mode'): xmode = func.mode()
        else:
            md = Mode(xmin, xmax)
            xmode = md(func, *args)

        if not xmin <= xmode <= xmax:
            raise AttributeError("Invalid mode value %s<=%s<=%s" %
                                 (xmin, xmode, xmax))

        #
        ## get the normalization
        #
        norm = _integral_(func, xmin, xmax)
        if 0 >= norm:
            raise AttributeError("Normalization integral is not positive %s" %
                                 norm)

        normL = _integral_(func, xmin, xmode)
        normR = _integral_(func, xmode, xmax)

        from ostap.math.base import isequal, iszero

        ## solve equation f(x)=a
        def _solve_(func, fval, xmn, xmx, *args):
            ##
            if isequal(xmn, xmx): return xmn
            ##
            ifun = lambda x, *a: func(x, *a) - fval
            ##
            fmn = ifun(xmn)
            if iszero(ifun(xmn)): return xmn
            fmx = ifun(xmx)
            if iszero(ifun(xmx)): return xmx
            ##
            if 0 < fmx * fmn:  ## more or less arbitrary choice
                return xmx if abs(fmx) <= abs(fmn) else xmn
            #
            from ostap.math.rootfinder import findroot
            return findroot(ifun, xmn, xmx, args=args)

        yval = self.prob * norm
        fm = func(xmode)

        def iifun(f):

            if iszero(f): x1, x2 = xmin, xmax
            elif isequal(f, fm): return -yval
            else:
                x1 = _solve_(func, f, xmin, xmode)
                x2 = _solve_(func, f, xmode, xmax)

            return _integral_(func, x1, x2) - yval

        from ostap.math.rootfinder import findroot
        l = findroot(iifun, 0, func(xmode))
        x1 = _solve_(func, l, xmin, xmode)
        x2 = _solve_(func, l, xmode, xmax)

        return x1, x2