
// Make newform 15.8.a.c in Magma, downloaded from the LMFDB on 25 April 2024.
// To make the character of type GrpDrchElt, type "MakeCharacter_15_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_15_8_a_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_15_8_a_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 := [-150, -1, 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_15_a();"
function MakeCharacter_15_a()
    N := 15;
    order := 1;
    char_gens := [11, 7];
    v := [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_15_a_Hecke(Kf)
    return MakeCharacter_15_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 := 8;
    raw_aps := [[4, -1], [27, 0], [125, 0], [624, 56], [1492, 464], [-4082, -824], [-3446, 1400], [-25820, 2056], [48528, -5208], [95030, -8288], [151032, 2168], [-243946, -14424], [326282, -21392], [180388, -7136], [-236696, 5912], [-290642, 13232], [218500, -149776], [-1257818, 1456], [-2601876, 129920], [-1912648, 76480], [-544502, -388208], [-2273640, -80440], [-2990532, -91872], [8247930, 20496], [1147394, 428640], [10675182, -8736], [-5990992, 1132824], [-4907436, 169872], [13745030, -868224], [-13485302, -333352], [-12891656, -80840], [21889452, 1997856], [8381634, -1736856], [-15466180, -1132776], [9945470, 423328], [-49805408, -2445800], [-32990386, -582696], [-39956692, 5261280], [8158464, -4533144], [42432678, 5942688], [16660540, -2028640], [12142142, -7184832], [-77667328, 5503744], [38927378, -7535472], [-93532866, 2549328], [33976240, 9242008], [79856372, -3795432], [38704328, -15208344], [123458444, -1323584], [70274430, -3081616], [43640898, 6736584], [117125920, 16874576], [202582162, 2024704], [-64839468, -2509440], [-389383686, 2436312], [276212528, 6242680], [-440639930, -12903904], [120902152, -20475656], [-304282026, 1032728], [224849562, 22369392], [-169730892, 31185056], [199600158, -28830960], [304115884, 20674672], [-20976168, -50718576], [497012858, -20019600], [-475806106, -39040208], [-768424548, 26844920], [452903554, 32257168], [273600004, 48760880], [-65056730, 28535632], [167192298, 64663656], [838005720, -3397056], [-34456296, -42508792], [209418838, 42314104], [-1357968740, -45621080], [186732888, 70448280], [-997815570, 21857664], [637917934, -56172248], [1331057682, -70766304], [-418875670, 71919744], [147644300, 169584736], [1679036542, -48162128], [484800912, 180701568], [2408386978, -10770800], [1099473760, 78666040], [-1888464012, -64063104], [2199133090, -6980512], [1418507674, -129013664], [-592610778, 3428160], [-495355032, 78012344], [874547564, 106491472], [545577120, -319785600], [1742886464, 77058600], [-611549068, -333038384], [1898558740, -129926504], [3026669888, 69836536], [1544346550, -770176], [1857518042, -337845152], [-1141720172, 71635504], [-1905841578, 447206528], [3573946444, 136171456], [-6673970106, -56076480], [-370924212, -153990192], [930957450, 449142336], [-3054615988, 73413144], [-679500286, 416347200], [-1332371436, -450613968], [1910226698, 26859064], [-1121065240, -265026752], [5489704682, -17413056], [-305992856, -163763000], [-5202891242, -368839832], [-5633002686, 280638024], [2181416540, 501025944], [-453776528, -133475960], [5501085042, 425664048], [2097102828, 254345984], [3878237824, 70414280], [-7464952282, 466888960], [5726091340, -230599600], [-305509778, -704647280], [-6135171822, -136211728], [-3048230706, -349481472], [4606469748, 260921520], [-3301794668, 202088344], [8368003862, 419583136], [-3562518530, 1222912336], [-2824461600, 206938608], [9351057584, 129861384], [9808347758, 463856184], [-5656294460, -860760776], [-5757945632, -590981176], [-1125442328, 55918264], [-6041179946, -64270856], [-6714717078, -255648], [7903135010, -392587872], [5073697758, 270360240], [-7362105716, 1177736752], [-2703318346, -703139168], [3429224330, -247598480], [4696931292, -504379240], [25247345022, 294960192], [24827010368, -380715912], [2011853524, -980297440], [-12967149450, -672141760], [-9338079400, -163088480], [1797295878, 594474440], [-10057620926, 2020109432], [2040151900, -839697080], [-14324964472, -9302936], [-15864468546, -1149994984], [8458290562, 627329072], [-7798164292, 662101824], [-22247348016, -626727288], [-32545967436, -200670448], [-6717296288, 2085079280], [7939532800, 1761682360], [-24906448990, 744734656], [9686843994, 488231168], [2585698022, 1679425888], [15802351884, -1175493936], [11272569298, 1188679976], [-8567703616, -3412763640], [14511369252, -521327712], [13970574154, -2008612360], [4163245488, 919222152], [-7482439768, -2162481240], [27880094694, 2455075064]];
    aps := ConvertToHeckeField(raw_aps);
    chi := MakeCharacter_15_a_Hecke(Universe(aps));
    return ExtendMultiplicatively(weight, aps, chi);
end function;


// To make the newform (type ModFrm), type "MakeNewformModFrm_15_8_a_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_15_8_a_c(:prec:=2)
    chi := MakeCharacter_15_a();
    f_vec := qexpCoeffs();
    Kf := Universe(f_vec);
    // SetVerbose("ModularForms", true);
    // SetVerbose("ModularSymbols", true);
    S := CuspidalSubspace(ModularForms(chi, 8));
    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_15_8_a_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_15_8_a_c( : sign := -1)
    R<x> := PolynomialRing(Rationals());
    chi := MakeCharacter_15_a();
    // SetVerbose("ModularSymbols", true);
    Snew := NewSubspace(CuspidalSubspace(ModularSymbols(chi,8,sign)));
    Vf := Kernel([<2,R![-138, -7, 1]>],Snew);
    return Vf;
end function;