
// Make newform 80.11.p.a in Magma, downloaded from the LMFDB on 10 February 2025.
// To make the character of type GrpDrchElt, type "MakeCharacter_80_p();"
// To make the character of type GrpDrchElt with Codomain the HeckeField, type "MakeCharacter_80_p_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_80_11_p_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_80_11_p_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 := [1, 0, 1];
        Kf := NumberField(Polynomial([elt : elt in poly]));
        AssignNames(~Kf, ["nu"]);
    end if;
    Rfbasis := [Kf.1^i : i in [0..Degree(Kf)-1]];
    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_80_p();"
function MakeCharacter_80_p()
    N := 80;
    order := 4;
    char_gens := [31, 21, 17];
    v := [4, 4, 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_80_p_Hecke();"
function MakeCharacter_80_p_Hecke(Kf)
    N := 80;
    order := 4;
    char_gens := [31, 21, 17];
    char_values := [[1, 0], [1, 0], [0, 1]];
    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]];
    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 := 11;
    raw_aps := [[0, 0], [-57, 57], [2925, 1100], [-6953, -6953], [-75242, 0], [109857, -109857], [-1528927, -1528927], [0, 4038680], [712423, -712423], [0, 446120], [29080718, 0], [-911847, -911847], [-163945678, 0], [-118422777, 118422777], [-276320313, -276320313], [308460097, -308460097], [0, 940888360], [-1353610038, 0], [-853570913, -853570913], [-2827014562, 0], [-2753297183, 2753297183], [0, -3324500640], [-1346339097, 1346339097], [0, -2667450320], [-526562847, -526562847], [1450352122, 0], [6946295783, -6946295783], [-11347640273, -11347640273], [0, -1871977240], [-1419237983, 1419237983], [20920923847, 20920923847], [47096289478, 0], [53630232273, 53630232273], [0, 2601608200], [0, 7572708600], [40194347198, 0], [-48907623447, -48907623447], [4657463623, -4657463623], [58658976887, 58658976887], [-106769168863, 106769168863], [0, -246435500200], [120624531482, 0], [-296325182962, 0], [-31446986943, 31446986943], [-37805903367, -37805903367], [0, 282326186640], [248218914598, 0], [-429371807097, 429371807097], [-798294971713, -798294971713], [0, 593201713080], [215614495617, -215614495617], [0, 1118777478240], [-1178085486398, 0], [726604882998, 0], [803958448033, 803958448033], [278593200263, -278593200263], [0, -695113280920], [-508238080722, 0], [959185971033, 959185971033], [670898141202, 0], [1732025787943, -1732025787943], [678141544257, -678141544257], [932236527807, 932236527807], [654904467518, 0], [2536537323297, -2536537323297], [991585927113, 991585927113], [-3294334470442, 0], [243243343713, 243243343713], [1830506262127, 1830506262127], [0, 668385151720], [3385118535297, -3385118535297], [0, 10142352378320], [6362438677927, 6362438677927], [6736568965537, -6736568965537], [0, -9031038671320], [-4640966295417, 4640966295417], [0, 3628818605400], [3518002224073, 3518002224073], [3986159363682, 0], [0, 19736021632080], [0, 6988754488440], [-24168657536998, 0], [-21975692912402, 0], [227495571617, -227495571617], [0, 5548284546160], [1026298045863, -1026298045863], [0, 5712046962080], [-4356519374607, -4356519374607], [38428053467402, 0], [23106390114343, -23106390114343], [-1279880156513, -1279880156513], [0, -11338756463360], [19432660215447, 19432660215447], [51355554695318, 0], [0, 17458496444440], [14749782969063, -14749782969063], [0, -26671363331800], [-46860417892398, 0], [-41875193200857, 41875193200857], [-1394996084438, 0], [39345887718207, 39345887718207], [-41436925934487, -41436925934487], [-3176382066297, 3176382066297], [0, -37530779614640], [-55891273825802, 0], [-74073155539487, -74073155539487], [-26873984692593, -26873984692593], [-707818062463, 707818062463], [0, -143123500258640], [75454571297042, 0], [-35914113526233, -35914113526233], [-75646944589983, 75646944589983], [1501654806033, 1501654806033], [0, 36818182913160], [-100278254876482, 0], [-67789669914398, 0], [-115027854162777, 115027854162777], [-13819519196713, -13819519196713], [49228706232897, -49228706232897], [0, 70778084407640], [42489366889082, 0], [-45160864071263, 45160864071263], [49133242282553, 49133242282553], [-53410666420857, 53410666420857], [193717020813798, 0], [114089807012042, 0], [0, -299855867654600], [0, -98148043190240], [-9017796729033, -9017796729033], [-222715377039263, 222715377039263], [0, 48829642490680], [-249851326504057, 249851326504057], [-199588025877522, 0], [55226254419033, 55226254419033], [-28039663665358, 0], [0, 129006345917120], [109208772611937, -109208772611937], [-288376291270273, -288376291270273], [-245302845038007, -245302845038007], [0, -29162284439600], [-284390883502442, 0], [-209755340979718, 0], [-106255049035097, 106255049035097], [-371353220550993, -371353220550993], [0, -310525596145720], [0, -417805708554160], [-542340616707743, 542340616707743], [-219826310387727, -219826310387727], [0, -331147778637080], [-528471960225497, 528471960225497], [700963333851273, 700963333851273], [24709332811202, 0], [188709623572103, -188709623572103], [188829735496887, 188829735496887], [688961060734127, 688961060734127], [-316488218531602, 0], [0, 709096902650800], [0, -696189745107040], [702940174325713, 702940174325713], [448743411217482, 0], [-725276278940353, -725276278940353], [488196424807137, -488196424807137], [494496524787767, 494496524787767], [174459439211798, 0], [588002341648833, 588002341648833], [962314168874183, -962314168874183], [-556497356294002, 0], [-816894351231527, -816894351231527]];
    aps := ConvertToHeckeField(raw_aps);
    chi := MakeCharacter_80_p_Hecke(Universe(aps));
    return ExtendMultiplicatively(weight, aps, chi);
end function;


// To make the newform (type ModFrm), type "MakeNewformModFrm_80_11_p_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_80_11_p_a(:prec:=2)
    chi := MakeCharacter_80_p();
    f_vec := qexpCoeffs();
    Kf := Universe(f_vec);
    // SetVerbose("ModularForms", true);
    // SetVerbose("ModularSymbols", true);
    S := CuspidalSubspace(ModularForms(chi, 11));
    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_80_11_p_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_80_11_p_a( : sign := -1)
    R<x> := PolynomialRing(Rationals());
    chi := MakeCharacter_80_p();
    // SetVerbose("ModularSymbols", true);
    Snew := NewSubspace(CuspidalSubspace(ModularSymbols(chi,11,sign)));
    Vf := Kernel([<3,R![6498, 114, 1]>],Snew);
    return Vf;
end function;