
// Make newform 26.3.f.a in Magma, downloaded from the LMFDB on 19 April 2024.
// To make the character of type GrpDrchElt, type "MakeCharacter_26_f();"
// To make the character of type GrpDrchElt with Codomain the HeckeField, type "MakeCharacter_26_f_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_26_3_f_a();".
// 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_26_3_f_a();".
// 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, 0, -1, 0, 1];
        Kf := NumberField(Polynomial([elt : elt in poly]));
        AssignNames(~Kf, ["nu"]);
    end if;
    Rfbasis := [Kf.1^i : i in [0..Degree(Kf)-1]];
    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_26_f();"
function MakeCharacter_26_f()
    N := 26;
    order := 12;
    char_gens := [15];
    v := [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_26_f_Hecke();"
function MakeCharacter_26_f_Hecke(Kf)
    N := 26;
    order := 12;
    char_gens := [15];
    char_values := [[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, 1, 1, -1], [0, -1, 0, -1], [-1, -2, 2, 1], [-4, -4, -3, 7], [1, 4, -5, -5], [-9, 8, 12, -2], [13, -6, 13, 0], [-12, 12, -5, -17], [4, 21, -2, -21], [0, -16, -27, -16], [-37, -10, 10, 37], [7, -13, 6, 6], [-13, 13, 26, -26], [20, -39, 20, 0], [33, 0, 0, 33], [-42, 44, 0, -22], [-10, -10, 23, -13], [39, 6, -39, -12], [33, 10, -23, 23], [-4, 4, 29, 25], [-7, -54, -54, -7], [48, 72, 0, -36], [25, -46, 46, -25], [13, 43, -56, -56], [71, -71, -2, 69], [-26, -84, 13, 84], [10, 0, -20, 6], [0, 1, -78, 1], [63, 122, -122, -63], [-177, 0, 177, 0], [-168, 25, 84, -25], [66, 128, 0, -64], [139, 139, -86, -53], [-14, 3, 14, -6], [7, -7, 46, 53], [-127, 94, 94, -127], [-56, -48, 0, 24], [-150, -150, 53, 97], [15, -36, 21, 21], [-83, -72, -83, 0], [92, -81, -46, 81], [-4, 0, 8, 150], [204, -47, -204, 94], [59, -41, -18, -18], [-239, -61, 178, -178], [102, -121, 102, 0], [0, 125, 162, 125], [-111, -44, 67, -67], [-86, 86, -95, -181], [29, 54, 54, 29], [108, 0, -216, 210], [-39, -174, 174, 39], [-5, -5, -168, 173], [30, 207, 30, 0], [-190, 138, 95, -138], [0, -47, -132, -47], [81, 22, -81, -44], [307, -238, -69, -69], [57, -114, 57, 0], [-35, -170, -170, -35], [-156, 11, 78, -11], [189, 189, 0, -189], [23, 70, 70, 23], [30, 0, -60, -438], [48, 96, 0, -48], [135, 108, -108, -135], [-116, 116, -67, -183], [-198, 0, 396, 248], [-366, -151, 366, 302], [87, 89, -176, -176], [53, 193, 140, -140], [-135, -90, -90, -135], [0, 225, -88, 225], [-273, 140, 273, -280], [231, 122, -109, 109], [274, -274, -119, 155], [-296, 0, 592, -60], [-61, -61, 48, 13], [183, -315, 132, 132], [-67, 67, 210, 143], [0, 3, -342, 3], [-333, -34, 34, 333], [-77, -322, -245, 245], [-147, -170, -147, 0], [-496, 9, 248, -9], [78, 464, 0, -232], [71, 71, 164, -235], [301, 223, -78, 78], [123, -123, -168, -45], [55, 18, 18, 55], [-236, 0, 472, 270], [-127, 116, 11, 11], [160, -160, 345, 505], [196, 693, -98, -693], [133, 18, -18, -133], [210, -113, -210, 226], [-97, -23, 74, -74], [-108, 152, 0, -76], [0, -525, 86, -525], [17, -156, -156, 17], [224, -852, 0, 426], [-255, 441, -186, -186], [-130, -195, -130, 0], [-222, 324, 111, -324], [450, 0, -900, 34], [323, -10, 10, -323], [-243, 90, 333, -333], [347, 134, 134, 347], [144, -984, 0, 492], [0, 54, -159, 54], [818, 189, -818, -378], [-249, 35, 284, -284], [439, -439, -566, -127], [511, 26, 26, 511], [646, 646, -283, -363], [269, 546, 269, 0], [-240, 240, -191, -431], [-1060, 243, 530, -243], [0, 190, -111, 190], [-336, 123, 336, -246], [-13, -579, 592, 592], [282, -180, -141, 180], [540, 480, 0, -240], [278, 278, -97, -181], [-193, 270, 463, -463], [406, 0, -812, 144], [205, 205, -474, 269], [-476, -33, -476, 0], [-528, 0, 1056, -100], [267, -368, 368, -267], [-177, 122, 55, 55], [-77, -658, -581, 581], [248, -525, -124, 525], [0, 202, -387, 202], [199, 199, 688, -887], [-493, -855, -362, 362], [313, -313, -266, 47], [632, 632, -785, 153], [-397, -606, -397, 0], [0, 648, -153, 648], [-23, 388, -388, 23], [381, -351, -732, 732], [-124, 429, -124, 0], [-283, 182, 182, -283], [-558, -928, 279, 928], [350, 350, 89, -439], [-217, 118, 118, -217], [-362, 0, 724, -1020], [174, 128, 0, -64], [471, -366, 366, -471], [-765, 765, 638, -127], [-278, -162, 139, 162], [-294, 0, 588, 706], [0, -45, 288, -45], [1440, -395, -720, 395], [996, -76, 0, 38], [132, 333, -132, -666], [-467, 467, -326, -793], [294, -1396, 0, 698], [-859, -932, 932, 859], [-839, 850, -11, -11], [163, -150, 163, 0], [499, 190, -190, -499], [-660, -489, 660, 978], [-23, -283, -260, 260], [309, -990, -990, 309], [0, -195, -122, -195], [863, -498, -863, 996]];
    aps := ConvertToHeckeField(raw_aps);
    chi := MakeCharacter_26_f_Hecke(Universe(aps));
    return ExtendMultiplicatively(weight, aps, chi);
end function;


// To make the newform (type ModFrm), type "MakeNewformModFrm_26_3_f_a();".
// 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_26_3_f_a(:prec:=4)
    chi := MakeCharacter_26_f();
    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_26_3_f_a();".
// 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_26_3_f_a( : sign := -1)
    R<x> := PolynomialRing(Rationals());
    chi := MakeCharacter_26_f();
    // SetVerbose("ModularSymbols", true);
    Snew := NewSubspace(CuspidalSubspace(ModularSymbols(chi,3,sign)));
    Vf := Kernel([<3,R![9, 0, 3, 0, 1]>],Snew);
    return Vf;
end function;