This file is indexed.

/usr/share/pyshared/uncertainties/test_umath.py is in python-uncertainties 2.4.4-1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
"""
Tests of the code in uncertainties.umath.

These tests can be run through the Nose testing framework.

(c) 2010-2013 by Eric O. LEBIGOT (EOL).
"""

from __future__ import division

# Standard modules
import sys
import math

# Local modules:
import uncertainties
import uncertainties.umath as umath
from uncertainties import ufloat
from uncertainties import __author__

import test_uncertainties

###############################################################################
# Unit tests
    
def test_fixed_derivatives_math_funcs():
    """
    Comparison between function derivatives and numerical derivatives.

    This comparison is useful for derivatives that are analytical.
    """

    for name in umath.many_scalars_to_scalar_funcs:
        # print "Checking %s..." % name
        func = getattr(umath, name)
        # Numerical derivatives of func: the nominal value of func() results
        # is used as the underlying function:
        numerical_derivatives = uncertainties.NumericalDerivatives(
            lambda *args: func(*args))
        test_uncertainties.compare_derivatives(func, numerical_derivatives)

    # Functions that are not in umath.many_scalars_to_scalar_funcs:

    ##
    # modf(): returns a tuple:
    def frac_part_modf(x):
        return umath.modf(x)[0]
    def int_part_modf(x):
        return umath.modf(x)[1]
    
    test_uncertainties.compare_derivatives(
        frac_part_modf,
        uncertainties.NumericalDerivatives(
            lambda x: frac_part_modf(x)))
    test_uncertainties.compare_derivatives(
        int_part_modf,
        uncertainties.NumericalDerivatives(
            lambda x: int_part_modf(x)))
    
    ##
    # frexp(): returns a tuple:
    def mantissa_frexp(x):
        return umath.frexp(x)[0]
    def exponent_frexp(x):
        return umath.frexp(x)[1]
    
    test_uncertainties.compare_derivatives(
        mantissa_frexp,
        uncertainties.NumericalDerivatives(
            lambda x: mantissa_frexp(x)))
    test_uncertainties.compare_derivatives(
        exponent_frexp,
        uncertainties.NumericalDerivatives(
            lambda x: exponent_frexp(x)))

def test_compound_expression():
    """
    Test equality between different formulas.
    """
    
    x = ufloat(3, 0.1)
    
    # Prone to numerical errors (but not much more than floats):
    assert umath.tan(x) == umath.sin(x)/umath.cos(x)

    
def test_numerical_example():
    "Test specific numerical examples"

    x = ufloat(3.14, 0.01)
    result = umath.sin(x)
    # In order to prevent big errors such as a wrong, constant value
    # for all analytical and numerical derivatives, which would make
    # test_fixed_derivatives_math_funcs() succeed despite incorrect
    # calculations:
    assert ("%.6f +/- %.6f" % (result.nominal_value, result.std_dev)
            == "0.001593 +/- 0.010000")

    # Regular calculations should still work:
    assert("%.11f" % umath.sin(3) == "0.14112000806")

def test_monte_carlo_comparison():
    """
    Full comparison to a Monte-Carlo calculation.

    Both the nominal values and the covariances are compared between
    the direct calculation performed in this module and a Monte-Carlo
    simulation.
    """
    
    try:
        import numpy
        import numpy.random
    except ImportError:
        import warnings
        warnings.warn("Test not performed because NumPy is not available")
        return

    # Works on numpy.arrays of Variable objects (whereas umath.sin()
    # does not):
    sin_uarray_uncert = numpy.vectorize(umath.sin, otypes=[object])
    
    # Example expression (with correlations, and multiple variables combined
    # in a non-linear way):
    def function(x, y):
        """
        Function that takes two NumPy arrays of the same size.
        """
        # The uncertainty due to x is about equal to the uncertainty
        # due to y:
        return 10 * x**2 - x * sin_uarray_uncert(y**3)

    x = ufloat(0.2, 0.01)
    y = ufloat(10, 0.001)
    function_result_this_module = function(x, y)
    nominal_value_this_module = function_result_this_module.nominal_value

    # Covariances "f*f", "f*x", "f*y":
    covariances_this_module = numpy.array(uncertainties.covariance_matrix(
        (x, y, function_result_this_module)))

    def monte_carlo_calc(n_samples):
        """
        Calculate function(x, y) on n_samples samples and returns the
        median, and the covariances between (x, y, function(x, y)).
        """
        # Result of a Monte-Carlo simulation:
        x_samples = numpy.random.normal(x.nominal_value, x.std_dev,
                                        n_samples)
        y_samples = numpy.random.normal(y.nominal_value, y.std_dev,
                                        n_samples)

        # !! astype() is a fix for median() in NumPy 1.8.0:
        function_samples = function(x_samples, y_samples).astype(float)

        cov_mat = numpy.cov([x_samples, y_samples], function_samples)

        return (numpy.median(function_samples), cov_mat)
        
    (nominal_value_samples, covariances_samples) = monte_carlo_calc(1000000)


    ## Comparison between both results:

    # The covariance matrices must be close:

    # We rely on the fact that covariances_samples very rarely has
    # null elements:
    
    assert numpy.vectorize(test_uncertainties.numbers_close)(
        covariances_this_module,
        covariances_samples,
        0.05).all(), (
        "The covariance matrices do not coincide between"
        " the Monte-Carlo simulation and the direct calculation:\n"
        "* Monte-Carlo:\n%s\n* Direct calculation:\n%s"
        % (covariances_samples, covariances_this_module)
        )
    
    # The nominal values must be close:
    assert test_uncertainties.numbers_close(
        nominal_value_this_module,
        nominal_value_samples,
        # The scale of the comparison depends on the standard
        # deviation: the nominal values can differ by a fraction of
        # the standard deviation:
        math.sqrt(covariances_samples[2, 2])
        / abs(nominal_value_samples) * 0.5), (
        "The nominal value (%f) does not coincide with that of"
        " the Monte-Carlo simulation (%f), for a standard deviation of %f."
        % (nominal_value_this_module,
           nominal_value_samples,
           math.sqrt(covariances_samples[2, 2]))
        )

    
def test_math_module():
    "Operations with the math module"

    x = ufloat(-1.5, 0.1)
    
    # The exponent must not be differentiated, when calculating the
    # following (the partial derivative with respect to the exponent
    # is not defined):
    assert (x**2).nominal_value == 2.25

    # Regular operations are chosen to be unchanged:
    assert isinstance(umath.sin(3), float)

    # Python >=2.6 functions:

    if sys.version_info >= (2, 6):
    
        # factorial() must not be "damaged" by the umath module, so as 
        # to help make it a drop-in replacement for math (even though 
        # factorial() does not work on numbers with uncertainties 
        # because it is restricted to integers, as for 
        # math.factorial()):
        assert umath.factorial(4) == 24

        # fsum is special because it does not take a fixed number of
        # variables:
        assert umath.fsum([x, x]).nominal_value == -3

    # Functions that give locally constant results are tested: they
    # should give the same result as their float equivalent:
    for name in umath.locally_cst_funcs:

        try:
            func = getattr(umath, name)
        except AttributeError:
            continue  # Not in the math module, so not in umath either
        
        assert func(x) == func(x.nominal_value)
        # The type should be left untouched. For example, isnan()
        # should always give a boolean:
        assert type(func(x)) == type(func(x.nominal_value))

    # The same exceptions should be generated when numbers with uncertainties
    # are used:

    ## !! The Nose testing framework seems to catch an exception when
    ## it is aliased: "exc = OverflowError; ... except exc:..."
    ## surprisingly catches OverflowError. So, tests are written in a
    ## version-specific manner (until the Nose issue is resolved).

    if sys.version_info < (2, 6):
            
        try:
            math.log(0)
        except OverflowError, err_math:  # "as", for Python 2.6+
            pass
        else:
            raise Exception('OverflowError exception expected')
        try:
            umath.log(0)
        except OverflowError, err_ufloat:  # "as", for Python 2.6+
            assert err_math.args == err_ufloat.args
        else:
            raise Exception('OverflowError exception expected')
        try:
            umath.log(ufloat(0, 0))
        except OverflowError, err_ufloat:  # "as", for Python 2.6+
            assert err_math.args == err_ufloat.args
        else:
            raise Exception('OverflowError exception expected')
        try:
            umath.log(ufloat(0, 1))
        except OverflowError, err_ufloat:  # "as", for Python 2.6+
            assert err_math.args == err_ufloat.args
        else:
            raise Exception('OverflowError exception expected')

    else:

        try:
            math.log(0)
        except ValueError, err_math:  # Python 2.6+: as err_math
            # Python 3 does not make exceptions local variables: they are
            # restricted to their except block:
            err_math_args = err_math.args
        else:
            raise Exception('ValueError exception expected')

        try:
            umath.log(0)
        except ValueError, err_ufloat:  # Python 2.6+: as err_math
            assert err_math_args == err_ufloat.args
        else:
            raise Exception('ValueError exception expected')
        try:
            umath.log(ufloat(0, 0))
        except ValueError, err_ufloat:  # Python 2.6+: as err_math
            assert err_math_args == err_ufloat.args
        else:
            raise Exception('ValueError exception expected')
        try:
            umath.log(ufloat(0, 1))
        except ValueError, err_ufloat:  # Python 2.6+: as err_math
            assert err_math_args == err_ufloat.args
        else:
            raise Exception('ValueError exception expected')

    
def test_hypot():
    '''
    Special cases where derivatives cannot be calculated:
    '''
    x = ufloat(0, 1)
    y = ufloat(0, 2)
    # Derivatives that cannot be calculated simply return NaN, with no
    # exception being raised, normally:
    result = umath.hypot(x, y)
    assert test_uncertainties.isnan(result.derivatives[x])
    assert test_uncertainties.isnan(result.derivatives[y])

def test_power_all_cases():
    '''
    Test special cases of umath.pow().
    '''
    test_uncertainties.power_all_cases(umath.pow)

# test_power_special_cases() is similar to
# test_uncertainties.py:test_power_special_cases(), but with small
# differences: the built-in pow() and math.pow() are slightly
# different:
def test_power_special_cases():
    '''
    Checks special cases of umath.pow().
    '''
    
    test_uncertainties.power_special_cases(umath.pow)

    # We want the same behavior for numbers with uncertainties and for
    # math.pow() at their nominal values:

    positive = ufloat(0.3, 0.01)
    negative = ufloat(-0.3, 0.01)
    
    # http://stackoverflow.com/questions/10282674/difference-between-the-built-in-pow-and-math-pow-for-floats-in-python

    try:
        umath.pow(ufloat(0, 0.1), negative)
    except (ValueError, OverflowError), err:  # Python 2.6+ "as err"
        err_class = err.__class__  # For Python 3: err is destroyed after except
    else:
        err_class = None
        
    err_msg = 'A proper exception should have been raised'

    # An exception must have occurred:
    if sys.version_info >= (2, 6):
        assert err_class == ValueError, err_msg
    else:
        assert err_class == OverflowError, err_msg
            
    try:
        result = umath.pow(negative, positive)
    except ValueError:
        # The reason why it should also fail in Python 3 is that the
        # result of Python 3 is a complex number, which uncertainties
        # does not handle (no uncertainties on complex numbers). In
        # Python 2, this should always fail, since Python 2 does not
        # know how to calculate it.
        pass
    else:
        if sys.version_info >= (2, 6):
            raise Exception('A proper exception should have been raised')
        else:
            assert test_uncertainties.isnan(result.nominal_value)
            assert test_uncertainties.isnan(result.std_dev)
    
def test_power_wrt_ref():
    '''
    Checks special cases of the umath.pow() power operator.
    '''
    test_uncertainties.power_wrt_ref(umath.pow, math.pow)