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)
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)
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)
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)
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)
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)
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)
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) (frac_part, int_part) = math.modf(aff_func.nominal_value) if aff_func.derivatives: # The derivative of the fractional part is simply 1: the # derivatives of modf(x)[0] are the derivatives of x: return (AffineScalarFunc(frac_part, aff_func.derivatives), 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)