
// Make newform 8.12.a.b in Magma, downloaded from the LMFDB on 25 April 2024.
// To make the character of type GrpDrchElt, type "MakeCharacter_8_a();"
// To make the coeffs of the qexp of the newform in the Hecke field type "qexpCoeffs();"
// To make the newform (type ModFrm), type "MakeNewformModFrm_8_12_a_b();".
// 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_8_12_a_b();".
// 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 := [-27, -1, 1];
        Kf := NumberField(Polynomial([elt : elt in poly]));
        AssignNames(~Kf, ["nu"]);
    end if;
    Rf_num := [[1, 0], [-64, 128]];
    Rf_basisdens := [1, 1];
    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_8_a();"
function MakeCharacter_8_a()
    N := 8;
    order := 1;
    char_gens := [7, 5];
    v := [1, 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;

function MakeCharacter_8_a_Hecke(Kf)
    return MakeCharacter_8_a();
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 := 12;
    raw_aps := [[0, 0], [28, 1], [3934, -12], [45528, 42], [79540, -693], [525238, 948], [715442, -10824], [-10933300, -4587], [17903368, -24738], [-114413850, 59556], [32361056, -28632], [37779390, -81564], [600607098, 647088], [-22759916, 324051], [-614539632, -816420], [-1904274962, 3514980], [-3006463292, 4307463], [4894896454, 4588692], [7351547612, -21317583], [2159995544, -20099142], [5527819738, -3259368], [25978811632, 41373444], [-54113987956, -13552251], [35594145930, 90758808], [-849903838, -64199400], [-106164817794, -92634300], [26674886392, 50222370], [13407152340, 188530755], [-63793647914, 274468740], [166050153426, -208211136], [-411600944768, 371112672], [-331390871140, 115327041], [362047564698, 1033633776], [82553600052, -1473987957], [837755895566, 366857652], [-135059652472, 1548661758], [-118438604186, -729117324], [-662406719748, 1877379273], [-170625773640, 170378802], [2220931930518, 87360852], [-3266916205908, 2019662589], [-1833626633874, -2662913388], [-1468064412096, 1288347312], [3568634818370, 1607179224], [637883345310, -8230229868], [6823043163160, -448305894], [-2876070121460, 7136309733], [4448445493408, 2824786200], [8245639158204, -4924252071], [12149846719486, 5056539540], [-1119442305350, 13283969496], [-2849517808432, 10531311756], [4871181329490, 5103988536], [-3171536779516, 3800992887], [7301187963650, 15425894400], [3809887845592, -38349015894], [14820455967926, -38561131740], [-10283934962896, -50164609740], [-28082353396082, -15327017244], [-19317940963126, 720896568], [-15376232371612, 17626108863], [-24415488581442, 8110845012], [-36620100537300, -21165122883], [13811172043368, 52649962182], [22315945231146, -3032481744], [-5387545186746, 94910740260], [-501431605132, -28404959205], [-5674330347150, -159119141664], [-112073612870364, -47657667729], [49547356978854, 101568625668], [-24408773417182, 31816574304], [-131372216198664, -127620087966], [1863162160720, -201722385300], [71214375912878, -32131359036], [111364335131780, -70641722025], [-24871259952000, 267266570976], [58034803698142, 374271158436], [-68300987233738, 424366642692], [-30114777459918, -19196303112], [-111138769262262, -100276540944], [-222907668646404, -170154440151], [148372558333502, -126728650188], [118462870934288, 30515528316], [-81412767904622, -337993815816], [-60863222277144, -264724812954], [-210064390799548, 212194562055], [432994655406658, 428869512792], [-475612698720934, -179877362448], [298927683145462, -819352812060], [-365689206288016, -284643247644], [-12116520483060, 94622157573], [135108912776096, 814899658584], [274331498697592, -935275669566], [-355579776154284, -306857986365], [-481126890995604, 330760589901], [1296515599776936, 70858539894], [30475621542534, 445583188404], [-294894463251430, 1001067839280], [261339746219188, -274688006901], [-130230290273562, -1569721347180], [1253091551415164, -739517598519], [-858937068443114, -194583008844], [-1738106274128084, 49976219901], [1632238377492010, -1654269929424], [178330487438532, -1292758218969], [1574346087244994, -479112404640], [1827102379576180, 1108487456667], [-1782340294025102, 1095734467008], [222332987606472, -158621623314], [-1538127868557686, 913547048088], [-888874797214432, -72506640456], [-411713349059458, 761856850356], [-1791520248001734, -1367136894984], [1626979808573140, -1652524634493], [-1848967722373592, 395635523094], [2599973563685506, 1610698374936], [1515392436397980, -168679278207], [1613899345060184, -1269867279990], [-1784800855693002, -1914593996700], [-1140460273591476, -6517772893611], [-210155119980274, -6306644384364], [-2712319338156062, -1517863423272], [3006533258809150, 1189073750052], [895743236649364, 4746602381619], [-2341028117860180, -4195173736323], [2698470051066054, -8327381465004], [441443294775710, 7633821262116], [1353773194884208, 5062750820772], [-1316093286508728, -13262240264562], [-183591045890266, 8199064836708], [4563583123492796, -7529229351], [-4101891520457096, 7623038736642], [3753544345283280, 2222109826188], [-8601707497754578, 1927481502324], [-4694017254829462, -4668541259472], [-2061411823085566, 6370963419096], [9871110970777182, 5087367157476], [1361409547835596, 61143137205], [3026035083440614, 105106834740], [-6917972741862790, -14005946425296], [13621048640000788, 2827940805747], [2887475255289582, -12658340643900], [2266681823023208, 2675815450182], [-4739349230424124, 8529035613735], [4311014318317126, -22206434892492], [11446785854446488, -7922455852614], [2613072328130894, 22663021742820], [9407331656491146, 19862875367856], [-4851243687566556, 4784564830575], [6284728207597600, -12865622741832], [4584076520666070, 13991637662436], [11464368132761810, -11108775904800], [7380329105986796, -29951535630387], [-17158078497588952, -3727798742634], [122732928868660, 2444482546443], [19218209289087664, 5754991611348], [4731820415400328, -5672751142338], [1887807701781218, 23747755508568], [-7084048080498438, 27080659647576], [-21791006540912490, -4938428055612], [22582783405203372, -4259752357539], [-2301285475012950, 22651936611696], [-11383027040469736, -53769873838758], [-6075750963818508, 49359340045659], [-17011948645798926, 7558463484600], [-35252018983785912, -21051023048370], [7269901828026784, 55397816058648], [36607141063696126, -23270745718620]];
    aps := ConvertToHeckeField(raw_aps);
    chi := MakeCharacter_8_a_Hecke(Universe(aps));
    return ExtendMultiplicatively(weight, aps, chi);
end function;


// To make the newform (type ModFrm), type "MakeNewformModFrm_8_12_a_b();".
// 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_8_12_a_b(:prec:=2)
    chi := MakeCharacter_8_a();
    f_vec := qexpCoeffs();
    Kf := Universe(f_vec);
    // SetVerbose("ModularForms", true);
    // SetVerbose("ModularSymbols", true);
    S := CuspidalSubspace(ModularForms(chi, 12));
    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_8_12_a_b();".
// 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_8_12_a_b( : sign := -1)
    R<x> := PolynomialRing(Rationals());
    chi := MakeCharacter_8_a();
    // SetVerbose("ModularSymbols", true);
    Snew := NewSubspace(CuspidalSubspace(ModularSymbols(chi,12,sign)));
    Vf := Kernel([<3,R![-445680, -56, 1]>],Snew);
    return Vf;
end function;