
// Make newform 1680.4.a.bo in Magma, downloaded from the LMFDB on 23 April 2024.
// To make the character of type GrpDrchElt, type "MakeCharacter_1680_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_1680_4_a_bo();".
// 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_1680_4_a_bo();".
// 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 := [-2, 0, 1];
        Kf := NumberField(Polynomial([elt : elt in poly]));
        AssignNames(~Kf, ["nu"]);
    end if;
    Rf_num := [[1, 0], [0, 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_1680_a();"
function MakeCharacter_1680_a()
    N := 1680;
    order := 1;
    char_gens := [1471, 421, 1121, 337, 241];
    v := [1, 1, 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_1680_a_Hecke(Kf)
    return MakeCharacter_1680_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], [3, 0], [5, 0], [7, 0], [8, 10], [-38, 1], [-62, 1], [48, -8], [8, -17], [94, 27], [60, 9], [-66, 33], [50, -40], [268, 31], [464, -21], [442, -32], [-52, -102], [-234, 21], [844, 19], [68, -75], [254, -161], [216, -116], [292, -42], [-702, -56], [-594, -23], [-82, 62], [664, 208], [-860, 195], [70, -84], [-130, 18], [184, 452], [316, 268], [1582, -212], [-904, -380], [1790, 313], [-456, -496], [-510, 599], [-300, 217], [-48, -185], [-514, -212], [1520, 450], [54, -503], [-220, 151], [322, -102], [3618, 98], [2788, 325], [-372, 342], [2232, -176], [-1772, -426], [30, -91], [-1834, 692], [-2068, -839], [-3062, -152], [5468, -44], [5850, 199], [-1184, 847], [2246, -396], [-5372, -273], [-2770, 115], [2498, -484], [5764, -216], [2614, -846], [420, 546], [-1528, 824], [1734, 823], [5730, -724], [2436, -1206], [-990, 478], [-1044, 493], [7686, -113], [-10830, -325], [6428, -1143], [4120, -594], [-1402, 375], [-7044, 1144], [-1928, -457], [-8322, 251], [4266, -25], [-6286, 934], [3626, 1186], [1116, -760], [-1378, -984], [2620, -1147], [-11490, 947], [-2172, 1107], [-4068, -1479], [5714, -854], [1442, -1858], [-2346, 2626], [-1160, -2038], [13508, -596], [2016, 1652], [4640, -2222], [-9752, 290], [-17948, 200], [15632, 377], [4790, 1612], [5378, -2478], [-21828, -250], [3238, 1442], [-3732, 2051], [4578, 2332], [-6436, -1548], [-12518, -1906], [-17268, 1172], [3566, -789], [11364, 592], [2802, -1771], [18108, 491], [-5470, -986], [8824, 108], [-8210, -1671], [-11994, 208], [-24424, -822], [8256, -1070], [17002, 966], [-3628, 2824], [1232, 4045], [2458, 952], [-8232, -2300], [-26866, 821], [-6390, 460], [4022, -2708], [-276, -801], [6056, -2024], [-418, 499], [-834, -3674], [14744, 616], [-3984, -2866], [-20950, 1005], [-3916, -1766], [-288, -761], [16152, -1372], [14838, -2865], [6194, -1382], [-11750, -2668], [-21018, 10], [-28364, -1232], [6254, -2544], [-26110, -1798], [5704, 5044], [-14474, -1551], [-5248, -6662], [6772, -1059], [-32130, -241], [-2688, -2204], [10642, -2397], [-5262, -4649], [3792, -422], [-20224, 5309], [-8186, 175], [-14678, 2032], [-22004, -599], [21736, 1573], [27428, 117], [15540, 3635], [2496, 2128], [-4470, 3714], [-1698, 5641], [-22794, -640], [-4604, -987], [2630, -74], [3256, -1982], [-33012, -3546], [12398, -6160], [-10088, -2055], [17032, 3680], [-32734, -1209], [30034, -4048], [23686, -3276], [-24488, 4526], [3470, -6169], [45268, 1063], [-3606, 846], [-32412, -3619], [25618, 4308], [-5948, 8774], [-9490, -5877], [-38192, -3618], [3038, 5417], [40368, -1752], [-25916, -6104], [-5546, 9179], [-23974, 881], [19240, -461], [-10818, 3594], [-15290, -5271], [-8044, -4274], [-33366, 48], [20136, -960], [-32002, -5355], [-20220, -6113], [12324, -3496], [16342, 4406], [30756, -4891], [9354, -3351], [11922, 3420], [-46402, 5237], [65226, 1143], [-19120, -1295], [15790, 623], [53500, 1141], [-23462, -8351], [-15430, 8362], [13596, 9886], [10958, 10698], [28420, 3621], [36140, -1331], [2850, 1656], [-34480, 3210], [24762, -9896], [-29906, -312], [48040, 3160], [40348, -434], [16016, -316], [18, 11908], [67016, 4318], [45482, 4010], [-40080, -5429], [13946, 5368], [-42498, 3158], [-51164, 3471], [-66598, 2774], [9488, -9642], [6300, 11242], [-20418, -7670], [-25646, 2607], [12756, -4043], [-4136, -10590], [-19912, 466], [-19058, -5515], [-48944, -1660], [10384, -11542], [35042, 548], [40908, -3234], [8320, -3761], [-33070, -5954], [-14254, -13346], [22712, -2718], [-2320, 15718], [61932, -8287], [-856, -966], [-48744, -9928], [13446, 16982], [-76678, -2851], [-60848, -6162], [-34024, 10666], [-36100, 1314], [-46316, 5044], [49248, -10131], [82262, 619], [-55382, -10826], [13272, -11753], [40730, -2496], [-24946, 8038], [-88432, -5532], [-12834, -196], [24660, -1320], [27750, -3594], [-33322, 17735], [98248, 4814], [15220, 2301], [-95874, -3873], [17026, 8119], [75250, 9259], [-27384, -6996], [62318, -2133], [49218, 4030], [81940, 2921], [-6846, 6640], [78670, -8489], [30340, 5545], [-39994, -8647], [10728, -426], [97870, 2149], [-79152, 7136], [-38188, 13779], [68854, -2642], [-10854, -4008], [-89868, 8774], [-61152, 9041], [81952, -7072], [-9880, -6825], [-234, 24281], [-73076, -2198], [-74812, -2091], [-29142, 10538], [28778, -7744], [-31244, 6153], [48986, 6698], [-33106, -1105], [71124, 12588], [-28986, -2420], [-62796, -3338], [33230, -931], [63846, -9534], [54260, 10277], [-32194, -15110], [-4452, -5128], [27988, 6076], [-16690, -2423], [87610, -9192], [-672, -21876], [7028, 10205], [76828, -2480], [27474, -10344], [-20972, -21395], [1574, -18561], [-39804, 18937], [-8090, 4147], [-38624, -12147], [-117962, 4079], [-118958, -4702], [90796, -8839], [-264, 3317], [-45214, 3646], [8444, 8302], [-42588, -2105], [4766, -4947], [82882, -1744], [29784, 20382], [64946, 1204], [9542, -7482], [-10624, -12088], [-45442, -2318], [157802, 5072], [-29548, 21828], [-71068, 13734], [-80448, 5979], [57034, -7098], [-23594, -20704], [-50982, -7828], [2372, 7173], [69148, -7566], [17988, -13734], [12676, -21202], [-98826, 8250], [-19846, 1401], [19506, -26826], [-72984, -15900], [-19866, 5463], [-34410, 21248], [-50450, 14664], [111720, 1954], [-21542, -16972], [62216, -9522], [-32914, 1637], [-54156, -27269], [4952, 9882], [4198, -2742], [-178864, 1770], [-70878, 11170], [12238, 29657], [-108480, 14296], [25502, 24226], [-167030, 9627], [-94744, 780], [-89292, 7674], [-22530, 12658], [-116480, 14457], [74550, 25455], [-104574, -7658], [41848, 19049], [-13568, 21660], [-29756, 9320], [-50286, -18818], [32406, 990], [-129944, -15760], [63178, -16276], [67728, 1832], [168224, 2458], [-22504, 11437], [9118, 13639], [-19220, 835], [-52778, 8647], [-56212, -12484], [-24684, -8685], [69566, -7861], [-29318, -31446], [-103714, 18767], [1894, -9994], [-47434, -23938], [18528, -41590], [-85962, -3742], [62272, 30848], [173712, -9621], [-34376, -14434], [-221118, 8209], [99748, 9267], [-27328, -19823], [93842, -14824], [-38130, 2444], [-24800, -1948], [-2588, 20618], [-2476, 5217], [186106, 11668], [5124, -38961], [111106, 13288], [61676, 35882], [-45466, 32165], [-52130, 2593], [133694, 23478], [-82176, -3472], [26226, 10477], [188238, 11096], [59820, -601], [-54074, -18481], [-30110, -34354], [6572, -3546], [119508, -5970], [-30602, -8675], [8954, 21130], [6780, -6687], [22300, -29092], [-50534, 3822], [79014, 8644], [35276, -6483], [30160, 9572], [180098, 1491], [-204120, 1229], [102822, 11455], [-56318, -5525], [59880, 20079], [-25236, 13438], [-22570, 23067], [60174, 9742], [-19316, -44153], [-91158, 2424], [-43168, 3750], [26096, 37856]];
    aps := ConvertToHeckeField(raw_aps);
    chi := MakeCharacter_1680_a_Hecke(Universe(aps));
    return ExtendMultiplicatively(weight, aps, chi);
end function;


// To make the newform (type ModFrm), type "MakeNewformModFrm_1680_4_a_bo();".
// 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_1680_4_a_bo(:prec:=2)
    chi := MakeCharacter_1680_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_1680_4_a_bo();".
// 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_1680_4_a_bo( : sign := -1)
    R<x> := PolynomialRing(Rationals());
    chi := MakeCharacter_1680_a();
    // SetVerbose("ModularSymbols", true);
    Snew := NewSubspace(CuspidalSubspace(ModularSymbols(chi,4,sign)));
    Vf := Kernel([<11,R![-3136, -16, 1]>,<13,R![1412, 76, 1]>,<17,R![3812, 124, 1]>],Snew);
    return Vf;
end function;