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'
Beispiel #2
0
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'
Beispiel #4
0
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
Beispiel #5
0
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)
Beispiel #9
0
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()