
// Make newform 2700.3.p.b in Magma, downloaded from the LMFDB on 23 April 2024.
// To make the character of type GrpDrchElt, type "MakeCharacter_2700_p();"
// To make the character of type GrpDrchElt with Codomain the HeckeField, type "MakeCharacter_2700_p_Hecke();"
// To make the coeffs of the qexp of the newform in the Hecke field type "qexpCoeffs();"
// To make the newform (type ModFrm), type "MakeNewformModFrm_2700_3_p_b();".
// 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_2700_3_p_b();".
// 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 := [9, -3, -2, -1, 1];
        Kf := NumberField(Polynomial([elt : elt in poly]));
        AssignNames(~Kf, ["nu"]);
    end if;
    Rf_num := [[1, 0, 0, 0], [-9, 16, 2, 1], [-9, -2, 2, 1], [12, 8, 1, -4]];
    Rf_basisdens := [1, 6, 6, 3];
    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_2700_p();"
function MakeCharacter_2700_p()
    N := 2700;
    order := 6;
    char_gens := [1351, 1001, 2377];
    v := [6, 1, 6];
    // 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;

// To make the character of type GrpDrchElt with Codomain the HeckeField, type "MakeCharacter_2700_p_Hecke();"
function MakeCharacter_2700_p_Hecke(Kf)
    N := 2700;
    order := 6;
    char_gens := [1351, 1001, 2377];
    char_values := [[1, 0, 0, 0], [0, 0, -1, 0], [1, 0, 0, 0]];
    assert UnitGenerators(DirichletGroup(N)) eq char_gens;
    values := ConvertToHeckeField(char_values : pass_field := true, Kf := Kf); // the value of chi on the gens as elements in the Hecke field
    F := Universe(values);// the Hecke field
    chi := DirichletCharacterFromValuesOnUnitGenerators(DirichletGroup(N,F),values);
    return chi;
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 := 3;
    raw_aps := [[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 2, 1, -1], [5, 0, -7, -2], [-1, 1, 2, -2], [-8, 1, -15, -1], [0, -1, -1, -1], [33, -1, 16, 0], [14, 0, -7, 7], [-3, 3, 2, -6], [14, -4, -4, -4], [6, 8, 7, 0], [23, 0, 23, 0], [-12, 0, 15, 3], [8, 8, 24, -8], [-42, -8, -25, 0], [22, -6, 19, 3], [-6, 6, 55, -12], [-16, 2, -30, -2], [-20, 3, 3, 3], [44, -10, 39, 5], [-12, 0, 15, 3], [-64, 8, -120, -8], [97, 4, 99, -2], [-74, 0, 73, -1], [3, -3, -98, 6], [-16, 11, -21, -11], [86, 6, 6, 6], [-99, -21, -60, 0], [-38, -18, -18, -18], [-21, 29, 4, 0], [67, 0, -65, 2], [2, -2, 45, 4], [39, -23, 8, 0], [-182, 18, -173, -9], [-21, 21, -122, -42], [-130, -4, -4, -4], [-9, 21, 6, 0], [-66, 0, 87, 21], [88, -20, 156, 20], [94, -14, -14, -14], [-38, 0, 1, -37], [0, 0, 49, 0], [-8, 64, 48, -64], [-126, 8, 8, 8], [-17, 17, 232, -34], [-34, 30, -19, -15], [-153, 0, 135, -18], [15, -15, -160, 30], [-136, -19, -291, 19], [135, 9, 72, 0], [33, 64, 65, -32], [16, 61, 93, -61], [54, -12, 21, 0], [26, 0, -49, -23], [136, -44, 228, 44], [14, -42, -42, -42], [-286, -42, -307, 21], [-76, 0, 137, 61], [-3, 3, 364, -6], [123, -7, 58, 0], [148, 3, 3, 3], [429, 47, 238, 0], [291, 8, 295, -4], [-28, 0, 23, -5], [-136, -82, -177, 41], [-38, 38, -9, -76], [-234, 84, -75, 0], [30, -86, -13, 43], [-257, 0, 223, -34], [-288, 18, -558, -18], [80, 66, 113, -33], [-1, 1, -142, -2], [256, 31, 31, 31], [-105, 85, -10, 0], [-110, 0, 73, -37], [-170, 24, 24, 24], [-12, -10, -11, 0], [38, -38, -135, 76], [243, 69, 156, 0], [-156, 118, -97, -59], [-400, -22, -822, 22], [-20, 27, 27, 27], [-38, 114, 19, -57], [-255, 0, 231, -24], [120, -87, 153, 87], [101, 12, 107, -6], [-148, 0, 137, -11], [-19, 19, -412, -38], [-160, -25, -345, 25], [18, 0, 81, 99], [150, -68, -68, -68], [264, 10, 137, 0], [-54, 54, 53, -108], [-96, -24, -216, 24], [-669, 5, -332, 0], [56, -43, 69, 43], [-578, 12, 12, 12], [154, -56, -56, -56], [227, -72, 191, 36], [40, -86, -6, 86], [1134, 12, 573, 0], [151, 0, -287, -136], [86, -86, 105, 172], [124, 3, 3, 3], [-61, 0, 215, 154], [-368, 28, -708, -28], [417, 67, 242, 0], [415, -132, 349, 66], [-29, 29, 558, -58], [190, 36, 36, 36], [-852, 10, -421, 0], [487, 60, 517, -30], [586, 52, 52, 52], [17, 0, 113, 130], [0, 0, 577, 0], [-288, -90, -666, 90], [915, -79, 418, 0], [-8, 0, 193, 185], [15, -15, 1088, 30], [376, -158, 297, 79], [524, 0, -505, 19], [-96, 57, -135, -57], [652, 54, 679, -27], [-152, -80, -384, 80], [2, 50, 27, -25], [-144, 198, -90, -198], [626, -90, 581, 45], [105, -105, 328, 210], [572, -3, -3, -3], [-117, -87, -102, 0], [35, -35, -132, 70], [742, -48, -48, -48], [1395, -27, 684, 0], [43, -43, 748, 86], [-312, 156, -468, -156], [69, -69, -524, 138], [-585, -75, -330, 0], [-568, 17, -1119, -17], [-304, -81, -81, -81], [-374, 0, 313, -61], [-7, 7, -280, -14], [376, -92, 660, 92], [426, -40, -40, -40], [-204, 0, 273, 69], [-1174, 6, -1171, -3], [252, 0, -297, -45], [-4, 4, -525, -8], [-176, -50, -402, 50], [-5, 5, -762, -10], [-464, -68, -996, 68], [456, -59, -59, -59], [759, -11, 374, 0], [-197, 136, -129, -68], [-48, 0, 33, -15], [-1210, 42, 42, 42], [180, 0, -279, -99], [614, 116, 116, 116], [-177, -47, -112, 0], [-261, 0, 135, -126], [72, -243, -99, 243], [129, -129, 352, 258], [216, -324, 108, 324], [456, -154, 151, 0], [-598, 0, 623, 25], [398, 150, 150, 150], [902, 30, 917, -15], [290, -120, -120, -120], [237, -149, 44, 0], [-469, 0, 473, 4], [111, -111, -256, 222], [-1029, 29, -500, 0], [15, -256, -113, 128], [-65, 65, -224, -130], [-69, 13, -28, 0], [91, -60, 61, 30], [-216, 18, -414, -18], [-378, 100, 100, 100], [328, -162, 247, 81], [-420, -262, -551, 131], [-137, 0, 217, 80], [33, -33, -464, 66], [312, -345, 279, 345], [183, 181, 182, 0], [820, 0, -887, -67], [322, 30, 30, 30], [456, 50, 481, -25], [-20, 20, -1853, -40], [368, -46, 690, 46], [-840, -23, -23, -23], [21, 0, 183, 204], [1804, 13, 13, 13], [520, 0, -647, -127], [496, 73, 1065, -73], [1572, -94, 739, 0], [-170, 170, 457, -340], [1126, -98, 1077, 49], [293, 0, -97, 196], [112, 4, 228, -4], [-783, -237, -510, 0], [590, -70, 555, 35], [-25, 25, -550, -50], [667, -300, 517, 150], [-656, -35, -1347, 35], [-488, 124, -852, -124], [-150, 140, 140, 140], [-330, 244, -43, 0], [-695, 0, 433, -262], [-172, 172, -1077, -344], [392, -31, -31, -31], [2055, 73, 1064, 0], [1412, 138, 1481, -69], [-316, 0, 95, -221], [531, 213, 372, 0], [-89, 492, 157, -246], [39, -39, 826, 78], [1059, 0, -975, 84], [-784, 188, -1380, -188], [141, -85, 28, 0], [-47, 47, -98, -94], [-69, 69, 788, -138], [-570, 296, -137, 0], [550, 60, 60, 60], [-576, -162, -369, 0], [1016, 62, 1047, -31], [84, 0, -537, -453], [-176, -302, -654, 302], [1032, 50, 1057, -25], [-868, 0, 929, 61], [85, -85, 876, 170], [1082, -144, -144, -144], [-141, 141, -868, -282], [78, 176, 127, 0], [-1728, 2, -1727, -1], [262, 0, 319, 581], [43, -43, -548, 86], [-168, 174, -162, -174], [1188, 102, 645, 0], [-176, 328, -24, -328], [353, 0, -217, 136], [-334, -108, -108, -108], [-87, 87, -440, -174], [-1402, 78, 78, 78], [132, 386, 259, 0], [1124, 0, -1039, 85], [1170, -134, -134, -134], [-1704, -166, -935, 0], [135, -135, -928, 270], [1056, -276, 1836, 276], [-147, 147, 4, -294], [840, -105, 1575, 105], [-75, 467, 196, 0], [-668, 54, -641, -27], [-444, 0, 807, 363], [-832, -265, -1929, 265], [758, -210, -210, -210], [320, -126, 257, 63], [-504, 306, -702, -306], [-908, -57, -57, -57], [-1346, -2, -1347, 1], [69, 0, 231, 300], [-111, 111, 494, -222], [-466, -172, -172, -172], [1461, 355, 908, 0], [1579, 324, 1741, -162], [-88, 20, -156, -20], [-231, 0, 273, 42], [-24, 24, -119, -48], [-9, -555, -282, 0], [-235, 235, -1302, -470], [2054, -64, -64, -64], [-1477, 312, -1321, -156], [-9, 9, 2984, -18], [-216, 216, -791, -432], [-494, -270, -270, -270], [453, 115, 284, 0], [-1484, -42, -1505, 21], [1172, 45, 45, 45], [307, 0, -311, -4], [1155, -383, 386, 0], [-39, 39, 2342, -78], [-518, 0, 79, -439], [-1622, -126, -1685, 63], [-252, 252, 733, -504], [1104, 204, 2412, -204], [2166, 4, 4, 4], [-1137, -115, -626, 0], [-422, -174, -509, 87], [888, -57, 1719, 57], [114, 0, -615, -501], [-688, 203, -1173, -203], [-930, 380, -275, 0], [1278, 384, 831, 0], [2012, 234, 2129, -117], [-2805, -179, -1492, 0], [-418, 506, -165, -253], [1394, 0, -1273, 121], [456, -120, 792, 120], [-140, 394, 57, -197], [-160, 160, -559, -320], [792, 216, 1800, -216], [1394, -96, -96, -96]];
    aps := ConvertToHeckeField(raw_aps);
    chi := MakeCharacter_2700_p_Hecke(Universe(aps));
    return ExtendMultiplicatively(weight, aps, chi);
end function;


// To make the newform (type ModFrm), type "MakeNewformModFrm_2700_3_p_b();".
// 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_2700_3_p_b(:prec:=4)
    chi := MakeCharacter_2700_p();
    f_vec := qexpCoeffs();
    Kf := Universe(f_vec);
    // SetVerbose("ModularForms", true);
    // SetVerbose("ModularSymbols", true);
    S := CuspidalSubspace(ModularForms(chi, 3));
    S := BaseChange(S, Kf);
    maxprec := NextPrime(1999) - 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_2700_3_p_b();".
// 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_2700_3_p_b( : sign := -1)
    R<x> := PolynomialRing(Rationals());
    chi := MakeCharacter_2700_p();
    // SetVerbose("ModularSymbols", true);
    Snew := NewSubspace(CuspidalSubspace(ModularSymbols(chi,3,sign)));
    Vf := Kernel([<7,R![5476, 74, 75, -1, 1]>],Snew);
    return Vf;
end function;