
// Make newform 529.4.a.c in Magma, downloaded from the LMFDB on 18 May 2024.
// To make the character of type GrpDrchElt, type "MakeCharacter_529_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_529_4_a_c();".
// 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_529_4_a_c();".
// 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 := [-21, -1, 1];
        Kf := NumberField(Polynomial([elt : elt in poly]));
        AssignNames(~Kf, ["nu"]);
    end if;
    Rf_num := [[1, 0], [-2, 4]];
    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_529_a();"
function MakeCharacter_529_a()
    N := 529;
    order := 1;
    char_gens := [5];
    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_529_a_Hecke(Kf)
    return MakeCharacter_529_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 := [[-2, 0], [-1, 0], [0, 1], [0, 1], [0, -3], [31, 0], [0, -5], [0, -2], [0, 0], [-223, 0], [-29, 0], [0, 7], [231, 0], [0, 16], [-297, 0], [0, -22], [284, 0], [0, -4], [0, -45], [251, 0], [-771, 0], [0, -58], [0, -39], [0, -30], [0, 47], [-582, 0], [0, -49], [0, -4], [0, 64], [0, 47], [-1087, 0], [-2169, 0], [0, 0], [-67, 0], [0, 112], [399, 0], [0, -2], [941, 0], [-2960, 0], [-2490, 0], [-3863, 0], [0, -145], [0, 277], [-99, 0], [-2407, 0], [0, -211], [5692, 0], [4340, 0], [0, 39], [0, 368], [3679, 0], [-2537, 0], [0, -49], [0, -183], [-173, 0], [0, -150], [2937, 0], [-3472, 0], [-1723, 0], [0, 277], [0, 1], [0, 294], [-3180, 0], [-6101, 0], [0, -338], [-850, 0], [1741, 0], [0, 226], [-6120, 0], [-7763, 0], [-351, 0], [0, 122], [0, 207], [0, 139], [0, 158], [0, 88], [0, 162], [13163, 0], [0, -633], [10673, 0], [0, 714], [0, 323], [0, 110], [0, 527], [11797, 0], [-9561, 0], [6066, 0], [0, 499], [6189, 0], [4300, 0], [0, -758], [0, 435], [-587, 0], [2409, 0], [-15693, 0], [0, -214], [-8603, 0], [0, 42], [0, 225], [3421, 0], [-5427, 0], [0, -1218], [0, 1032], [0, 823], [0, -853], [17777, 0], [-15117, 0], [8350, 0], [-6944, 0], [14581, 0], [17680, 0], [0, -717], [0, -554], [0, 162], [0, 34], [0, 1718], [0, 1311], [-15273, 0], [21659, 0], [0, -487], [0, -396], [26411, 0], [0, -196], [32469, 0], [21668, 0], [0, 1285], [0, -853], [-11424, 0], [0, 1479], [0, 1235], [-21667, 0], [0, 93], [0, 686], [0, -1517], [-35859, 0], [0, 1207], [0, 1502], [0, 1266], [0, -510], [-3094, 0], [-25661, 0], [18002, 0], [-24241, 0], [0, -414], [2854, 0], [0, -2349], [-21990, 0], [9207, 0], [-3617, 0], [-5871, 0], [-12490, 0], [0, 1197], [42980, 0], [-14413, 0], [0, -2404], [0, 1088], [0, 1449], [-54057, 0], [0, -1063], [0, -413], [11603, 0], [0, -2726], [-2643, 0], [0, 1036], [0, -693], [0, 1720], [-16608, 0], [-19050, 0], [0, -306], [-18881, 0], [0, -1333], [-28251, 0], [0, 2183], [0, 2968], [-58547, 0], [0, 789], [-38279, 0], [-10029, 0], [0, -3242], [0, 733], [-56803, 0], [0, 3392], [5721, 0], [4570, 0], [0, 253], [0, 2393], [36210, 0], [0, -232], [34613, 0], [54328, 0], [2759, 0], [-70740, 0], [0, 2209], [-43798, 0], [0, 1571], [0, -2238], [0, -229], [0, -3938], [0, 1542], [-37571, 0], [0, -1760], [-27928, 0], [-6347, 0], [0, 2715], [0, -3294], [-40463, 0], [0, 1801], [7131, 0], [-32313, 0], [-74291, 0], [20647, 0], [73631, 0], [0, -786], [0, -4740], [-58196, 0], [0, 1092], [-60313, 0], [56821, 0], [0, 425], [69131, 0], [93451, 0], [0, 4299], [26457, 0], [0, 499], [-50253, 0], [54923, 0], [0, -4185], [-40587, 0], [0, 530], [-15872, 0], [40330, 0], [0, -4267], [0, -4807], [-25422, 0], [0, 2872], [0, -4443], [0, 2134], [0, -4783], [54567, 0], [-74711, 0], [0, 4532], [18891, 0], [91791, 0], [-12357, 0], [-61370, 0], [-84777, 0], [8003, 0], [0, -1908], [0, -4190], [0, -2601], [0, -3393], [0, -1235], [0, 1212], [0, 4761], [11430, 0], [-17947, 0], [0, -831], [0, -1891], [49277, 0], [12077, 0], [0, 7154], [0, -1452], [46146, 0], [0, 6263], [-126890, 0], [0, -2192], [0, -3081], [0, 412], [0, -3886], [97721, 0], [-9391, 0], [0, -2116], [0, -620], [0, 4689], [72917, 0], [42291, 0], [-62820, 0], [43954, 0], [0, -1931], [0, 2502], [49089, 0], [0, 1249], [0, -4783], [0, -850], [-123660, 0], [-138328, 0], [0, 7624], [0, -3420], [-43224, 0], [-14054, 0], [0, -3408], [0, 2945], [-106410, 0], [0, -1932], [-80199, 0], [0, 3238], [0, 2275], [134551, 0], [-58303, 0], [-166987, 0], [0, -3017], [0, -3636], [0, -1609], [-50579, 0], [0, -5578], [-89293, 0], [31900, 0], [0, -4530], [0, 5447], [47870, 0], [-160041, 0], [0, 6164], [0, 4919], [-147031, 0], [0, 3376], [0, -9593], [-4087, 0], [-85881, 0], [0, 476], [-49373, 0], [0, 2802], [0, -3679], [-175101, 0], [127040, 0], [0, -6433], [0, 8602], [0, 2893], [121809, 0], [0, -483], [0, -3679], [66501, 0], [-86197, 0], [104897, 0], [168561, 0], [0, -5504], [113053, 0], [0, 9633], [0, 6001], [-99349, 0], [0, 11166], [114211, 0], [0, 7836], [-24686, 0], [0, 4574], [0, -10569], [29364, 0], [-183309, 0], [224620, 0], [0, 162], [0, 7219], [-91289, 0], [101953, 0], [128518, 0], [0, -9492], [0, 1005], [-184550, 0], [0, -6577], [0, 10463], [-36687, 0], [117800, 0], [0, 2875], [101429, 0], [38817, 0], [0, -6945], [111097, 0], [134981, 0], [-120113, 0], [0, 4391], [0, -9676], [100581, 0], [144364, 0], [-37321, 0], [0, -1543], [0, 6142], [186127, 0], [184137, 0], [0, -8169], [0, -10102], [0, -4980], [-100233, 0], [0, 897], [0, -6282], [66100, 0], [-203717, 0], [0, -10849], [238281, 0], [-156539, 0], [258950, 0], [0, 13819], [0, -3291], [0, -12557], [177650, 0], [125367, 0], [-139180, 0], [0, -12289], [0, -5451], [0, -850], [0, 7977], [0, -9113], [-119382, 0], [101447, 0], [-133591, 0], [0, 4003], [0, 3767], [48123, 0], [-177221, 0], [0, -62], [170569, 0], [0, 10941], [33864, 0], [-101281, 0], [23247, 0], [0, 9253], [0, 10074], [0, -8210], [-2399, 0], [181044, 0], [76400, 0], [0, -1518], [0, 12766], [0, 5149], [0, -2992], [-131300, 0], [-125004, 0], [-227339, 0], [-2913, 0], [0, -2670], [113526, 0], [79959, 0], [68487, 0]];
    aps := ConvertToHeckeField(raw_aps);
    chi := MakeCharacter_529_a_Hecke(Universe(aps));
    return ExtendMultiplicatively(weight, aps, chi);
end function;


// To make the newform (type ModFrm), type "MakeNewformModFrm_529_4_a_c();".
// 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_529_4_a_c(:prec:=2)
    chi := MakeCharacter_529_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_529_4_a_c();".
// 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_529_4_a_c( : sign := -1)
    R<x> := PolynomialRing(Rationals());
    chi := MakeCharacter_529_a();
    // SetVerbose("ModularSymbols", true);
    Snew := NewSubspace(CuspidalSubspace(ModularSymbols(chi,4,sign)));
    Vf := Kernel([<2,R![2, 1]>,<3,R![1, 1]>,<5,R![-340, 0, 1]>],Snew);
    return Vf;
end function;