Example #1
0
def cusp_matrix(cusp):
	"""
	Returns a matrix `M` such that `M * \infinity == cusp`.

	INPUT:

	- `cusp` -- a number \in \QQ.

	OUTPUT:

	- A matrix `M` \in \SL_2(\ZZ) such that

	      M * \infinity == cusp .
	"""
	if cusp == 0:
		return matrix(ZZ,2,2,[0,-1,1,0])
	else:
		a = cusp.numerator()
		c = cusp.denominator()
		_div, d, b = orig_xgcd(a, -c)
		assert _div == 1
		return matrix(ZZ,2,2,[a,b,c,d])
Example #2
0
	def xgcd(self, a, b):
		"""
		The extended Euclidean algorithm. Mostly a standard implementation
		with a few fast paths. For the generic case, it uses `self.divmod`.

		INPUT:

		- `a`, `b` -- two elements of `self.maxorder`.

		OUTPUT:

		- A tuple `(d, s, t)`, such that `d == a * s + b * t` and
		  `d` divides both `s` and `t`. `d` is the greatest common divisor.
		  These are all elements of `self.maxorder`.
		"""
		if a == b: return a, 1, 0
		if a == -b: return a, 1, 0
		if a == 1: return 1, 1, 0
		if b == 1: return 1, 0, 1
		if a == 0: return b, 0, 1
		if b == 0: return a, 1, 0
		a1,a2 = self.as_tuple_b(a)
		b1,b2 = self.as_tuple_b(b)
		if a2 == b2 == 0:
			return orig_xgcd(a1, b1)
		if a1 == b1 == 0:
			d,s,t = orig_xgcd(a2, b2)
			B2 = (self.D + self.Droot) / 2
			return d * B2, s, t

		# a,b = map(self.field, [a,b])
		# gcd = 1
		# factors_a,factors_b = [dict(list(x.factor())) for x in [a,b]]
		# for q in factors_a.keys():
		# 	if q in factors_b:
		# 		e = min(factors_a[q], factors_b[q])
		# 		factors_a[q] -= e
		# 		factors_b[q] -= e
		# 		gcd *= q * e

		a,b = map(self.maxorder, [a,b])

		euc_a = self.euclidean_func(a)
		euc_b = self.euclidean_func(b)
		if euc_a < euc_b:
			d,s,t = self.xgcd(b, a)
			return d,t,s
		# We have euc_b <= euc_a now.
		q,r = self.divmod(a, b)
		# q * b + r == a.
		assert q * b + r == a
		# => a - b*q == r
		d2,s2,t2 = self.xgcd(b, r)
		# d2 = b * s2 + r * t2
		assert d2 == b * s2 + r * t2
		# => d2 = b * s2 + (a - b*q) * t2
		# => d2 = a * t2 + b * (s2 - q * t2)
		d = d2
		s = _simplify(t2)
		t = _simplify(s2 - q * t2)
		assert d == a * s + b * t
		assert self.divides(a, d)
		assert self.divides(b, d)
		return d, s, t