
// Make newform 1815.4.a.m in Magma, downloaded from the LMFDB on 23 April 2024.
// To make the character of type GrpDrchElt, type "MakeCharacter_1815_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_1815_4_a_m();".
// 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_1815_4_a_m();".
// 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 := [-15, 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_1815_a();"
function MakeCharacter_1815_a()
    N := 1815;
    order := 1;
    char_gens := [1211, 727, 1696];
    v := [1, 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_1815_a_Hecke(Kf)
    return MakeCharacter_1815_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 := 4;
    raw_aps := [[0, 1], [3, 0], [-5, 0], [0, -4], [0, 0], [0, 18], [0, -4], [0, 2], [48, 0], [0, -54], [160, 0], [-266, 0], [0, 46], [0, -80], [-504, 0], [-342, 0], [-660, 0], [0, -56], [496, 0], [-708, 0], [0, -166], [0, -46], [0, -22], [-606, 0], [254, 0], [0, 470], [1508, 0], [0, -230], [0, -176], [18, 0], [0, 72], [0, -212], [-1866, 0], [0, 110], [0, -422], [0, -470], [274, 0], [-3688, 0], [0, 462], [0, -204], [3204, 0], [4490, 0], [0, 0], [0, 974], [0, 108], [-3680, 0], [0, 594], [-3568, 0], [0, 1286], [5170, 0], [0, 1204], [0, 752], [0, 1440], [-1272, 0], [1986, 0], [0, -1222], [-6570, 0], [0, 358], [0, -2006], [0, -1738], [0, 848], [0, 1988], [0, 1492], [5328, 0], [442, 0], [-7794, 0], [-2140, 0], [0, -126], [0, -2374], [0, -848], [-4602, 0], [0, 1996], [3176, 0], [0, 2674], [-8020, 0], [-1128, 0], [-2070, 0], [3314, 0], [3030, 0], [0, -3252], [2436, 0], [-11810, 0], [0, -2540], [-15658, 0], [0, 3122], [-13812, 0], [8706, 0], [0, -1410], [0, 3410], [-12328, 0], [-6036, 0], [0, -480], [5716, 0], [0, 2876], [-8420, 0], [0, 5366], [10470, 0], [-6090, 0], [0, 2572], [0, -6104], [0, -3524], [0, 2240], [0, 5466], [0, -4570], [0, 3562], [-1514, 0], [-10956, 0], [0, -3352], [15996, 0], [0, -4132], [0, 328], [0, 34], [1746, 0], [2036, 0], [-7328, 0], [-5790, 0], [24128, 0], [-20904, 0], [-13482, 0], [0, 6488], [4498, 0], [0, 6574], [0, -3152], [2052, 0], [12572, 0], [0, -5202], [27646, 0], [-10896, 0], [-21656, 0], [0, 7062], [0, 3642], [0, 2238], [26752, 0], [38194, 0], [0, 7574], [0, -6228], [7422, 0], [0, -2816], [-19626, 0], [0, 6242], [0, -9242], [0, 2282], [-34732, 0], [0, 938], [4106, 0], [-41280, 0], [0, 6330], [0, -3300], [11756, 0], [-33048, 0], [0, -2534], [38502, 0], [26332, 0], [0, -9238], [9956, 0], [-41160, 0], [0, 682], [41430, 0], [0, 7258], [0, 2878], [-51036, 0], [0, 6104], [0, 9824], [27720, 0], [-19794, 0], [-51672, 0], [48280, 0], [0, 9882], [0, 15848], [2178, 0], [0, -7208], [-18790, 0], [0, 3028], [0, 1070], [39944, 0], [-56490, 0], [0, 4346], [6078, 0], [0, 9192], [0, -16532], [64096, 0], [0, 4016], [15658, 0], [0, 6256], [38688, 0], [34014, 0], [0, -17034], [-12412, 0], [0, -19220], [0, -16788], [25798, 0], [0, 11874], [11788, 0], [-20622, 0], [0, -14614], [70458, 0], [0, -1732], [-2338, 0], [0, -160], [0, -15946], [0, -13154], [0, 10334], [69734, 0], [0, 19936], [25284, 0], [-64506, 0], [-83320, 0], [0, -8054], [0, -8430], [45100, 0], [0, -6534], [10230, 0], [56032, 0], [-81396, 0], [0, 10876], [28222, 0], [0, 19520], [0, 306], [63936, 0], [-55818, 0], [0, 6572], [0, -406], [-29850, 0], [2132, 0], [0, -17290], [0, -4380], [-78858, 0], [-6840, 0], [0, 17820], [0, -12448], [-4558, 0], [0, -18738], [0, 17006], [0, -19614], [20032, 0], [0, -11434], [75994, 0], [0, -20524], [60120, 0], [-36780, 0], [62508, 0], [0, 13902], [108688, 0], [87694, 0], [0, 16092], [0, -20332], [41164, 0], [-90888, 0], [0, -20102], [0, -2490], [0, -3750], [0, -5038], [44304, 0], [15550, 0], [0, -30880], [0, 11284], [-65230, 0], [0, -15888], [106086, 0], [0, -2742], [0, 9472], [0, 10026], [0, 14612], [0, 5990], [-100626, 0], [-120140, 0], [55926, 0], [68262, 0], [0, -28860], [0, -35616], [-17962, 0], [-101284, 0], [-144458, 0], [0, -29718], [0, -31898], [-58988, 0], [-104724, 0], [0, -19408], [0, 1124], [0, 21492], [0, 16162], [70480, 0], [0, -20242], [0, -12900], [0, -17700], [26820, 0], [-82042, 0], [0, 7088], [10816, 0], [0, -20278], [-12102, 0], [-59676, 0], [0, 4084], [0, -6644], [0, -42962], [0, 36114], [-75152, 0], [-93618, 0], [0, -17564], [0, -10148], [0, 2314], [0, -42848], [0, 43174], [-45228, 0], [61540, 0], [-114926, 0], [-31716, 0], [-10550, 0], [104676, 0], [0, 3562], [0, -21354], [-870, 0], [0, 31666], [-80312, 0], [0, -25298], [0, -4768], [-130464, 0], [0, -32556], [-135722, 0], [0, 3790], [0, -15950], [-145466, 0], [0, 13470], [-10172, 0], [0, 15076], [-85090, 0], [154156, 0], [68908, 0], [0, 23410], [0, 20988], [0, -52932], [49146, 0], [0, 31986], [0, 2510], [0, 38102], [102684, 0], [129110, 0], [0, -42324], [-37930, 0], [0, 15108], [74522, 0], [-42306, 0], [0, 33858], [166880, 0], [-83082, 0], [0, 24712], [60638, 0], [-65344, 0], [0, 34024], [14094, 0], [0, 11078], [104306, 0], [-9330, 0], [0, -15208], [0, -17544], [0, -3476], [-47940, 0], [0, 10024], [0, 29320], [-49872, 0], [0, 590], [0, 14418], [26976, 0], [0, 3568], [130156, 0], [65902, 0], [0, -33760], [0, 48220], [0, -19020], [5412, 0], [160076, 0], [0, -22762], [0, 8550], [0, 11402], [-187094, 0], [34644, 0], [0, -45592], [0, -16974], [0, 25046], [0, -1490], [96162, 0], [-84918, 0], [0, 55448], [0, 7364], [0, -3082], [-156672, 0], [-12512, 0], [55874, 0], [0, 21652], [67704, 0], [-3874, 0], [-208758, 0], [31920, 0], [174904, 0], [55368, 0], [0, 24254], [0, 1902], [-142110, 0], [38012, 0], [0, 9890], [0, 60180], [189378, 0], [0, -54508], [-113094, 0], [0, 41282], [0, -53646], [-170854, 0], [0, -44430], [50968, 0], [-47160, 0], [0, 51242], [0, -4740], [-206292, 0], [0, 20370], [0, -48950], [49170, 0], [0, 5428], [-47236, 0], [-161394, 0], [0, 16310], [-113946, 0], [0, -47194], [179904, 0], [0, 57344], [107522, 0], [-8586, 0], [-59532, 0], [0, -47318], [-60892, 0], [0, 38648]];
    aps := ConvertToHeckeField(raw_aps);
    chi := MakeCharacter_1815_a_Hecke(Universe(aps));
    return ExtendMultiplicatively(weight, aps, chi);
end function;


// To make the newform (type ModFrm), type "MakeNewformModFrm_1815_4_a_m();".
// 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_1815_4_a_m(:prec:=2)
    chi := MakeCharacter_1815_a();
    f_vec := qexpCoeffs();
    Kf := Universe(f_vec);
    // SetVerbose("ModularForms", true);
    // SetVerbose("ModularSymbols", true);
    S := CuspidalSubspace(ModularForms(chi, 4));
    S := BaseChange(S, Kf);
    maxprec := NextPrime(2999) - 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_1815_4_a_m();".
// 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_1815_4_a_m( : sign := -1)
    R<x> := PolynomialRing(Rationals());
    chi := MakeCharacter_1815_a();
    // SetVerbose("ModularSymbols", true);
    Snew := NewSubspace(CuspidalSubspace(ModularSymbols(chi,4,sign)));
    Vf := Kernel([<2,R![-15, 0, 1]>,<7,R![-240, 0, 1]>],Snew);
    return Vf;
end function;