Ejemplo n.º 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)
Ejemplo n.º 2
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.derivatives:
        result = math.frexp(aff_func.nominal_value)
        # With frexp(x) = (m, e), dm/dx = 1/(2**e):
        factor = 1 / (2**result[1])
        return (
            AffineScalarFunc(
                result[0],
                # Chain rule:
                dict([(var, factor * deriv)
                      for (var, deriv) in aff_func.derivatives.iteritems()])),
            # The exponent is an integer and is supposed to be
            # continuous (small errors):
            result[1])
    else:
        # This function was not called with an AffineScalarFunc
        # argument: there is no need to return numbers with uncertainties:
        return math.frexp(x)
Ejemplo n.º 3
0
def ldexp(x, y):
    # 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.).

    # 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.derivatives:
        factor = 2**y
        return AffineScalarFunc(
            math.ldexp(aff_func.nominal_value, y),
            # Chain rule:
            dict([(var, factor * deriv)
                  for (var, deriv) in aff_func.derivatives.iteritems()]))
    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, y)
Ejemplo n.º 4
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)
Ejemplo n.º 5
0
def modf(x):
    """
    Version of modf 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)  # Uniform treatment of all numbers

    (frac_part, int_part) = math.modf(aff_func.nominal_value)

    if aff_func._linear_part:  # If not a constant
        # The derivative of the fractional part is simply 1: the
        # linear part of modf(x)[0] is the linear part of x:
        return (AffineScalarFunc(frac_part, aff_func._linear_part), int_part)
    else:
        # This function was not called with an AffineScalarFunc
        # argument: there is no need to return numbers with uncertainties:
        return (frac_part, int_part)