def __iter__(self): r""" Create an iterator that generates the elements of `\Q/n\Z` without repetition, organized by increasing denominator. For a fixed denominator, elements are listed by increasing numerator. EXAMPLES: The first 19 elements of `\Q/5\Z`:: sage: import itertools sage: list(itertools.islice(QQ/(5*ZZ), 19r)) [0, 1, 2, 3, 4, 1/2, 3/2, 5/2, 7/2, 9/2, 1/3, 2/3, 4/3, 5/3, 7/3, 8/3, 10/3, 11/3, 13/3] """ if self.n == 0: for x in QQ: yield self(x) else: d = ZZ(0) while True: for a in d.coprime_integers((d * self.n).floor()): yield self(a / d) d += 1
def zeta(self, n=2, all=False): """ Return one, or a list of all, primitive n-th root of unity in this unit group. EXAMPLES:: sage: x = polygen(QQ) sage: K.<z> = NumberField(x^2 + 3) sage: U = UnitGroup(K) sage: U.zeta(1) 1 sage: U.zeta(2) -1 sage: U.zeta(2, all=True) [-1] sage: U.zeta(3) -1/2*z - 1/2 sage: U.zeta(3, all=True) [-1/2*z - 1/2, 1/2*z - 1/2] sage: U.zeta(4) Traceback (most recent call last): ... ValueError: n (=4) does not divide order of generator sage: r.<x> = QQ[] sage: K.<b> = NumberField(x^2+1) sage: U = UnitGroup(K) sage: U.zeta(4) -b sage: U.zeta(4,all=True) [-b, b] sage: U.zeta(3) Traceback (most recent call last): ... ValueError: n (=3) does not divide order of generator sage: U.zeta(3,all=True) [] """ N = self.__ntu K = self.number_field() n = ZZ(n) if n <= 0: raise ValueError("n (=%s) must be positive" % n) if n == 1: if all: return [K(1)] else: return K(1) elif n == 2: if all: return [K(-1)] else: return K(-1) if n.divides(N): z = self.torsion_generator().value()**(N // n) if all: return [z**i for i in n.coprime_integers(n)] else: return z else: if all: return [] else: raise ValueError("n (=%s) does not divide order of generator" % n)
def zeta(self, n=2, all=False): """ Return one, or a list of all, primitive n-th root of unity in this unit group. EXAMPLES:: sage: x = polygen(QQ) sage: K.<z> = NumberField(x^2 + 3) sage: U = UnitGroup(K) sage: U.zeta(1) 1 sage: U.zeta(2) -1 sage: U.zeta(2, all=True) [-1] sage: U.zeta(3) -1/2*z - 1/2 sage: U.zeta(3, all=True) [-1/2*z - 1/2, 1/2*z - 1/2] sage: U.zeta(4) Traceback (most recent call last): ... ValueError: n (=4) does not divide order of generator sage: r.<x> = QQ[] sage: K.<b> = NumberField(x^2+1) sage: U = UnitGroup(K) sage: U.zeta(4) -b sage: U.zeta(4,all=True) [-b, b] sage: U.zeta(3) Traceback (most recent call last): ... ValueError: n (=3) does not divide order of generator sage: U.zeta(3,all=True) [] """ N = self.__ntu K = self.number_field() n = ZZ(n) if n <= 0: raise ValueError, "n (=%s) must be positive"%n if n == 1: if all: return [K(1)] else: return K(1) elif n == 2: if all: return [K(-1)] else: return K(-1) if n.divides(N): z = self.torsion_generator().value() ** (N//n) if all: return [z**i for i in n.coprime_integers(n)] else: return z else: if all: return [] else: raise ValueError, "n (=%s) does not divide order of generator"%n