
// Make newform 1680.4.a.bd in Magma, downloaded from the LMFDB on 18 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_bd();".
// 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_bd();".
// 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 := [-1, -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_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], [46, -1], [4, 19], [-22, -22], [54, 13], [160, -10], [-118, -6], [30, 51], [102, -12], [22, 40], [-68, 64], [-200, -84], [8, -43], [232, -18], [-342, -42], [-368, 82], [370, -69], [212, 61], [204, -242], [-304, -42], [-666, 56], [-1224, 43], [34, 316], [736, -128], [-568, 156], [1318, -168], [-572, 309], [1180, 314], [956, 104], [968, -193], [1982, -239], [2014, -52], [-48, -304], [96, -379], [348, -32], [996, 38], [190, -610], [-674, 63], [-1386, -356], [1558, -103], [2266, 276], [684, 199], [2614, 175], [-2184, -258], [-2748, 586], [-1456, -534], [2850, -70], [2212, 397], [2674, 155], [2182, -698], [2200, -178], [-498, -328], [2612, -496], [-3326, 324], [274, 93], [1334, 1108], [1918, -866], [-2780, -504], [4142, 498], [6432, 42], [9784, 28], [888, -293], [-936, -887], [264, 1122], [6642, -488], [-924, -970], [-2358, 742], [-1350, -1694], [3982, -207], [2860, -234], [-3310, -270], [5772, -188], [740, 166], [1134, -1472], [-3636, -2245], [1570, 2804], [-7198, -1520], [12828, -668], [-5362, -1632], [1274, 739], [-7032, 839], [3366, -657], [-15468, 6], [4570, 1076], [950, 2822], [6690, -1216], [-6548, -310], [-9632, 458], [12144, -1412], [5636, 3190], [-490, 3871], [-3116, -652], [388, 3754], [-5150, 2204], [-722, -1752], [-4680, -3034], [-3194, -568], [3432, 1022], [-9264, 2357], [-10652, -84], [-190, -968], [444, -904], [-2272, -261], [-5436, -3544], [-8718, -1226], [4158, 1057], [854, -650], [-4028, -1398], [14662, 1956], [-12612, 1337], [-7930, -627], [13860, 718], [2318, -4854], [5240, 4510], [-4220, 2294], [-14884, -3529], [16482, -3067], [3962, 5210], [4542, -1250], [-33866, -154], [-1644, -2922], [22130, 535], [15610, 962], [18534, -2756], [-23108, 2246], [14820, -430], [1436, 2295], [-25564, 2368], [-8340, -2272], [-708, 6050], [-20790, -1626], [13558, -3832], [4438, -22], [20622, -2374], [-28712, 2434], [10078, 5958], [-3242, 1990], [-18914, 2545], [-10702, 942], [11588, -4358], [11144, 5964], [-7074, 7412], [18372, -622], [-8420, -2025], [-4818, -196], [-2766, -5489], [26872, -3986], [-11138, 2020], [-5506, -3820], [18904, -3686], [14264, -6136], [9728, -4230], [1854, 3397], [29868, 214], [654, -1440], [-16476, 625], [-31782, -3056], [5132, 594], [9508, -751], [-10880, -2912], [2568, 1218], [6940, -9347], [19568, -5856], [20596, -6922], [-7372, -7365], [6754, 7016], [-3322, -4818], [43478, -5], [20270, 7664], [-32230, 6047], [16914, 3084], [3162, 4613], [6758, 924], [23152, 242], [-1226, 9732], [26212, 5370], [54614, -2836], [-48024, -3816], [-27880, -5290], [-10886, 7094], [3058, 3370], [17348, -676], [-35046, -5472], [40726, -3768], [39488, 766], [-9870, -8412], [-18948, 11022], [-24472, -6021], [-31320, 9020], [-28572, -10780], [-23734, 1516], [-21396, 4258], [-6846, 15546], [67650, -2856], [-4030, 7766], [-14922, -1260], [-19652, -8398], [16274, 10114], [-36602, -9941], [46312, 3961], [-18466, -3998], [-15696, -7234], [-8426, -13110], [40162, -3135], [-15392, 3068], [-18282, -6114], [-6838, -8229], [-79434, -710], [48602, 6132], [54448, -4220], [63344, 2498], [-6140, 4186], [-1890, 13498], [-46252, -2798], [-47978, 5848], [11124, 13040], [45460, 3971], [43638, 2660], [37462, 171], [-4442, -3206], [2864, 14304], [1980, -2644], [81630, -1976], [46478, -5244], [53718, 12029], [11224, 7020], [-39818, -6817], [65098, -4126], [10414, 15641], [54616, 7544], [43990, -314], [-8592, -22242], [-65656, 5960], [-53158, 1264], [12844, 18815], [-16394, 5991], [652, 1130], [8520, -12836], [29606, -13131], [-45144, -13360], [-51186, 5780], [91918, 4600], [49700, 1746], [26804, -13922], [31540, 9624], [15160, -50], [37968, -8118], [38942, 15388], [42182, -12520], [-40488, -12106], [-4678, 4404], [-93794, 2678], [21454, 6867], [-15330, -2008], [19716, 3072], [-31746, 18114], [-43168, -3265], [20644, 11342], [94364, 174], [16410, -5994], [-35672, -12839], [26066, 9998], [98802, -8985], [45106, -3102], [43038, -5776], [-68864, 2222], [5460, -25369], [57910, -5660], [-4196, -7556], [-71200, -685], [23724, -19854], [-26984, -18509], [-47988, -6250], [30496, -8352], [8830, -17636], [63450, 6984], [50232, 6106], [4512, 24052], [-68756, 10370], [19000, 27012], [-59370, 16904], [-80048, -5894], [-28346, -25239], [104406, 5354], [-30608, -29087], [-74474, 12267], [12766, 88], [-32462, -8318], [-62424, -462], [67428, 5], [-14700, 23876], [-45430, -15574], [-19134, 33504], [-55390, -8479], [-85118, -5080], [-133032, 2398], [62344, -326], [-61612, -15359], [-29236, 6639], [-11040, -14832], [-55100, -8594], [48340, 14188], [-15438, -23568], [-35176, -6688], [-19510, 17538], [-25710, 10451], [16402, 26890], [-128296, -4224], [-71110, 2590], [6938, -13760], [-35144, -11998], [24072, -6710], [-92146, -19466], [-25412, -7744], [-94506, 1229], [-125032, -4509], [83114, 12256], [-27342, -8229], [-94666, -2906], [4186, 16332], [-16312, 18476], [-107264, 599], [-10906, -5314], [-37996, -19752], [8228, -4152], [60528, -2538], [22208, 22029], [-62810, 19064], [-102300, 3811], [-95998, -23163], [-77764, -3624], [40440, 17958], [72500, -20240], [66534, 12840], [-29378, 10416], [10710, -17022], [-75972, 4314], [22098, -28542], [114396, 18697], [-50230, -29172], [-39672, -31556], [75668, -16349], [28018, -1659], [-78454, 590], [-2496, 7138], [-35468, -6606], [-418, -9150], [159158, -7755], [-45378, 22498], [65858, -33470], [-38808, -22100], [-62362, -17564], [-81814, 11910], [-44180, 22734], [-117012, 852], [97428, 7637], [-31516, 20772], [-60078, 27354], [-62442, 16040], [-105892, 21964], [-31246, -25911], [-6104, -9982], [-62178, 13090], [-83166, -4380], [-52760, 31772], [58330, -3472], [3078, 3595], [20594, -24017], [126964, -10744], [58190, -39340], [-19766, 11029], [-100154, -31712], [112012, -14216], [-53850, 20757], [88376, 32519], [-3370, -33912], [-82828, -21595], [-86422, -8924], [-61292, 17977], [18900, 7166], [73824, 33259], [-103970, -14851], [-46884, 31662], [108148, 12950], [-143700, -22325], [-137768, -4830], [182536, 10988], [-115894, 13052], [-148878, 15928], [-78214, 37813], [-104, -16930], [-150710, -21801], [-99686, 31696], [55266, 11961], [-6778, -27580], [-195172, 5120], [-178862, -8438], [-20306, -23672], [-16292, -32895], [-149280, 5204], [-49506, 13028], [-25470, -1064], [-81942, -439], [192694, 8768], [120170, 14812], [-172372, -11292], [-34056, -27126], [-144500, 18961], [-7808, -21715], [49644, 31074], [-126872, -5146], [-99878, -28608], [-119694, 31316], [-45854, 19635], [-131444, -23002], [138010, 27786], [28224, -18764], [71286, -11416], [-81260, -31757], [-249636, 2532], [77640, -2926], [96152, 34875], [60486, -20086], [35096, -20332], [42714, 42828], [68186, 10311], [101236, -36878]];
    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_bd();".
// 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_bd(: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_bd();".
// 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_bd( : sign := -1)
    R<x> := PolynomialRing(Rationals());
    chi := MakeCharacter_1680_a();
    // SetVerbose("ModularSymbols", true);
    Snew := NewSubspace(CuspidalSubspace(ModularSymbols(chi,4,sign)));
    Vf := Kernel([<11,R![2096, -92, 1]>,<13,R![-7204, -8, 1]>,<17,R![-9196, 44, 1]>],Snew);
    return Vf;
end function;