def test_carlson_E(): """Test expression for complete elliptic integral E(k)` via Carlson's symmetruc forms - see Ostap.Math.elliptic_E - see Ostap.Math.carlson_RG """ logger = getLogger('test_carlson_E') logger.info('Test expression for E(k) via Carlson Forms') from ostap.math.models import f1_draw def e1(k): return Ostap.Math.elliptic_E(k) def e2(k): return 2 * Ostap.Math.carlson_RG(1 - k * k, 1, 0) with wait(3), use_canvas('test_carlson_E'): f1_draw(e1, xmin=0, xmax=1, min=0, linecolor=2, linewidth=2) f1_draw(e2, 'same', xmin=0, xmax=1, min=0, linecolor=4, linewidth=2, linestyle=9) logger.info('Red line : E (k) complete elliptic integral') logger.info( "Blue line : E (k) expressed via symmetric Carlson's RG function")
def test_phasespace3_compare(): ## if 1 < 2 : masses = (3, 1, 0.1) fun1 = lambda x: Ostap.Kinematics.phasespace3i(x, *masses ) ## numerical integration fun2 = lambda x: Ostap.Kinematics.phasespace3s(x, *masses ) ## symmetric form fun3 = lambda x: Ostap.Kinematics.phasespace3a(x, *masses ) ## non-symmetric form fun4 = lambda x: Ostap.Kinematics.phasespace3nr( x, *masses) ## non-relativistic limit xmin = sum(masses) with wait(3), use_canvas('test_phasespace3_compare'): for i, f in enumerate((fun1, fun2, fun3, fun4)): color = i + 2 if i == 0: f1_draw(f, line_color=color, linewidth=2, xmin=xmin, xmax=40) else: f1_draw(f, 'same', line_color=color, linewidth=2, xmin=xmin, xmax=40)
def test_interpolation(): """Test spline interpolation """ if 62006 <= root_version_int: logger.warning("Test_interpolation segfaults for ROOT %s" % root_version_int) return from math import sin, pi, sqrt fun = lambda x: sin(2 * pi * x) bs = ostap.math.bspline.interpolate( fun, None, [0] + [random.uniform(0.01, 0.99) for i in range(30)] + [1], 2) from ostap.stats.counters import SE s = SE() for i in range(10000): x = random.uniform(0, 1) vf = fun(x) vb = bs(x) s += vf - vb logger.info('Interpolation quality %s' % s) functions.add(bs) with wait(3), use_canvas('test_interpolation'): f1_draw(fun, xmin=0, xmax=1, linecolor=2) bs.draw('same', linecolor=4)
def make_test(func, xmin, xmax, ptype, orders, logger): results = {} for order in orders: r = ptype(func=func, xmin=xmin, xmax=xmax, N=order) results[order] = r f1_draw(func, xmin=xmin, xmax=xmax, linecolor=2, linewidth=3) logger.info('Thick red line - original function') for o in results: r = results[o] r.draw('same', xmin=xmin, xmax=xmax, linecolor=o) logger.info('Lone color %2d : approximation with order %s' % (o, o))
def test_phasespace3(): """Test 3-body phase space calculation via elliptic integrals - see Ostap.Math.PhaseSpace3 - see Ostap.Math.PhaseSpace3s - see Ostap.Kinematics.phasespace3 - see https://indico.cern.ch/event/368497/contributions/1786992/attachments/1134067/1621999/davydychev.PDF - see http://cds.cern.ch/record/583358/files/0209233.pdf - see https://www.researchgate.net/publication/2054534_Three-body_phase_space_symmetrical_treatments - see A.Davydychev and R.Delbourgo, ``Explicitly symmetrical treatment of three body phase space'', J.Phys. A37 (2004) 4871, arXiv:hep-th/0311075, doi = 10.1088/0305-4470/37/17/016 - see https://arxiv.org/abs/hep-th/0311075 - see https://iopscience.iop.org/article/10.1088/0305-4470/37/17/016 """ logger = getLogger('test_carlson_PS3') logger.info('Test 3-body phase space calculation via elliptic integrals') masses = (3, 1, 0.1) ps1 = Ostap.Math.PhaseSpace3(*masses) ps2 = Ostap.Math.PhaseSpace3s(*masses) ## <--- HERE ps3 = lambda x: Ostap.Kinematics.phasespace3a(x, *masses ) ## non-symmetric form with wait(3), use_canvas('test_phasespace3'): ps1.draw(xmin=ps1.threshold(), xmax=50, linecolor=2, linewidth=2) logger.info( 'Red line - 3-body phase space via numerical integration') ps2.draw('same', xmin=ps1.threshold(), xmax=50, linecolor=4, linewidth=2, linestyle=9) logger.info( 'Blue line - symmetric expression of 3-body phase space via elliptic integrals' ) f1_draw(ps3, 'same', xmin=ps1.threshold(), xmax=50, linecolor=8, linewidth=2, linestyle=11) logger.info( 'Green line - non-symmetric expression of 3-body phase space via elliptic integrals' )
def test_carlson_KmE(): """Test expressions for complete elliptic integral `K(k)-E(k)` via Carlson's symmetruc forms - see Ostap.Math.elliptic_K - see Ostap.Math.elliptic_E - see Ostap.Math.elliptic_KmE - see Ostap.Math.elliptic_RD - see Ostap.Math.elliptic_RF - see Ostap.Math.elliptic_RG """ logger = getLogger('test_carlson_KmE') logger.info('Test expression for K(k)-E(k) via Carlson Forms') from ostap.math.models import f1_draw def e1(k): return Ostap.Math.elliptic_K(k) - Ostap.Math.elliptic_E(k) def e2(k): return k * k * Ostap.Math.carlson_RD(0, 1 - k * k, 1) / 3.0 def e3(k): return Ostap.Math.carlson_RF( 1 - k * k, 1) - 2 * Ostap.Math.carlson_RG(1 - k * k, 1) def e4(k): return Ostap.Math.elliptic_KmE(k) with wait(3), use_canvas('test_carlson_E'): f1_draw(e1, xmin=0, xmax=1 - 1.e-10, min=0, linecolor=2, linewidth=2) logger.info('Red line : K(k) - E(k) as they are ') f1_draw(e2, 'same', xmin=0, xmax=1 - 1.e-10, min=0, linecolor=4, linewidth=2, linestyle=9) logger.info("Blue line : K(k) - E(k) expression via Carlson's RD") f1_draw(e3, 'same', xmin=0, xmax=1 - 1.e-10, min=0, linecolor=8, linewidth=2, linestyle=3) logger.info( "Green line : K(k) - E(k) expression via Carlson's RF and RG") f1_draw(e4, 'same', xmin=0, xmax=1 - 1.e-10, min=0, linecolor=5, linewidth=2, linestyle=4) logger.info("Yellow line : K(k) - E(k) expression via Carlson's RD ")
def test_phasespace3s_permutations(): masses = (3, 1, 0.1) funcs = [] for p in itertools.permutations(masses): f = lambda x: Ostap.Kinematics.phasespace3s(x, *p) funcs.append(f) xmin = sum(masses) with wait(3), use_canvas('test_phasespace3s_permutations'): for i, f in enumerate(funcs): color = i + 1 if i == 0: f1_draw(f, line_color=color, linewidth=2, xmin=xmin, xmax=50) else: f1_draw(f, 'same', line_color=color, linewidth=2, xmin=xmin, xmax=50)
def test_derivative_6 (): """Function with discontiniute derivatives """ logger = getLogger ( 'test_derivative_6' ) ## function a = 1.5 fun = lambda x : abs ( math.sin ( a * x ) ) ## NB! ## singular points singular = [ i * math.pi / a for i in range ( -20 , 21 ) ] derivs = ( Derivative1 ( fun , singular = singular , max_step = 0.5 ) , Derivative2 ( fun , singular = singular , max_step = 0.5 ) , Derivative3 ( fun , singular = singular , max_step = 0.5 ) , Derivative4 ( fun , singular = singular , max_step = 0.5 ) , Derivative5 ( fun , singular = singular , max_step = 0.5 ) , Derivative6 ( fun , singular = singular , max_step = 0.5 ) , ) lines = [] with wait ( 5 ) , use_canvas ( 'test_derivative_6' ) : xmin, xmax = -4 , 4 f1_draw ( fun , xmin = xmin , xmax = xmax , linecolor=2 , linewidth = 3 , min = -12 , max = 12 ) for i, d in enumerate ( derivs , start = 1 ) : color = 2 + i d.draw ( 'same' , xmin = xmin , xmax = xmax , linecolor = color , linewidth = 2 ) v = a**i l1 = ROOT.TLine ( xmin , -v , xmax , -v ) l2 = ROOT.TLine ( xmin , v , xmax , v ) for l in ( l1 ,l2 ) : l.SetLineColor ( color ) l.SetLineStyle ( 8 ) lines.append ( l ) l.draw()
def test_approximation(): """Test spline approximation """ from math import sin, pi, sqrt fun = lambda x: sin(2 * pi * x) bs = ostap.math.bspline.approximate( fun, [0] + [random.uniform(0.01, 0.99) for i in range(50)] + [1], 2) from ostap.stats.counters import SE s = SE() for i in range(10000): x = random.uniform(0, 1) vf = fun(x) vb = bs(x) s += vf - vb logger.info('Approximation quality %s' % s) functions.add(bs) with wait(3), use_canvas('test_approximation'): f1_draw(fun, xmin=0, xmax=1, linecolor=2) bs.draw('same', linecolor=4)
s = r.sigma_G*1.0 results [ m ] = s gr [i] = m , s del ds interpolants = [ Berrut1st ( results ) , Berrut2nd ( results ) , Barycentric ( results ) ] + [ FloaterHormann ( results , i ) for i in range ( 10 ) ] graphs = [] with wait ( 5 ) , use_canvas ( 'test_fitresults' ) : f1_draw ( sigma , linecolor=1 , linewidth = 4 , minimum = 0 , xmin = 0 , xmax = 100 ) gr.red() gr.draw ('pe1') K = 255 for i,f in enumerate ( interpolants ) : g = ROOT.TGraphErrors ( K + 1 ) for j,x in enumerate ( vrange ( 0 , 100 , K ) ) : g[j] = x , f ( x ) graphs.append ( g ) for i, g in enumerate ( graphs ) : g.draw ('lpe1', linecolor = i+3 , markercolor = i+3 ) gr.draw ('pe1')
def draw1D(fun, **kwargs): """draw function via conversion to TF1""" from ostap.math.models import f1_draw return f1_draw(fun, **kwargs)
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, 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))