From b95ecd1f1d7769341c65520ad817b751201dc005 Mon Sep 17 00:00:00 2001 From: Enrique Artal Date: Thu, 7 Mar 2024 22:20:50 +0100 Subject: [PATCH] more general isolated surfaces --- zetas_triples_general.py | 256 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 256 insertions(+) create mode 100644 zetas_triples_general.py diff --git a/zetas_triples_general.py b/zetas_triples_general.py new file mode 100644 index 0000000..8699728 --- /dev/null +++ b/zetas_triples_general.py @@ -0,0 +1,256 @@ +def trinomiales_general(A, Vf, Vg, Vhs, Vks, Vd, total=True): + r""" + Return data necessary to compute the zeta functions of + a triple singularity defined by :math:`z^3 -3 f z^2 + 2 g`, where + :math:`f, g` are polynomials in two variables. + + We consider an embedded resolution of :math:`fg(f^3 - g^2)` with + a stratification of the exceptional divisor: + + - :math:`\check{E}_i`: the smooth part of the total divisor + + - :math:`E_i\cap E_j`: the double points of the divisor + + - :math:`E_i\cap \{f=0\}`: the intersections with the strict + transform of :math:`f` + + - :math:`E_i\cap \{g=0\}`: the intersections with the strict + transform of :math:`g` + + - :math:`E_i\cap \{f^3=g^2\}`: the intersections with the strict + transform of :math:`f^3-g^2` + + It is also possible to forget the strict transforms of :math:`f, g` + and even to consider only resolutions of :math:`f^3 - g^2`. + + INPUT: + + - ``A`` -- the incidence matrix of a resolution + + - ``Vf`` -- the vector with the intersection numbers of the strict + transform of :math:`f` with the divisors of the resolution + + - ``Vg`` -- the vector with the intersection numbers of the strict + transform of :math:`g` with the divisors of the resolution + + - ``Vd`` -- the vector with the intersection numbers of the strict + transform of :math:`f^3 - g^2` with the divisors of the resolution + + - ``total`` -- boolean (default: ``True``), whether we consider also + the strata corresponding to the strict transforms of :math:`f, g`. + + OUTPUT: + + Polynomials :math:`z^3 + M_1 z + M_0` or :math:`z^3 + M_2 z^2 + M_0` are + assigned to each strata. The monomials are of the form :math:`x^k` for the + smooth parts of the divisors and :math:`x^k y^l` for the double points. + Each variable is associated to a divisor or to a strict transform + + - ``n`` -- the number of irreducible components of the exceptional divisor + + - ``Nf`` -- the vector in :math:`\mathbb{Z}^n` of the multiplicities for + the total transform of :math:`f` + + - ``Ng`` -- the vector in :math:`\mathbb{Z}^n` of the multiplicities for + the total transform of :math:`g` + + - ``Nd`` -- the vector in :math:`\mathbb{Z}^n` of the multiplicities for + the total transform of :math:`f^3 - g^2` + + - ``euler`` -- the vector in :math:`\mathbb{Z}^n` of the Euler + characteristic of the smooth part of the strata. If ``total=True`` this + smooth part does not contain the intersections with total transform + of :math:`f, g` + + - ``nus`` -- the vector in :math:`\mathbb{Z}^n` of the canonical + multiplicities + + - ``pols`` -- a dictionary with keys ``(i, )``, ``(i, j)``, ``(i, 'f')`` + (if ``total=True``), ``(i, 'g')`` (if ``total=True``), and ``(i, 'd')`` + assigning the polynomial of the stratum (non-degenerated with respect + to its Newton polytope), the weights ``(nui, nuj, 1)`` coding + the form + :math:`x^{\nu_i-1}y^{\nu_j-1}\operatorname{d}\! x \operatorname{d}\! y \operatorname{d}\! z` + + EXAMPLES:: + + sage: R. = QQ[] + sage: f, g = (x, y) + sage: A = Matrix(QQ, 3, [-3, 0, 1, 0, -2, 1, 1, 1, -1]) + sage: Vf = vector(QQ, [1, 0, 0]) + sage: Vg = vector(QQ, [0, 1, 0]) + sage: Vd = vector(QQ, [0, 0, 1]) + sage: trinomiales(A, Vf, Vg, Vd) + (3, (1, 1, 2), (1, 2, 3), (2, 3, 6), (0, 0, -1), (2, 3, 5), + {(0, 'f'): (x + x*y*z + z^3, (2, 1, 1), 1), + (0, 2): (z^3 + x*y^3 + x*y^2*z, (2, 5, 1), 1), + (1, 'g'): (x*z + x^2*y + z^3, (3, 1, 1), 1), + (1, 2): (z^3 + x*y^2*z + x^2*y^3, (3, 5, 1), 1), + (2, 'd'): (x*z^2 + z^3 + x^3*y, (5, 1, 1), 1), + 0: (x + x*z + z^3, (2, 1, 1), 0), + 1: (x^2 + x*z + z^3, (3, 1, 1), 0), + 2: (x^3 + x^2*z + z^3, (5, 1, 1), -1)}) + sage: trinomiales(A, Vf, Vg, Vd, total=False) + (3, (1, 1, 2), (1, 2, 3), (2, 3, 6), (1, 1, -1), (2, 3, 5), + {(0, 2): (z^3 + x*y^3 + x*y^2*z, (2, 5, 1), 1), + (1, 2): (z^3 + x*y^2*z + x^2*y^3, (3, 5, 1), 1), + (2, 'd'): (x*z^2 + z^3 + x^3*y, (5, 1, 1), 1), + 0: (x + x*z + z^3, (2, 1, 1), 1), + 1: (x^2 + x*z + z^3, (3, 1, 1), 1), + 2: (x^3 + x^2*z + z^3, (5, 1, 1), -1)}) + """ + R = PolynomialRing(QQ, 'x, y, z', order='negdeglex') + x, y, z = R.gens() + n = A.nrows() + A1 = -A ** -1 + Nf, Ng, Nd = [A1 * N0 for N0 in (Vf, Vg, Vd)] + Nhs = [(A1 * N0, h) for N0, h in Vhs] + ch = len(Nhs) + Nks = [(A1 * N0, k) for N0, k in Vks] + ck = len(Nks) + NNf = Nf + sum(j * V0 for V0, j in Nhs) + sum(V0 for V0, j in Nks) + NNg = Ng + sum(j * V0 for V0, j in Nks) + sum(V0 for V0, j in Nhs) + NNd = Nd + 3 * sum(V0 for V0, j in Nks) + 2 * sum(V0 for V0, j in Nhs) + diag = vector(A.diagonal()) + unos = vector(n * [1]) + if total: + VV = Vf + Vg + else: + VV = Vf.parent()(0) + resta = VV + Vd + sum(V0 for V0, m in Vhs + Vks) + euler = (-A + 2 * identity_matrix(n)) * unos + diag - resta + nus = A1 * (diag + 2 * unos) + unos + expos = {} + for j in range(n): + a, b = (NNf[j], NNg[j]) + eq = 3 * a == 2 * NNg[j] + nnd = min(3 * a, 2 * b) == NNd[j] + if nnd: + expos[j] = ((a, b), (a / 2, b), nus[j], eq, nnd) + else: + expos[j] = ((a, b), (a / 2, NNd[j] - b), nus[j], eq, nnd) + cadenas = ('d', ) + cadenash = tuple(('h', h) for h in range(ch)) + cadenask = tuple(('k', k) for k in range(ck)) + if total: + expos['f'] = ((1, 0), (0, 0), 1, False, True) + expos['g'] = ((0, 1), (0, 0), 1, False, True) + cadenas = ('f', 'g') + cadenas + expos['d'] = ((0, 0), (0, 1), 1, True, False) + for h, V0 in enumerate(Vhs): + expos['h', h] = ((V0[1], 1), (0, 0), 1, False, True) + for k, V0 in enumerate(Vks): + expos['k', k] = ((1, V0[1]), (0, 0), 1, False, True) + pols = {} + for j in range(n): + if expos[j][-1]: + a, b = expos[j][0] + pols[j] = (z ** 3 + x ** a * z + x ** b, (expos[j][2], 1, 1), + euler[j]) + else: + a, b = expos[j][1] + pols[j] = (z ** 3 + x ** a * z ** 2 + x ** b, + (expos[j][2], 1, 1), euler[j]) + interdiv = [(i, j) for i, j in Combinations(n, 2) if A[i, j] != 0] + interstrict = [(i, j) for i in range(n) for j in cadenas + if eval('V' + j)[i] != 0] + interh = [(i, j) for i in range(n) for j in cadenash if Vhs[j[1]][0][i] != 0] + interk = [(i, j) for i in range(n) for j in cadenask if Vks[j[1]][0][i] != 0] + for i, j in interdiv + interstrict + interh + interk: + if isinstance(j, str): + ep = eval('V' + j)[i] + else: + ep = 1 + eqi, nndi = expos[i][-2:] + eqj, nndj = expos[j][-2:] + nd = eqi and eqj and not (nndi and nndj) + if not nd: + ai, bi = expos[i][0] + aj, bj = expos[j][0] + pols[i, j] = (z ** 3 + x ** ai * y ** aj * z + x ** bi * y ** bj, + (expos[i][2], expos[j][2], 1), ep) + else: + ai, bi = expos[i][1] + aj, bj = expos[j][1] + pols[i, j] = (z ** 3 + x ** ai * y ** aj * z ** 2 + + x ** bi * y ** bj, (expos[i][2], expos[j][2], 1), ep) + return n, Nf, Ng, Nd, Nhs, Nks, euler, nus, pols + + +def estrato(pol, pesos, euler, info=False): + r""" + Return the topological and Igusa zeta functions associated to a stratum + + INPUT: + + - ``pol`` -- a trinomial non degenerated with respect to its Newton + polyhedron + + - ``pesos`` -- the canonical weights :math:`\nu:i` + + - `euler`` -- the Euler characteristic of the stratum + + - ``info`` -- boolean (default: False), if ``True`` a dictionary giving + the powers of cyclotomic polynomials for the monodromy zeta function + is given + + EXAMPLES:: + + sage: R. = QQ[] + sage: F = z^3 + x^4 * y^6 * z + x^7 * y^9 + sage: estrato(F, (1, 1, 1), 1, info=True) + ((1/3*s^2 + 1/2*s + 2/9)/(s^3 + 35/18*s^2 + 7/6*s + 2/9), -t^3 + 1, + {1: 1, 3: 1}) + """ + Z1 = ZetaFunctions(pol) + zetatop = euler * Z1.topological_zeta(local=True, weights=pesos) + zetamon = Z1.monodromy_zeta() ** euler + if info: + dic = {} + for p, j in zetamon.factor(): + c = p.is_cyclotomic(certificate=True) + dic[c] = j + return zetatop, zetamon, dic + return zetatop, zetamon + + +def zetas(n, pols, info=False): + r""" + Return the topological and Igusa zeta functions from the data of + a stratification + + INPUT: + + - ``n`` -- the number of exceptional divisors + + - ``pols`` -- a dictionary from ``trinomiales`` + + - ``info`` -- boolean (default: False), if ``True`` a dictionary giving + the powers of cyclotomic polynomials for the monodromy zeta function + is given + + EXAMPLES:: + + sage: A = Matrix(QQ, 3, [-3, 0, 1, 0, -2, 1, 1, 1, -1]) + sage: Vf = vector(QQ, [1, 0, 0]) + sage: Vg = vector(QQ, [0, 1, 0]) + sage: Vd = vector(QQ, [0, 0, 1]) + sage: n, Nf, Ng, Nd, euler, nus, pols = trinomiales(A, Vf, Vg, Vd) + sage: zetas(n, pols, info=True) + (1/(s + 1), -t + 1, {1: 1}) + """ + zetatop = 0 + T = PolynomialRing(QQ, 't') + t = T.gen(0) + zetamon = 1 / (1 - t ** 3) ** n + for k in pols: + zt, zm = estrato(*pols[k]) + zetatop += zt + zetamon *= zm + if info: + dic = {} + for p, j in zetamon.factor(): + c = p.is_cyclotomic(certificate=True) + dic[c] = j + return zetatop, zetamon, dic + return zetatop, zetamon