
// Make newform 78.3.l.c in Magma, downloaded from the LMFDB on 17 April 2024.
// To make the character of type GrpDrchElt, type "MakeCharacter_78_l();"
// To make the character of type GrpDrchElt with Codomain the HeckeField, type "MakeCharacter_78_l_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_78_3_l_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_78_3_l_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 := [5635876, 275384, 6728, -6736, 5053, 82, 2, -2, 1];
        Kf := NumberField(Polynomial([elt : elt in poly]));
        AssignNames(~Kf, ["nu"]);
    end if;
    Rf_num := [[1, 0, 0, 0, 0, 0, 0, 0], [0, 1, 0, 0, 0, 0, 0, 0], [-561922481148, -589968133288, 914252484693, -13767350850, -167602931, -175318185, 125878448, -4081829], [15143464458814, 1720952318288, 326689911519, 3978860609, 5297934372, 496632472, 114752803, -900565], [-276718188, -118350522, -10377280, -2587559, -34750, -42132, -2974, -887], [-2461440553912712, -775067199122402, 12062579279902, 16988141226435, -695422749614, -272272114360, -1375000768, 5758773899], [-13671329236226, -1704850356072, -342802118751, 21421095309, -5101492538, -491845918, -119540717, 4272345], [2105738, -13670, -47339, -6888, 798, 16, -17, -2]];
    Rf_basisdens := [1, 1, 28390156409030, 813197403460, 320442520, 1930530635814040, 813197403460, 134980];
    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_78_l();"
function MakeCharacter_78_l()
    N := 78;
    order := 12;
    char_gens := [53, 67];
    v := [12, 11];
    // 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_78_l_Hecke();"
function MakeCharacter_78_l_Hecke(Kf)
    N := 78;
    order := 12;
    char_gens := [53, 67];
    char_values := [[1, 0, 0, 0, 0, 0, 0, 0], [0, 0, 1, 0, 0, -1, 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, -1, -1, 0, 0], [0, 0, 2, 0, 0, -1, 0, 0], [0, 0, 1, -1, 0, 0, -1, 0], [1, -1, 0, 0, 0, -1, 0, -1], [2, 0, -2, 0, 0, 2, 0, -2], [4, 0, -6, 1, 8, 1, 0, 1], [-7, -1, 7, 0, 7, -7, 1, 0], [6, -1, -7, -1, 7, 5, 0, 1], [-2, 2, 0, -2, -2, 16, 0, 0], [-3, 3, -6, 3, -11, 3, 1, 1], [-4, -1, 21, 0, 17, -17, 0, -2], [22, 0, -22, 0, 4, 18, 0, 5], [12, -6, 12, 0, 5, -7, -2, -3], [-19, 2, 21, 1, 18, -21, -1, 1], [34, 0, 42, 2, -6, -6, -2, 0], [11, 1, -17, 2, 0, 34, -1, 3], [2, -2, 12, -4, 12, 2, -8, -2], [-25, 7, 15, -3, -28, 15, 4, 3], [45, 2, 45, 0, 13, -32, -2, 1], [-32, 4, 12, -2, -12, -34, 0, -4], [-14, 5, 16, 1, -29, -29, -1, 0], [-12, 0, -34, -5, 0, 68, 0, -5], [-26, 2, -24, 10, -40, 40, 10, 4], [80, 0, -78, -2, 68, 10, -1, 1], [-34, -4, -40, -1, 40, -35, 0, 4], [3, 5, 0, -5, -1, 31, -6, 6], [-28, -1, -25, -10, -76, 0, -1, 9], [-2, 2, -12, 2, 32, 6, 6, 6], [-43, -3, 106, 0, 63, -63, 0, -6], [3, -9, 23, 12, 15, 23, 3, -12], [-11, 3, 0, -3, -7, -94, -9, 9], [-40, -2, -38, -4, 0, 76, 2, -6], [115, -1, -9, -2, -9, -113, -4, -1], [27, -14, -25, -5, 22, -25, -19, 5], [-49, -3, 15, 2, -15, -47, 0, 3], [-12, -7, -29, -3, 14, 14, 3, 0], [40, -21, -26, 21, 0, 52, 21, 0], [-35, -16, -11, -5, -11, 40, -10, -16], [64, 0, -72, 8, 36, 36, 4, 12], [-46, 16, 22, 22, 24, -22, 6, 22], [-20, -20, 0, 20, 0, -40, 18, -18], [-94, 6, 47, 13, -162, 0, 6, -7], [-122, 14, 44, 0, -122, 44, 14, 0], [49, 0, -31, -18, -19, 50, -9, 5], [46, 6, 46, 0, 6, -40, 17, 3], [27, -15, -106, 0, -27, 106, 15, 0], [-11, 11, 68, 11, -35, -34, 23, 23], [206, -26, 206, 0, 111, -95, -3, -13], [98, -12, -54, -4, 54, 94, 0, 12], [-189, 24, -37, 20, -132, -132, -20, 0], [40, -30, -54, -12, 56, 0, -30, -18], [58, -2, -200, -6, -148, 148, -6, -4], [-175, 8, 12, -5, 12, 180, -10, 8], [-28, 8, 0, -8, 36, 0, -16, -8], [39, -11, 0, 11, 25, -121, 6, -6], [4, -4, -160, -4, 92, 80, -6, -6], [72, -6, 170, -14, 58, 170, -20, 14], [-81, 0, 87, -6, -180, 93, -3, 16], [82, 12, -75, 15, -97, 75, 3, 15], [-25, -5, 105, -10, -140, -140, 10, 0], [-97, -7, 0, 7, -45, -194, 23, -23], [6, -30, -79, 1, -79, -7, 2, -30], [8, 3, -23, -28, 3, 3, 28, 0], [54, 4, 222, 8, 124, 0, 4, -4], [236, -8, 142, 3, 0, -284, 8, -5], [-51, 1, 33, 18, 0, 0, 18, 2], [185, -6, -149, -13, 149, 172, 0, 6], [164, 24, -13, 0, 328, 0, 24, 24], [-54, 6, 104, -22, -76, 104, -16, 22], [-7, 0, -63, 70, 21, 42, 35, 8], [-324, -28, -324, 0, -139, 185, -5, -14], [2, 24, -110, 0, 112, 112, 0, 0], [-25, 25, -186, 25, -110, 93, -16, -16], [298, -46, -83, 16, 314, -83, -30, -16], [19, 12, 19, 0, -40, -59, 25, 6], [200, -16, -96, -28, 96, 172, 0, 16], [-92, 10, 47, -9, -202, 0, 10, 19], [56, 15, 103, -4, 103, -52, -8, 15], [-154, 0, 148, 6, 67, -215, 3, -36], [-91, -15, -155, 41, 155, -50, 0, 15], [4, -4, 256, -4, -60, -128, -20, -20], [109, 24, -64, 16, 61, -61, 16, 48], [-56, -84, -56, 0, -120, -64, 14, -42], [111, 15, 223, -27, -84, -223, -42, -27], [275, 15, 0, -15, 130, 249, -54, 54], [248, -26, -186, 14, 0, 372, 26, -12], [133, 61, 130, -19, 130, -114, -38, 61], [-131, 40, -131, 0, -24, 107, -24, 20], [133, 17, -149, -12, 149, 121, 0, -17], [-42, 62, -164, 9, 131, 131, -9, 0], [26, -40, 266, -22, 8, 0, -40, -18], [-140, 0, 172, -32, -4, -168, -16, -4], [-282, 41, 87, 17, -87, -265, 0, -41], [10, -26, 0, 26, 18, -476, -4, 4], [-158, 7, -73, -15, -246, 246, -15, 14], [44, 52, -36, -34, 10, -36, 18, 34], [-402, 38, -402, 0, -337, 65, 16, 19], [-74, 20, -105, -27, 0, 210, -20, -7], [-14, 14, 484, 14, -332, -242, 34, 34], [249, 1, 17, 33, 265, 265, -33, 0], [-558, -7, 11, -16, 0, -22, 7, -23], [134, 0, -130, -4, 455, -325, -2, -3], [-214, 16, -22, 6, 208, 22, -10, 6], [138, -34, 0, 34, 86, 576, 38, -38], [-114, 34, -260, -4, -236, 0, 34, 38], [-416, 27, 408, 8, 0, 0, 8, 54], [318, -28, 318, 0, 486, 168, 36, -14], [-294, -52, -69, -25, -250, -250, 25, 0], [248, -2, 66, 16, 0, -132, 2, 14], [-35, 35, -146, 35, -63, 73, -29, -29], [-186, -52, 170, 14, -172, 170, -38, -14], [263, -6, 263, 0, -306, -569, -13, -3], [-155, -23, 413, -16, -413, -171, 0, 23], [-132, -4, -192, -27, 33, 33, 27, 0], [227, 32, 107, 33, 107, -260, 66, 32], [-175, 17, -169, -34, 209, 169, -51, -34], [-569, -7, 500, 48, -500, -521, 0, 7], [398, 18, 0, -18, 190, -364, 2, -2], [-48, 48, 396, 48, -382, -198, 26, 26], [-76, -86, -86, 58, -18, -86, -28, -58], [9, 0, -35, 26, 612, -577, 13, 11], [284, 26, 0, -26, 129, 566, -35, 35], [38, 4, 40, -50, 0, -80, -4, -46], [-510, 4, -530, 6, -530, 504, 12, 4], [-161, -72, -161, 0, 96, 257, -45, -36], [-28, -40, 122, -46, -148, 0, -40, 6], [268, -56, 105, 4, 105, -272, 8, -56], [22, 84, -362, 38, -60, 362, -46, 38], [192, 64, -322, 17, 418, 0, 64, 47], [212, -76, 123, -42, 293, -293, -42, -152], [164, 0, -202, 38, 157, 45, 19, -27], [410, 120, 410, 0, -172, -582, 74, 60], [380, -108, 0, 108, 244, -164, -2, 2], [22, -22, -1140, -22, 34, 570, -4, -4], [57, 17, 162, 59, 162, -116, 118, 17], [-232, -92, -232, 0, -15, 217, -22, -46], [601, 11, 26, 17, -26, 618, 0, -11], [-303, 35, -200, -10, -200, 313, -20, 35], [-62, 66, 206, 40, 22, -206, -26, 40], [13, -13, 462, -13, -543, -231, 1, 1], [368, 21, -425, 36, -21, 21, 36, 42], [-556, -10, -556, 0, -260, 296, -9, -5], [96, -48, -92, -40, -56, 92, 8, -40], [388, -52, 172, 24, 240, 240, -24, 0], [784, 4, 0, -4, 390, 349, 19, -19], [-250, 10, 16, -20, 16, 270, -40, 10], [556, 28, 427, 28, 157, 157, -28, 0], [-279, -35, 89, 12, -534, 0, -35, -47], [-106, 58, 118, -37, 0, -236, -58, 21], [-22, 26, -196, 0, -218, 218, 0, 52], [108, 7, 202, -74, -202, 34, 0, -7], [-755, 3, 0, -3, -379, -149, 52, -52], [282, -6, -158, -39, 486, 0, -6, 33], [-14, 14, -60, 14, -336, 30, -20, -20], [762, 22, 0, -22, 370, -364, -2, 2], [464, 82, 106, -82, 0, -212, -82, 0], [-476, 8, -24, 32, -444, -24, 40, -32], [-90, 24, -413, -7, 413, -97, 0, -24], [-383, -31, -83, 10, 0, 166, 31, -21], [65, -13, -156, 95, 4, -4, 95, -26], [236, 0, -252, 16, -340, 592, 8, -80], [-154, -16, -374, 18, 136, 374, 34, 18], [128, -1, -783, 49, -606, 606, 49, -2], [-120, 6, -18, 42, -78, -18, 48, -42], [-108, -122, -108, 0, -113, -5, 26, -61], [-308, -24, -196, -30, -142, -142, 30, 0], [2, -2, -436, -2, -52, 218, 14, 14], [-173, -44, 446, 34, -139, 446, -10, -34]];
    aps := ConvertToHeckeField(raw_aps);
    chi := MakeCharacter_78_l_Hecke(Universe(aps));
    return ExtendMultiplicatively(weight, aps, chi);
end function;


// To make the newform (type ModFrm), type "MakeNewformModFrm_78_3_l_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_78_3_l_c(:prec:=8)
    chi := MakeCharacter_78_l();
    f_vec := qexpCoeffs();
    Kf := Universe(f_vec);
    // SetVerbose("ModularForms", true);
    // SetVerbose("ModularSymbols", true);
    S := CuspidalSubspace(ModularForms(chi, 3));
    S := BaseChange(S, Kf);
    maxprec := NextPrime(997) - 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_78_3_l_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_78_3_l_c( : sign := -1)
    R<x> := PolynomialRing(Rationals());
    chi := MakeCharacter_78_l();
    // SetVerbose("ModularSymbols", true);
    Snew := NewSubspace(CuspidalSubspace(ModularSymbols(chi,3,sign)));
    Vf := Kernel([<5,R![5253264, -632592, 38088, 11916, 4065, -282, 18, 6, 1]>],Snew);
    return Vf;
end function;