def test_triangular(plot=False): a = uc.gummy(uc.TriangularDist(1, 1)) a.sim() assert abs((a.usim - 1 / np.sqrt(6)) / a.usim) < 0.1 if plot: print( 'This should be a triangle with mode 1, lower limit 0 and upper limit 1:' ) a.hist() a = uc.gummy(uc.TriangularDist(-2.5, left_width=0.5, right_width=1.5)) a.sim() if plot: print( 'this should be a triangle with mode -2.5, lower limit -3 and upper limit -1:' ) a.hist() a = uc.gummy(uc.TriangularDist(1, lower_limit=0.5, upper_limit=1.5)) a.sim() if plot: print( 'this should be a triangle with mode 1, lower limit 0.5 and upper limit 1.5:' ) a.hist()
def from_floats(xs, weights=None, unit=None): """ Given a list of x values, returns a gummy with mean center and std error uncertainty. The calculation of the uncertainty is based on Sect. 4.2 of the BIPM's "Guide to the Expression of Uncertainty in Measurement" Parameters ---------- xs : [number] The values to convert into a single mean with uncertainty. weights : [number], optional The weights to be considered for each x value when averaging and taking the standard deviation., by default None unit : str, optional The unit of the value and uncertainty to pass to gummy, by default None Returns ------- gummy The gummy object containing the mean and uncertainty. """ if weights is not None: if len(xs) != len(weights): raise RuntimeError("xs and weights must be of same length") mean = np.average(xs, weights=weights) # Calculate standard deviation, weighted if needed. # np.average divides sum of squared deviations by n. To properly compute # variance this should be (n-1) var = np.average((xs - mean)**2, weights=weights) * len(xs) / (len(xs) - 1) # Standard error on mean is sqrt of (variance divided by n) stder = np.sqrt(var / len(xs)) return mp.gummy(mean, stder, unit=unit)
def make_gummy(sign=None,exp=None,uexp=-6,sometimes_small=True,dof=None, unit=None,units=None,mpf=False,allowzero=True,allowlargeu=True): utypes = ['A','B','D',None] if units is None: units = ['m','lb','m**2 s**3/kg**4','m**3','s**-2','1'] if rand.randint(10) == 0: if exp is None: x = rand.randint(6000) else: x = rand.randint(int(10**exp)) else: x = rand.rand()*0.9 + 0.1 if exp is None: exp = rand.randint(1,6) if rand.randint(2): exp = -exp x = x*10**exp if sign is None: if rand.randint(2): x = -x else: x *= sign if not allowzero and x == 0: x = x + 1 if allowlargeu and rand.randint(10) == 0: u = rand.randint(20) + 1 else: u = rand.rand()*0.5 + 0.5 if sometimes_small and not rand.randint(10): uexp -= 4 u = abs(x)*u*10**uexp if mpf and mp is not None and not rand.randint(4): x = mp.mpf(x) if rand.randint(2): u = mp.mpf(u) if dof is None: if not rand.randint(4): dof = float('inf') else: dof = rand.randint(5,15) if unit is None: unit = units[rand.randint(len(units))] utype = utypes[rand.randint(len(utypes))] g = uc.gummy(x,u=u,dof=dof,unit=unit,utype=utype) return (g,x,u,dof,unit,utype)
def test_zero_derivative(): u = 0.00223 a = uc.gummy(0, u) b = a**2 assert b.u == 0 b.sim() assert abs((np.sqrt(2) * u**2 - b.usim) / b.usim) < 0.1 b.style = 'pmsim' assert '?' not in b.tostring()
def __init__(self): self.MODEL = "5522A" self.MFR = "FLUKE" ## Fluke Generators self.V_DC = InstFunciton(unit = uc.unit('V'),ranges = [ Interval(limits=[0, 329.9999E-3], nominal=lambda x : uc.gummy(x,unit = "mV",u = 20, uunit = "ppm"), error=lambda x: uc.gummy(0,unit = "mV",u = 0,uunit = "ppm"), resolution=0.0001, u_floor=uc.gummy(x=0, u=1, unit="mV", uunit="uV"), u_foor_stability=uc.gummy(x=0, u=1, unit="mV", uunit="uV"), u_resolution=uc.gummy(uc.UniformDist(center=0, half_width=0.0001 / 2), unit="mV", uunit="mV")), Interval(limits=[0, 3.2999999E0], nominal=lambda x: uc.gummy(x, unit="V", u=11, uunit="ppm"), error=lambda x :uc.gummy(0, unit="V", u=0, uunit="ppm"), resolution=0.000001, u_floor=uc.gummy(x=0, u=1, unit="V", uunit="uV"), u_foor_stability=uc.gummy(x=0, u=1, unit="V", uunit="uV"), u_resolution=uc.gummy(uc.UniformDist(center=0, half_width=0.0001 / 2), unit="mV", uunit="mV")) ])
def from_fit(result): """ Converts the results from a fit into a dict of gummys with names taken from the parameters. Parameters ---------- result : lmfit.ModelResult The fit result from lmfit to extract the data from. """ params = result.params return { name: mp.gummy(param.value, param.stderr) for name, param in params.items() }
def __init__(self,limits:list = [], nominal:function = lambda x:uc.gummy(x), error:function = lambda x:0, resolution = 0.1E-16, **kwargs): self.NOMINAL = nominal self.E = error self.min = min(limits) self.max = max(limits) self.unit = self.NOMINAL(0).unit self.Res = resolution self.u = [] ## Uncertainties from different sources for key in kwargs: if "u_" in key: self.u.append(kwargs[key])
def make_number(sign=None,gconst=True,exp=None,fionly=True,allowzero=True): q = rand.randint(4) if fionly and q > 1: q = 1 if q == 0: if exp is not None: x = rand.randint(10**(exp+1)) else: x = rand.randint(100000) if q == 1 or q == 2: x = rand.rand()*0.9 + 0.1 if exp is None: exp = rand.randint(1,6) if rand.randint(2): exp = -exp x = x*10**exp if q == 2 and mp is not None: x = mp.mpf(x) elif q == 3: if exp is not None: a = rand.randint(10**(exp+1)) b = rand.randint(10**(exp+1)) else: a = rand.randint(100000) b = rand.randint(100000) if b == 0: x = Fraction(0) else: x = Fraction(a,b) if sign is None: if rand.randint(2): x = -x else: x *= sign if gconst and rand.randint(2): x = uc.gummy(x) if not allowzero and x == 0: x = x + 1 return x
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_ufrom_multiletter(): a = uc.gummy(10.0, 1, utype='A') b = uc.gummy(20.0, 2, utype='DUT') y = a - b assert abs(y.ufrom('A') - 1) < 1e-15 assert abs(y.ufrom('DUT') - 2) < 1e-15
def test_zero_degc(): a = uc.gummy(0, 0.15, unit='degC') a.style = 'xf' assert a.tostring() == '0.00'
def test_reduce(): a = uc.gummy(12.367, 0.22, unit='mm/m') a.reduce_unit() assert abs(a.x - 0.012367) < 1e-15 assert abs(a.u - 0.00022) < 1e-15 assert a.unit is uc.one