def _init_by_float_float(self, numerator, denominator): """ Initialize by a float numbers. """ dp = 53 frexp_num = math.frexp(numerator) frexp_den = math.frexp(denominator) self.numerator = Integer(frexp_num[0] * 2 ** (2 * dp - frexp_den[1])) self.denominator = Integer(frexp_den[0] * 2 ** (2 * dp - frexp_num[1]))
def AGM(a, b): """ Arithmetic-Geometric Mean. """ x = (a + b) * 0.5 y = math.sqrt(a * b) while abs(x - y) > y * 1e-15: x, y = (x + y) * 0.5, math.sqrt(x * y) return x
def AGM(a, b): """ Arithmetic-Geometric Mean. """ x = (a+b) * 0.5 y = math.sqrt(a*b) while abs(x-y) > y*1e-15: x, y = (x+y) * 0.5, math.sqrt(x*y) return x
def _init_by_float_float(self, numerator, denominator): """ Initialize by a float numbers. """ dp = 53 frexp_num = math.frexp(numerator) frexp_den = math.frexp(denominator) self.numerator = Integer(frexp_num[0] * 2**(2 * dp - frexp_den[1])) self.denominator = Integer(frexp_den[0] * 2**(2 * dp - frexp_num[1]))
def aks(n): """ AKS ( Cyclotomic Congruence Test ) primality test for a natural number. Input: a natural number n ( n > 1 ). Output: n is prime => return True n is not prime => return False. """ import nzmath.multiplicative as multiplicative if arith1.powerDetection(n)[1] != 1: #Power Detection return False lg = math.log(n, 2) k = int(lg * lg) start = 3 while 1: d = gcd.gcd(start, n) if 1 < d < n: return False x = n % start N = x for i in range(1, k + 1): if N == 1: break N = (N * x) % start if i == k: r = start break start += 1 d = gcd.gcd(r, n) if 1 < d < n: return False if n <= r: return True e = multiplicative.euler(r) #Cyclotomic Conguence e = math.sqrt(e) e = int(e * lg) for b in range(1, e + 1): f = array_poly.ArrayPolyMod([b, 1], n) total = array_poly.ArrayPolyMod([1], n) count = n while count > 0: if count & 1: total = total * f total = _aks_mod(total, r) f = f.power() f = _aks_mod(f, r) count = count >> 1 total_poly = total.coefficients_to_dict() if total_poly != {0: b, n % r: 1}: return False return True
def exp(x, err=defaultError): """ Return exponential of x. """ if err <= defaultError: reduced = rational.Rational(x) if reduced < 0: reverse = -1 reduced = -reduced else: reverse = 1 i = 0 while reduced >= 2: reduced /= 2 i += 1 if reduced == 0: retval = rational.Integer(1) else: series = ExponentialPowerSeries( itertools.cycle((rational.Integer(1), ))) retval = series(reduced, err) if i > 0: retval **= 2**i if reverse < 0: retval = 1 / retval else: retval = rational.Rational(math.exp(x)) return retval
def asin(x, err=defaultError): """ asin(x [,err]) returns arc sine of x. """ if x > 1 or x < -1: raise ValueError("%s is not in the range [-1, 1]." % str(x)) if x < 0: return -asin(-x) if err <= defaultError: u = sqrt(rational.Rational(1, 2)) if x > u: return pi(err) / 2 - asin(sqrt(1 - x**2)) if x == 0: return rational.Integer(0) y = rational.Rational(x) y2 = y**2 i = 2 retval = y term = rational.Rational(y) oldvalue = 0 while not err.nearlyEqual(retval, oldvalue): oldvalue = +retval term *= y2 * (i - 1)**2 / (i * (i + 1)) i += 2 retval += term else: retval = rational.Rational(math.asin(x)) return retval
def atan(x, err=defaultError): """ atan(x [,err]) returns arc tangent of x. """ if not isinstance(err, defaultError.__class__) or err <= defaultError: # atan(x) = -atan(-x) if x < 0: return -atan(-x, err) # atan(x) = pi/2 - atan(1/x) elif x > 1: return pi(err) / 2 - atan(1 / x, err) elif x == 1: return pi(err) / 4 elif x == 0: return rational.Integer(0) y = rational.Rational(x) y2 = y**2 retval = y oldvalue = 0 term = rational.Rational(x) i = 1 while not err.nearlyEqual(retval, oldvalue): oldvalue = +retval i += 2 term *= -y2 * (i - 2) / i retval += term else: retval = rational.Rational(math.atan(x)) return retval
def _init_by_int_float(self, numerator, denominator): """ Initailize by an integer and a float """ dp = 53 frexp_den = math.frexp(denominator) self.numerator = Integer(numerator * (2 ** (dp - frexp_den[1]))) self.denominator = Integer(frexp_den[0] * 2 ** dp)
def _init_by_Rational_float(self, numerator, denominator): """ Initialize by a rational number and a float. """ dp = 53 frexp = math.frexp(denominator) self.numerator = numerator.numerator * (2 ** (dp - frexp[1])) self.denominator = numerator.denominator * (frexp[0] * 2 ** dp)
def _init_by_Rational_float(self, numerator, denominator): """ Initialize by a rational number and a float. """ dp = 53 frexp = math.frexp(denominator) self.numerator = numerator.numerator * (2**(dp - frexp[1])) self.denominator = numerator.denominator * (frexp[0] * 2**dp)
def _init_by_float_int(self, numerator, denominator): """ Initialize by a float number and an integer. """ dp = 53 frexp = math.frexp(numerator) self.numerator = Integer(frexp[0] * 2**dp) self.denominator = Integer(2**(dp - frexp[1]) * denominator)
def _init_by_int_float(self, numerator, denominator): """ Initailize by an integer and a float """ dp = 53 frexp_den = math.frexp(denominator) self.numerator = Integer(numerator * (2**(dp - frexp_den[1]))) self.denominator = Integer(frexp_den[0] * 2**dp)
def _init_by_float_int(self, numerator, denominator): """ Initialize by a float number and an integer. """ dp = 53 frexp = math.frexp(numerator) self.numerator = Integer(frexp[0] * 2 ** dp) self.denominator = Integer(2 ** (dp - frexp[1]) * denominator)
def e2(x): """ 0 = x[0] + x[1]*t + x[2]*t**2 """ c, b, a = x d = b**2 - 4*a*c if d >= 0: sqrtd = math.sqrt(d) else: sqrtd = cmath.sqrt(d) return ((-b + sqrtd)/(2*a), (-b - sqrtd)/(2*a))
def e2(x): """ 0 = x[0] + x[1]*t + x[2]*t**2 """ c, b, a = x d = b**2 - 4 * a * c if d >= 0: sqrtd = math.sqrt(d) else: sqrtd = cmath.sqrt(d) return ((-b + sqrtd) / (2 * a), (-b - sqrtd) / (2 * a))
def floorsqrt(a): """ Return the floor of square root of the given integer. """ if a < 2 ** 59: return int(math.sqrt(a)) else: b_old = a b = pow(10, log(a, 10)//2 + 1) while b_old > b: b_old, b = b, (b+a//b)//2 return b_old
def log(x, base=None, err=defaultError): """ log(x) returns logarithm of a positive number x. If an additional argument base is given, it returns logarithm of x to the base. """ if isinstance(x, complex): raise TypeError("real.log is not for complex numbers.") if x <= 0: raise ValueError("log is not defined for %s" % str(x)) if err <= defaultError: if base: d = log(base, err=err) else: d = 1 rx = rational.Rational(x) upper = rational.Rational(4, 3) lower = rational.Rational(2, 3) shift = 0 while rx > upper: rx /= 2 shift += 1 while rx < lower: rx *= 2 shift -= 1 if rx == 1: return shift * _log2(err) / d value = oldvalue = 0 for term in log1piter(rx - 1): value += term if err.nearlyEqual(value, oldvalue): break oldvalue = +value if shift != 0: return (value + shift * _log2(err)) / d else: if base: value = rational.Rational(math.log(x, base)) else: value = rational.Rational(math.log(x)) return value
def continued_fraction_expansion(target, terms): """ Return continued fraction expansion of a real number. >>> continued_fraction_expansion(1.4142, 2) [1, 2, 2] The first component is the integer part, and rest is fractional part, whose number of terms is specified by the second argument. """ # integer part ipart = math.floor(target) target -= ipart result = [int(ipart)] # expansion for i in range(terms): reverse = 1 / target term = math.floor(reverse) target = reverse - term result.append(int(term)) return result
def floorsqrt(a): """ Return the floor of square root of the given integer. """ if a < (1 << 59): return int(math.sqrt(a)) else: # Newton method x = pow(10, (log(a, 10) >> 1) + 1) # compute initial value while True: x_new = (x + a // x) >> 1 if x <= x_new: return x x = x_new
def cosh(x, err=defaultError): """ cosh(x [,err]) returns the hyperbolic cosine of x. """ if err <= defaultError: series = ExponentialPowerSeries( itertools.cycle(( rational.Integer(1), 0, ))) rx = rational.Rational(x) if rx == 0: return rational.Integer(1) return series(rx, err) else: return rational.Rational(math.cosh(x))
def sinh(x, err=defaultError): """ sinh(x [,err]) returns the hyperbolic sine of x. """ if not isinstance(err, defaultError.__class__) or err <= defaultError: series = ExponentialPowerSeries( itertools.cycle(( 0, rational.Integer(1), ))) rx = rational.Rational(x) if rx == 0: return rational.Rational(0) return series(rx, err) else: return rational.Rational(math.sinh(x))
def acos(x, err=defaultError): """ acos(x [,err]) returns arc cosine of x. """ if x > 1 or x < -1: raise ValueError("%s is not in the range [-1, 1]." % str(x)) if x == 0: return pi(err) / 2 if err <= defaultError: rx = rational.Rational(x) y = sqrt(1 - rx**2) if rx > 0: return asin(y, err) else: return pi(err) + asin(-y, err) else: return rational.Rational(math.acos(x))
def sqrt(x, err=defaultError): """ sqrt(x [,err]) returns the positive square root of real number x. """ rx = rational.Rational(x) if rx.numerator < 0: raise ValueError("negative number is passed to sqrt") if rx.numerator == 0: return rational.Integer(0) if err <= defaultError: n = rx.denominator * rx.numerator rt = rational.Rational(arith1.floorsqrt(n), rx.denominator) newrt = (rt + rx / rt) / 2 while not err.nearlyEqual(rt, newrt): rt = newrt newrt = (rt + rx / rt) / 2 else: newrt = rational.Rational(math.sqrt(x.toFloat())) return newrt
def sin(x, err=defaultError): """ sin(x [,err]) returns the sine of x. """ if not isinstance(err, defaultError.__class__) or err <= defaultError: rx = rational.Rational(x) sign = rational.Rational(1) # sin(-x) = -sin(x) if rx < 0: sign = -sign rx = -rx # sin(x + 2 * pi) = sin(x) if rx >= 2 * pi: rx -= floor(rx / (pi * 2)) * (pi * 2) # sin(x + pi) = -sin(x) if rx >= pi: rx -= pi sign = -sign # sin(x) = sin(pi - x) if rx > pi / 2: rx = pi - rx # sin(0) = 0 is a special case which must not be computed with series. if rx == 0: return rational.Rational(0) # sin(x) = cos(pi/2 - x) (pi/2 >= x > 4/pi) if rx > pi / 4: if rx == pi / 3: retval = sqrt(3) / 2 else: retval = _cosTaylor(pi / 2 - rx, err) elif rx == pi / 4: retval = 1 / sqrt(2) elif rx == pi / 6: retval = rational.Rational(1, 2) else: retval = _sinTaylor(rx, err) if retval > 1: retval = rational.Integer(1) retval *= sign else: retval = rational.Rational(math.sin(x)) return retval
def cos(x, err=defaultError): """ cos(x [,err]) returns the cosine of x. """ if err <= defaultError: rx = rational.Rational(x) sign = rational.Rational(1) # cos(-x) = cos(x) if rx < 0: rx = -rx # cos(x + 2 * pi) = cos(x) if rx > 2 * pi: rx -= floor(rx / (pi * 2)) * (pi * 2) # cos(x + pi) = -cos(x) if rx > pi: rx -= pi sign = -sign # cos(x) = -cos(pi - x) if rx > pi / 2: rx = pi - rx sign = -sign # cos(x) = sin(pi/2 - x) (pi/2 >= x > 4/pi) if rx > pi / 4: if rx == pi / 3: retval = rational.Rational(1, 2) else: retval = _sinTaylor(pi / 2 - rx, err) elif rx == pi / 4: retval = 1 / sqrt(2) elif rx == pi / 6: retval = sqrt(3) / 2 else: retval = _cosTaylor(rx, err) if retval > 1: retval = rational.Integer(1) retval *= sign else: retval = rational.Rational(math.cos(x)) return retval
def __pow__(self, other): if isinstance(other, Real): result = math.pow(self.data, other.data) elif isinstance(other, self.convertable): result = math.pow(self.data, other) return result
def __abs__(self): if self.imag == 0: return abs(self.real) if self.real == 0: return abs(self.imag) return math.hypot(self.real, self.imag)
def arg(self): x = self.real y = self.imag return math.atan2(y,x)