def degeneracy_matrix(self, p=None): """ Map from self to QuaterniocModule of level self/p. EXAMPLES:: sage: from sage.modular.hilbert.sqrt5_hmf import F, QuaternionicModule sage: H = QuaternionicModule(2*F.prime_above(31)); H Quaternionic module of dimension 4, level 10*a-4 (of norm 124=2^2*31) over QQ(sqrt(5)) sage: H.degeneracy_matrix(2) [1 0] [0 1] [0 1] [0 1] sage: H.degeneracy_matrix(F.prime_above(31)) [1] [1] [1] [1] sage: H.degeneracy_matrix() [1 0 1] [0 1 1] [0 1 1] [0 1 1] sage: H.degeneracy_matrix() is H.degeneracy_matrix() False sage: H.degeneracy_matrix(2) is H.degeneracy_matrix(2) True """ if self.level().is_prime(): return matrix(QQ, self.dimension(), 0, sparse=True) if self._degeneracy_matrices.has_key(p): return self._degeneracy_matrices[p] if p is None: A = None for p in prime_divisors(self._level): A = self.degeneracy_matrix(p) if A is None else A.augment(self.degeneracy_matrix(p)) A.set_immutable() self._degeneracy_matrices[None] = A return A p = sqrt5_ideal(p) if self._degeneracy_matrices.has_key(p): return self._degeneracy_matrices[p] d = self._icosians_mod_p1.degeneracy_matrix(p) d.set_immutable() self._degeneracy_matrices[p] = d return d
def __init__(self, level): """ INPUT: - ``level`` -- an ideal or element of ZZ[(1+sqrt(5))/2]. TESTS:: sage: H = sage.modular.hilbert.sqrt5_hmf.QuaternionicModule(3); H Quaternionic module of dimension 1, level 3 (of norm 9=3^2) over QQ(sqrt(5)) sage: loads(dumps(H)) == H True """ self._level = sqrt5_ideal(level) self._gen = self._level.gens_reduced()[0] self._icosians_mod_p1 = IcosiansModP1ModN(self._level) self._dimension = self._icosians_mod_p1.cardinality() self._vector_space = QQ**self._dimension self._hecke_matrices = {} self._degeneracy_matrices = {}
def hecke_matrix(self, n): """ Return the matrix of the `n`-th Hecke operator. This is only implemented when `n` is a prime ideal that is coprime to the level, though the notion of Hecke operator is defined for any nonzero ideal `n`. INPUT: - `n` -- nonzero prime ideal of ring of integers of QQ(sqrt(5)) OUTPUT: - a matrix over the rational numbers with integer entries EXAMPLES:: sage: from sage.modular.hilbert.sqrt5_hmf import F, QuaternionicModule sage: H = QuaternionicModule(F.prime_above(31)); H Quaternionic module of dimension 2, level 5*a-2 (of norm 31=31) over QQ(sqrt(5)) sage: H.hecke_matrix(2) [0 5] [3 2] sage: P = F.prime_above(5); P Fractional ideal (-2*a + 1) sage: H.hecke_matrix(P) [1 5] [3 3] At least the prime does not have to be coprime to the norm of the level:: sage: v = F.primes_above(31) sage: H = QuaternionicModule(v[0]); H Quaternionic module of dimension 2, level 5*a-2 (of norm 31=31) over QQ(sqrt(5)) sage: H.hecke_matrix(v[1]) [17 15] [ 9 23] The input must be nonzero, or you get a ValueError:: sage: H.hecke_matrix(F.ideal(0)) Traceback (most recent call last): ... ValueError: n must be nonzero We illustrate some shortcomings of this function:: sage: H.hecke_matrix(P^2) Traceback (most recent call last): ... NotImplementedError: n must be prime sage: H.hecke_matrix(F.prime_above(31)) Traceback (most recent call last): ... NotImplementedError: n must be coprime to the level You may also use T as an alias for hecke_matrix:: sage: H.T(3) [5 5] [3 7] """ # I'm not using @cached_method, since I want to ensure that # the input "n" is properly normalized. I also want it # to be transparent to see which matrices have been computed, # to clear the cache, etc. n = sqrt5_ideal(n) if n.is_zero(): raise ValueError, "n must be nonzero" if not n.is_prime(): raise NotImplementedError, "n must be prime" if not self.level().is_coprime(n): raise NotImplementedError, "n must be coprime to the level" if self._hecke_matrices.has_key(n): return self._hecke_matrices[n] t = self._icosians_mod_p1.hecke_matrix(n) t.set_immutable() self._hecke_matrices[n] = t return t