
// Make newform 22.12.a.a in Magma, downloaded from the LMFDB on 18 April 2024.
// To make the character of type GrpDrchElt, type "MakeCharacter_22_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_22_12_a_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_22_12_a_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 := [-331, 0, 1];
        Kf := NumberField(Polynomial([elt : elt in poly]));
        AssignNames(~Kf, ["nu"]);
    end if;
    Rf_num := [[1, 0], [0, 8]];
    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_22_a();"
function MakeCharacter_22_a()
    N := 22;
    order := 1;
    char_gens := [13];
    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;

function MakeCharacter_22_a_Hecke(Kf)
    return MakeCharacter_22_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 := [[32, 0], [-213, 3], [1145, -50], [-43162, -165], [-161051, 0], [-1050092, 8839], [-1441138, 19951], [-9785856, 6371], [6340267, 106463], [22831248, -420342], [-253252085, 190135], [201336259, 2302978], [304432008, -6012597], [550047282, 8085116], [506171136, 14560338], [-34094638, -24738110], [-3395808759, 22140099], [2852023260, -57000010], [-18257155851, -9427609], [10336098297, -115678293], [1541435428, 51530311], [-14340691090, -2327652], [14766320386, -68251162], [42531871231, 35615342], [-90416224839, -149119060], [-34502427406, -115832021], [26500603864, 347063314], [68463658, -1072891261], [-29762292086, 1282642792], [-110135773279, -1410207746], [154543838440, -1856756651], [-100092160058, -3674893387], [592565725889, 155949790], [49727511746, -5756504061], [69063013190, 1107721057], [964440597018, -1619633158], [-546664167079, 9260916702], [-1640287827276, -7490309152], [-1824158287308, 2429513895], [-399282892870, -3474109316], [-2737311307843, -289272563], [440573666727, -6260591164], [-5340979893099, 1038616233], [1489538502228, 40101218468], [41124261454, 14151840140], [-1308567639928, 13059773124], [5763595954364, -966941496], [-1266643632257, 5162499181], [-2970964988454, -21543168585], [11040278671175, 17226153696], [-5938634061896, 34870960550], [6860219694266, 84597780370], [843579945912, 126545520746], [-8064255839947, -148097926913], [-23597939277538, -49265836958], [-9226578646506, 23265942507], [-29610963427534, 63516251428], [-18530154940684, 77438471187], [50128939126382, -119970198], [15426539765774, 70361347162], [27119568647268, 95838127418], [-12320346682088, -220169533171], [26382849351288, -220047858217], [-886903392620, 248953145726], [-60329587340713, 189756801510], [-24700235574891, 451623133914], [29564111890187, -34593064155], [22101684548458, 699075518383], [60248894837660, 386739714793], [-17236301254034, 551715890011], [39041736777531, -178615929858], [55450615481100, -532961647857], [47236757453459, 420126710799], [128627429848038, 752307934847], [59646456102599, -140914632717], [-64787541631093, -1081862068931], [101354336528769, -565758907320], [-42719911857642, -1008716991382], [23506958686882, -1155004755982], [-118661790173454, 675249812696], [56831358151764, 72908944062], [153231348067934, -792127169886], [-68026876853994, -2720820259863], [-306418977346723, 1357449602760], [-184868813381496, 1856301356462], [103342695806929, -656068128469], [599659609477619, -54205939514], [14704105282452, -2265750462322], [176882479716332, -1036754528126], [-410902446163127, -2144707622813], [-477368118670863, 2092811251659], [260605555456452, 4962968851389], [409020938392379, 1198553829321], [180022547466440, -1599116546612], [346199829715124, -1225330823268], [-851361384641602, -1492316884460], [841445428220855, 3622411586248], [-843589509877059, -1236271238328], [218352309859184, 4313077557261], [-923141486464632, -5635010056543], [-852648498951640, -3201581635506], [-267802030981122, 6262578626541], [-1044960468602684, -4495046879194], [1570787606510896, 1403621653118], [-817548621477084, 4485693246044], [493496654056769, 14268192005034], [-781216306998228, -12851178532854], [-1933431971657028, -3220672914408], [-1824391051328208, 2852031109128], [-1254884263805598, 3418170122849], [-1028359481498814, -20616778575988], [-3230808279200, 19543328058844], [-1078414736741374, 3971981450956], [611246057771603, -3062026410201], [133409916841779, 12358223960735], [1062124037708247, -22575265966188], [-189269833471279, -29012660844483], [-1929778959523531, 13081565359777], [-1730657395564161, 5432539860552], [2240811386180802, 9473828453280], [3090856189716925, -5016788494532], [-417139902179650, -27891185671296], [-489266841154154, 7369102089377], [2725708099260864, 12181253478822], [-3842593039203419, 13320953238937], [2314382389219746, 39718998327123], [-822976401992945, 28374495641392], [-2774009337476157, -48152655596799], [-2523675871591049, 34506836235013], [130390733170364, 23130054890742], [-3532699386418774, -205998855870], [-6831081542966252, -11865593726860], [-3853018444929091, 44414297395047], [-1544192242439086, 26010244226580], [-5431798906564164, 514461554037], [-2072761159974252, -51255068993917], [-4398336104942766, -57723429757572], [-7326663424045488, -35282372336362], [13972490892373965, -7151977811820], [11768103036327280, 16579497668411], [-5385864215022526, -44768168612016], [1513956255866662, 67550493418388], [-4643433454477885, 3642979238745], [14036351749693964, 26123810368345], [-3806427963000975, -58161821335198], [12796198342303263, -43501685277387], [1747984352287342, 5506682565196], [1322077531312280, 36879462725092], [-6943937078232891, -52322298493615], [1870631064478112, -70157673856220], [-2417294827745132, -66929100850763], [-4961250586686587, -99180083648710], [-13872717494235036, 67301513361638], [-21363715948979358, -73756262523468], [6975362123433972, 144913690545992], [1370565792759060, -12306985677126], [3203826564905090, -91025764730304], [-21797801874008478, 1893208931502], [24794922173359752, 99607468186547], [18391022435287674, -102381012283806], [-6398208592176807, -31377341799471], [-11562674085210558, -2699880092865], [1683473987762496, -78278481088126], [25485489437386995, -128513002922187], [-2160090295354531, -146862939056750], [1038385101720411, 263389526130489], [15551501282673056, -127802660121468], [16809243624738198, 38591343432233]];
    aps := ConvertToHeckeField(raw_aps);
    chi := MakeCharacter_22_a_Hecke(Universe(aps));
    return ExtendMultiplicatively(weight, aps, chi);
end function;


// To make the newform (type ModFrm), type "MakeNewformModFrm_22_12_a_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_22_12_a_a(:prec:=2)
    chi := MakeCharacter_22_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_22_12_a_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_22_12_a_a( : sign := -1)
    R<x> := PolynomialRing(Rationals());
    chi := MakeCharacter_22_a();
    // SetVerbose("ModularSymbols", true);
    Snew := NewSubspace(CuspidalSubspace(ModularSymbols(chi,12,sign)));
    Vf := Kernel([<3,R![-145287, 426, 1]>],Snew);
    return Vf;
end function;