//
/******************************************************
*                                                     *
*     A GLIMPSE OF MODULAR FORMS IN MAGMA 2.14        *
*                                                     *
*           Steve Donnelly, August 2008               *
*                                                     *
******************************************************/
//
//  This demo is designed to be run using the command  
//     iload "filename";                                  
//
SetSeed(1); // this takes the suspense out of it
//
/******************************************************
*    CLASSICAL MODULAR FORMS                          *
******************************************************/
//
// For integral weight k >= 2, most of the computations 
// are done using modular symbols.  Example:
//
M := ModularForms(571); 
M;
time   nfs := Newforms(CuspidalSubspace(M));
#nfs;
nfs[1];
_<x> := PolynomialRing(Rationals()); // use 'x' for printing
[DefiningPolynomial(BaseRing(Parent(nf[1]))) : nf in nfs];
//
// Digression: let's look at the elliptic curve 
// associated to the first newform
//
E := EllipticCurve(nfs[1][1]);
E;
CremonaReference(E);
_ := MordellWeilShaInformation(E : ShaInfo);
//
// M has a uniquely determined basis: the echelonised basis
// of the Z-space of forms with integral Fourier coefficients
//
M := ModularForms(571); // redefine ==> don't use stored newforms
time   Basis(M, 20);
qExpansion( M.1, 50);
//
// Disadvantage: this requires computing up to a Sturm bound
PrecisionBound(ModularForms(571));
//
// Sometimes one might prefer to work directly with modular symbols: 
//
MS := ModularSymbols(571, 2, 1); // sign = +1 
                                 // ==> same dimension as modular forms
MS;
//
time   bas := qExpansionBasis( CuspidalSubspace(MS), 50);
bas[1];
//  
/******************************************************
*    HALF INTEGRAL WEIGHT MODULAR FORMS               *
******************************************************/
//
// This uses Basmaji's trick using two obvious multipliers
// (of weight 1/2 with levels 4 and 8).
//
// So for level N, this involves computing some integral weight
// forms with level LCM(8,N)
//
SetVerbose( "ModularForms", 1); // print info during computation
//
H := ModularForms(200, 3/2);
H;
time   Basis(H, 30);
//
// The space for level 196 has comparable size, but will take
// longer because it requires computations with level 392:
//
H := ModularForms(196, 3/2);
H;
time   Basis(H, 30);
// 
// Future functionality might include Hecke operators, 
// Shimura lifts, fast computation in weight 3/2, ...
//  
/******************************************************
*    WEIGHT ONE MODULAR FORMS                         *
******************************************************/
// 
SetVerbose( "ModularForms", 0); // switch off verbosity
//
// First we define an odd quadratic character 
// 
chi := KroneckerCharacter(-29);  
IsOdd(chi);
Modulus(chi);
Conductor(chi);
Order(chi);
//
M := ModularForms(chi, 1);
M;
// Magma obtains the Eisenstein forms directly (same as with k>1).
Basis(EisensteinSubspace(M), 20);
// 
// This constructs those cuspidal eigenforms associated to 
// dihedral Galois representations.
DihedralForms(CuspidalSubspace(M));
// 
// In the output, $.1*$.2 denotes chi.
//
// In weight 1, no dimension formula is available, so the next line
// will force Magma to do the full computation of the space. 
Dimension(M);
//
// The algorithm uses an intersection trick to try to prove that the 
// dihedral forms span the cuspidal space.
// 
// In cases where they don't seem to, the intersection trick gives us
// a space that contains the correct space, and if equality holds, we 
// prove it by considering the squares of the basis elements. 
// 
/******************************************************
*    HILBERT MODULAR FORMS VIA JACQUET-LANGLANDS      *
*                                                     *
*    (ie automorphic forms on quaternion orders)      *
*                                                     *
*    To be released in Magma 2.15                     *
******************************************************/
//
// Two independent methods will be available for computing spaces 
// of parallel weight 2. 
// (For any given field and level, at least one of them applies.)
// 
// Dembele's algorithm: 
// 
// This uses a definite quaternion algebra, and computes Brandt matrices 
// in an optimized way.  A particular feature is that for forms over a 
// given field, the most time consuming computations are independent of 
// the level. 
//
// Greenberg-Voight algorithm:

// This uses an algebra that is unramified at exactly one infinite place.  
// Let Gamma be the Fuchsian group consisting of the units of norm 1 
// in some Eichler order contained in the algebra.
// The algorithm obtains a presentation of H^1( upper half plane / Gamma )
// by computing a fundamental domain, and calculates the Hecke action on H^1.
//
// 
/******************************************************
*    SOME REMARKS FOR MAGMA USERS                     *
******************************************************/
//
// We would like to make Magma better, and you can help us 
// by reporting any bugs or difficulties you encounter, to 
//          magma-bugs@maths.usyd.edu.au
//
// People sometimes hesitate to report a problem due to 
// being unsure whether it's really a bug.  In fact, we'd
// like to receive more feedback from users generally.
// 
// Handy hints:
// '%P' prints all commands entered so far during a Magma session.
// To direct output to a file, use  SetOutputFile("filename"); 
//
// Happy Magma!
//
// Steve Donnelly
// donnelly@maths.usyd.edu.au
