
// Make newform 7.5.d.a in Magma, downloaded from the LMFDB on 23 April 2024.
// To make the character of type GrpDrchElt, type "MakeCharacter_7_d();"
// To make the character of type GrpDrchElt with Codomain the HeckeField, type "MakeCharacter_7_d_Hecke();"
// To make the coeffs of the qexp of the newform in the Hecke field type "qexpCoeffs();"
// To make the newform (type ModFrm), type "MakeNewformModFrm_7_5_d_a();".
// This may take a long time!  To see verbose output, uncomment the SetVerbose lines below.
// The precision argument determines an initial guess on how many Fourier coefficients to use.
// This guess is increased enough to uniquely determine the newform.
// To make the Hecke irreducible modular symbols subspace (type ModSym)
// containing the newform, type "MakeNewformModSym_7_5_d_a();".
// This may take a long time!  To see verbose output, uncomment the SetVerbose line below.
// The default sign is -1.  You can change this with the optional parameter "sign".
function ConvertToHeckeField(input: pass_field := false, Kf := [])
    if not pass_field then
        poly := [484, 0, 22, 0, 1];
        Kf := NumberField(Polynomial([elt : elt in poly]));
        AssignNames(~Kf, ["nu"]);
    end if;
    Rf_num := [[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]];
    Rf_basisdens := [1, 1, 22, 22];
    Rf_basisnums := ChangeUniverse([[z : z in elt] : elt in Rf_num], Kf);
    Rfbasis := [Rf_basisnums[i]/Rf_basisdens[i] : i in [1..Degree(Kf)]];
    inp_vec := Vector(Rfbasis)*ChangeRing(Transpose(Matrix([[elt : elt in row] : row in input])),Kf);
    return Eltseq(inp_vec);
end function;


// To make the character of type GrpDrchElt, type "MakeCharacter_7_d();"
function MakeCharacter_7_d()
    N := 7;
    order := 6;
    char_gens := [3];
    v := [1];
    // chi(gens[i]) = zeta^v[i]
    assert UnitGenerators(DirichletGroup(N)) eq char_gens;
    F := CyclotomicField(order);
    chi := DirichletCharacterFromValuesOnUnitGenerators(DirichletGroup(N,F),[F|F.1^e:e in v]);
    return MinimalBaseRingCharacter(chi);
end function;

// To make the character of type GrpDrchElt with Codomain the HeckeField, type "MakeCharacter_7_d_Hecke();"
function MakeCharacter_7_d_Hecke(Kf)
    N := 7;
    order := 6;
    char_gens := [3];
    char_values := [[1, 0, 1, 0]];
    assert UnitGenerators(DirichletGroup(N)) eq char_gens;
    values := ConvertToHeckeField(char_values : pass_field := true, Kf := Kf); // the value of chi on the gens as elements in the Hecke field
    F := Universe(values);// the Hecke field
    chi := DirichletCharacterFromValuesOnUnitGenerators(DirichletGroup(N,F),values);
    return chi;
end function;


function ExtendMultiplicatively(weight, aps, character)
    prec := NextPrime(NthPrime(#aps)) - 1; // we will able to figure out a_0 ... a_prec
    primes := PrimesUpTo(prec);
    prime_powers := primes;
    assert #primes eq #aps;
    log_prec := Floor(Log(prec)/Log(2)); // prec < 2^(log_prec+1)
    F := Universe(aps);
    FXY<X, Y> := PolynomialRing(F, 2);
    // 1/(1 - a_p T + p^(weight - 1) * char(p) T^2) = 1 + a_p T + a_{p^2} T^2 + ...
    R<T> := PowerSeriesRing(FXY : Precision := log_prec + 1);
    recursion := Coefficients(1/(1 - X*T + Y*T^2));
    coeffs := [F!0: i in [1..(prec+1)]];
    coeffs[1] := 1; //a_1
    for i := 1 to #primes do
        p := primes[i];
        coeffs[p] := aps[i];
        b := p^(weight - 1) * F!character(p);
        r := 2;
        p_power := p * p;
        //deals with powers of p
        while p_power le prec do
            Append(~prime_powers, p_power);
            coeffs[p_power] := Evaluate(recursion[r + 1], [aps[i], b]);
            p_power *:= p;
            r +:= 1;
        end while;    
    end for;
    Sort(~prime_powers);
    for pp in prime_powers do
        for k := 1 to Floor(prec/pp) do
            if GCD(k, pp) eq 1 then
                coeffs[pp*k] := coeffs[pp]*coeffs[k];
            end if;
        end for;
    end for;
    return coeffs;
end function;


function qexpCoeffs()
    // To make the coeffs of the qexp of the newform in the Hecke field type "qexpCoeffs();"
    weight := 5;
    raw_aps := [[-2, 1, -2, 0], [2, -1, 1, 1], [-5, 2, 5, 4], [21, 0, 42, -7], [0, 17, 29, 17], [-70, -28, -140, -14], [-82, 34, -41, -34], [107, 37, -107, 74], [145, -41, 145, 0], [-544, 0, 0, 70], [1206, -29, 603, 29], [-135, -104, -135, 0], [-798, -84, -1596, -42], [618, 0, 0, -350], [-257, -187, 257, -374], [0, -340, 2255, -340], [842, -449, 421, 449], [-47, 240, 47, 480], [0, 45, 659, 45], [-2602, 0, 0, 238], [1738, 272, 869, -272], [-4055, 351, -4055, 0], [1932, -168, 3864, -84], [5665, -376, -5665, -752], [-686, 2548, -1372, 1274], [-19402, -50, -9701, 50], [-4611, 1325, 4611, 2650], [4891, -461, 4891, 0], [0, -2398, -279, -2398], [-1888, 0, 0, -2366], [10418, 0, 0, 966], [-3407, 317, 3407, 634], [0, 3230, -19879, 3230], [6160, 1288, 12320, 644], [10603, 7078, 10603, 0], [0, -6451, 1485, -6451], [-1118, -2752, -559, 2752], [-29591, 2871, -29591, 0], [13566, -336, 27132, -168], [21037, 128, -21037, 256], [0, -1663, 15737, -1663], [-5712, -168, -11424, -84], [-31565, -4157, -31565, 0], [0, 4994, 31977, 4994], [3068, 0, 0, -4046], [17054, -1569, 8527, 1569], [9690, 0, 0, -12866], [-38556, 3864, -77112, 1932], [48638, 1147, 24319, -1147], [30403, 6246, -30403, 12492], [-401, -15266, -401, 0], [-11464, 0, 0, 4186], [-49446, -4796, -24723, 4796], [61362, 3024, 122724, 1512], [-5045, -5542, 5045, -11084], [0, 19421, 40223, 19421], [-13942, 13012, -6971, -13012], [-5031, 1157, 5031, 2314], [0, -10224, -11101, -10224], [-72364, 0, 0, 4102], [56534, -4593, 28267, 4593], [9408, -9408, 18816, -4704], [-12712, 9968, -25424, 4984], [-39478, -16577, -19739, 16577], [-43111, -10988, 43111, -21976], [-63695, 12412, -63695, 0], [46653, 379, 46653, 0], [42912, 0, 0, 18214], [0, -10399, -36469, -10399], [15302, 8708, 30604, 4354], [106094, -2066, 53047, 2066], [73435, -32969, 73435, 0], [-173486, 11003, -86743, -11003], [8209, -2820, 8209, 0], [-154992, 0, 0, 24010], [82399, -14047, -82399, -28094], [0, -46, -43819, -46], [-63705, -7054, 63705, -14108], [39079, 35050, 39079, 0], [63422, 15714, 31711, -15714], [11424, 16800, 22848, 8400], [-28936, 0, 0, -8190], [0, 12449, -63139, 12449], [-52346, -27524, -104692, -13762], [-48865, 12553, 48865, 25106], [255463, 14239, 255463, 0], [112688, 0, 0, -10346], [-319167, -13628, -319167, 0], [22974, -64428, 45948, -32214], [279302, 0, 0, 3906], [160393, -2959, -160393, -5918], [-208654, 895, -104327, -895], [0, 6653, 214887, 6653], [-199960, 0, 0, 13762], [189873, 2143, 189873, 0], [-110124, 44856, -220248, 22428], [21667, -42838, -21667, -85676], [287954, -22520, 143977, 22520], [120367, -8307, -120367, -16614], [-36689, -23358, -36689, 0], [-203992, 0, 0, -46662], [0, -6514, 249341, -6514], [-150358, -2717, -75179, 2717], [240469, 47944, 240469, 0], [0, 112017, 32201, 112017], [55946, 45828, 27973, -45828], [156408, -11760, 312816, -5880], [-15881, 74090, 15881, 148180], [0, -80959, -62425, -80959], [85778, -96460, 171556, -48230], [-222157, 5329, 222157, 10658], [0, 8298, -341767, 8298], [179804, 0, 0, 101962], [-358062, -30605, -179031, 30605], [157586, 0, 0, -87738], [0, -18820, 359507, -18820], [113596, 104944, 227192, 52472], [-159094, 21895, -79547, -21895], [20557, -125096, 20557, 0], [-367582, 0, 0, -88130], [-161726, 54368, -80863, -54368], [-584568, 0, 0, 3766], [-138101, -11842, 138101, -23684], [0, 18245, -556051, 18245], [228237, -9259, -228237, -18518], [-84502, 0, 0, -67928], [364005, 102796, 364005, 0], [-250367, 14429, 250367, 28858], [-24416, 180040, -48832, 90020], [185061, -18856, -185061, -37712], [0, -24651, 539729, -24651], [554906, 0, 0, -49490], [-304509, -63797, -304509, 0], [163284, 0, 0, 65338], [-1013, 15122, 1013, 30244], [-211806, -24276, -423612, -12138], [-269218, 1042, -134609, -1042], [1097210, -21561, 548605, 21561], [-401478, 44268, -802956, 22134], [0, 132464, 76595, 132464], [-118524, -244272, -237048, -122136], [-255593, 68230, -255593, 0], [0, -42039, 238799, -42039], [333566, 0, 0, 49882], [335302, -28414, 167651, 28414], [-349356, -44016, -698712, -22008], [251706, 57876, 503412, 28938], [775154, 76, 387577, -76], [267507, 38201, -267507, 76402], [-5819, 2311, -5819, 0], [343915, -30330, 343915, 0], [-261072, 102312, -522144, 51156], [-489690, 0, 0, 126406], [-508037, 1325, 508037, 2650], [0, -188143, -341865, -188143], [483170, 0, 0, 132874], [-339453, -54977, -339453, 0], [644485, -2392, -644485, -4784], [78904, 102592, 157808, 51296], [-383710, 107596, -191855, -107596], [-14303, -209789, -14303, 0], [120248, 0, 0, 95242], [220670, 0, 0, -299418], [-142511, -111067, 142511, -222134], [0, 170978, -209719, 170978], [-1173058, -43709, -586529, 43709], [0, 157433, 780039, 157433], [-563974, -109236, -281987, 109236]];
    aps := ConvertToHeckeField(raw_aps);
    chi := MakeCharacter_7_d_Hecke(Universe(aps));
    return ExtendMultiplicatively(weight, aps, chi);
end function;


// To make the newform (type ModFrm), type "MakeNewformModFrm_7_5_d_a();".
// This may take a long time!  To see verbose output, uncomment the SetVerbose lines below.
// The precision argument determines an initial guess on how many Fourier coefficients to use.
// This guess is increased enough to uniquely determine the newform.
function MakeNewformModFrm_7_5_d_a(:prec:=4)
    chi := MakeCharacter_7_d();
    f_vec := qexpCoeffs();
    Kf := Universe(f_vec);
    // SetVerbose("ModularForms", true);
    // SetVerbose("ModularSymbols", true);
    S := CuspidalSubspace(ModularForms(chi, 5));
    S := BaseChange(S, Kf);
    maxprec := NextPrime(997) - 1;
    while true do
        trunc_vec := Vector(Kf, [0] cat [f_vec[i]: i in [1..prec]]);
        B := Basis(S, prec + 1);
        S_basismat := Matrix([AbsEltseq(g): g in B]);
        if Rank(S_basismat) eq Min(NumberOfRows(S_basismat), NumberOfColumns(S_basismat)) then
            S_basismat := ChangeRing(S_basismat,Kf);
            f_lincom := Solution(S_basismat,trunc_vec);
            f := &+[f_lincom[i]*Basis(S)[i] : i in [1..#Basis(S)]];
            return f;
        end if;
        error if prec eq maxprec, "Unable to distinguish newform within newspace";
        prec := Min(Ceiling(1.25 * prec), maxprec);
    end while;
end function;


// To make the Hecke irreducible modular symbols subspace (type ModSym)
// containing the newform, type "MakeNewformModSym_7_5_d_a();".
// This may take a long time!  To see verbose output, uncomment the SetVerbose line below.
// The default sign is -1.  You can change this with the optional parameter "sign".
function MakeNewformModSym_7_5_d_a( : sign := -1)
    R<x> := PolynomialRing(Rationals());
    chi := MakeCharacter_7_d();
    // SetVerbose("ModularSymbols", true);
    Snew := NewSubspace(CuspidalSubspace(ModularSymbols(chi,5,sign)));
    Vf := Kernel([],Snew);
    return Vf;
end function;