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 )
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))