def test_vectorize_units(): def test(x): ''' A function that will fail if called with an array ''' if x > 0: return x * 2 else: return x # First run has no units u = uc.UncertCalc(test, samples=1000) u.set_input('x', nom=100, std=1) u.calculate(gum=False) assert np.isclose(u.out.mc.nom().magnitude, 200, atol=1) assert str(u.out.mc._units[0]) == 'dimensionless' # Now input has units but output units are not specified u = uc.UncertCalc(test, samples=1000) u.set_input('x', nom=100, std=1, units='cm') u.calculate(gum=False) assert np.isclose(u.out.mc.nom().magnitude, 200, atol=1) assert str(u.out.mc._units[0]) == 'centimeter' # Finally, request a unit conversion on the output u = uc.UncertCalc(test, units='meter', samples=1000) u.set_input('x', nom=100, std=1, units='cm') u.calculate(gum=False) assert np.isclose(u.out.mc.nom().magnitude, 2, atol=.1) assert str(u.out.mc._units[0]) == 'meter'
def test_inductance(): ''' Inductance calculation. Test wrapping callable with units ''' from scipy.special import ellipk, ellipe def inductance_nagaoka(radius, length, N, mu0): ''' Calculate inductance using Nagaoka formula ''' k = numpy.sqrt(4 * radius**2 / (4 * radius**2 + length**2)) kprime = numpy.sqrt(1 - k**2) Kk = ellipk(k**2) Ek = ellipe(k**2) kL = 4 / 3 / numpy.pi / kprime * ((kprime / k)**2 * (Kk - Ek) + Ek - k) return mu0 * numpy.pi * N**2 * radius**2 / length * kL u = uc.UncertCalc( inductance_nagaoka, units='uH', finunits=['meter', 'meter', 'dimensionless', 'henry/meter'], foutunits=['henry']) u.set_input('radius', 2.7, units='mm', unc=.005, k=1) u.set_input('length', 9, units='mm', unc=.01, k=1) u.set_input('N', 100, units='dimensionless') # No uncertainty u.set_input('mu0', 1.25663706212E-6, unc=0.00000000019E-6, units='H/m', k=2) u.calculate() assert numpy.isclose(u.out.gum.nom().magnitude, 25.21506) assert numpy.isclose(u.out.mc.nom().magnitude, 25.21506)
def test_units(): # Basic units propagation u = uc.UncertCalc('J*V', units='mW', seed=12345) u.set_input('J', nom=4, unc=.04, k=2, units='V') u.set_input('V', nom=20, units='mA') u.set_uncert('V', name='u(typeA)', std=.1, k=2) u.set_uncert('V', name='u(typeB)', std=.15, k=2) u.calculate() assert str(u.out.gum._units[0]) == 'milliwatt' assert np.isclose(u.out.gum.nom().magnitude, 80) assert str(u.out.mc._units[0]) == 'milliwatt' assert np.isclose(u.out.mc.nom().magnitude, 80) assert str(u.out.mc.nom().units) == 'milliwatt' assert 'mW' in str(u.out.gum.report()) assert 'mW' in str(u.out.gum.report_expanded()) assert 'mW' in str(u.out.mc.report()) assert 'mW' in str(u.out.mc.report_expanded()) # Change output to microwatts and recalculate u.model.outunits = ['uW'] u.calculate() assert str(u.out.gum._units[0]) == 'microwatt' assert np.isclose(u.out.gum.nom().magnitude, 80000) assert str(u.out.gum.nom().units) == 'microwatt' assert str(u.out.mc._units[0]) == 'microwatt' assert np.isclose(u.out.mc.nom().magnitude, 80000) assert str(u.out.mc.nom().units) == 'microwatt'
def test_uc(capsys): ''' Test uncertainty calc ''' u = uc.UncertCalc('f = a * b + c', seed=4848484) u.set_input('a', nom=10, std=1) u.set_input('b', nom=5, dist='uniform', a=.5) u.set_input('c', nom=3, unc=3, k=2) u.correlate_vars('a', 'b', .6) u.correlate_vars('c', 'b', -.3) out = u.calculate() report = out.report().get_md(mathfmt='text', figfmt='text') cli.main_unc(['f=a*b+c', '--variables', 'a=10', 'b=5', 'c=3', '--uncerts', 'a; std=1', 'b; dist=uniform; a=.5', 'c; unc=3; k=2', '--correlate', 'a; b; .6', 'c; b; -.3', '--seed=4848484']) report2, err = capsys.readouterr() assert report == report2 # HTML format reporthtml = out.report().get_html(mathfmt='latex', figfmt='svg') cli.main_unc(['f=a*b+c', '--variables', 'a=10', 'b=5', 'c=3', '--uncerts', 'a; std=1', 'b; dist=uniform; a=.5', 'c; unc=3; k=2', '--correlate', 'a; b; .6', 'c; b; -.3', '-f', 'html', '--seed=4848484']) report2html, err = capsys.readouterr() assert reporthtml == report2html # MD format reportmd = out.report().get_md(mathfmt='latex', figfmt='svg') cli.main_unc(['f=a*b+c', '--variables', 'a=10', 'b=5', 'c=3', '--uncerts', 'a; std=1', 'b; dist=uniform; a=.5', 'c; unc=3; k=2', '--correlate', 'a; b; .6', 'c; b; -.3', '-f', 'md', '--seed=4848484']) report2md, err = capsys.readouterr() assert reportmd == report2md
def test_projrem(): # Test add/remove items from project u = suncal.UncertCalc('f = a*b', name='function1') u2 = suncal.UncertCalc('g = c*d', name='function2') proj = project.Project() proj.add_item(u) proj.add_item(u2) assert proj.get_names() == ['function1', 'function2'] proj.rem_item(0) assert proj.get_names() == ['function2'] proj = project.Project() proj.add_item(u) proj.add_item(u2) proj.rem_item('function2') assert proj.get_names() == ['function1']
def test_multifunc(): ''' Test multiple functions in UncertCalc with different units ''' # Start without units -- convert all inputs to base units and *1000 to get milliwatt u1 = uc.UncertCalc(['P = J*V*1000', 'R = V/J'], seed=398232) u1.set_input('V', nom=10, std=.5) u1.set_input('J', nom=5) u1.set_uncert('J', name='u_A', std=.05) # 50 mA u1.set_uncert('J', name='u_B', std=.01) # 1 mA = 10000 uA u1.calculate() meanP = u1.out.gum.nom('P').magnitude uncertP = u1.out.gum.uncert('P').magnitude meanR = u1.out.gum.nom('R').magnitude uncertR = u1.out.gum.uncert('R').magnitude # Now with units specified instead of converting first u = uc.UncertCalc(['P = J*V', 'R = V/J'], units=['mW', 'ohm'], seed=398232) u.set_input('V', nom=10, std=.5, units='V') u.set_input('J', nom=5, units='ampere') u.set_uncert('J', name='u_A', std=50, units='mA') # Uncert not same units as variable u.set_uncert('J', name='u_B', std=10000, units='uA') u.calculate() # And compare. assert np.isclose(u.out.gum.nom('P').magnitude, meanP) assert np.isclose(u.out.gum.uncert('P').magnitude, uncertP) assert str(u.out.gum.nom('P').units) == 'milliwatt' assert np.isclose(u.out.mc.nom('P').magnitude, meanP, rtol=.0001) assert np.isclose(u.out.mc.uncert('P').magnitude, uncertP, rtol=.001) assert str(u.out.mc.nom('P').units) == 'milliwatt' assert np.isclose(u.out.mc.nom('R').magnitude, meanR, rtol=.0001) assert np.isclose(u.out.mc.uncert('R').magnitude, uncertR, rtol=.001) assert str(u.out.mc.nom('R').units) == 'ohm' assert np.isclose(u.out.mc.nom('R').magnitude, meanR, rtol=.0001) assert np.isclose(u.out.mc.uncert('R').magnitude, uncertR, rtol=.001) assert str(u.out.mc.nom('R').units) == 'ohm'
def test_power(): ''' Test case for powers of dimensionless quantities ''' # See https://github.com/hgrecco/pint/issues/670 # Make sure we have a workaround since this inconsistency was closed without a fix # with x = np.arange(5) * ureg.dimensionless # np.exp(x) --> returns dimensionless array # 2**x --> raises DimensionalityError u = uc.UncertCalc('f = 2**x') u.seed = 8833293 u.set_input('x', nom=4, std=.1) # No units / dimensionless u.calculate() assert u.out.mc.uncert().units == ureg.dimensionless assert np.isclose(u.out.mc.nom().magnitude, 16.0, rtol=.01) assert np.isclose(u.out.mc.uncert().magnitude, u.out.gum.uncert().magnitude, rtol=.02)
def test_savesamples(tmpdir): ''' Test savesamples function, in txt and npz formats. ''' np.random.seed(1111) u = uc.UncertCalc('f=a+b', units='meter', samples=20) u.set_input('a', nom=10, std=.1, units='cm') u.set_input('b', nom=20, std=.2, units='mm') u.calculate() sfile = os.path.join(tmpdir, 'samples.txt') nfile = os.path.join(tmpdir, 'samples.npz') u.save_samples(sfile, fmt='csv') u.save_samples(nfile, fmt='npz') # Load in and compare (only comparing output column here) loadedsamples = np.genfromtxt(sfile, skip_header=1) assert np.allclose(loadedsamples[:, 2], u.out.mc.samples('f').magnitude) loadednpz = np.load(nfile) assert np.allclose(loadednpz['samples'][:, 2], u.out.mc.samples('f').magnitude)
def test_saveload_fname(tmpdir): # Set up a Project with all types of calculations. Save it to a file (both using file NAME # and file OBJECT, read back the results, and compare the output report. # Make sure to store seeds for everything that does MC. np.random.seed(588132535) # Set up several project components of the different types u = suncal.UncertCalc('f = m/(pi*r**2)', seed=44444) u.set_input('m', nom=2, std=.2) u.set_input('r', nom=1, std=.1) u2 = suncal.UncertCalc('g = m * 5', seed=4444) u2.set_input('m', nom=5, std=.5) rsk = risk.Risk() rsk.set_procdist(distributions.get_distribution('t', loc=.5, scale=1, df=9)) swp = sweeper.UncertSweep(u) swp.add_sweep_nom('m', values=[.5, 1, 1.5, 2]) x = np.linspace(-10, 10, num=21) y = x * 2 + np.random.normal(loc=0, scale=.5, size=len(x)) arr = curvefit.Array(x, y, uy=0.5) fit = curvefit.CurveFit(arr, seed=909090) rev = reverse.UncertReverse('f = m/(pi*r**2)', seed=5555, targetnom=20, targetunc=.5, solvefor='m') rev.set_input('r', nom=5, std=.05) revswp = sweeper.UncertSweepReverse(rev) revswp.add_sweep_unc('r', values=[.01, .02, .03, .04], comp='u(r)', param='std') explore = dist_explore.DistExplore(seed=8888) explore.dists = { 'a': distributions.get_distribution('normal', loc=3, scale=2), 'b': distributions.get_distribution('uniform', loc=0, scale=2), 'a+b': None } explore.get_config() dset = dataset.DataSet() dset.set_data( np.vstack((np.repeat(np.arange(5), 5), np.random.normal(loc=10, scale=1, size=25))).transpose()) proj = project.Project() proj.add_item(u) proj.add_item(u2) proj.add_item(rsk) proj.add_item(swp) proj.add_item(fit) proj.add_item(rev) proj.add_item(revswp) proj.add_item(explore) proj.add_item(dset) reportorig = proj.calculate() # Save_config given file NAME outfile = tmpdir.join('projconfig.yaml') proj.save_config(outfile) # Save_config given file OBJECT outfileobj = StringIO() proj.save_config(outfileobj) outfileobj.seek(0) proj2 = project.Project.from_configfile(outfile) reportnew = proj2.calculate() assert str(reportorig) == str(reportnew) proj3 = project.Project.from_configfile(outfileobj) reportobj = proj3.calculate() assert str(reportorig) == str(reportobj) outfileobj.close()