275 lines
10 KiB
Python
275 lines
10 KiB
Python
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 \prod_{i=1}^h h_i^{n_i} \prod_{j=1}^h k_j f z^2
|
|
+ \prod_{i=1}^h h_i \prod_{j=1}^h k_j^{m_j} g,
|
|
|
|
where :math:`f, g, h_i, k_j` are polynomials in two variables,
|
|
and :math:`n_i > 1, m_j \geq 1`.
|
|
|
|
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
|
|
|
|
- ``Vhs`` -- a list of tuple whose elements are tuples `(h_i, n_i)`
|
|
|
|
- ``Vks`` -- a list of tuple whose elements are tuples `(k_j, m_j)`
|
|
|
|
- ``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`
|
|
|
|
- ``Nhs`` -- a list of tuple whose elements are tuples, the first element
|
|
is the vector in :math:`\mathbb{Z}^n` of the multiplicities for
|
|
the total transform of :math:`h_i` and the second is :math:`n_i`
|
|
|
|
- ``Nks`` -- a list of tuple whose elements are tuples, the first element
|
|
is the vector in :math:`\mathbb{Z}^n` of the multiplicities for
|
|
the total transform of :math:`k_j` and the second is :math:`m_j`
|
|
|
|
- ``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.<x, y, z> = 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.<x, y, z> = 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
|