
// Make newform 15.12.a.b in Magma, downloaded from the LMFDB on 25 April 2024.
// To make the character of type GrpDrchElt, type "MakeCharacter_15_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_15_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_15_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 := [-402, -1, 1];
        Kf := NumberField(Polynomial([elt : elt in poly]));
        AssignNames(~Kf, ["nu"]);
    end if;
    Rf_num := [[1, 0], [-1, 2]];
    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_15_a();"
function MakeCharacter_15_a()
    N := 15;
    order := 1;
    char_gens := [11, 7];
    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_15_a_Hecke(Kf)
    return MakeCharacter_15_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 := [[-11, -1], [243, 0], [-3125, 0], [-5432, 1276], [-180896, -10384], [-1066866, 1916], [-3902294, -67540], [-7781112, 208364], [-18725124, -692028], [-35160334, -3089792], [149292436, -1112588], [118000478, 9027036], [-232471294, 22327912], [-121104300, -41066656], [-2187898460, 19806332], [-1094770694, -29631928], [-2740192928, 146298896], [7278951990, -14026936], [-7959194444, 50570080], [560280512, -295730240], [-12260787174, 71528792], [-39621527780, 90478060], [4622613348, 1383234048], [11058660618, -312314856], [-80181836734, 127385280], [113445524874, 1322187696], [32593822280, -4711723236], [-27974235420, 4997381112], [73158839678, 3118256064], [-22306676222, -941590852], [552341474016, 2562263180], [-104294393400, -3671031096], [446021080674, 12943304484], [763301268512, 5030439156], [48555435554, -8378506688], [-529617336588, -26416008460], [-239135300986, -16855505916], [194203341812, 10003265280], [176856049788, -10083303324], [-3448894030902, -12275463552], [388402263040, -26235100360], [-761722402714, 93271306752], [4269690203624, -46826390384], [-1222513253662, -58020905112], [789899036442, 32684883528], [2339003330484, -23879575468], [4635820444136, 10014038292], [7483652539304, 197517886596], [-4895852823652, 44953541536], [1967365938022, -345569551544], [-15037334419590, -112266665676], [10105249165648, -142468883656], [5149232049954, -370789115584], [22344095553792, -175198571160], [2028693508770, -346329524868], [-15384026907148, 396429037420], [13874729235538, 587003925824], [-19874929614276, 393080981156], [-24507575627498, 90661477348], [-26862644193462, 643888506648], [-13528219075556, -861396394544], [-30267426420198, 264033028680], [8804850290580, 332847947432], [14863332479304, 813970249176], [-36189476223238, 304257257880], [-41256869915950, -973004298248], [-30826815830408, -1066271872460], [-46963163867838, -1615424237992], [-18422579231924, 401591453720], [51173774475846, 3201136569848], [-108073085226606, 2288226355716], [28211766996072, -331894152624], [65687828914552, 809746132228], [-64035433076130, 1701399680084], [-44503523093880, -894750619540], [22067107925412, -1699283923620], [100700244270402, 165065346816], [-106748019312570, 1364193413132], [178816373223450, 1716584891904], [110898568107242, -958866789024], [-73875455485192, 6569323744504], [36819592711398, -3696850511992], [-43717791596304, -1698363582288], [-269437780659198, -3828272061160], [-251654288972700, -6476552348380], [-267386732241276, -6687594005664], [386416946436394, -5264777213488], [206169228308298, 1655650402016], [-403860346046838, 9378521648400], [-172164682675640, 6103155045724], [263213248702460, -864103163048], [-689797104414120, 1050874049280], [867625899557336, 2290363146660], [-882056682444280, 1652275041424], [207537820865328, -10882350972316], [270898731869084, 7753625176876], [9253846260082, -5451910969024], [-145717890789454, 14801030642992], [249462013931460, 9176440901144], [882954676508446, 18079954542592], [585932152045308, -15141638249584], [531537406547226, -22733152481040], [747320298467028, -30019887098712], [-361714092431022, -16412932358736], [754756227994904, -47934633355164], [-337159950218254, -1996480106160], [-623735690115660, 7682807149992], [-790473914823550, 61176048109804], [-188401552717336, 20128630028752], [-1373930301215206, -13206326703744], [-1242150722415744, -5395934115100], [695296528544718, -11145584965972], [-1574867911758006, -28254990308076], [-394789180406128, 6778670222676], [726336491520612, 42960384018380], [2743703310843786, 4190262617592], [2465920563819940, 2117386399504], [-179619925832204, -54343487061100], [-372324597003958, 105385966817920], [984686397477520, 36077858837840], [352650413788302, -81473955203080], [-1784656716562574, 37684946972872], [21947189882562, 13163607464448], [-1176257777551308, -104663368737720], [-1136678583742176, 64605663053156], [-1996204865443390, 27466228238704], [-5155665639535002, -45668782985416], [-2312670496900776, 164713147085832], [2919000858144104, -108655352948076], [-6366635072714530, 19122832258164], [4286663041109232, -50188263681004], [1794455985619300, -23832123897676], [-152162747082876, 117835995143156], [-1886106486932346, -3758557894156], [-803604979627662, -276502602332592], [-11336012213523886, 24079080750192], [4113183192163962, 43717655538840], [1665228170489820, 66978898368152], [-3179799449149990, 178296892031392], [-5568391936950910, -94130549293640], [323906781937312, -320308657536620], [9475621638696138, 209826123136848], [6056144315790368, 116871358866348], [-20383014102825164, 30780713917520], [-3562232372234930, -350832703878080], [6085737343565960, 86766954338560], [-4583344146881618, -263525495245700], [-5538511040715710, -283004572320148], [4990482797870040, -208975593250660], [-5006396970730300, -81978552335996], [11542621551650278, -393646860840764], [-10352567404473662, 155412038840648], [-9597701456808700, -129879745594896], [-18737558696154420, 262359684421332], [14941633916712700, 323818294528072], [-19347207318497288, 251476245847160], [12101729331911340, 612397272443060], [-309977035117702, -651432130524416], [-10711704376692758, -371940435979712], [5302728946725146, 51766938146992], [-9153837794942556, -248957456747256], [-5735277270925886, 680703656296676], [9772112971835216, -860736007798380], [-35142405165896544, -229889546483688], [-1867765330496774, 664979522722220], [30113095682457636, 432907387363572], [-1353409115892268, 536298482695020], [28632558289942414, 145069626212164]];
    aps := ConvertToHeckeField(raw_aps);
    chi := MakeCharacter_15_a_Hecke(Universe(aps));
    return ExtendMultiplicatively(weight, aps, chi);
end function;


// To make the newform (type ModFrm), type "MakeNewformModFrm_15_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_15_12_a_b(:prec:=2)
    chi := MakeCharacter_15_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_15_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_15_12_a_b( : sign := -1)
    R<x> := PolynomialRing(Rationals());
    chi := MakeCharacter_15_a();
    // SetVerbose("ModularSymbols", true);
    Snew := NewSubspace(CuspidalSubspace(ModularSymbols(chi,12,sign)));
    Vf := Kernel([<2,R![-1488, 22, 1]>],Snew);
    return Vf;
end function;