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 cosh(z, err=defaultError): if z == 0: return rational.Integer(1) if (defaultError >= err) or isinstance(err, AbsoluteError): series = ExponentialPowerSeries(itertools.cycle((rational.Integer(1),0,))) return series(z, err) else: return Complex(cmath.cosh(complex(z.real,z.imag)))
def _cosTaylor(x, err=defaultError): """ _cosTaylor(x [,err]) returns the cosine of x by Taylor series. It is recomended to use only for 0 <= x <= pi / 4. """ cosSeries = ExponentialPowerSeries( itertools.cycle((rational.Integer(1), 0, rational.Integer(-1), 0))) rx = rational.Rational(x) return cosSeries(rx, err)
def _sinTaylor(x, err=defaultError): """ _sinTaylor(x [,err]) returns the sine of x by Taylor expansion. It is recommended to use only for 0 <= x <= pi / 4. """ rx = rational.Rational(x) sinSeries = ExponentialPowerSeries( itertools.cycle((0, rational.Integer(1), 0, rational.Integer(-1)))) return sinSeries(rx, err)
def __pow__(self, other): if rational.isIntegerObject(other): if other == 0: return rational.Integer(1) elif other == 1: return +self elif other < 0: return (self**(-other)).inverse() elif other == 2: return self.__class__(self.real ** 2 - self.imag ** 2, 2 * self.real * self.imag) else: return rational.Integer(other).actMultiplicative(self) return exp(other * log(self))
def testBuchberger(self): """ test Buchberger's algorithm. http://www.geocities.com/famancin/buchberger.html """ F = (multiutil.polynomial( { (2, 0): rational.Integer(1), (1, 2): rational.Integer(2) }, rational.theRationalField, 2), multiutil.polynomial( { (1, 1): rational.Integer(1), (0, 3): rational.Integer(2), (0, 0): rational.Integer(-1) }, rational.theRationalField, 2)) G_from_F = groebner.buchberger(F, self.lex) G_expected = list(F + (multiutil.polynomial( {(1, 0): rational.Integer(1)}, rational.theRationalField, 2), multiutil.polynomial( { (0, 3): rational.Integer(2), (0, 0): rational.Integer(-1) }, rational.theRationalField, 2))) self.assertEqual(len(G_expected), len(G_from_F)) for p, q in zip(G_expected, G_from_F): self.assertEqualUptoUnit(p, q)
def testNormalStrategy(self): """ test Buchberger's algorithm (normal strategy). same example with testBuchberger. """ F = (multiutil.polynomial( { (2, 0): rational.Integer(1), (1, 2): rational.Integer(2) }, rational.theRationalField, 2), multiutil.polynomial( { (1, 1): rational.Integer(1), (0, 3): rational.Integer(2), (0, 0): rational.Integer(-1) }, rational.theRationalField, 2)) G_from_F = groebner.normal_strategy(F, self.lex) G_expected = list(F + (multiutil.polynomial( {(1, 0): rational.Integer(1)}, rational.theRationalField, 2), multiutil.polynomial( { (0, 3): rational.Integer(2), (0, 0): rational.Integer(-1) }, rational.theRationalField, 2))) self.assertEqual(len(G_expected), len(G_from_F)) for p, q in zip(G_expected, G_from_F): self.assertEqualUptoUnit(p, q)
def terms(self, x): """ Generator of terms of series with assigned x value. """ if x == 0: yield self.iterator.next() else: f = rational.Integer(1) i = 0 y = rational.Integer(1) for an in self.iterator: yield an * y / f y *= x i += 1 f *= i
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 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 testReduce(self): F = (multiutil.polynomial( { (2, 0): rational.Integer(1), (1, 2): rational.Integer(2) }, rational.theRationalField, 2), multiutil.polynomial( { (1, 1): rational.Integer(1), (0, 3): rational.Integer(2), (0, 0): rational.Integer(-1) }, rational.theRationalField, 2)) rgb_expected = [ multiutil.polynomial({(1, 0): rational.Integer(1)}, rational.theRationalField, 2), multiutil.polynomial( { (0, 3): rational.Integer(1), (0, 0): rational.Rational(-1, 2) }, rational.theRationalField, 2) ] G_from_F = groebner.normal_strategy(F, self.lex) rgb = groebner.reduce_groebner(G_from_F, self.lex) self.assertEqual(2, len(rgb)) self.assertEqual(rgb_expected, rgb)
def ceil(x): """ ceil(x) returns the integer; if x is an integer then x itself, otherwise the smallest integer greater than x. """ rx = rational.Rational(x) if rx.denominator == 1: return rational.Integer(rx.numerator) return rx.numerator // rx.denominator + 1
def floor(x): """ floor(x) returns the integer; if x is an integer then x itself, otherwise the biggest integer less than x. """ rx = rational.Rational(x) if rx.denominator == 1: return rational.Integer(rx.numerator) return rx.numerator // rx.denominator
def minimumAbsolute(self): """ Return the minimum absolute representative integer of the residue class. """ result = self.n % self.m if result > self.m // 2: result -= self.m return rational.Integer(result)
def tranc(x): """ tranc(x) returns the integer; if x is an integer then x itself, otherwise the nearest integer to x. If x has the fraction part 1/2, then bigger one will be chosen. """ rx = rational.Rational(x) if rx.denominator == 1: return rational.Integer(rx.numerator) return floor(x + rational.Rational(1, 2))
def _li_terms(x): """ Generate terms of infinite part of Li(x): x^i / (i * i!) for each i. """ d = rational.Integer(1) t = x for i in bigrange.count(2): yield t t = t * x * (i - 1) / (i * i)
def expi(x, err=defaultError): """ expi(x [,err]) returns exp(i * x) where i is the imaginary unit and x must be a real number. """ if x == 0: return rational.Integer(1) if isinstance(err, RelativeError): _err = real.RelativeError(0, err.relativeerrorrange, 2) elif isinstance(err, AbsoluteError): _err = real.AbsoluteError(0, err.absoluteerrorrange, 2) re = real.cos(x, _err) im = real.sin(x, _err) return Complex(re, im)
def _rational_mul(self, other): """ return other * self, assuming other is a rational element """ if rational.isIntegerObject(other): other_numerator = rational.Integer(other) other_denominator = rational.Integer(1) else: other_numerator = other.numerator other_denominator = other.denominator denom_gcd = gcd.gcd(self.denominator, other_numerator) if denom_gcd != 1: new_denominator = ring.exact_division( self.denominator, denom_gcd) * other_denominator multiply_num = other_numerator.exact_division(denom_gcd) else: new_denominator = self.denominator * other_denominator multiply_num = other_numerator new_module = self.__class__( [self.mat_repr * multiply_num, new_denominator], self.number_field, self.base, self.mat_repr.ishnf) new_module._simplify() return new_module
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 getRingInstance(obj): """ Return a RingElement instance which eqauls 'obj'. Mainly for python built-in objects such as int or float. """ if isinstance(obj, RingElement): return obj elif isinstance(obj, int): import nzmath.rational as rational return rational.Integer(obj) elif isinstance(obj, float): import nzmath.real as real return real.Real(obj) elif isinstance(obj, complex): import nzmath.imaginary as imaginary return imaginary.Complex(obj) return None
def testExtgcd(self): u, v, d = gcd.extgcd(8, 11) self.assertEqual(1, abs(d)) self.assertEqual(d, 8 * u + 11 * v) #sf.bug 1924839 u, v, d = gcd.extgcd(-8, 11) self.assertEqual(1, abs(d)) self.assertEqual(d, -8 * u + 11 * v) u, v, d = gcd.extgcd(8, -11) self.assertEqual(1, abs(d)) self.assertEqual(d, 8 * u - 11 * v) u, v, d = gcd.extgcd(-8, -11) self.assertEqual(1, abs(d)) self.assertEqual(d, -8 * u - 11 * v) import nzmath.rational as rational u, v, d = gcd.extgcd(rational.Integer(8), 11) self.assertEqual(1, abs(d)) self.assertEqual(d, 8 * u + 11 * v)
def atan2(y, x, err=defaultError): """ atan2(y, x [,err]) returns the arc tangent of y/x. Unlike atan(y/x), the signs of both x and y are considered. It is unrecomended to obtain the value of pi with atan2(0,1). """ if x > 0 and y > 0: return atan(y / x) elif x > 0 and y < 0: return pi(err) * 2 + atan(y / x) elif x < 0: return pi(err) + atan(y / x) elif x == 0 and y > 0: return pi(err) / 2 elif x == 0 and y < 0: return -pi(err) / 2 return rational.Integer(0)
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 piGaussLegendre(err=defaultError): """ piGaussLegendre computes pi by Gauss-Legendre algorithm. """ if isinstance(err, RelativeError): _err = err.absoluteerror(3.1415926535897932) else: _err = err werr = AbsoluteError(0, _err.absoluteerrorrange**2) maxdenom = int(1 / werr.absoluteerrorrange) * 2 a = rational.Integer(1) b = (1 / sqrt(rational.Rational(2), werr)).trim(maxdenom) t = rational.Rational(1, 4) x = 1 while not _err.nearlyEqual(a, b): a, b, c = (a + b) / 2, sqrt(a * b, werr).trim(maxdenom), (b - a)**2 / 4 t -= x * c x *= 2 return (a + b)**2 / (t * 4)
def _convertToRational(x): """ Convert to rational from: * int, * long, or * float. A complex object cannot be converted and raise TypeError. """ if isinstance(x, float): retval = +rational.Rational(long(math.frexp(x)[0] * 2**53), 2 **(53 - math.frexp(x)[1])) elif isinstance(x, (int, long)): retval = rational.Integer(x) elif isinstance(x, complex): raise TypeError, "The real module cannot handle %s. Please use imaginary module." % x else: # fall back retval = rational.Rational(x) return retval
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 eContinuedFraction(err=defaultError): """ Compute the base of natural logarithm e by continued fraction expansion. """ if isinstance(err, RelativeError): _err = err.absoluteerror(math.e) else: _err = err ipart = rational.Integer(2) fpart_old = rational.Rational(1, 1) fpart = rational.Rational(2, 3) i = 4 while not _err.nearlyEqual(fpart_old, fpart): fpart, fpart_old = rational.Rational( fpart.numerator + fpart_old.numerator, fpart.denominator + fpart_old.denominator), fpart fpart, fpart_old = rational.Rational( fpart.numerator + fpart_old.numerator, fpart.denominator + fpart_old.denominator), fpart fpart, fpart_old = rational.Rational( fpart.numerator * i + fpart_old.numerator, fpart.denominator * i + fpart_old.denominator), fpart i += 2 return ipart + fpart
def minimumNonNegative(self): """ Return the smallest non-negative representative element of the residue class. """ return rational.Integer(self.n % self.m)