unlisted
ubuntu2004r"""1Multiplication in the strata algebra.2"""34import itertools56from sage.misc.cachefunc import cached_function7from sage.rings.integer_ring import ZZ8from sage.modules.free_module_element import vector91011from .graph import Graph, R, X, all_strata, all_pure_strata, num_strata, single_stratum, unpurify_map, contraction_table, pure_strata_autom_count, automorphism_cosets, graph_isomorphic, num_of_stratum12from .moduli import MODULI_SM, MODULI_CT, MODULI_ST, MODULI_SMALL, dim_form13from .utils import simplify_sparse, setparts_with_auts141516def get_marks(n, symm):17if symm == 0:18return tuple(range(1, n + 1))19return (1,) * symm + tuple(range(2, n - symm + 2))202122@cached_function23def multiply(r1, i1, r2, i2, g, rmax, markings=(), moduli_type=MODULI_ST):24r"""25Return the result of the multiplication of the ``(r1, i1)``-th generator26with the ``(r2, i2)`` one.2728The output is a list representing the coefficients with respect to the29generators in rank ``r1+r2``.3031EXAMPLES::3233sage: from admcycles.DR.graph import num_strata34sage: from admcycles.DR.algebra import multiply35sage: r1 = 136sage: r2 = 237sage: for i1 in range(num_strata(2, r1)):38....: for i2 in range(num_strata(2, r2)):39....: print(i1, i2, multiply(r1, i1, r2, i2, 2, r1 + r2))400 0 [0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]410 1 [0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]420 2 [0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]430 3 [0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]440 4 [0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0]450 5 [0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0]460 6 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0]470 7 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0]481 0 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]491 1 [0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]501 2 [0, 0, 0, 0, -2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]511 3 [0, 0, 0, 0, 0, -2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]521 4 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0]531 5 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]541 6 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -2, 0, 0, 0, 0]551 7 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0]562 0 [0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]572 1 [0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0]582 2 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0]592 3 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0]602 4 [0, 0, 0, 0, 0, 0, 0, 0, -4, 0, 0, 0, 0, 1, 0, 0, 0]612 5 [0, 0, 0, 0, 0, 0, 0, 0, 0, -2, -2, 0, 0, 0, 1, 0, 0]622 6 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0]632 7 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -8, 0, 4]64"""65unpurify = unpurify_map(g, r1 + r2, markings, moduli_type)66gens = all_strata(g, r1 + r2, markings, moduli_type)67ngens = num_strata(g, r1 + r2, markings, moduli_type)68answer = [0 for i in range(ngens)]69pure_strata = [all_pure_strata(g, r, markings, moduli_type)70for r in range(rmax + 1)]71contraction_dict = contraction_table(g, rmax, markings, moduli_type)72G1 = single_stratum(i1, g, r1, markings, moduli_type)73G2 = single_stratum(i2, g, r2, markings, moduli_type)74G1copy = Graph(G1.M)75G2copy = Graph(G2.M)76G1copy.purify()77G2copy.purify()78pure_r1 = G1copy.num_edges() - len(markings)79pure_r2 = G2copy.num_edges() - len(markings)80found = False81for i in range(len(pure_strata[pure_r1])):82if G1copy.M == pure_strata[pure_r1][i].M:83G1_key = (pure_r1, i)84found = True85break86assert found, "G1 purification failed"87found = False88for i in range(len(pure_strata[pure_r2])):89if G2copy.M == pure_strata[pure_r2][i].M:90G2_key = (pure_r2, i)91found = True92break93assert found, "G2 purification failed"94if G1_key > G2_key:95return multiply(r2, i2, r1, i1, g, rmax, markings, moduli_type)9697if (G1_key, G2_key) not in contraction_dict:98return answer99for L in contraction_dict[(G1_key, G2_key)]:100H = pure_strata[L[0][0]][L[0][1]]101Hloops = []102if moduli_type > MODULI_CT:103for i in range(1, H.M.nrows()):104for j in range(1, H.M.ncols()):105if H.M[i, j][0] == 2:106Hloops.append((i, j))107auts = pure_strata_autom_count(108L[0][1], g, L[0][0], markings, moduli_type)109B = L[1]110if len(B) == pure_r1 and len(B) == pure_r2:111auts *= 2112aut_cosets1 = automorphism_cosets(i1, g, r1, markings, moduli_type)113aut_cosets2 = automorphism_cosets(i2, g, r2, markings, moduli_type)114auts /= aut_cosets1[0] * aut_cosets2[0]115for isom1 in aut_cosets1[1]:116for isom2 in aut_cosets2[1]:117Hcopy = Graph(H.M)118vmap1 = [0 for i in range(G1.M.nrows())]119for i in range(1, G1.M.nrows()):120vmap1[i] = L[2][0][L[4][0][isom1[0]121[i - 1] - 1] - 1]122emap1 = [0 for i in range(G1.M.ncols())]123for i in range(1, G1.M.ncols()):124emap1[i] = L[2][1][L[4][1][isom1[1]125[i - 1] - 1] - 1]126vmap2 = [0 for i in range(G2.M.nrows())]127for i in range(1, G2.M.nrows()):128vmap2[i] = L[3][0][L[5][0][isom2[0]129[i - 1] - 1] - 1]130emap2 = [0 for i in range(G2.M.ncols())]131for i in range(1, G2.M.ncols()):132emap2[i] = L[3][1][L[5][1][isom2[1]133[i - 1] - 1] - 1]134135psilooplist = []136psiindexlist = []137loop_factor = ZZ.one()138for i in range(1, G1.M.nrows()):139for j in range(1, G1.M.ncols()):140if G1.M[i, j][0] != 0:141if G1.M[i, j][0] == 1:142if G1.M[i, j][1] != 0:143jj = emap1[j]144for ii in vmap1[i]:145if H.M[ii, jj] != 0:146Hcopy.M[ii, jj] += G1.M[i, j][1] * X147break148elif G1.M[i, j][1] == 0:149loop_factor *= 2150else:151jj = emap1[j]152psilooplist.append([[G1.M[i, j][1], G1.M[i, j][2]], [153G1.M[i, j][2], G1.M[i, j][1]]])154psiindexlist.append([jj])155for ii in vmap1[i]:156for k in range(H.M[ii, jj][0]):157psiindexlist[-1].append(ii)158for i in range(1, G2.M.nrows()):159for j in range(1, G2.M.ncols()):160if G2.M[i, j][0] != 0:161if G2.M[i, j][0] == 1:162if G2.M[i, j][1] != 0:163if G2.M[i, j][0] == 1:164jj = emap2[j]165for ii in vmap2[i]:166if H.M[ii, jj] != 0:167Hcopy.M[ii,168jj] += G2.M[i, j][1] * X169break170elif G2.M[i, j][1] == 0:171loop_factor *= 2172else:173jj = emap2[j]174psilooplist.append([[G2.M[i, j][1], G2.M[i, j][2]], [175G2.M[i, j][2], G2.M[i, j][1]]])176psiindexlist.append([jj])177for ii in vmap2[i]:178for k in range(H.M[ii, jj][0]):179psiindexlist[-1].append(ii)180181Klocationlist = []182Kindexlist = []183for i in range(1, G1.M.nrows()):184for r in range(1, rmax + 1):185for k in range(G1.M[i, 0][r]):186Klocationlist.append(vmap1[i])187Kindexlist.append(r)188for i in range(1, G2.M.nrows()):189for r in range(1, rmax + 1):190for k in range(G2.M[i, 0][r]):191Klocationlist.append(vmap2[i])192Kindexlist.append(r)193194psilist = []195for j in B:196S = [i for i in range(1, H.M.nrows()) if H.M[i, j][0] != 0]197if len(S) == 2:198psilist.append([[S[0], j], [S[1], j]])199else:200psilooplist.append([[0, 1], [1, 0]])201psiindexlist.append([j, S[0], S[0]])202203for psiloopvals in itertools.product(*psilooplist):204for Klocs in itertools.product(*Klocationlist):205for psilocs in itertools.product(*psilist):206Hcopycopy = Graph(Hcopy.M)207for i in range(len(psiindexlist)):208Hcopycopy.M[psiindexlist[i][1],209psiindexlist[i][0]] += psiloopvals[i][0] * X210if psiindexlist[i][1] == psiindexlist[i][2]:211Hcopycopy.M[psiindexlist[i][1],212psiindexlist[i][0]] += psiloopvals[i][1] * X**2213else:214Hcopycopy.M[psiindexlist[i][2],215psiindexlist[i][0]] += psiloopvals[i][1] * X216for i in range(len(Kindexlist)):217Hcopycopy.M[Klocs[i],2180] += X**Kindexlist[i]219for i in psilocs:220Hcopycopy.M[i[0], i[1]] += X221for k in Hloops:222if Hcopycopy.M[k][2] > Hcopycopy.M[k][1]:223Hcopycopy.M[k] += (Hcopycopy.M[k]224[2] - Hcopycopy.M[k][1]) * (X - X**2)225Hcopycopy.compute_invariant()226for which_gen in unpurify[L[0]]:227if graph_isomorphic(Hcopycopy, gens[which_gen]):228answer[which_gen] += (-1)**len(B) * \229loop_factor / auts230break231return answer232233234def check_associativity(g, r1, r2, r3, markings=(), moduli_type=MODULI_ST):235r"""236Check associativity of the strata algebra.237238If it fails a ``ValueError`` is raised.239240EXAMPLES::241242sage: from admcycles.DR.algebra import check_associativity243sage: check_associativity(2, 1, 1, 1)244"""245ngens1 = num_strata(g, r1, markings, moduli_type)246ngens2 = num_strata(g, r2, markings, moduli_type)247ngens3 = num_strata(g, r3, markings, moduli_type)248for i1, i2, i3 in itertools.product(range(ngens1), range(ngens2), range(ngens3)):249a = multiply(r1, i1, r2, i2, g, r1 + r2 +250r3, markings, moduli_type)251answer1 = vector(252[0 for i in range(num_strata(g, r1 + r2 + r3, markings, moduli_type))])253for j in range(num_strata(g, r1 + r2, markings, moduli_type)):254if a[j] == 0:255continue256answer1 += a[j] * vector(multiply(r1 + r2, j, r3,257i3, g, r1 + r2 + r3, markings, moduli_type))258a = multiply(r1, i1, r3, i3, g, r1 + r2 +259r3, markings, moduli_type)260answer2 = vector(261[0 for i in range(num_strata(g, r1 + r2 + r3, markings, moduli_type))])262for j in range(num_strata(g, r1 + r3, markings, moduli_type)):263if a[j] == 0:264continue265answer2 += a[j] * vector(multiply(r1 + r3, j, r2,266i2, g, r1 + r2 + r3, markings, moduli_type))267if answer1 != answer2:268raise ValueError("i1=%s i2=%s i3=%s" % (i1, i2, i3))269270271@cached_function272def kappa_conversion(sigma):273r"""274EXAMPLES::275276sage: from admcycles.DR.algebra import kappa_conversion277sage: kappa_conversion((1, 1, 1))278[[3*X, 1], [X^2 + X, 3], [X^3, 2]]279"""280answer = []281for spart in setparts_with_auts(list(sigma)):282coeff = spart[1]283poly = R(0)284for part in spart[0]:285coeff *= ZZ(len(part) - 1).factorial()286poly += X**sum(part)287answer.append([poly, coeff])288return answer289290291@cached_function292def kappa_conversion_inverse(sigma):293r"""294EXAMPLES::295296sage: from admcycles.DR.algebra import kappa_conversion_inverse297sage: kappa_conversion_inverse((1, 1, 1))298[[3*X, 1], [X^2 + X, -3], [X^3, 1]]299"""300answer = []301for spart in setparts_with_auts(list(sigma)):302coeff = spart[1] * (-1)**(len(sigma) - len(spart[0]))303poly = R(0)304for part in spart[0]:305poly += X**sum(part)306answer.append([poly, coeff])307return answer308309310@cached_function311def convert_to_monomial_basis(num, g, r, markings=(), moduli_type=MODULI_ST):312r"""313EXAMPLES::314315sage: from admcycles.DR.algebra import convert_to_monomial_basis316317sage: convert_to_monomial_basis(1, 2, 3, (1, 2, 3))318[(1, 1), (0, 1)]319sage: convert_to_monomial_basis(2, 2, 3, (1, 2, 3))320[(2, 1), (1, 3), (0, 2)]321"""322answer = []323G = single_stratum(num, g, r, markings, moduli_type)324genus_vec = []325kappa_vec = []326for i in range(1, G.M.nrows()):327genus_vec.append(G.M[i, 0][0])328kappa_vec.append([])329for j in range(1, r + 1):330for k in range(G.M[i, 0][j]):331kappa_vec[-1].append(j)332kappa_vec[-1] = kappa_conversion(tuple(kappa_vec[-1]))333for choice in itertools.product(*kappa_vec):334coeff = 1335GG = Graph(G.M)336for i in range(1, G.M.nrows()):337GG.M[i, 0] = genus_vec[i - 1] + choice[i - 1][0]338coeff *= choice[i - 1][1]339answer.append((num_of_stratum(GG, g, r, markings, moduli_type), coeff))340return answer341342343# NOTE: this function is not used anywhere344@cached_function345def convert_to_pushforward_basis(num, g, r, markings=(), moduli_type=MODULI_ST):346answer = []347G = single_stratum(num, g, r, markings, moduli_type)348genus_vec = []349kappa_vec = []350for i in range(1, G.M.nrows()):351genus_vec.append(G.M[i, 0][0])352kappa_vec.append([])353for j in range(1, r + 1):354for k in range(G.M[i, 0][j]):355kappa_vec[-1].append(j)356kappa_vec[-1] = kappa_conversion_inverse(357tuple(kappa_vec[-1]))358for choice in itertools.product(*kappa_vec):359coeff = 1360GG = Graph(G.M)361for i in range(1, G.M.nrows()):362GG.M[i, 0] = genus_vec[i - 1] + choice[i - 1][0]363coeff *= choice[i - 1][1]364answer.append((num_of_stratum(GG, g, r, markings, moduli_type), coeff))365return answer366367368def convert_vector_to_monomial_basis(vec, g, r, markings=(), moduli_type=MODULI_ST):369r"""370EXAMPLES::371372sage: from admcycles.DR.moduli import MODULI_SM, MODULI_RT, MODULI_CT, MODULI_ST373sage: from admcycles.DR.algebra import convert_vector_to_monomial_basis374sage: convert_vector_to_monomial_basis(vec=(-24504480, 1663200, -36000), g=8, r=3, markings=(), moduli_type=MODULI_SM)375[-22913280, 1555200, -36000]376sage: convert_vector_to_monomial_basis(vec=(0, 0, -15, 0, 15, 15, 0, 0, 0), g=2, r=2, markings=(1, 2), moduli_type=MODULI_RT)377[0, 0, -15, 0, 15, 15, 0, 0, 0]378sage: convert_vector_to_monomial_basis(vec=(71820, -7020, 9720, -41580, 9288, -3240, -18900, 756), g=2, r=2, markings=(1,), moduli_type=MODULI_CT)379[64800, -7020, 9720, -41580, 9288, -3240, -18900, 756]380sage: convert_vector_to_monomial_basis(vec=(81/2, -45/2, -45/2, -45/2, 9/2, 9/2, 9/2, -27/2, -9/4), g=1, r=1, markings=(1, 2, 3), moduli_type=MODULI_ST)381[81/2, -45/2, -45/2, -45/2, 9/2, 9/2, 9/2, -27/2, -9/4]382"""383l = len(vec)384vec2 = [0 for i in range(l)]385for i in range(l):386if vec[i] != 0:387for x in convert_to_monomial_basis(i, g, r, markings, moduli_type):388vec2[x[0]] += x[1] * vec[i]389return vec2390391392# NOTE: this function is not used anywhere393def convert_vector_to_pushforward_basis(vec, g, r, markings=(), moduli_type=MODULI_ST):394l = len(vec)395vec2 = [0 for i in range(l)]396for i in range(l):397if vec[i] != 0:398for x in convert_to_pushforward_basis(i, g, r, markings, moduli_type):399vec2[x[0]] += x[1] * vec[i]400return vec2401402403def kappa_multiple(vec, which_kappa, g, r, n, symm, moduli_type=MODULI_ST):404r"""405Return the multiplication of the sparse vector ``vec`` by a kappa-class.406"""407vec2 = []408for num, coeff in vec:409for num2, coeff2 in single_kappa_multiple(num, which_kappa, g, r, n, symm, moduli_type):410vec2.append([num2, coeff * coeff2])411return simplify_sparse(vec2)412413414# TODO: why using (n, symm) rather than a tuple of markings here?415def psi_multiple(vec, which_psi, g, r, n, symm, moduli_type=MODULI_ST):416r"""417Return the multiplication of the sparse vector ``vec`` by a psi-class.418"""419vec2 = []420for num, coeff in vec:421for num2, coeff2 in single_psi_multiple(num, which_psi, g, r, n, symm, moduli_type):422vec2.append([num2, coeff * coeff2])423return simplify_sparse(vec2)424425426# TODO: why using (n, symm) rather than a tuple of markings here?427def insertion_pullback(vec, new_mark, g, r, n, symm, moduli_type=MODULI_ST, from_small=False):428r"""429For a relation ``vec`` we return its pullback along the forgetfulmap that forgets a point.430"""431vec2 = []432for x in vec:433for y in single_insertion_pullback(x[0], new_mark, g, r, n, symm, moduli_type, from_small):434vec2.append([y[0], x[1] * y[1]])435return simplify_sparse(vec2)436437438# TODO: why using (n, symm) rather than a tuple of markings here?439@cached_function440def single_psi_multiple(num, which_psi, g, r, n, symm, moduli_type=MODULI_ST):441r"""442Takes the index of a stratum ``num`` and returns the stratum in degree ``r+1``443(as a sparse vector of length 1) corresponding to its multiplication by a psi-class.444445EXAMPLES::446447sage: from admcycles.DR.moduli import MODULI_RT, MODULI_CT, MODULI_ST448sage: from admcycles.DR.algebra import single_psi_multiple449sage: single_psi_multiple(5, 1, 2, 2, 2, 0, MODULI_ST)450[(11, 1)]451"""452markings = get_marks(n, symm)453G = single_stratum(num, g, r, markings, moduli_type)454answer = []455for j in range(1, G.M.ncols()):456if G.M[0, j] == which_psi:457good_j = j458break459for i in range(1, G.M.nrows()):460if G.M[i, good_j] != 0:461deg = 0462dim_used = 0463for j in range(1, r + 1):464dim_used += j * G.M[i, 0][j]465for j in range(1, G.M.ncols()):466dim_used += G.M[i, j][1] + G.M[i, j][2]467deg += G.M[i, j][0]468if dim_used < dim_form(G.M[i, 0][0], deg, moduli_type):469GG = Graph(G.M)470GG.M[i, good_j] += X471answer.append(472(num_of_stratum(GG, g, r + 1, markings, moduli_type), 1))473break474return answer475476477# TODO: why using (n, symm) rather than a tuple of markings here?478@cached_function479def single_kappa_multiple(num, which_kappa, g, r, n, symm, moduli_type=MODULI_ST):480r"""481Takes the index of a stratum ``num`` and returns the index of its multiplication by a kappa-class.482This uses the multi-indexed pushforward kappa-classes, rather than monomials in kappa-classes.483"""484markings = get_marks(n, symm)485G = single_stratum(num, g, r, markings, moduli_type)486answer = []487for i in range(1, G.M.nrows()):488deg = 0489dim_used = 0490for j in range(1, r + 1):491dim_used += j * G.M[i, 0][j]492for j in range(1, G.M.ncols()):493dim_used += G.M[i, j][1] + G.M[i, j][2]494deg += G.M[i, j][0]495if dim_used + which_kappa <= dim_form(G.M[i, 0][0], deg, moduli_type):496GG = Graph(G.M)497GG.M[i, 0] += X**which_kappa498answer.append((num_of_stratum(GG, g, r + which_kappa,499markings, moduli_type), 1))500for j in range(1, r + 1):501if G.M[i, 0][j] > 0:502GG = Graph(G.M)503GG.M[i, 0] += X**(j + which_kappa)504GG.M[i, 0] -= X**j505answer.append((num_of_stratum(506GG, g, r + which_kappa, markings, moduli_type), -G.M[i, 0][j]))507return answer508509510# NOTE: this function is not used anywhere511def single_kappa_psi_multiple(num, kappa_partition, psi_exps, g, r, n=0, moduli_type=MODULI_ST):512markings = tuple(range(1, n + 1))513G = single_stratum(num, g, r, markings, moduli_type)514GG = Graph(G.M)515for j in range(1, G.M.ncols()):516if GG.M[0, j] != 0:517for i in range(1, G.M.nrows()):518if GG.M[i, j] != 0:519GG.M[i, j] += psi_exps[GG.M[0, j][0] - 1] * X520break521rnew = r + sum(kappa_partition) + sum(psi_exps)522answer = []523kappa_options = [list(range(1, G.M.nrows()))524for i in range(len(kappa_partition))]525for kappa_distrib in itertools.product(*kappa_options):526GGG = Graph(GG.M)527for i in range(len(kappa_partition)):528GGG.M[kappa_distrib[i], 0] += X**(kappa_partition[i])529is_bad = False530for i in range(1, GGG.M.nrows()):531deg = 0532dim_used = 0533for j in range(1, rnew + 1):534dim_used += j * GGG.M[i, 0][j]535for j in range(1, GGG.M.ncols()):536dim_used += GGG.M[i, j][1] + GGG.M[i, j][2]537deg += GGG.M[i, j][0]538if dim_used > dim_form(GGG.M[i, 0][0], deg, moduli_type):539is_bad = True540break541if is_bad:542continue543answer.append(544(num_of_stratum(GGG, g, rnew, markings, moduli_type), 1))545return answer546547548# TODO: why using (n, symm) rather than markings here?549@cached_function550def single_insertion_pullback(num, new_mark, g, r, n, symm, moduli_type=MODULI_ST, from_small=False):551r"""552Takes the index of a stratum ``num`` and returns the sparse vector553representation of its pullback along the forgetfulmap that foregets a554point.555556EXAMPLES::557558sage: from admcycles.DR.algebra import single_insertion_pullback559560sage: single_insertion_pullback(0, 1, 5, 2, 0, 0, 1, False)561[(0, 1), (3, -1)]562sage: single_insertion_pullback(1, 1, 5, 2, 0, 0, 1, False)563[(1, 1), (2, -1), (2, -1)]564sage: single_insertion_pullback(10, 1, 2, 2, 1, 0, 3, False)565[(25, 1), (27, -1)]566"""567markings = get_marks(n, symm)568if new_mark == 1:569new_markings = get_marks(n + 1, symm + 1)570else:571new_markings = get_marks(n + 1, symm)572if from_small:573G = single_stratum(num, g, r, markings, MODULI_SMALL)574else:575G = single_stratum(num, g, r, markings, moduli_type)576answer = []577for i in range(1, G.M.nrows()):578GG = Graph(G.M)579if not (new_mark == 1 and symm > 0):580for j in range(1, G.M.ncols()):581if GG.M[0, j][0] >= new_mark:582GG.M[0, j] += 1583GG.add_edge(i, 0, new_mark)584answer.append(585(num_of_stratum(GG, g, r, new_markings, moduli_type), 1))586for j in range(1, r + 1):587for k in range(GG.M[i, 0][j]):588GGG = Graph(GG.M)589GGG.M[i, 0] -= X**j590GGG.M[i, -1] += j * X591answer.append(592(num_of_stratum(GGG, g, r, new_markings, moduli_type), -1))593if moduli_type <= MODULI_SM:594continue595for j in range(1, G.M.ncols()):596if G.M[i, j][0] == 1:597if G.M[i, j][1] >= 1:598x = G.M[i, j][1]599GGG = Graph(GG.M)600row1 = [GG.M[i, k] for k in range(GG.M.ncols())]601row2 = [0 for k in range(GG.M.ncols())]602row1[j] = 0603row1[-1] = 0604row2[j] = 1605row2[-1] = 1606GGG.split_vertex(i, row1, row2)607GGG.M[-2, -6081] += (x - 1) * X609answer.append(610(num_of_stratum(GGG, g, r, new_markings, moduli_type), -1))611if not from_small:612if G.M[i, j][0] == 2:613if G.M[i, j][1] >= 1 or G.M[i, j][2] >= 1:614x = G.M[i, j][1]615y = G.M[i, j][2]616row1 = [GG.M[i, k] for k in range(GG.M.ncols())]617row2 = [0 for k in range(GG.M.ncols())]618row1[j] = 0619row1[-1] = 0620row2[j] = 1621row2[-1] = 1622if y >= 1:623row1[j] = 1 + x * X624GGG = Graph(GG.M)625GGG.split_vertex(i, row1, row2)626GGG.M[-2, -6271] += (y - 1) * X628answer.append(629(num_of_stratum(GGG, g, r, new_markings, moduli_type), -1))630if x >= 1:631row1[j] = 1 + y * X632GGG = Graph(GG.M)633GGG.split_vertex(i, row1, row2)634GGG.M[-2, -6351] += (x - 1) * X636answer.append(637(num_of_stratum(GGG, g, r, new_markings, moduli_type), -1))638return answer639640641