def test_mulxpow(n=1000): def f(*x): r = x[0] for i in range(len(x) - 1): r *= x[i + 1] return r for j in range(n): k = rand.randint(10) + 2 x = make_gummy(unit=1)[0] a = f(*(k * [x])) b = x**k xx = x.x c = uc.gummy.apply(f, lambda *x: len(x) * [xx**(k - 1)], *(k * [x])) d = uc.gummy.napply(f, *(k * [x])) if b.x == 0: assert abs(a.x - b.x) < 1e-14 else: assert abs((a.x - b.x) / b.x) < 1e-14 if x.u == 0: assert a.u == 0 assert b.u == 0 else: assert abs((a.u - b.u) / b.u) < 1e-3 assert a.correlation(b) == 1 if k % 2 == 0 and x.x < 0: assert a.correlation(x) == -1 else: assert a.correlation(x) == 1 if b.x == 0: assert abs(c.x - b.x) < 1e-14 else: assert abs((c.x - b.x) / b.x) < 1e-14 if x.u == 0: assert c.u == 0 else: assert abs((c.u - b.u) / b.u) < 1e-3 assert c.correlation(b) == 1 if b.x == 0: assert abs(d.x - b.x) < 1e-14 else: assert abs((d.x - b.x) / b.x) < 1e-14 if x.u == 0: assert d.u == 0 else: assert abs((d.u - b.u) / b.u) < 1e-3 assert d.correlation(b) == 1
def test_addxmul(n=1000): def f(*x): r = x[0] for i in range(len(x) - 1): r += x[i + 1] return r for j in range(n): k = rand.randint(10) + 2 x = make_gummy(unit=1)[0] a = f(*(k * [x])) b = k * x c = uc.gummy.apply(f, lambda *x: len(x) * [1], *(k * [x])) d = uc.gummy.napply(f, *(k * [x])) if b.x == 0: assert abs(a.x - b.x) < 1e-14 else: assert abs((a.x - b.x) / b.x) < 1e-14 if x.u == 0: assert a.u == 0 assert b.u == 0 else: assert (a.u - b.u) / b.u < 1e-3 assert a.correlation(b) == 1 assert a.correlation(x) == 1 if b.x == 0: assert abs(c.x - b.x) < 1e-14 else: assert abs((c.x - b.x) / b.x) < 1e-14 if x.u == 0: assert c.u == 0 else: assert (c.u - b.u) / b.u < 1e-3 assert c.correlation(b) == 1 if b.x == 0: assert abs(d.x - b.x) < 1e-14 else: assert abs((d.x - b.x) / b.x) < 1e-14 if x.u == 0: assert d.u == 0 else: assert abs((d.u - b.u) / b.u) < 1e-3 assert d.correlation(b) == 1
def test_mulxnpow(n=1000): def f(*x): r = 1 / x[0] for i in range(len(x) - 1): r *= 1 / x[i + 1] return r for j in range(n): k = rand.randint(10) + 2 x = make_gummy(unit=1, allowzero=False, allowlargeu=False)[0] a = f(*(k * [x])) b = x**-k d = uc.gummy.napply(f, *(k * [x])) if b.x == 0: assert abs(a.x - b.x) < 1e-14 else: assert abs((a.x - b.x) / b.x) < 1e-14 if x.u == 0: assert a.u == 0 assert b.u == 0 else: assert abs((a.u - b.u) / b.u) < 1e-3 assert a.correlation(b) == 1 if k % 2 == 0 and x.x < 0: assert a.correlation(x) == 1 else: assert a.correlation(x) == -1 if b.x == 0: assert abs(d.x - b.x) < 1e-14 else: assert abs((d.x - b.x) / b.x) < 1e-14 if x.u == 0: assert d.u == 0 else: assert abs((d.u - b.u) / b.u) < 1e-3 assert d.correlation(b) == 1
def test_gummy_init(n=None, exception_on_warning=True, prnt=False, plot=False): print( 'uc.gummy.p_method may be modified\nset uc.gummy.p_method = \'loc\' to recover the default value' ) from scipy.stats import norm, t uc.gummy.p_method = None if n is None: if prnt or plot: n = 100 else: n = 10000 units = ['m', 'lb', 'm**2 s**3/kg**4', 'degF', 'cm', '%', 'kg'] uunits = {'%': 100, 'ppm': 1e6, 'ppb': 1e9, 'ms/s': 1000} with warnings.catch_warnings(): if exception_on_warning: warnings.simplefilter('error') else: warnings.simplefilter('ignore') for i in range(n): if rand.randint(2): unit = units[rand.randint(len(units))] else: unit = uc.one if rand.randint(2): if unit == 'm': if rand.randint(2): uunit = 'mm' elif rand.randint(2): uunit = 'm' else: uunit = 'in' else: if unit in ['degF', 'dB(SPL)', 'Np']: uunit = None else: uunit = list(uunits.keys())[rand.randint(len(uunits))] else: uunit = None bayesian = bool(rand.randint(2)) if rand.randint(2): dof = rand.randint(3, 20) else: dof = float('inf') if rand.randint(2): if rand.randint(2): k = 4 * rand.rand() + 0.1 p = None else: p = rand.rand() / 2 + 0.49 k = 1 else: k = 1 p = None if rand.randint(2): pmethods = [ 'loc', 'level of confidence', 'cp', 'coverage probability', 'gauss', 'ccp', 'ccp', 'conservative coverage probability', 'chebyshev' ] uc.gummy.p_method = pmethods[rand.randint(len(pmethods))] else: uc.gummy.p_method = None if unit == 'dB(SPL)': if rand.randint(10) == 0: x = rand.randint(-10, 10) else: x = 100.0 * (2 * rand.rand() - 1) elif unit == 'Np': if rand.randint(10) == 0: x = rand.randint(-10, 10) else: x = 20.0 * (2 * rand.rand() - 1) else: if rand.randint(10) == 0: x = rand.randint(-60000, 60000) else: x = (2 * rand.rand() - 1) * 10.0**rand.randint(-10, 10) if rand.randint(20) == 0: x = 0 if uunit in ['%', 'ppm', 'ppb', 'ms/s' ] and not (unit == '%' and uunit == '%'): U = 1.0e3 * rand.rand() u = abs(x) * U / uunits[uunit] elif unit == 'm' and uunit == 'mm': if x == 0: U = 1.0e3 * rand.rand() else: U = abs(x) * 1.0e3 * rand.rand() u = U / 1000 elif unit == 'm' and uunit == 'in': if x == 0: U = 100 * rand.rand() else: U = abs(x) * 100 * rand.rand() u = U * 0.0254 else: if x == 0: U = 1.0e12 * rand.rand() else: if rand.randint(20) == 0: U = 1e6 * abs(x) * rand.rand() elif rand.randint(20) == 0: U = rand.randint(20) + 1 else: U = 1.1 * abs(x) * rand.rand() u = U if rand.randint(2): name = chr(rand.randint(20) + 65) + chr(rand.randint(20) + 65) + chr(rand.randint(20) + 65) else: name = None if rand.randint(2): utype = chr(rand.randint(20) + 65) + chr(rand.randint(20) + 65) + chr(rand.randint(20) + 65) else: utype = None if rand.randint(20) == 0: assert uc.gummy(x) == x continue if rand.randint(20) == 0: const = True U = 0 u = 0 else: if u == 0: const = True else: const = False uc.gummy.bayesian = bayesian if uunit is not None and rand.randint(2): uu = uc.gummy(U, unit=uunit) g = uc.gummy(x, u=uu, unit=unit, dof=dof, k=k, p=p, name=name, utype=utype) else: g = uc.gummy(x, u=U, unit=unit, dof=dof, k=k, p=p, uunit=uunit, name=name, utype=utype) if not const: u = u / g.k orig_g = g if rand.randint(10) == 0: n = rand.randint(12) if bayesian and n > 0: dof = float('inf') if n == 0: g = uc.gummy(g) assert g.name is None elif n == 1: if unit == 'degF': g = g + uc.gummy(0, unit='degF-i') else: g = 1 * g elif n == 2: if unit == 'degF': g = g + uc.gummy(0, unit='degF-i') else: g = g * 1 elif n == 3: if unit == 'degF': g = g + uc.gummy(0, unit='degF-i') else: g = g / 1 elif n == 4: if unit == 'degF': v = uc.gummy(0, unit='degF-i') elif unit is not uc.one or rand.randint(2): v = uc.gummy(0, unit=unit) else: v = 0 g = g + v elif n == 5: if unit == 'degF': v = uc.gummy(0, unit='degF-i') elif unit is not uc.one or rand.randint(2): v = uc.gummy(0, unit=unit) else: v = 0 g = v + g elif n == 6: if unit == 'degF': v = uc.gummy(0, unit='degF-i') elif unit is not uc.one or rand.randint(2): v = uc.gummy(0, unit=unit) else: v = 0 g = g - v elif n == 7: if unit == 'degF': g = g + uc.gummy(0, unit='degF-i') elif unit in ['dB(SPL)', 'Np']: g = g + uc.gummy(0, unit=unit) else: g = g**1 elif n == 8: if unit == 'degF': g = g + uc.gummy(0, unit='degF-i') else: g = +g elif n == 9: if unit == 'degF': g = g + uc.gummy(0, unit='degF-i') else: g = 2.1 * g g = g / 2.1 elif n == 10: if unit == 'degF': g = g + uc.gummy(0, unit='degF-i') else: if unit is not uc.one or rand.randint(2): v = uc.gummy(3.5 * x, u=0.45 * u, unit=unit) else: v = 3.3 * x g = v - g g = g - v g = -g else: if unit == 'degF': g = g + uc.gummy(0, unit='degF-i') else: if x >= 0: g = abs(g) else: g = -abs(g) k = 1 p = None reinit = True uunit = None name = None else: reinit = False if x != 0 and g.x != 0: assert abs(g.x - x) / abs(x) < 1e-10 else: assert abs(g.x - x) < 1e-10 if x != 0 and g.x != 0: assert abs(g.x - x) / abs(x) < 1e-10 else: assert abs(g.x - x) < 1e-10 if unit == 'degF': assert g.unit in [uc.Unit.unit('degF'), uc.Unit.unit('degF-i')] else: assert g.unit is uc.Unit.unit(unit) assert g.name == name if const: assert g.u == 0 if unit is uc.one: if x == 0: assert abs(g - x) < 1e-10 else: assert abs(g - x) / x < 1e-10 elif unit == '%': if x == 0: assert abs(g - x / 100) < 1e-10 else: assert abs((g - x / 100) / (x / 100)) < 1e-10 elif unit == 'Np': assert abs(g.convert(1) - np.exp(x)) / np.exp(x) < 1e-10 continue if uunit in ['%', 'ppm', 'ppb', 'dB', 'ms/s'] and unit != uunit: assert g.uunit_is_rel else: assert not g.uunit_is_rel assert (g.x - x) / u < 1e-6 if dof == float('inf'): assert g.dof == float('inf') else: assert (g.dof - dof) / dof < 1e-6 if uunit is not None and uunit != unit: assert g.uunit is uc.Unit.unit(uunit) if g.p == 0: assert p is None assert k <= 3 else: if p is None: assert g.k == k else: assert g.p == p if uc.gummy.p_method in ['loc', 'level of confidence', None]: if dof == float('inf'): assert abs(g.k - norm.ppf(0.5 + g.p / 2)) < 1e-6 else: if bayesian: if g.p is not None: assert abs(g.k - np.sqrt((dof - 2) / dof) * t.ppf(0.5 + g.p / 2, dof)) < 1e-6 else: assert abs(g.k - t.ppf(0.5 + g.p / 2, dof)) < 1e-6 elif uc.gummy.p_method in [ 'cp', 'coverage probability', 'gauss' ]: if dof == float('inf') or bayesian: if g.p is not None: assert abs(g.k - 2 / (3 * (np.sqrt(1 - g.p)))) < 1e-6 else: if g.p is not None: assert abs(g.k - np.sqrt(dof / (dof - 2)) * (2 / (3 * (np.sqrt(1 - g.p))))) < 1e-6 else: if dof == float('inf') or bayesian: if g.p is not None: assert abs(g.k - 1 / np.sqrt(1 - g.p)) < 10.0**-6 else: if g.p is not None: assert abs(g.k - np.sqrt(dof / (dof - 2)) * (1 / np.sqrt(1 - g.p))) < 1e-6 assert abs((g.u - u) / u) < 1e-10 if not reinit: assert abs(g.U - U) / U < 1e-10 assert abs((g.u - u) / u) < 1e-10 assert '?' not in g.tostring() if prnt: print('------') print() if rand.randint(2): styles = [ 'pm', 'pmi', 'concise', 'ueq', 'x', 'xf', 'u', 'uf', 'xunit', 'uunit' ] g.style = styles[rand.randint(10)] g.show_k = bool(rand.randint(2)) g.show_dof = bool(rand.randint(2)) g.show_p = bool(rand.randint(2)) g.show_name = bool(rand.randint(2)) g.solidus = bool(rand.randint(2)) g.mulsep = bool(rand.randint(2)) if not rand.randint(5): g.nsig = rand.randint(5) + 1 assert '?' not in g.tostring() print(g.style, ', show_k=', g.show_k, ', show_dof=', g.show_dof, ', show_p=', g.show_p, ', show_name=', g.show_name, ', solidus=', g.solidus, ', mulsep=', g.mulsep, ', nsig=', g.nsig, ':') print() display(g) print() if plot: print('------') print() print(g) g.sim() if rand.randint(2): styles = [ 'pmsim', 'pmsimi', 'mcisim', 'cisim', 'usim', 'ufsim' ] g.style = styles[rand.randint(6)] g.slashaxis = bool(rand.randint(2)) print(g.style, ', slashaxis=', g.slashaxis, ':') print() display(g) print() g.hist() print() uc.gummy.bayesian = False
def test_ubreakdown(n=None, prnt=False, budget=False): uc.gummy.p_method = None if n is None: if prnt or budget: n = 100 else: n = 1000 for i in range(n): k = rand.randint(1, 6) if rand.randint(2): unt = '1' else: unt = None g, x, u, dof, unit, utype = zip( *[make_gummy(unit=unt) for y in range(k)]) for i, y in enumerate(g): if y.u != 0: assert y.utype is utype[i] c = rand.rand() * 0.9 + 0.1 if rand.randint(2): c = -c def f(*p): r = c for y in p: r *= y return r def d(k, *p): r = c for i, y in enumerate(p): if i != k: r *= y return r gr = f(*g) ut = None for q in g: if gr.value._ref is q.value._ref: ut = q.utype assert gr.utype is ut x = list(x) u = list(u) lb = 'lb' in str(gr.unit) kg = 'kg' in str(gr.unit) for i, un in enumerate(unit): if 'lb' in un and not lb: x[i] *= 0.45359237 u[i] *= 0.45359237 if 'kg' in un and not kg and lb: x[i] *= 0.45359237**4 u[i] *= 0.45359237**4 xr = f(*x) if xr == 0: assert abs(gr.x - xr) < 1e-10 else: assert abs(gr.x - xr) / abs(xr) < 1e-10 ur = 0 for i, y in enumerate(u): ur += y**2 * d(i, *x)**2 ur = np.sqrt(ur) if ur == 0: assert abs(gr.u) < 1e-10 else: assert abs(gr.u - ur) / ur < 1e-10 dofr = 0 for i, (v, idof) in enumerate(zip(u, dof)): dofr += v**4 * d(i, *x)**4 / idof if dofr == 0: dofr = float('inf') else: dofr = ur**4 / dofr if dofr > uc.gummy.max_dof: dofr = float('inf') # Due to the fact that any dof larger than gummy.mox_dof is rounded to # infinity in intermediate calculations, gr.dof may not be exactly dofr # particularly for large dofr. #if dofr > 100: #assert gr.dof > 100 #else: #assert abs(gr.dof - dofr)/dofr < 1e-2 if unt == '1': if k == 1: dr = lambda *x: d(0, *x) else: dr = lambda *x: [d(i, *x) for i in range(k)] ga = uc.gummy.apply(f, dr, *g) if xr == 0: assert abs(ga.x) < 1e-10 else: assert abs(ga.x - xr) / abs(xr) < 1e-10 if ur == 0: assert abs(ga.u) < 1e-6 else: assert abs(ga.u - ur) / ur < 1e-6 if dofr > 100: assert ga.dof > 100 else: assert abs(ga.dof - dofr) / dofr < 1e-2 gn = uc.gummy.napply(f, *g) if xr == 0: assert abs(gn.x) < 1e-10 else: assert abs(gn.x - xr) / abs(xr) < 1e-10 if ur == 0: assert abs(gn.u) < 1e-3 else: assert abs(gn.u - ur) / ur < 1e-3 if dofr > 100: assert gn.dof > 100 else: assert abs(gn.dof - dofr) / dofr < 1e-2 if rand.randint(2): if rand.randint(2): gf = ga else: gf = gn else: gf = gr else: gf = gr gl = list(g) if not rand.randint(4): gl.append(make_gummy(unit=unt)[0]) if rand.randint(2): e = gl[rand.randint(len(gl))] else: e = [ gl[rand.randint(len(gl))] for i in range(rand.randint(len(gl))) ] if ur > 0: ua = 0 ub = 0 ud = 0 ue = 0 dofa = 0 dofb = 0 dofd = 0 dofe = 0 for i, (ig, iu, idof) in enumerate(zip(g, u, dof)): if gf.ufrom(ig) == 0: assert iu * d(i, *x) / ur < 1e-3 else: if ig.utype == 'A': ua += iu**2 * d(i, *x)**2 dofa += iu**4 * d(i, *x)**4 / idof elif ig.utype == 'B': ub += iu**2 * d(i, *x)**2 dofb += iu**4 * d(i, *x)**4 / idof elif ig.utype == 'D': ud += iu**2 * d(i, *x)**2 dofd += iu**4 * d(i, *x)**4 / idof try: if e is ig or ig in e: ue += iu**2 * d(i, *x)**2 dofe += iu**4 * d(i, *x)**4 / idof except TypeError: pass ua = np.sqrt(ua) ub = np.sqrt(ub) ud = np.sqrt(ud) ue = np.sqrt(ue) if dofa == 0: dofa = float('inf') else: dofa = ua**4 / dofa if dofb == 0: dofb = float('inf') else: dofb = ub**4 / dofb if dofd == 0: dofd = float('inf') else: dofd = ud**4 / dofd if dofe == 0: dofe = float('inf') else: dofe = ue**4 / dofe if ua == 0: assert gf.ufrom('A') == 0 else: assert abs(gf.ufrom('A') - ua) / ur < 1e-3 if ua / ur > 0.01: if dofa > 100 or gf.ufrom('A') == 0: assert gf.doffrom('A') > 100 else: assert abs(gf.doffrom('A') - dofa) / dofa < 1e-2 if ub == 0: assert gf.ufrom('B') == 0 else: assert abs(gf.ufrom('B') - ub) / ur < 1e-3 if ub / ur > 0.01: if dofb > 100 or gf.ufrom('B') == 0: assert gf.doffrom('B') > 100 else: assert abs(gf.doffrom('B') - dofb) / dofb < 1e-2 if ud == 0: assert gf.ufrom('D') == 0 else: assert abs(gf.ufrom('D') - ud) / ur < 1e-3 if ud / ur > 0.01: if dofd > 100 or gf.ufrom('D') == 0: assert gf.doffrom('D') > 100 else: assert abs(gf.doffrom('D') - dofd) / dofd < 1e-2 if ue == 0: assert gf.ufrom(e) == 0 else: assert abs(gf.ufrom(e) - ue) / ur < 1e-3 #if ue/ur > 0.01: #if dofe > 100 or gf.ufrom(e) == 0: #assert gf.doffrom(e) > 100 #else: #assert abs(gf.doffrom(e) - dofe)/dofe < 1e-2 if not rand.randint(4): gf.uunit = '%' styles = ['pm', 'pmi', 'concise', 'ueq', 'u', 'uf'] gf.style = styles[rand.randint(6)] assert '?' not in gf.tostring() ub = {i.utype for i in g if i.utype is not None} if not rand.randint(8) and len(ub) > 1: ub.pop() ub = list(ub) gfub = gf.copy(formatting=True) if len(ub) > 0: gfub.ubreakdown = ub assert '?' not in gfub.tostring() if prnt: w = rand.randint(5) if w == 0: print(gf) print(gfub) elif w == 1: gf.latex() gfub.latex() elif w == 2: gf.html() gfub.html() elif w == 3: gf.unicode() gfub.unicode() else: gf.ascii() gfub.ascii() if budget: show_expanded_u = bool(rand.randint(2)) show_subtotals = bool(rand.randint(2)) k = None p = None if bool(rand.randint(2)): if bool(rand.randint(2)): if bool(rand.randint(2)): gf.k = 2 else: k = 2 else: if bool(rand.randint(2)): gf.p = 0.95 else: p = 0.95 if bool(rand.randint(2)): gl[0].name = 'gl0' if bool(rand.randint(2)) and len(gl) > 1: gl[1].name = 'gl1' if bool(rand.randint(2)): gf.name = 'gf' if not bool(rand.randint(4)): description = [ 'description ' + str(i) for i in range(len(gl) + 1) ] else: description = None if not bool(rand.randint(4)): custom = [str(i) for i in range(len(gl) + 1)] custom_heading = 'n' else: custom = None custom_heading = None show_s = None show_c = None show_d = None if bool(rand.randint(2)): show_s = bool(rand.randint(2)) show_c = bool(rand.randint(2)) show_d = bool(rand.randint(2)) b = gf.budget(gl, show_subtotals=show_subtotals, show_expanded_u=show_expanded_u, k=k, p=p, description=description, show_s=show_s, show_c=show_c, show_d=show_d, custom=custom, custom_heading=custom_heading) w = rand.randint(5) if w == 0: print(b) elif w == 1: b.latex() elif w == 2: b.html() else: b.unicode() if prnt or budget: print() print('---') print()
def binary_func(f, df, sim=False, exp=None, fionly=False, uexp=-6, allowazero=True, allowbzero=True, allowlargeu=True): if sim: dof = dof = float('inf') else: dof = None a, ax, au, adof, _, _ = make_gummy(unit=1, dof=dof, exp=exp, mpf=(not fionly), uexp=uexp, allowzero=allowazero, allowlargeu=allowlargeu) if rand.randint(2): b = make_number(exp=exp, fionly=fionly, allowzero=allowbzero) if isinstance(b, uc.gummy): bx = b.x else: bx = b bu = 0 bdof = float('inf') else: b, bx, bu, bdof, _, _ = make_gummy(unit=1, dof=dof, exp=exp, mpf=(not fionly), uexp=uexp, allowzero=allowbzero, allowlargeu=allowlargeu) ax = float(ax) bx = float(bx) au = float(au) bu = float(bu) x = f(ax, bx) d = df(ax, bx) da = float(d[0]) db = float(d[1]) u = np.sqrt((da * au)**2 + (db * bu)**2) if dof is None: dof = ((da * au)**4 / adof + (db * bu)**4 / bdof) if dof == 0: dof = float('inf') else: dof = u**4 / dof if dof > uc.gummy.max_dof: dof = float('inf') if dof < 1: dof = 1 dof = float(dof) g = f(a, b) if x == 0: assert abs(g.x) < 1e-15 else: assert abs((g.x - x) / x) < 1e-14 if u == 0: assert abs(u) < 1e-6 else: assert abs((g.u - u) / u) < 1e-3 if dof is not None and not np.isinf(dof): assert abs((g.dof - dof) / dof) < 0.01 assert a.correlation(b) == 0 if sim and x != 0 and abs(u / x) > 1e-10: uc.gummy.simulate([a, b, g]) assert abs((g.xsim - x) / (g.u / np.sqrt(1e5))) < 5 assert abs((g.u - g.usim) / g.u) < 0.1 if g.correlation(a) > 0.1: assert abs((g.correlation_sim(a) - g.correlation(a)) / g.correlation(a)) < 0.1 if isinstance(b, uc.gummy) and g.correlation(b) > 0.1: assert abs((g.correlation_sim(b) - g.correlation(b)) / g.correlation(b)) < 0.1