Exemple #1
0
def interpolate ( func , abscissas , xmin = 0.0 , xmax = 1.0 ) :
    """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 )  
    >> b4 = interpolate ( lambda x : x * x , Abscissas( 4 , -2 , 2 , 1 ) )  
    """
    if xmin > xmax :
        xmin , xmax = xmax , xmin

    from ostap.math.interpolation import points
    pnts = points ( func , abscissas )
    ##
    xmin = float ( xmin ) 
    xmax = float ( xmax ) 
    ##
    return Ostap.Math.Interpolation.bernstein ( pnts , xmin , xmax ) 
Exemple #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    : the spline will be constructed from ``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 = None
    if isinstance(func, Ostap.Math.Interpolation.Table) and not abscissas:

        if isinstance(spline, int) and 0 <= spline and not args:
            ## get initial spline
            a = [p[0] for p in func]
            a.sort()
            bs = Ostap.Math.BSpline(a, spline)
            ## get the Greville's abscissas
            ga = [g for g in bs.greville_abscissas()]
            ##
            N = len(func)
            while N + 1 < len(ga) + bs.degree():
                del ga[1]
                if N + 1 < len(ga) + bs.degree():
                    del ga[-2]

            ## and use them as knots
            bs = Ostap.Math.BSpline(ga, spline)
        else:
            bs = Ostap.Math.BSpline(spline, *args)

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

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

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

    from ostap.math.interpolation import points
    table = points(func, abscissas)

    ## print ( "Table", type ( table ) , table.size () )

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

    return bs
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))
def run_grid_interpolation ( tfunc , dct , N , low , high , scale = 1.e-8 ) :
    
    Abscissas =  Ostap.Math.Interpolation.Abscissas
        
    data = points ( dct )

    ##  uniform abscissas 
    i0 = interpolate           ( data )
    
    ## bernstein interpolant 
    i1 = interpolate_bernstein ( data , None , low , high )

    ## neville interpolant
    i2 = Ostap.Math.Neville    ( data )

    ## largange interpolant 
    i3 = Ostap.Math.Lagrange   ( data )

    ## newton interpolant 
    i4 = Ostap.Math.Newton     ( data )

    ## bspline interpolant
    degree = 3
    ## bs = Ostap.Math.BSpline   ( low  , high ,  len ( data ) - 1 - degree , degree  )
    i5 = interpolate_bspline  ( data , None , degree ) 
        
    xx = []
    for i in range ( 100000 ) : xx.append ( random.uniform ( low , high ) ) 
    xx.sort()

    c0 = SE ()
    c1 = SE ()
    c2 = SE ()
    c3 = SE ()
    c4 = SE ()
    c5 = SE ()
    
    for x in xx :

        f  = tfunc    ( x )
        
        f0 = i0       ( x ) 
        f1 = i1       ( x ) 
        f2 = i2       ( x )
        f3 = i3       ( x )
        f4 = i4       ( x )
        f5 = i5       ( x )
        
        d0 = f0 - f 
        d1 = f1 - f
        d2 = f2 - f
        d3 = f3 - f
        d4 = f4 - f
        d5 = f5 - f
        
        c0 += abs ( d0 ) / scale  
        c1 += abs ( d1 ) / scale 
        c2 += abs ( d2 ) / scale 
        c3 += abs ( d3 ) / scale 
        c4 += abs ( d4 ) / scale 
        c5 += abs ( d5 ) / scale 
        
    logger.info ( 'Grid      precision: mean/max[%s] = %9.2f +- %-09.1f/%-9.1f' % ( scale , c0.mean () . value () , c0.rms () , c0.max () ) )
    logger.info ( 'Bernstein precision: mean/max[%s] = %9.2f +- %-09.1f/%-9.1f' % ( scale , c1.mean () . value () , c1.rms () , c1.max () ) )
    logger.info ( 'Neville   precision: mean/max[%s] = %9.2f +- %-09.1f/%-9.1f' % ( scale , c2.mean () . value () , c2.rms () , c2.max () ) )
    logger.info ( 'Lagrange  precision: mean/max[%s] = %9.2f +- %-09.1f/%-9.1f' % ( scale , c3.mean () . value () , c3.rms () , c3.max () ) )
    logger.info ( 'Newton    precision: mean/max[%s] = %9.2f +- %-09.1f/%-9.1f' % ( scale , c4.mean () . value () , c4.rms () , c4.max () ) )
    logger.info ( 'bSpline   precision: mean/max[%s] = %9.2f +- %-09.1f/%-9.1f' % ( scale , c5.mean () . value () , c5.rms () , c5.max () ) )

    import time
    i5.draw()
    time.sleep(5)
def run_grid_interpolation(tfunc,
                           dct,
                           N,
                           low,
                           high,
                           scale=1.e-8,
                           logger=logger,
                           name='interpolation'):
    """Interpolate the grid"""

    Abscissas = Ostap.Math.Interpolation.Abscissas

    data = points(dct)

    ## list of interpolants
    interpolants = []

    ## bernstein interpolant
    interpolants.append(
        ('Bernstein', interpolate_bernstein(data, None, low, high)))

    ## neville interpolant
    interpolants.append(('Neville', Ostap.Math.Neville(data)))

    ## largange interpolant
    interpolants.append(('Lagrange', Ostap.Math.Lagrange(data)))

    ## (true) Barycentric interpolant
    interpolants.append(('Barycentric', Ostap.Math.Barycentric(data)))

    ## Newton interpolant
    interpolants.append(('Newton', Ostap.Math.Newton(data)))

    ## 1st Berrut interpolant
    interpolants.append(('Berrut 1st', Ostap.Math.Berrut1st(data)))

    ## 2nd Berrut interpolant
    interpolants.append(('Berrut 2nd', Ostap.Math.Berrut2nd(data)))

    ## Thiele rational interpolant
    interpolants.append(('Thiele', Ostap.Math.Thiele(data)))

    for d in range(10):
        interpolants.append(
            ('FloaterHormann/%d' % d, Ostap.Math.FloaterHormann(data, d)))

    ## bspline interpolant (Ostap)
    for d in range(1, 6):
        interpolants.append(
            ('BSpline/%s' % d, interpolate_bspline(data, None, d)))

    ## bspline interpolant (scipy)
    if bspline_interpolate:
        for d in range(1, 9, 2):
            item = ('BSpline%dSP' % d, bspline_interpolate(data, d))
            interpolants.append(item)

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

    graphs = []
    with wait(1), use_canvas(name):

        ff = lambda x: tfunc(x)
        f1_draw(ff, xmin=low, xmax=high, linecolor=1, linewidth=3)

        for i, c in enumerate(interpolants):

            n, f = c

            color = i + 2
            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' % (color, n))

    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:

        cnt = counters[(n, fi)]

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

        cpu[n] = t.delta

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

        n, ff = item
        c = counters[item]

        d = distance(ff, tfunc, low, high) / scale
        row = n, '%9.2f +/- %-09.1f' % (
            c.mean().value(), c.rms()), '%-9.1f' % c.max(), '%.3g' % d
        rows.append(row)

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

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

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

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

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

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