Example #1
0
    def interpolation(table, degree=3, bc_type=None):
        """Create interpolation spline using scipy machinery
        >>> table = ... ## interpolation table
        >>>  spline  = intepolation ( table , degree = 3 ) 
        - see `scipy.interpolation.make_innterp_spline` 
        - see `Ostap.Math.Interpolaiton.Table` 
        """
        assert isinstance ( table  , Ostap.Math.Interpolation.Table ), \
               "Inavalid interpolation type "
        assert isinstance ( degree  , integer_types )  \
               and 0 <= degree < len ( table )         \
               and ( 0 == degree or 1 == degree %2 ) , \
               "Invalid ``degree'' parameter %s" % degree

        N = len(table)
        K = degree
        spl = scipy.interpolate.make_interp_spline(
            [table.x(i) for i in range(N)],
            table.values(),
            k=K,
            bc_type=bc_type)

        if 0 < K: knots = doubles(spl.t[K:-K])
        else: knots = doubles(spl.t)

        pars = doubles(spl.c)

        return Ostap.Math.BSpline(knots, pars)
Example #2
0
def interpolate(func, abscissas, spline, *args):
    """Construct the interpolation B-spline
    
    func      : the ``function''
    abscissas : abscissas, if None/Empty,  Greville's abscissas from spline will be used
    spline    : th epsline qwill be constructed forem ``spline'' and ``args''
    
    :Example:
    
    >> b1 = interpolate ( lambda x : x*x , [0,0.5,1,2]    , 3 )  
    >> b2 = interpolate ( { 0:0 , 0.5:0.25 , 1:1 } , None , 1 )  
    >> b3 = interpolate ( [0,0.25,1,4] , [ 0,0.5, 1,2]    , 2 )  
    >> b4 = interpolate ( lambda x : x*x , None    , 3 )  
    """

    bs = Ostap.Math.BSpline(spline, *args)
    if not abscissas:
        abscissas = bs.greville_abscissas()

    from types import GeneratorType as GT
    from collections import Iterable as IT
    from collections import Mapping as MT

    if isinstance(abscissas, GT):
        abscissas = [x for x in abscissas]

    if callable(func) and abscissas:
        func = [func(x) for x in abscissas]  ## callable
    elif isinstance(func, dict) and not abscissas:  ## mapping
        keys = func.keys()
        keys.sort()
        abscissas = [x for x in keys]
        func = [func[x] for x in keys]
    elif isinstance(func, GT):
        func = [f for f in func]  ## generator
    elif isinstance(func, IT):
        pass  ## iterable
    else:
        raise TypeError("Can't treat ``func''=%s" % func)

    ##
    from ostap.math.base import doubles
    _x = doubles(abscissas)
    _y = doubles(func)

    bs = Ostap.Math.BSpline(spline, *args)
    if len(bs) != len(_x):
        raise TypeError(
            "Can't interpolate:  different number of parameters  %s/%s" %
            (len(_x), len(bs)))

    sc = Ostap.Math.Interpolation.bspline(_x, _y, bs)
    if sc.isFailure():
        raise TypeError("Ostap.Math.Bspline: Can't iterpolate!%s" % sc)

    return bs
Example #3
0
def sp_factory(klass, knots, pars, *args):
    """Factory for deserisalization of splines 
    - see Ostap.Math.BSPline 
    - see Ostap.Math.PositiveSpline 
    - see Ostap.Math.MonotonicSpline 
    - see Ostap.Math.ConvexSpline 
    - see Ostap.Math.ConvexOnlySpline 
    
    """
    return klass(doubles(knots), doubles(pars), *args)
Example #4
0
def deboor(x, order, knots, points):
    """Evaluate the spline given by the set of knots, control points and the order
    using de Boor's algorithm
    - see https://en.wikipedia.org/wiki/De_Boor%27s_algorithm
    """
    VD = cpp.std.vector('double')
    ## convert knots if needed
    if not isinstance(knots, VD): knots = doubles(knots)
    ## convert knots if needed
    if not isinstance(points, VD): points = doubles(points)
    ##
    return Ostap.Math.deboor(x, order, knots, points)
Example #5
0
def interpolate(func, abscissas, xmin=0, xmax=1):
    """Construct the interpolation Bernstein polynomial
    It relies on Newton-Bernstein algorithm
    - see http://arxiv.org/abs/1510.09197
    - see Mark Ainsworth and Manuel A. Sanches, 
    ``Computing of Bezier control points of Largangian interpolant 
    in arbitrary dimension'', arXiv:1510.09197 [math.NA]
    - see http://adsabs.harvard.edu/abs/2015arXiv151009197A

    func      : the ``function''
    abscissas : absciccas
    xmin      : minimal x-value 
    xmax      : maximal x-value 

    :Example:
    
    >> b1 = interpolate ( lambda x : x*x , [0,0.5,1,2]    , 0 , 4 )  
    >> b2 = interpolate ( { 0:0 , 0.5:0.25 , 1:1 } , None , 0 , 4 )  
    >> b3 = interpolate ( [0,0.25,1,4] , [ 0,0.5, 1,2]    , 0 , 4 )  
    """
    if xmin > xmax:
        xmin, xmax = xmax, xmin

    from types import GeneratorType as GT
    from collections import Iterable as IT
    from collections import Mapping as MT

    if isinstance(abscissas, GT):
        abscissas = [x for x in abscissas]

    if callable(func):
        func = [func(x) for x in abscissas]  ## callable
    elif isinstance(func, GT):
        func = [f for f in func]  ## generator
    elif isinstance(func, dict) and not abscissas:  ## mapping
        keys = func.keys()
        keys.sort()
        abscissas = [x for x in keys]
        func = [func[x] for x in keys]
    elif isinstance(func, IT):
        pass  ## iterable
    else:
        raise TypeError("Can't treat ``func''=%s" % func)

    ##
    from ostap.math.base import doubles
    _x = doubles(abscissas)
    _y = doubles(func)
    ##
    return Ostap.Math.Interpolation.bernstein(_x, _y, xmin, xmax)
Example #6
0
def data_quantiles(data, quantiles, expression, cuts='', *args):
    """Get the quantiles
    >>> data =  ...
    >>> print data_quantiles ( data , 0.1       , 'mass' , 'pt>1' ) ## quantile 
    >>> print data_quantiles ( data , (0.1,0.5) , 'mass' , 'pt>1' )
    >>> print data_quantiles ( data , 10        , 'mass' , 'pt>1' ) ## deciles!     
    >>> print data.quantiles (        0.1       , 'mass' , 'pt>1' ) ## quantile 
    >>> print data.quantiles (        (0.1,0.5) , 'mass' , 'pt>1' )
    >>> print data.quantiles (        10        , 'mass' , 'pt>1' ) ## deciles!     
    - see Ostap::StatVar::quantile
    """
    if isinstance(quantiles, float) and 0 < quantiles < 1:
        quantiles = [quantiles]
    elif isinstance(quantiles, int) and 1 < quantiles:
        N = quantiles
        quantiles = (float(i) / N for i in xrange(1, N))

    qq = []
    for q in quantiles:
        assert isinstance(q, float) and 0 < q < 1, 'Invalid quantile:%s' % q
        qq.append(q)
    qq.sort()

    from ostap.math.base import doubles
    rr = StatVar.quantiles(data, doubles(qq), expression, cuts, *args)
    rr = [r for r in rr]
    return tuple(rr)
Example #7
0
def _new_init_ ( t ,  *args )  :
    """(Redefine standard constructor to allow usage of python lists&tuples)
    Lists and tuples are  converted on flight to :
    - std::vector<double> 
    - or std::vector<std::complex<double>>
    """
    from ostap.math.base        import doubles      , complexes
    from ostap.core.ostap_types import string_types , listlike_types 
    
    largs = list (  args )

    for i , arg in enumerate ( largs ) :

        if not isinstance ( arg ,  ( list , tuple ) ) : continue 
        
        try: 
            _arg = doubles  ( arg  )
            largs [ i ] = _arg
            continue 
        except TypeError : pass
        
        try: 
            _arg = complexes ( arg  )
            largs [ i ] = _arg
            continue 
        except TypeError : pass
        
    targs = tuple ( largs )

    ## use old constructor 
    return t._old_init_ ( *targs ) 
Example #8
0
def _new_init_ ( t ,  *args )  :
    """(Redefine standard constructor to allow usage of python lists&tuples)
    Lists and tuples are  converted on flight to :
    - std::vector<double> 
    - or std::vector<std::complex<double>>
    """
    from ostap.math.base import doubles, complexes
    
    largs = list (  args )
    alen  = len  ( largs )
    
    for i in range(alen) :
        
        arg = largs[i] 
        if not isinstance ( arg ,  ( list , tuple ) ) : continue 
        
        try: 
            _arg = doubles  ( *arg  )
            largs[i] = _arg
            continue 
        except TypeError : pass
        
        try: 
            _arg = complexes ( *arg  )
            largs[i] = _arg
            continue 
        except TypeError : pass
        
    targs = tuple(largs)
    ## use old constructor 
    t._old_init_ ( *targs ) 
Example #9
0
def abs_factory(arg, *args):
    """Factory for deserialisation of interpolation abscissas
    """
    if isinstance(arg, sequence_types):
        vals = doubles(arg)
        return Ostap.Math.Interpolation.Abscissas(vals, *args)

    return Ostap.Math.Interpolation.Abscissas(arg, *args)
Example #10
0
def knots_from_abscissas(abscissas, order, convert=True):
    """Reconstruct knot vector from greville abscissas and spline degree
    abscissas : vector of abscissas
    order     : the order/degree  of spline
    convert   : convert to tuple ?
    >>> data = [ 0,2,3,4,5,10,11]
    >>> knots = knots_from_abscissas ( data , 3 ) 
    """

    ## VD = cpp.std.vector('double')
    ## ## convert knots if needed
    ## if not isinstance ( abscissas , VD ) : abscissas =  doubles ( abscissas )
    ## knots = Ostap.Math.knots_from_abscissas ( abscissas , order )
    ## if convert  : knots = tuple ( knots )
    ## return  knots

    if isinstance(abscissas, Ostap.Math.Interpolation.Table):
        data = abscissas.data()
        abscissas = [i.first for i in data]
    elif isinstance(anscissas, Ostap.Math.Interpolation.TABLE):
        data = abscissas
        abscissas = [i.first for i in data]
    elif isinstance(abscissas, list):
        abscissas.sort()
    else:
        abscissas = list(abscissas)
        abscissas.sort()

    if len(abscissas) < order + 1:
        raise AttributeError("Vector of abscissas is too short")

    degree = order
    af = abscissas[0]
    al = abscissas[-1]

    ## knots = [ af ] + abscissas + [ al ]
    ##
    ## if 1 ==  order : return knots
    ## while len(knots) < len(abscissas) + order + 1 :
    ##     knots = [ af ] + knots + [ al ]
    ##
    ## return knots

    knots = (degree + 1) * [af]
    N = len(abscissas)

    for i in range(1, N):
        st = sum(knots[-(degree - 1):])
        ti = abscissas[i] * (degree) - st
        knots.append(ti)

    while len(knots) < N + order + 1:
        knots.append(al)

    abscissas = doubles(abscissas)
    knots2 = Ostap.Math.knots_from_abscissas(abscissas, order)

    return knots2
Example #11
0
def poly_factory(klass, params, *args):
    """Factory for deserisalization of polynomials with parameters
    - see Ostap.Math.Polynomial
    - see Ostap.Math.ChebyshevSum
    - see Ostap.Math.LegendreSum
    - see Ostap.Math.HermiteSum
    - see Ostap.Math.Bernstein
    - see Ostap.Math.BernsteinEven
    """
    return klass(doubles(params), *args)
Example #12
0
def _a_new_init_(a, arg1, *args):
    """ create abscissas
    """

    if isinstance(arg1, Ostap.Math.Interpolation.Abscissas):
        return a._old_init_(arg1)

    if isinstance(arg1, sequence_types):
        if not args:
            return a._old_init_(doubles(arg1))
        elif 1 == len(args) and isinstance(args[0], bool):
            return a._old_init_(doubles(arg1), args[0])

    if isinstance(arg1, integer_types) and 0 <= arg1:
        if 2 == len(args):
            return a._old_init_(arg1, args[0], args[1])
        elif 3 == len(args) and isinstance(args[2],
                                           integer_types) and 0 <= args[2]:
            return a._old_init_(arg1, *args)

    return a._old_init_(doubles(arg1, *args))
Example #13
0
def data_quantiles ( data , quantiles , expression , cuts  = '' , exact = QEXACT , *args ) :
    """Get the quantiles
    >>> data =  ...
    >>> print data_quantiles ( data , 0.1       , 'mass' , 'pt>1' ) ## quantile 
    >>> print data_quantiles ( data , (0.1,0.5) , 'mass' , 'pt>1' )
    >>> print data_quantiles ( data , 10        , 'mass' , 'pt>1' ) ## deciles!     
    >>> print data.quantiles (        0.1       , 'mass' , 'pt>1' ) ## quantile 
    >>> print data.quantiles (        (0.1,0.5) , 'mass' , 'pt>1' )
    >>> print data.quantiles (        10        , 'mass' , 'pt>1' ) ## deciles!     
    - see Ostap::StatVar::quantile
    """
    if   isinstance ( quantiles , float ) and 0 < quantiles < 1 : 
        quantiles = [ quantiles ]
    elif isinstance ( quantiles , int   ) and 1 < quantiles     :
        N         = quantiles 
        quantiles =  ( float ( i ) / N for i in range ( 1 , N ) )

    qq = [] 
    for q in quantiles :
        assert isinstance ( q , float ) and 0 < q < 1 , 'Invalid quantile:%s' % q
        qq.append ( q )
    qq.sort ()

    from ostap.math.base import doubles
    qqq = doubles ( qq )

    if   exact is True  :
        ##  exact slow algorithm 
        qn = StatVar.  quantiles ( data , qqq , expression , cuts , *args )

    elif exact is False :
        ## approximate fast formula 
        qn = StatVar.p2quantiles ( data , qqq , expression , cuts , *args )

    elif isinstance ( exact , int ) and len ( data ) <= exact  :
        ## exact slow algorithm 
        qn = StatVar.  quantiles ( data , qqq , expression , cuts , *args )

    else :
        ## approximate fast algorithm 
        qn = StatVar.p2quantiles ( data , qqq , expression , cuts , *args )

    return qn 
Example #14
0
def _new_init_(t, *args):
    """(Redefine standard constructor to allow usage of python lists&tuples)
    Lists and tuples are  converted on flight to :
    - std::vector<double> 
    - or std::vector<std::complex<double>>
    """
    from ostap.math.base import doubles, complexes, VCT_TYPES
    from ostap.core.ostap_types import Generator, Sequence, list_types

    largs = list(args)

    for i, arg in enumerate(largs):

        if isinstance(arg, VCT_TYPES): continue

        if isinstance(arg, Generator): pass
        elif isinstance(arg, Sequence): pass
        elif isinstance(arg, list_types): pass
        else:
            continue

        try:
            _arg = doubles(arg)
            largs[i] = _arg
            continue
        except TypeError:
            pass

        try:
            _arg = complexes(arg)
            largs[i] = _arg
            continue
        except TypeError:
            pass

    targs = tuple(largs)

    ## use old constructor
    return t._old_init_(*targs)
Example #15
0
def tab_factory(abscissas, values):
    """The factory for serialisation of the interpolation table
    """
    return Ostap.Math.Interpolation.Table(abscissas, doubles(values))
Example #16
0
def points ( func , abscissas  = None ) :
    """Construct collection of interpolation points
    
    func      : the ``function''
    abscissas : abscissas
    
    :Example:
    
    >> b1 = points ( lambda x : x*x , [0,0.5,1,2] )  
    >> b2 = points ( { 0:0 , 0.5:0.25 , 1:1 }     )  
    >> b3 = points ( [0,0.25,1,4] , [ 0,0.5, 1,2] )    
    >> b4 = points ( lambda x : x * x , Abscissas ( 4 , -2 , 2 , 1 ) )  
    
    """
       
    from types       import GeneratorType as GT
    from collections import Iterable      as IT
    from collections import Mapping       as MT

    ## switch on abscissas:
    _A = isinstance ( abscissas , Ostap.Math.Interpolation.Abscissas )
    
    if   isinstance ( abscissas , GT ) : abscissas = [ x for x in abscissas ]
    elif abscissas is None             :
        if   isinstance ( func , MT )  :
            _new_abscissas = []
            _new_func      = []
            _keys          = func.keys()
            _keys.sort() 
            for _k in _keys :
                _new_abscissas.append (      _k  )
                _new_func     .append ( func[_k] )
            abscissas = _new_abscissas 
            func      = _new_func
        elif isinstance ( func , Ostap.Math.Interpolation.Table ) : return func
        elif hasattr ( func , 'iteritems' ) : 
            _new_abscissas = []
            _new_func      = []
            for _a,_f in func.iteritems() :
                _new_abscissas.append ( _a )
                _new_func     .append ( _f )
            abscissas = _new_abscissas 
            func      = _new_func
        elif isinstance ( func , IT ) :
            try :
                _new_abscissas = []
                _new_func      = []
                for _a , _f in func :
                    _new_abscissas.append ( _a  )
                    _new_func     .append ( _f  )
                abscissas = _new_abscissas
                func      = _new_func
            except :
                raise TypeError ( "Invalid iterable ``func'' for ``None''-abscissas!" )                 
        else  :
            raise TypeError ( "For ``None''-abscissas ``func'' must be Table or Mapping!" ) 

    ## switch on func         
    if   callable   ( func ) :
        nfunc  = func 
        func   = ( nfunc ( x ) for x in abscissas )
    elif isinstance ( func , GT ) : pass                         ## generator 
    elif isinstance ( func , IT ) : pass                         ## iterable
    else :
        raise TypeError("Can't treat ``func''=%s"  %  func )
    ##
    from ostap.math.base import doubles
    ##
    if _A : return Ostap.Math.Interpolation.Table (   abscissas   , doubles ( func ) )
    return Ostap.Math.Interpolation.Table ( doubles ( abscissas ) , doubles ( func ) )
Example #17
0
def lagrange ( func , abscissas  = None ) :
    """Construct very efficient Barycentric Lagrange interpolant
    
    - it takes O(n)   flops for initialization with Chebyshev/Lobatto or uniform abscissas 
    - it takes O(n^2) flops for initialization with arbitrary interpolation      abscissas
    - it takes O(n)   flops for evaluation! It is very fast! 
    
    - see Jean-Paul Berrut and Lloyd N. Trefethen, 
    ...   Barycentric Lagrange Interpolation, SIAM Rev., 46(3), 501–517.
    ...   ISSN (print): 0036-1445
    ...   ISSN (online): 1095-7200
    - see https://doi.org/10.1137/S0036144502417715
    - see https://en.wikipedia.org/wiki/Lagrange_polynomial
    - see https://people.maths.ox.ac.uk/trefethen/barycentric.pdf
    
    func      : the ``function''
    abscissas : abscissas

    :Example:
    
    >>> b1 = interpolate ( lambda x : x*x , [0,0.5,1,2] )  
    >>> b2 = interpolate ( { 0:0 , 0.5:0.25 , 1:1 }     )  
    >>> b3 = interpolate ( [0,0.25,1,4] , [ 0,0.5, 1,2] )    
    >>> b4 = interpolate ( lambda x : x * x , Abscissas( 4 , -2 , 2 , 1 ) )
    
    >>> b1 = lagrange    ( lambda x : x*x , [0,0.5,1,2] )  
    >>> b2 = lagrange    ( { 0:0 , 0.5:0.25 , 1:1 }     )  
    >>> b3 = lagrange    ( [0,0.25,1,4] , [ 0,0.5, 1,2] )    
    >>> b4 = lagrange    ( lambda x : x * x , Abscissas( 4 , -2 , 2 , 1 ) )  

    >>> b1 = barycentric ( lambda x : x*x , [0,0.5,1,2] )  
    >>> b2 = barycentric ( { 0:0 , 0.5:0.25 , 1:1 }     )  
    >>> b3 = barycentric ( [0,0.25,1,4] , [ 0,0.5, 1,2] )    
    >>> b4 = barycentric ( lambda x : x * x , Abscissas( 4 , -2 , 2 , 1 ) )  
    
    """
       
    from types       import GeneratorType as GT
    from collections import Iterable      as IT
    from collections import Mapping       as MT

    ## switch on abscissas:
    _W = isinstance ( abscissas , Ostap.Math.Interpolation.Weights   )
    _A = isinstance ( abscissas , Ostap.Math.Interpolation.Abscissas )
    
    if   isinstance ( abscissas , GT ) : abscissas = [ x for x in abscissas ]
    elif abscissas is None             :
        if   isinstance ( func , MT )  :
            _new_abscissas = []
            _new_func      = []
            _keys          = func.keys()
            _keys.sort() 
            for _k in _keys :
                _new_abscissas.append (      _k  )
                _new_func     .append ( func[_k] )
            abscissas = _new_abscissas 
            func      = _new_func
        elif isinstance ( func , Ostap.Math.Interpolation.Table ) :
            return Ostap.Math.Barycentric ( func )                   ## ready
        else  :
            raise TypeError ( "For ``None''-abscissas ``func'' must be Table or Mapping!" ) 

    ## switch on func         
    if   callable   ( func ) :        
        nfunc = func        
        if _W or _A : func = ( nfunc ( x ) for x in abscissas.x() )
        else        : func = ( nfunc ( x ) for x in abscissas     )
    elif isinstance ( func , GT ) : pass                         ## generator 
    elif isinstance ( func , IT ) : pass                         ## iterable
    else :
        raise TypeError("Can't treat ``func''=%s"  %  func )
    ##
    from ostap.math.base import doubles
    if _W or _A : return Ostap.Math.Barycentric ( abscissas , doubles ( func ) )
    ##
    return Ostap.Math.Barycentric ( doubles ( abscissas ) , doubles ( func ) )
Example #18
0
def run_func_interpolation(fun,
                           N,
                           low,
                           high,
                           scale=1.e-5,
                           logger=logger,
                           name='Interpolation'):
    """Interpolate the function"""

    Abscissas = Ostap.Math.Interpolation.Abscissas

    abscissas = (('Uniform', Abscissas(N, low, high, 0)),
                 ('Chebyshev', Abscissas(N, low, high,
                                         1)), ('Lobatto',
                                               Abscissas(N, low, high, 2)),
                 ('Random',
                  Abscissas(doubles([x for x in more_uniform(low, high, N, N)
                                     ]))))

    tables = [(a[0], points(fun, a[1])) for a in abscissas]

    interpolants = []

    for i, t in enumerate(tables):

        item = ('Bernstein',
                t[0]), interpolate_bernstein(t[1], None, low, high)
        interpolants.append(item)

        item = ('Neville', t[0]), Ostap.Math.Neville(t[1])
        interpolants.append(item)

        item = ('Lagrange', t[0]), Ostap.Math.Lagrange(t[1])
        interpolants.append(item)

        item = ('Newton', t[0]), Ostap.Math.Newton(t[1])
        interpolants.append(item)

        item = ('Berrut1st', t[0]), Ostap.Math.Berrut1st(t[1])
        interpolants.append(item)

        item = ('Berrut2nd', t[0]), Ostap.Math.Berrut2nd(t[1])
        interpolants.append(item)

        item = ('Barycentric', t[0]), Ostap.Math.Barycentric(t[1])
        interpolants.append(item)

        item = ('Thiele', t[0]), Ostap.Math.Thiele(t[1])
        interpolants.append(item)

        for d in range(0, 9):
            item = ('FloaterHormann%d' % d,
                    t[0]), Ostap.Math.FloaterHormann(t[1], d)
            interpolants.append(item)

        for d in range(1, 6):
            item = ('BSpline%d' % d, t[0]), interpolate_bspline(t[1], None, d)
            interpolants.append(item)

        if bspline_interpolate:
            for d in (1, 3, 5, 7):
                item = ('BSpline%dSP' % d, t[0]), bspline_interpolate(t[1], d)
                interpolants.append(item)

    for n, t in interpolants:
        functions.add((n, t))

    graphs = []
    with wait(3), use_canvas(name):
        ff = lambda x: fun(x)
        f1_draw(ff, xmin=low, xmax=high, linecolor=2, linewidth=2)

        for i, item in enumerate(interpolants):

            p, f = item
            n1, n2 = p

            color = i + 3
            f.draw('same', linecolor=color, xmin=low, xmax=high)
            if hasattr(f, 'graph'):
                g = f.graph()
                g.draw('p', markercolor=color, markersize=2)
                graphs.append(g)

            if 1 == color: color = 'Black'
            elif 2 == color: color = 'Red'
            elif 3 == color: color = 'Green'
            elif 4 == color: color = 'Blue'
            elif 5 == color: color = 'Yellow'
            elif 6 == color: color = 'Magenta'
            elif 7 == color: color = 'Cyan'
            elif 8 == color: color = 'DarkGreen'

            logger.info('Color %10s for %s:%s' % (color, n1, n2))

    graphs = [t[1].graph() for t in tables]
    for i, g in enumerate(graphs, start=3):
        g.draw('p', markercolor=i)

    xx = []
    NP = 50000
    for i in range(NP):
        xx.append(random.uniform(low, high))
    xx.sort()

    from collections import defaultdict
    counters = defaultdict(SE)

    cpu = {}
    ## loop over all interpolants
    for n, fi in interpolants:

        n1, n2 = n

        cnt = counters[(n1, n2, fi)]

        with timing('', logger=None) as t:
            for x in xx:
                v = fun(x)
                vi = fi(x)
                cnt += abs(vi - v) / scale

        cpu[(n1, n2)] = t.delta

    rows = [('Interpolant', 'Grid', 'mean+/-rms', 'max', 'distance')]
    for item in counters:

        n1, n2, ff = item

        c = counters[item]
        d = distance(ff, fun, low, high) / scale
        vmax = c.max()

        if 1.e+6 < vmax: vmax = '+inf'
        else: vmax = '%-9.1f' % vmax

        row = n1, n2, '%9.2f +/- %-09.1f' % (c.mean().value(),
                                             c.rms()), vmax, '%.3g' % d
        rows.append(row)

    title = 'Interpolation precision (%d random points)[x%s]' % (NP, scale)
    table = T.table(rows, title=title, prefix='# ', alignment='lllll')

    logger.info('%s:\n%s' % (title, table))

    lst = []
    for k in cpu:
        item = cpu[k], k[0], k[1]
        lst.append(item)
    lst.sort()

    rows = [('Interpolant', 'Grid', 'CPU [s]')]
    for t, k0, k1 in lst:
        row = k0, k1, '%.4g' % cpu[(k0, k1)]
        rows.append(row)

    title = 'CPU: %d points' % NP
    table = T.table(rows, title=title, prefix='# ', alignment='ll')

    logger.info('%s:\n%s' % (title, table))
Example #19
0
def int_factory(klass, abscissas, values, *args):
    """The factory for serialisation of the interpolation table
    """
    the_table = Ostap.Math.Interpolation.Table(abscissas, doubles(values))
    return klass(the_table, *args)