
// Make newform 1216.4.a.n in Magma, downloaded from the LMFDB on 25 April 2024.
// To make the character of type GrpDrchElt, type "MakeCharacter_1216_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_1216_4_a_n();".
// 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_1216_4_a_n();".
// 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 := [-23, -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_1216_a();"
function MakeCharacter_1216_a()
    N := 1216;
    order := 1;
    char_gens := [191, 837, 705];
    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_1216_a_Hecke(Kf)
    return MakeCharacter_1216_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, 0], [1, 0], [2, 2], [22, 1], [-20, 2], [10, 3], [23, -8], [-19, 0], [-110, 5], [42, 19], [-42, 18], [-152, 6], [84, -20], [186, 2], [292, 24], [-242, -33], [537, -4], [-44, -14], [-715, -28], [924, -2], [-647, -8], [416, 78], [-264, -90], [922, -74], [-182, -52], [-978, 64], [886, -108], [363, 112], [-682, -31], [-110, -76], [-200, -30], [-638, -30], [1627, 28], [-610, 2], [24, -88], [-234, 172], [220, -282], [2202, -114], [1396, -128], [1656, 18], [1048, 0], [-68, -86], [54, 421], [-172, 382], [2604, -12], [2034, -251], [685, 432], [-1998, 124], [125, -520], [-2440, 194], [-1830, -208], [-1642, 225], [-3440, -216], [-1054, -676], [-2550, -394], [2064, -620], [2060, 530], [-1534, 45], [1358, -282], [-1772, 644], [6664, 262], [-5062, 181], [624, -228], [6418, -187], [1421, 344], [918, -203], [-6949, 240], [1574, 378], [618, -792], [24, -682], [-7487, -140], [3418, -93], [-4148, -156], [-5254, -167], [1669, -836], [6058, 196], [6582, 240], [-5238, 246], [-2596, 1372], [7198, 214], [1098, -450], [2314, 79], [188, -510], [4288, -1362], [-8584, -612], [3068, -450], [-5612, 1070], [-1051, 612], [-15364, -216], [164, -628], [-10878, -104], [-4780, 1476], [4054, 1344], [-7188, 1168], [-10702, 422], [-13614, 473], [-1752, -718], [-7944, 516], [6151, 380], [-4322, 24], [-8144, 1052], [14230, -778], [1988, -440], [-6232, 1912], [468, -2120], [13815, -704], [10488, 516], [13842, 208], [-5364, -1428], [4158, -742], [-10280, -902], [6774, 464], [-10474, 588], [4286, 728], [21784, 660], [-20064, -846], [-3958, -776], [-9422, -1755], [-11610, -1882], [3135, -1980], [8166, -1175], [11100, 1872], [6910, 925], [-13200, 332], [4318, -1208], [-16216, 652], [-8268, 690], [11262, 1529], [-5762, -1279], [938, -2718], [20812, -564], [17970, 766], [5916, -404], [-24976, -1454], [-12021, 760], [-247, -1876], [23062, -1551], [-32267, 64], [-2994, 119], [7865, -948], [13375, -564], [25354, -558], [326, -1173], [2445, 740], [18246, 545], [18546, -374], [-6302, 2204], [3212, 616], [6712, 3186], [26772, 306], [-21342, -2211], [-21522, -2144], [-27530, -1400], [17868, 2578], [-6373, -3416], [-994, -418], [22370, -841], [7725, 2068], [1957, -2808], [17262, 215], [22510, -1634], [6264, 3770], [-20168, 244], [32916, 1672], [-16754, 1234], [40876, -322], [-17870, -2922], [-6554, 5142], [20046, 3522], [-18562, 3678], [12387, -3404], [19250, -1161], [-21496, 3348], [-6021, -5480], [-15816, 2472], [1790, -6352], [426, -1430], [-12550, 3696], [6598, -4866], [7376, 584], [26, -6305], [-12693, -2676], [11888, 134], [9830, 2062], [8510, -3831], [14802, -1372], [-38778, -415], [-5704, -4968], [19886, 1328], [-11498, -4475], [13696, 634], [-38208, 1308], [34512, 2552], [-6930, -2035], [7962, -5298], [50106, 1734], [-49219, 1524], [-13540, -480], [37799, -1252], [-20514, -157], [-4968, 3010], [530, -3710], [-20206, -1989], [38812, -2528], [74612, -1414], [-13676, 4204], [38110, -183], [1857, -1076], [-31335, -4272], [-43671, -3584], [12325, -156], [36338, 1082], [8396, 3868], [-55681, 2104], [35898, -4050], [-18824, -7450], [62426, 913], [-48020, 2334], [35268, -5178], [17562, -1132], [-4032, -4606], [17090, 6888], [83010, -160], [12674, -5423], [-41597, 5800], [-27774, 3472], [-10398, -4696], [-40106, -2220], [-4928, 8278], [31650, -4312], [82012, -926], [5825, -2360], [10420, -3388], [13470, 3588], [40150, -3316], [-7230, -2529], [1234, -4692], [30372, -4924], [74928, 1326], [23412, 5936], [-8448, 4980], [-53790, 4456], [-40634, 3571], [57262, -2693], [48360, 2564], [-57556, 3796], [-88088, -1964], [-68896, 1132], [-82212, -1768], [45894, 2801], [-73978, -4212], [-64405, 2340], [-19426, 4369], [-85368, 2386], [75160, -4124], [1708, -10118], [49960, 2114], [45260, 1320], [21204, -9666], [-51038, 556], [52878, 5914], [30564, -8312], [-61184, -176], [53498, -7193], [10090, -1704], [-32927, 1096], [-109886, 441], [11191, -692], [-72865, 5616], [62874, -1276], [112282, -917], [-42881, -9632], [62261, 4520], [55818, 5143], [75302, -3912], [20450, 6455], [72528, -38], [-4538, -6481], [-3898, 2026], [-69438, 2786], [-27404, -1686], [9818, -2615], [27510, 4805], [34150, 10007], [64734, 10], [52268, -4856], [-28239, 10900], [84416, 3566], [-12926, 3503], [-28872, 7442], [41160, -11734], [-80720, 556], [20356, -11958], [-99260, 5424], [-150920, -50], [-80090, -118], [60388, -1234], [-51716, 866], [-39917, 4832], [-40218, -9004], [43178, -3156], [-78682, -5195], [31230, 5221], [-7559, 9176], [-44200, 4772], [-9554, -14272], [17249, 14732], [48838, -9479], [70316, 5672], [4998, 5018], [-30984, -1828], [-36768, -3402], [34086, -1500], [82720, 1140], [25512, -14052], [-17840, 2920], [113342, -1732], [153222, 812], [-79533, 2012], [-21954, -11360], [71191, 88], [95523, 4656], [-36078, 15575], [18306, 812], [18807, 10440], [-65734, 4192], [-7931, 7108], [-47425, 1108], [51300, -2260], [-45928, 14188], [-83002, -1418], [107334, 4677], [93494, 2065], [41502, -12400], [-8472, 7078], [26934, 13678], [-42682, 10089], [69162, -4190], [-155317, -2172], [15830, 3027], [-75370, -623], [32067, -5736], [-125218, -5821], [-99608, 7950], [-53542, 1019], [144996, -3360], [118920, -4694], [-52889, -2520], [84514, 7040], [-135636, -44], [72952, 360], [203780, 906], [116464, -336], [46818, -14566], [-112632, 2894], [84048, 1136], [49514, 1489], [34826, -5542], [62271, 12744], [47706, 8852], [14480, 1240], [11430, -672], [12874, -14572], [-76659, 1056], [-71174, 15448], [12172, 6440], [-48948, 11498], [108096, -5678], [-20384, -350], [44760, -290], [55247, 4288], [-8922, 8201], [73490, 9623], [-152908, -3084], [-67892, 6956], [64923, -5092], [-46260, -1512], [30634, 2196], [17817, 2508], [55208, 12772], [75720, -11738], [-14362, -6780], [23714, -7485], [-22874, -152], [160413, -84], [156930, -10384], [-19798, 4911], [8314, -19362], [2140, 12822], [82660, 15460], [64416, 210], [69050, 6981], [12150, 7652], [-20154, 9112], [220892, 1376], [132844, 4542], [-67598, 6420], [-159550, 6162], [-59300, 3856], [115736, -13496], [5336, 24730], [27270, 12516], [-179096, -7494], [-156948, 2636], [-8376, -18182], [8490, 3861], [73754, -1240], [-110940, 9112], [-79677, 4976], [-66774, -1230], [-67254, -5734], [-102236, -7102], [104649, -14476], [67022, 9720], [69545, 3208], [79014, 8474], [149506, -6456], [-158182, 7342], [248375, -4096], [-11716, 9556], [227936, -8634], [176782, 6417], [-12350, 3687], [59411, 9212], [21742, -13476], [-207958, 7333], [69985, 15988], [190131, -5340], [152240, 5904], [85842, -51]];
    aps := ConvertToHeckeField(raw_aps);
    chi := MakeCharacter_1216_a_Hecke(Universe(aps));
    return ExtendMultiplicatively(weight, aps, chi);
end function;


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