def mpi_from_str_a_b(x, y, percent, prec): wp = prec + 20 xa = from_str(x, wp, round_floor) xb = from_str(x, wp, round_ceiling) #ya = from_str(y, wp, round_floor) y = from_str(y, wp, round_ceiling) assert mpf_ge(y, fzero) if percent: y = mpf_mul(MAX(mpf_abs(xa), mpf_abs(xb)), y, wp, round_ceiling) y = mpf_div(y, from_int(100), wp, round_ceiling) a = mpf_sub(xa, y, prec, round_floor) b = mpf_add(xb, y, prec, round_ceiling) return a, b
def mpf_convert_arg(x, prec, rounding): if isinstance(x, int_types): return from_int(x) if isinstance(x, float): return from_float(x) if isinstance(x, basestring): return from_str(x, prec, rounding) if isinstance(x, constant): return x.func(prec, rounding) if hasattr(x, '_mpf_'): return x._mpf_ if hasattr(x, '_mpmath_'): t = mpmathify(x._mpmath_(prec, rounding)) if isinstance(t, mpf): return t._mpf_ raise TypeError("cannot create mpf from " + repr(x))
def mpf_convert_arg(x, prec, rounding): if isinstance(x, int_types): return from_int(x) if isinstance(x, float): return from_float(x) if isinstance(x, basestring): return from_str(x, prec, rounding) if isinstance(x, constant): return x.func(prec, rounding) if hasattr(x, '_mpf_'): return x._mpf_ if hasattr(x, '_mpmath_'): t = convert_lossless(x._mpmath_(prec, rounding)) if isinstance(t, mpf): return t._mpf_ raise TypeError("cannot create mpf from " + repr(x))
def convert_lossless(x, strings=True): """Attempt to convert x to an mpf or mpc losslessly. If x is an mpf or mpc, return it unchanged. If x is an int, create an mpf with sufficient precision to represent it exactly. If x is a str, just convert it to an mpf with the current working precision (perhaps this should be done differently...)""" if isinstance(x, mpnumeric): return x if isinstance(x, int_types): return make_mpf(from_int(x)) if isinstance(x, float): return make_mpf(from_float(x)) if isinstance(x, complex): return mpc(x) if strings and isinstance(x, basestring): return make_mpf(from_str(x, *prec_rounding)) if hasattr(x, '_mpf_'): return make_mpf(x._mpf_) if hasattr(x, '_mpc_'): return make_mpc(x._mpc_) if hasattr(x, '_mpmath_'): return convert_lossless(x._mpmath_(*prec_rounding)) raise TypeError("cannot create mpf from " + repr(x))
def mpmathify(x, strings=True): """ Converts *x* to an ``mpf`` or ``mpc``. If *x* is of type ``mpf``, ``mpc``, ``int``, ``float``, ``complex``, the conversion will be performed losslessly. If *x* is a string, the result will be rounded to the present working precision. Strings representing fractions or complex numbers are permitted. >>> from sympy.mpmath import * >>> mp.dps = 15 >>> mpmathify(3.5) mpf('3.5') >>> mpmathify('2.1') mpf('2.1000000000000001') >>> mpmathify('3/4') mpf('0.75') >>> mpmathify('2+3j') mpc(real='2.0', imag='3.0') """ if isinstance(x, mpnumeric): return x if isinstance(x, int_types): return make_mpf(from_int(x)) if isinstance(x, float): return make_mpf(from_float(x)) if isinstance(x, complex): return mpc(x) if strings and isinstance(x, basestring): try: return make_mpf(from_str(x, *prec_rounding)) except Exception, e: if '/' in x: fract = x.split('/') assert len(fract) == 2 return mpmathify(fract[0]) / mpmathify(fract[1]) if 'j' in x.lower(): x = x.lower().replace(' ', '') match = get_complex.match(x) re = match.group('re') if not re: re = 0 im = match.group('im').rstrip('j') return mpc(mpmathify(re), mpmathify(im)) raise e
def mpi_from_str(s, prec): """ Parse an interval number given as a string. Allowed forms are "-1.23e-27" Any single decimal floating-point literal. "a +- b" or "a (b)" a is the midpoint of the interval and b is the half-width "a +- b%" or "a (b%)" a is the midpoint of the interval and the half-width is b percent of a (`a \times b / 100`). "[a, b]" The interval indicated directly. "x[y,z]e" x are shared digits, y and z are unequal digits, e is the exponent. """ e = ValueError("Improperly formed interval number '%s'" % s) s = s.replace(" ", "") wp = prec + 20 if "+-" in s: x, y = s.split("+-") return mpi_from_str_a_b(x, y, False, prec) # case 2 elif "(" in s: # Don't confuse with a complex number (x,y) if s[0] == "(" or ")" not in s: raise e s = s.replace(")", "") percent = False if "%" in s: if s[-1] != "%": raise e percent = True s = s.replace("%", "") x, y = s.split("(") return mpi_from_str_a_b(x, y, percent, prec) elif "," in s: if ('[' not in s) or (']' not in s): raise e if s[0] == '[': # case 3 s = s.replace("[", "") s = s.replace("]", "") a, b = s.split(",") a = from_str(a, prec, round_floor) b = from_str(b, prec, round_ceiling) return a, b else: # case 4 x, y = s.split('[') y, z = y.split(',') if 'e' in s: z, e = z.split(']') else: z, e = z.rstrip(']'), '' a = from_str(x + y + e, prec, round_floor) b = from_str(x + z + e, prec, round_ceiling) return a, b else: a = from_str(s, prec, round_floor) b = from_str(s, prec, round_ceiling) return a, b
def mpi_from_str(s, prec): """ Parse an interval number given as a string. Allowed forms are "-1.23e-27" Any single decimal floating-point literal. "a +- b" or "a (b)" a is the midpoint of the interval and b is the half-width "a +- b%" or "a (b%)" a is the midpoint of the interval and the half-width is b percent of a (`a \times b / 100`). "[a, b]" The interval indicated directly. "x[y,z]e" x are shared digits, y and z are unequal digits, e is the exponent. """ e = ValueError("Improperly formed interval number '%s'" % s) s = s.replace(" ", "") wp = prec + 20 if "+-" in s: x, y = s.split("+-") return mpi_from_str_a_b(x, y, False, prec) # case 2 elif "(" in s: # Don't confuse with a complex number (x,y) if s[0] == "(" or ")" not in s: raise e s = s.replace(")", "") percent = False if "%" in s: if s[-1] != "%": raise e percent = True s = s.replace("%", "") x, y = s.split("(") return mpi_from_str_a_b(x, y, percent, prec) elif "," in s: if ('[' not in s) or (']' not in s): raise e if s[0] == '[': # case 3 s = s.replace("[", "") s = s.replace("]", "") a, b = s.split(",") a = from_str(a, prec, round_floor) b = from_str(b, prec, round_ceiling) return a, b else: # case 4 x, y = s.split('[') y, z = y.split(',') if 'e' in s: z, e = z.split(']') else: z, e = z.rstrip(']'), '' a = from_str(x+y+e, prec, round_floor) b = from_str(x+z+e, prec, round_ceiling) return a, b else: a = from_str(s, prec, round_floor) b = from_str(s, prec, round_ceiling) return a, b