예제 #1
0
def frexp(x):
    """
    Version of frexp that works for numbers with uncertainty, and also
    for regular numbers.
    """

    # The code below is inspired by uncert_core.wrap().  It is
    # simpler because only 1 argument is given, and there is no
    # delegation to other functions involved (as for __mul__, etc.).

    aff_func = to_affine_scalar(x)

    if aff_func._linear_part:
        (mantissa, exponent) = math.frexp(aff_func.nominal_value)
        return (
            AffineScalarFunc(
                mantissa,
                # With frexp(x) = (m, e), x = m*2**e, so m = x*2**-e
                # and therefore dm/dx = 2**-e (as e in an integer that
                # does not vary when x changes):
                LinearCombination([2**-exponent, aff_func._linear_part])),
            # The exponent is an integer and is supposed to be
            # continuous (errors must be small):
            exponent)
    else:
        # This function was not called with an AffineScalarFunc
        # argument: there is no need to return numbers with uncertainties:
        return math.frexp(x)
예제 #2
0
def ldexp(x, i):
    # Another approach would be to add an additional argument to
    # uncert_core.wrap() so that some arguments are automatically
    # considered as constants.

    aff_func = to_affine_scalar(x)  # y must be an integer, for math.ldexp

    if aff_func._linear_part:
        return AffineScalarFunc(
            math.ldexp(aff_func.nominal_value, i),
            LinearCombination([(2**i, aff_func._linear_part)]))
    else:
        # This function was not called with an AffineScalarFunc
        # argument: there is no need to return numbers with uncertainties:

        # aff_func.nominal_value is not passed instead of x, because
        # we do not have to care about the type of the return value of
        # math.ldexp, this way (aff_func.nominal_value might be the
        # value of x coerced to a difference type [int->float, for
        # instance]):
        return math.ldexp(x, i)