Brandt Modules#
Introduction#
The construction of Brandt modules provides us with a method to compute modular forms, as outlined in Pizer’s paper [Piz1980].
Given a prime number
Quaternion Algebras#
A quaternion algebra over
A = QuaternionAlgebra(p)
returns the quaternion algebra
A = QuaternionAlgebra(a, b)
returns the quaternion algebra
An order
A particularly important kind of orders are those that have a level;
see Definition 1.2 in [Piz1980]. This is a positive integer
R = A.maximal_order()
returns a maximal order
A right
The right order of
Brandt Modules#
B = BrandtModule(p, M=1)
returns the Brandt module associated to
the prime number
A = B.quaternion_algebra()
returns the quaternion algebra attached
to
O = B.order_of_level_N()
returns an order
B.right_ideals()
returns a tuple of representatives for all right
ideal classes of
The implementation of this method is especially interesting. It depends on the construction of a Hecke module defined as a free abelian group on right ideal classes of a quaternion algebra with the following action:
where cyclic_submodules(self, I, q)
one then
repeatedly computes
One can prove that two ideals
is_equivalent(I,J)
returns true if
The theta series of a lattice
L.theta_series(T,q)
returns a power series representing
Hecke Structure#
The Hecke structure defined on the Brandt module is given by the Brandt matrices which can be computed using the definition of the Hecke operators given earlier.
hecke_matrix_from_defn(self,n)
returns the matrix of the n-th Hecke
operator
However, one can efficiently compute Brandt matrices using theta
series. In fact, let
compute_hecke_matrix_brandt(self,n)
returns the n-th Hecke matrix,
computed using theta series.
EXAMPLES:
sage: B = BrandtModule(23)
sage: B.maximal_order()
Order of Quaternion Algebra (-1, -23) with base ring Rational Field with basis (1/2 + 1/2*j, 1/2*i + 1/2*k, j, k)
sage: B.right_ideals()
(Fractional ideal (2 + 2*j, 2*i + 2*k, 4*j, 4*k), Fractional ideal (2 + 2*j, 2*i + 6*k, 8*j, 8*k), Fractional ideal (2 + 10*j + 8*k, 2*i + 8*j + 6*k, 16*j, 16*k))
sage: B.hecke_matrix(2)
[1 2 0]
[1 1 1]
[0 3 0]
sage: B.brandt_series(3)
[1/4 + q + q^2 + O(q^3) 1/4 + q^2 + O(q^3) 1/4 + O(q^3)]
[ 1/2 + 2*q^2 + O(q^3) 1/2 + q + q^2 + O(q^3) 1/2 + 3*q^2 + O(q^3)]
[ 1/6 + O(q^3) 1/6 + q^2 + O(q^3) 1/6 + q + O(q^3)]
REFERENCES:
Further Examples#
We decompose a Brandt module over both
sage: B = BrandtModule(43, base_ring=ZZ); B
Brandt module of dimension 4 of level 43 of weight 2 over Integer Ring
sage: D = B.decomposition()
sage: D
[
Subspace of dimension 1 of Brandt module of dimension 4 of level 43 of weight 2 over Integer Ring,
Subspace of dimension 1 of Brandt module of dimension 4 of level 43 of weight 2 over Integer Ring,
Subspace of dimension 2 of Brandt module of dimension 4 of level 43 of weight 2 over Integer Ring
]
sage: D[0].basis()
((0, 0, 1, -1),)
sage: D[1].basis()
((1, 2, 2, 2),)
sage: D[2].basis()
((1, 1, -1, -1), (0, 2, -1, -1))
sage: B = BrandtModule(43, base_ring=QQ); B
Brandt module of dimension 4 of level 43 of weight 2 over Rational Field
sage: B.decomposition()[2].basis()
((1, 0, -1/2, -1/2), (0, 1, -1/2, -1/2))
AUTHORS:
Jon Bober
Alia Hamieh
Victoria de Quehen
William Stein
Gonzalo Tornaria
- sage.modular.quatalg.brandt.BrandtModule(N, M=1, weight=2, base_ring=Rational Field, use_cache=True)#
Return the Brandt module of given weight associated to the prime power
and integer , where and are coprime.INPUT:
– a product of primes with odd exponents – an integer coprime to (default: 1)weight
– an integer that is at least 2 (default: 2)base_ring
– the base ring (default:QQ
)use_cache
– whether to use the cache (default:True
)
OUTPUT:
a Brandt module
EXAMPLES:
sage: BrandtModule(17) Brandt module of dimension 2 of level 17 of weight 2 over Rational Field sage: BrandtModule(17,15) Brandt module of dimension 32 of level 17*15 of weight 2 over Rational Field sage: BrandtModule(3,7) Brandt module of dimension 2 of level 3*7 of weight 2 over Rational Field sage: BrandtModule(3,weight=2) Brandt module of dimension 1 of level 3 of weight 2 over Rational Field sage: BrandtModule(11, base_ring=ZZ) Brandt module of dimension 2 of level 11 of weight 2 over Integer Ring sage: BrandtModule(11, base_ring=QQbar) Brandt module of dimension 2 of level 11 of weight 2 over Algebraic Field
The
use_cache
option determines whether the Brandt module returned by this function is cached:sage: BrandtModule(37) is BrandtModule(37) True sage: BrandtModule(37,use_cache=False) is BrandtModule(37,use_cache=False) False
- class sage.modular.quatalg.brandt.BrandtModuleElement(parent, x)#
Bases:
sage.modular.hecke.element.HeckeModuleElement
EXAMPLES:
sage: B = BrandtModule(37) sage: x = B([1,2,3]); x (1, 2, 3) sage: parent(x) Brandt module of dimension 3 of level 37 of weight 2 over Rational Field
- monodromy_pairing(x)#
Return the monodromy pairing of
self
andx
.EXAMPLES:
sage: B = BrandtModule(5,13) sage: B.monodromy_weights() (1, 3, 1, 1, 1, 3) sage: (B.0 + B.1).monodromy_pairing(B.0 + B.1) 4
- class sage.modular.quatalg.brandt.BrandtModule_class(N, M, weight, base_ring)#
Bases:
sage.modular.hecke.ambient_module.AmbientHeckeModule
A Brandt module.
EXAMPLES:
sage: BrandtModule(3, 10) Brandt module of dimension 4 of level 3*10 of weight 2 over Rational Field
- Element#
alias of
BrandtModuleElement
- M()#
Return the auxiliary level (prime to
part) of the quaternion order used to compute this Brandt module.EXAMPLES:
sage: BrandtModule(7,5,2,ZZ).M() 5
- N()#
Return ramification level
.EXAMPLES:
sage: BrandtModule(7,5,2,ZZ).N() 7
- brandt_series(prec, var='q')#
Return matrix of power series
to the given precision.Note that the Hecke operators in this series are always over
, even if the base ring of this Brandt module is not .INPUT:
prec
– positive integervar
– string (default: )
OUTPUT:
matrix of power series with coefficients in
EXAMPLES:
sage: B = BrandtModule(11) sage: B.brandt_series(2) [1/4 + q + O(q^2) 1/4 + O(q^2)] [ 1/6 + O(q^2) 1/6 + q + O(q^2)] sage: B.brandt_series(5) [1/4 + q + q^2 + 2*q^3 + 5*q^4 + O(q^5) 1/4 + 3*q^2 + 3*q^3 + 3*q^4 + O(q^5)] [ 1/6 + 2*q^2 + 2*q^3 + 2*q^4 + O(q^5) 1/6 + q + q^3 + 4*q^4 + O(q^5)]
Asking for a smaller precision works:
sage: B.brandt_series(3) [1/4 + q + q^2 + O(q^3) 1/4 + 3*q^2 + O(q^3)] [ 1/6 + 2*q^2 + O(q^3) 1/6 + q + O(q^3)] sage: B.brandt_series(3,var='t') [1/4 + t + t^2 + O(t^3) 1/4 + 3*t^2 + O(t^3)] [ 1/6 + 2*t^2 + O(t^3) 1/6 + t + O(t^3)]
- character()#
The character of this space.
Always trivial.
EXAMPLES:
sage: BrandtModule(11,5).character() Dirichlet character modulo 55 of conductor 1 mapping 12 |--> 1, 46 |--> 1
- cyclic_submodules(I, p)#
Return a list of rescaled versions of the fractional right ideals
such that contains and the quotient has group structure the product of two cyclic groups of order .We emphasize again that
is rescaled to be integral.INPUT:
– ideal I in R = self.order_of_level_N() – prime coprime to self.level()
OUTPUT:
list of the
fractional right R-ideals that contain I such that J/I is GF(p) x GF(p).EXAMPLES:
sage: B = BrandtModule(11) sage: I = B.order_of_level_N().unit_ideal() sage: B.cyclic_submodules(I, 2) [Fractional ideal (1/2 + 3/2*j + k, 1/2*i + j + 1/2*k, 2*j, 2*k), Fractional ideal (1/2 + 1/2*i + 1/2*j + 1/2*k, i + k, j + k, 2*k), Fractional ideal (1/2 + 1/2*j + k, 1/2*i + j + 3/2*k, 2*j, 2*k)] sage: B.cyclic_submodules(I, 3) [Fractional ideal (1/2 + 1/2*j, 1/2*i + 5/2*k, 3*j, 3*k), Fractional ideal (1/2 + 3/2*j + 2*k, 1/2*i + 2*j + 3/2*k, 3*j, 3*k), Fractional ideal (1/2 + 3/2*j + k, 1/2*i + j + 3/2*k, 3*j, 3*k), Fractional ideal (1/2 + 5/2*j, 1/2*i + 1/2*k, 3*j, 3*k)] sage: B.cyclic_submodules(I, 11) Traceback (most recent call last): ... ValueError: p must be coprime to the level
- eisenstein_subspace()#
Return the 1-dimensional subspace of
self
on which the Hecke operators act as for coprime to the level.Note
This function assumes that the base field has characteristic 0.
EXAMPLES:
sage: B = BrandtModule(11); B.eisenstein_subspace() Subspace of dimension 1 of Brandt module of dimension 2 of level 11 of weight 2 over Rational Field sage: B.eisenstein_subspace() is B.eisenstein_subspace() True sage: BrandtModule(3,11).eisenstein_subspace().basis() ((1, 1),) sage: BrandtModule(7,10).eisenstein_subspace().basis() ((1, 1, 1, 1/2, 1, 1, 1/2, 1, 1, 1),) sage: BrandtModule(7,10,base_ring=ZZ).eisenstein_subspace().basis() ((2, 2, 2, 1, 2, 2, 1, 2, 2, 2),)
- free_module()#
Return the underlying free module of the Brandt module.
EXAMPLES:
sage: B = BrandtModule(10007,389) sage: B.free_module() Vector space of dimension 325196 over Rational Field
- hecke_matrix(n, algorithm='default', sparse=False, B=None)#
Return the matrix of the
-th Hecke operator.INPUT:
– integeralgorithm
– string (default: ‘default’)‘default’ – let Sage guess which algorithm is best
‘direct’ – use cyclic subideals (generally much better when you want few Hecke operators and the dimension is very large); uses ‘theta’ if n divides the level.
‘brandt’ – use Brandt matrices (generally much better when you want many Hecke operators and the dimension is very small; bad when the dimension is large)
sparse
– bool (default:False
) – integer orNone
(default:None
); in direct algorithm, use theta series to this precision as an initial check for equality of ideal classes.
EXAMPLES:
sage: B = BrandtModule(3,7); B.hecke_matrix(2) [0 3] [1 2] sage: B.hecke_matrix(5, algorithm='brandt') [0 6] [2 4] sage: t = B.hecke_matrix(11, algorithm='brandt', sparse=True); t [ 6 6] [ 2 10] sage: type(t) <class 'sage.matrix.matrix_rational_sparse.Matrix_rational_sparse'> sage: B.hecke_matrix(19, algorithm='direct', B=2) [ 8 12] [ 4 16]
- is_cuspidal()#
Return whether
self
is cuspidal, i.e. has no Eisenstein part.EXAMPLES:
sage: B = BrandtModule(3, 4) sage: B.is_cuspidal() False sage: B.eisenstein_subspace() Brandt module of dimension 1 of level 3*4 of weight 2 over Rational Field
- maximal_order()#
Return a maximal order in the quaternion algebra associated to this Brandt module.
EXAMPLES:
sage: BrandtModule(17).maximal_order() Order of Quaternion Algebra (-3, -17) with base ring Rational Field with basis (1/2 + 1/2*i, 1/2*j - 1/2*k, -1/3*i + 1/3*k, -k) sage: BrandtModule(17).maximal_order() is BrandtModule(17).maximal_order() True
- monodromy_weights()#
Return the weights for the monodromy pairing on this Brandt module.
The weights are associated to each ideal class in our fixed choice of basis. The weight of an ideal class
is half the number of units of the right order .NOTE: The base ring must be
or .EXAMPLES:
sage: BrandtModule(11).monodromy_weights() (2, 3) sage: BrandtModule(37).monodromy_weights() (1, 1, 1) sage: BrandtModule(43).monodromy_weights() (2, 1, 1, 1) sage: BrandtModule(7,10).monodromy_weights() (1, 1, 1, 2, 1, 1, 2, 1, 1, 1) sage: BrandtModule(5,13).monodromy_weights() (1, 3, 1, 1, 1, 3) sage: BrandtModule(2).monodromy_weights() (12,) sage: BrandtModule(2,7).monodromy_weights() (3, 3)
- order_of_level_N()#
Return an order of level
in the quaternion algebra.EXAMPLES:
sage: BrandtModule(7).order_of_level_N() Order of Quaternion Algebra (-1, -7) with base ring Rational Field with basis (1/2 + 1/2*j, 1/2*i + 1/2*k, j, k) sage: BrandtModule(7,13).order_of_level_N() Order of Quaternion Algebra (-1, -7) with base ring Rational Field with basis (1/2 + 1/2*j + 12*k, 1/2*i + 9/2*k, j + 11*k, 13*k) sage: BrandtModule(7,3*17).order_of_level_N() Order of Quaternion Algebra (-1, -7) with base ring Rational Field with basis (1/2 + 1/2*j + 35*k, 1/2*i + 65/2*k, j + 19*k, 51*k)
- quaternion_algebra()#
Return the quaternion algebra
over ramified precisely at and infinity used to compute this Brandt module.EXAMPLES:
sage: BrandtModule(997).quaternion_algebra() Quaternion Algebra (-2, -997) with base ring Rational Field sage: BrandtModule(2).quaternion_algebra() Quaternion Algebra (-1, -1) with base ring Rational Field sage: BrandtModule(3).quaternion_algebra() Quaternion Algebra (-1, -3) with base ring Rational Field sage: BrandtModule(5).quaternion_algebra() Quaternion Algebra (-2, -5) with base ring Rational Field sage: BrandtModule(17).quaternion_algebra() Quaternion Algebra (-3, -17) with base ring Rational Field
- right_ideals(B=None)#
Return sorted tuple of representatives for the equivalence classes of right ideals in
self
.OUTPUT:
sorted tuple of fractional ideals
EXAMPLES:
sage: B = BrandtModule(23) sage: B.right_ideals() (Fractional ideal (2 + 2*j, 2*i + 2*k, 4*j, 4*k), Fractional ideal (2 + 2*j, 2*i + 6*k, 8*j, 8*k), Fractional ideal (2 + 10*j + 8*k, 2*i + 8*j + 6*k, 16*j, 16*k))
- class sage.modular.quatalg.brandt.BrandtSubmodule(ambient, submodule, dual_free_module=None, check=True)#
- sage.modular.quatalg.brandt.basis_for_left_ideal(R, gens)#
Return a basis for the left ideal of
with given generators.INPUT:
– quaternion ordergens
– list of elements of
OUTPUT:
list of four elements of
EXAMPLES:
sage: B = BrandtModule(17); A = B.quaternion_algebra(); i,j,k = A.gens() sage: sage.modular.quatalg.brandt.basis_for_left_ideal(B.maximal_order(), [i+j,i-j,2*k,A(3)]) [1/2 + 1/6*i + 1/3*k, 1/3*i + 2/3*k, 1/2*j + 1/2*k, k] sage: sage.modular.quatalg.brandt.basis_for_left_ideal(B.maximal_order(), [3*(i+j),3*(i-j),6*k,A(3)]) [3/2 + 1/2*i + k, i + 2*k, 3/2*j + 3/2*k, 3*k]
- sage.modular.quatalg.brandt.benchmark_magma(levels, silent=False)#
INPUT:
levels
– list of pairs where is a prime not dividingsilent
– bool, defaultFalse
; ifTrue
suppress printing during computation
OUTPUT:
list of 4-tuples (‘magma’, p, M, tm), where tm is the CPU time in seconds to compute T2 using Magma
EXAMPLES:
sage: a = sage.modular.quatalg.brandt.benchmark_magma([(11,1), (37,1), (43,1), (97,1)]) # optional - magma ('magma', 11, 1, ...) ('magma', 37, 1, ...) ('magma', 43, 1, ...) ('magma', 97, 1, ...) sage: a = sage.modular.quatalg.brandt.benchmark_magma([(11,2), (37,2), (43,2), (97,2)]) # optional - magma ('magma', 11, 2, ...) ('magma', 37, 2, ...) ('magma', 43, 2, ...) ('magma', 97, 2, ...)
- sage.modular.quatalg.brandt.benchmark_sage(levels, silent=False)#
INPUT:
levels
– list of pairs where is a prime not dividingsilent
– bool, defaultFalse
; ifTrue
suppress printing during computation
OUTPUT:
list of 4-tuples (‘sage’, p, M, tm), where tm is the CPU time in seconds to compute T2 using Sage
EXAMPLES:
sage: a = sage.modular.quatalg.brandt.benchmark_sage([(11,1), (37,1), (43,1), (97,1)]) ('sage', 11, 1, ...) ('sage', 37, 1, ...) ('sage', 43, 1, ...) ('sage', 97, 1, ...) sage: a = sage.modular.quatalg.brandt.benchmark_sage([(11,2), (37,2), (43,2), (97,2)]) ('sage', 11, 2, ...) ('sage', 37, 2, ...) ('sage', 43, 2, ...) ('sage', 97, 2, ...)
- sage.modular.quatalg.brandt.class_number(p, r, M)#
Return the class number of an order of level
in the quaternion algebra over ramified precisely at and infinity.This is an implementation of Theorem 1.12 of [Piz1980].
INPUT:
– a prime – an odd positive integer (default: 1) – an integer coprime to (default: 1)
OUTPUT:
Integer
EXAMPLES:
sage: sage.modular.quatalg.brandt.class_number(389,1,1) 33 sage: sage.modular.quatalg.brandt.class_number(389,1,2) # TODO -- right? 97 sage: sage.modular.quatalg.brandt.class_number(389,3,1) # TODO -- right? 4892713
- sage.modular.quatalg.brandt.maximal_order(A)#
Return a maximal order in the quaternion algebra ramified at
and infinity.This is an implementation of Proposition 5.2 of [Piz1980].
INPUT:
– quaternion algebra ramified precisely at and infinity
OUTPUT:
a maximal order in
EXAMPLES:
sage: A = BrandtModule(17).quaternion_algebra() sage: sage.modular.quatalg.brandt.maximal_order(A) Order of Quaternion Algebra (-3, -17) with base ring Rational Field with basis (1/2 + 1/2*i, 1/2*j - 1/2*k, -1/3*i + 1/3*k, -k) sage: A = QuaternionAlgebra(17,names='i,j,k') sage: A.maximal_order() Order of Quaternion Algebra (-3, -17) with base ring Rational Field with basis (1/2 + 1/2*i, 1/2*j - 1/2*k, -1/3*i + 1/3*k, -k)
- sage.modular.quatalg.brandt.quaternion_order_with_given_level(A, level)#
Return an order in the quaternion algebra A with given level.
This is implemented only when the base field is the rational numbers.
INPUT:
level
– The level of the order to be returned. Currently this is only implemented when the level is divisible by at most one power of a prime that ramifies in this quaternion algebra.
EXAMPLES:
sage: from sage.modular.quatalg.brandt import quaternion_order_with_given_level, maximal_order sage: A.<i,j,k> = QuaternionAlgebra(5) sage: level = 2 * 5 * 17 sage: O = quaternion_order_with_given_level(A, level) sage: M = maximal_order(A) sage: L = O.free_module() sage: N = M.free_module() sage: L.index_in(N) == level/5 #check that the order has the right index in the maximal order True
- sage.modular.quatalg.brandt.right_order(R, basis)#
Given a basis for a left ideal
, return the right order in the quaternion order of elements such that is contained in .INPUT:
– order in quaternion algebrabasis
– basis for an ideal
OUTPUT:
order in quaternion algebra
EXAMPLES:
We do a consistency check with the ideal equal to a maximal order:
sage: B = BrandtModule(17); basis = sage.modular.quatalg.brandt.basis_for_left_ideal(B.maximal_order(), B.maximal_order().basis()) sage: sage.modular.quatalg.brandt.right_order(B.maximal_order(), basis) Order of Quaternion Algebra (-3, -17) with base ring Rational Field with basis (1/2 + 1/6*i + 1/3*k, 1/3*i + 2/3*k, 1/2*j + 1/2*k, k) sage: basis [1/2 + 1/6*i + 1/3*k, 1/3*i + 2/3*k, 1/2*j + 1/2*k, k] sage: B = BrandtModule(17); A = B.quaternion_algebra(); i,j,k = A.gens() sage: basis = sage.modular.quatalg.brandt.basis_for_left_ideal(B.maximal_order(), [i*j-j]) sage: sage.modular.quatalg.brandt.right_order(B.maximal_order(), basis) Order of Quaternion Algebra (-3, -17) with base ring Rational Field with basis (1/2 + 1/6*i + 1/3*k, 1/3*i + 2/3*k, 1/2*j + 1/2*k, k)