Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download
180 views
unlisted
ubuntu2004
1
# -*- coding: utf-8 -*-
2
r"""
3
Chern character of the derived pushforward of a line bundle `\O(D)` on
4
the universal curve C_{g,n} over the space Mbar_{g,n} of stable curves via
5
the Grothendieck-Riemann-Roch (GRR) formula.
6
7
The algorithm implemented is the formula of Theorem 1 from the paper [PRvZ20]_ of
8
Pagani, Ricolfi and van Zelm. The formula itself is in the function
9
``generalized_hodge_chern(l,d,a,dmax,g,n)`` where using the notation from [PRvZ20]_:
10
11
- ``l`` is the integer l from equation (0.1)
12
- ``d`` is a list [d_1,...,d_n]
13
- ``a`` is a list of triples [h,S,a_{h,S}], where h is an integer and S a list
14
so that [h,S] indicates the graph with two vertices and one edge with genus h
15
on the left and markings S on the left. The integer a_{h,S} is the
16
corresponding value to this graph from equation (0.1). Only the graphs with
17
nonzero a_{h,S} need to be entered.
18
19
- ``dmax`` is the maximal codim to which we want to compute the formula of Theorem 1.
20
- ``g`` and ``n`` are respectively the genus and the number of marked points
21
22
As described in the paper [PRvZ20]_ this can be used to compute the DR cycle in
23
certain cases (namely when (d=[0,...,\pm 1,...,\mp 1,...,0]). The DR cycle can
24
be computed directly in this case by
25
26
DR_phi(g,d)
27
28
The DR cycle can also be computed using [JPPZ17]_. This method has already been
29
implemented in admcycles.sage as DR_cycle(g,d). To verify that the methods give
30
the same result modulo Pixton relations one can type:
31
32
(DR_phi(g,d) - DR_cycle(g,d)).is_zero()
33
34
We verified that these classes are the same for d=[1,-1] and g=1,2,3,4. For
35
higher values of g the computation takes too long. Note that in the case of
36
g=4 these are codimension 4 classes. The ring R^4(M_4,2) is generated by 3990
37
distinct decorated stratum classes, so this is a serious check on the
38
correctness of these formula's. Note also that the two methods do not give the
39
same result if we do not mod out by Pixton relations. i.e.
40
41
(DR_phi(g,d) - DR_cycle(g,d)).simplify()
42
43
is not zero.
44
"""
45
import operator
46
47
from .admcycles import tautclass, decstratum, stgraph, psicl, kappacl, psiclass, kappaclass
48
from .admcycles import chern_char_to_poly, chern_char_to_class, fundclass
49
50
from sage.rings.all import ZZ, QQ
51
from sage.matrix.constructor import matrix
52
from sage.misc.misc import powerset
53
from sage.misc.misc_c import prod
54
from sage.arith.all import bernoulli, binomial, multinomial
55
from sage.combinat.all import bernoulli_polynomial, IntegerVectors
56
57
58
def divided_bernoulli(n):
59
"""
60
Return Bernoulli number of index ``n`` divided by ``n!``.
61
62
EXAMPLES::
63
64
sage: from admcycles import *
65
sage: from admcycles.GRRcomp import *
66
sage: divided_bernoulli(12)
67
-691/1307674368000
68
"""
69
return bernoulli(n) / ZZ(n).factorial()
70
71
72
def divided_bernoulli_polynomial(l, n):
73
"""
74
Return Bernoulli polynomial of index ``n`` at ``l``, divided by ``n!``.
75
76
EXAMPLES::
77
78
sage: from admcycles import *
79
sage: from admcycles.GRRcomp import *
80
sage: x = polygen(QQ,'x')
81
sage: divided_bernoulli_polynomial(x,4)
82
1/24*x^4 - 1/12*x^3 + 1/24*x^2 - 1/720
83
"""
84
return bernoulli_polynomial(l, n) / ZZ(n).factorial()
85
86
87
def handle_g_n(g, n):
88
"""
89
Helper function that fetches the global ``g`` and ``n`` parameters.
90
91
See also :func:`admcycles.reset_g_n`.
92
93
The global ``g`` and ``n`` should rather be replaced by the creation
94
of an object ``MMbar(g, n)`` with attributes ``g`` and ``n``.
95
"""
96
if g is None:
97
from .admcycles import g
98
if n is None:
99
from .admcycles import n
100
return g, n
101
102
103
def generalized_hodge_chern(l, d, a, dmax=None, g=None, n=None):
104
r"""
105
Computes the Chern character of the derived pushforward of a line bundle \O(D) on
106
the universal curve C_{g,n} over the space Mbar_{g,n} of stable curves.
107
108
A divisor D on C_{g,n} up to pullbacks from Mbar_{g,n} takes the form
109
110
D = l \tilde{K} + sum_{i=1}^n d_i \sigma_i + \sum_{h,S} a_{h,S} C_{h,S}
111
112
where the numbers l, d_i and a_{h,S} are integers, \tilde{K} is the relative canonical
113
class of the morphism C_{g,n} -> Mbar_{g,n}, \sigma_i is the image of the ith section
114
and C_{h,S} is the boundary divisor of C_{g,n} where the moving point lies on a genus h
115
component with markings given by the set S.
116
For such a divisor this function computes the Chern character
117
118
ch(R^\bullet \pi_* \O(D))
119
120
up to codimension dmax using the formula given in [PRvZ20]_.
121
122
NOTE: This formula assumes that the number n of marked points is at least 1.
123
124
INPUT:
125
126
l : integer
127
the coefficient in front of \tilde{K}
128
d : list
129
vector of integers (d_1,...,d_n)
130
a : list
131
list of triples [h,S,a_{h,S}] where a_{h,S} is nonzero (and S is a subset of [1,...,n] )
132
dmax : integer
133
maximum codimension, set to 3g+3-n by default
134
g : integer
135
genus
136
n : integer
137
number of markings, for the formula to be correct we need at least one
138
139
EXAMPLES::
140
141
sage: from admcycles import *
142
sage: from admcycles.GRRcomp import *
143
sage: g=1;n=2
144
sage: l=0;d=[1,-1];a=[[1,[],-1]]
145
sage: generalized_hodge_chern(l,d,a,1,g,n)
146
Graph : [1] [[1, 2]] []
147
Polynomial : 1/12*(kappa_1)_0 - 13/12*psi_1 - 1/12*psi_2
148
<BLANKLINE>
149
Graph : [0] [[4, 5, 1, 2]] [(4, 5)]
150
Polynomial : 1/24
151
<BLANKLINE>
152
Graph : [0, 1] [[1, 2, 4], [5]] [(4, 5)]
153
Polynomial : -11/12
154
"""
155
g, n = handle_g_n(g, n)
156
if dmax is None:
157
dmax = 3 * g - 3 + n
158
159
return sum(generalized_hodge_chern_single(t, l, d, a, g, n) for t in range(1, dmax + 1))
160
161
162
def generalized_hodge_chern_single(t, l, d, a, g=None, n=None):
163
r"""
164
Computes the degree t part of the Chern character of the derived pushforward of a line
165
bundle \O(D) on the universal curve C_{g,n} over the space Mbar_{g,n} of stable curves.
166
167
A divisor D on C_{g,n} up to pullbacks from Mbar_{g,n} takes the form
168
169
D = l \tilde{K} + sum_{i=1}^n d_i \sigma_i + \sum_{h,S} a_{h,S} C_{h,S}
170
171
where the numbers l, d_i and a_{h,S} are integers, \tilde{K} is the relative canonical
172
class of the morphism C_{g,n} -> Mbar_{g,n}, \sigma_i is the image of the ith section
173
and C_{h,S} is the boundary divisor of C_{g,n} where the moving point lies on a genus h
174
component with markings given by the set S.
175
For such a divisor this function computes the degree t part
176
177
ch_t(R^\bullet \pi_* \O(D))
178
179
of the Chern character of R^\bullet \pi_* \O(D) using the formula given in
180
[PRvZ20]_.
181
182
NOTE: This formula assumes that the number n of marked points is at least 1.
183
184
EXAMPLES::
185
186
sage: from admcycles import *
187
sage: from admcycles.GRRcomp import *
188
sage: l=0; d=[1,-1]; a=[[1,[],-1]]
189
sage: generalized_hodge_chern_single(1, l, d, a, 1, 2)
190
Graph : [1] [[1, 2]] []
191
Polynomial : 1/12*(kappa_1)_0 - 13/12*psi_1 - 1/12*psi_2
192
<BLANKLINE>
193
Graph : [0] [[4, 5, 1, 2]] [(4, 5)]
194
Polynomial : 1/24
195
<BLANKLINE>
196
Graph : [0, 1] [[1, 2, 4], [5]] [(4, 5)]
197
Polynomial : -11/12
198
199
TESTS::
200
201
sage: reset_g_n(1, 2)
202
doctest:...: DeprecationWarning: reset_g_n is deprecated. Please use TautologicalRing instead.
203
See https://gitlab.com/modulispaces/admcycles/-/merge_requests/109 for details.
204
sage: generalized_hodge_chern_single(1, l, d, a)
205
Graph : [1] [[1, 2]] []
206
Polynomial : 1/12*(kappa_1)_0 - 13/12*psi_1 - 1/12*psi_2
207
<BLANKLINE>
208
Graph : [0] [[4, 5, 1, 2]] [(4, 5)]
209
Polynomial : 1/24
210
<BLANKLINE>
211
Graph : [0, 1] [[1, 2, 4], [5]] [(4, 5)]
212
Polynomial : -11/12
213
"""
214
g, n = handle_g_n(g, n)
215
if n == 0:
216
raise ValueError('There needs to be at least one marked point for generalized_hodge_chern_single to work')
217
218
a.sort(key=operator.itemgetter(1, 2)) # Order a to our convention
219
result = generalized_hodge_chern_K(t, l, a, g, n) + generalized_hodge_chern_S(t, l,
220
d, a, g, n) + todd_inv_exp(a, t, g, n) # -generalized_hodge_chern_exp(t,a,g,n)
221
result = result.degree_part(t)
222
result.simplify()
223
return result
224
225
226
def todd_inv_exp(a, t, g=None, n=None):
227
"""
228
EXAMPLES::
229
230
sage: from admcycles import *
231
sage: from admcycles.GRRcomp import *
232
sage: todd_inv_exp([],1,1,2)
233
Graph : [0] [[4, 5, 1, 2]] [(4, 5)]
234
Polynomial : 1/24
235
<BLANKLINE>
236
Graph : [0, 1] [[1, 2, 4], [5]] [(4, 5)]
237
Polynomial : 1/12
238
"""
239
g, n = handle_g_n(g, n)
240
a.sort(key=operator.itemgetter(1, 2)) # Order a to our convention
241
result = tautclass([], g, n)
242
for t1 in range(1, t, 2):
243
coeff_t1 = divided_bernoulli(t1 + 1) / ZZ(t - t1).factorial()
244
for tvect in IntegerVectors(t - t1, len(a)):
245
result += coeff_t1 * prod(ai[2]**tvecti for ai, tvecti in zip(a, tvect)) * \
246
multinomial(tvect) * todd_inv_exp_graphs(a, t1, tvect, g, n)
247
result += todd_inv_sigma(t, g, n)
248
return result
249
250
251
##
252
# The case without the graphs
253
def todd_inv_sigma(t, g, n):
254
if t % 2 == 0:
255
return tautclass([], g, n)
256
257
if n > 0:
258
seprange = [[h, [1] + s] for h in range(g + 1) for s in powerset(range(2, n + 1))
259
if not (h == 0 and not s) and not (h == g and len(s) > n - 3)]
260
else:
261
seprange = [[h, []] for h in range(1, g // 2 + 1)]
262
# The list [h,S] of possible nonisomorphic irreducible codimension 1 graphs
263
decsum = sum((-psicl(n + 1, n + 2))**i * psicl(n + 2, n + 2)**(t - 1 - i) for i in range(t)) # The decoration
264
tautclass1 = tautclass([decstratum(stgraph([g - 1], [list(range(1, n + 3))],
265
[(n + 1, n + 2)]), poly=decsum)], g, n) # The irreducible graph
266
tautclass2 = sum(tautclass([decstratum(stgraph([ahS[0], g - ahS[0]], [ahS[1] + [n + 1], list(set(range(1, n + 1)) - set(
267
ahS[1])) + [n + 2]], [(n + 1, n + 2)]), poly=decsum)], g, n) for ahS in seprange) # The separating graphs
268
269
result = divided_bernoulli(t + 1) * (QQ((1, 2)) * tautclass1 + tautclass2)
270
result = result.degree_part(t)
271
result.simplify()
272
return result
273
274
275
##
276
# The graphs in the sigma part
277
def todd_inv_exp_graphs(a, t1, tvect, g, n):
278
r"""
279
TESTS:
280
281
We check that https://gitlab.com/modulispaces/admcycles/-/merge_requests/149 does not reappear::
282
283
sage: from admcycles.GRRcomp import todd_inv_exp_graphs
284
sage: len(todd_inv_exp_graphs([[1, [1], -1]], 1, [1], 3, 2)._terms) == 5
285
True
286
"""
287
# assume a is ordered
288
tvn = [tvi for tvi in tvect if tvi != 0]
289
atn = [ai for ai, tvi in zip(a, tvect) if tvi != 0]
290
L = len(tvn)
291
result = 0 * fundclass(g, n)
292
if all(atn[i][0] <= atn[i + 1][0] and atn[i][1] <= atn[i + 1][1]
293
for i in range(L - 1)):
294
# restrict to the case nonzero elements of tvect give a ordered sequence in a (i.e. each element smaller than or equal to the next).
295
296
Snc = list(powerset(set(range(1, n + 1)) - set(atn[-1][1]))) # Powerset of complement of Sn
297
298
# The sum of different graphs (bigger than or equal (hn,Sn))
299
for h in range(atn[-1][0], g + 1):
300
for S in Snc:
301
# the strictly bigger ones:
302
if not (h == atn[-1][0] and not S) and not (h == g and n - len(atn[-1][1]) - len(S) < 2):
303
vertices = [atn[0][0]] + [atn[i][0] - atn[i - 1][0]
304
for i in range(1, L)] + [h - atn[-1][0]] + [g - h]
305
labels = [atn[0][1] + [n + 1]] + [list(set(atn[i][1]) - set(atn[i - 1][1])) + [n + 2 * i, n + 2 * i + 1] for i in range(1, L)] + [list(
306
set(S) - set(atn[-1][1])) + [n + 2 * L, n + 2 * L + 1]] + [list(set(range(1, n + 1)) - set(atn[-1][1]) - set(S)) + [n + 2 * L + 2]]
307
involution = [(n + 2 * i + 1, n + 2 * i + 2) for i in range(L + 1)]
308
graph = stgraph(vertices, labels, involution)
309
psi = prod([sum([binomial(tvn[i] - 1, j) * (-1)**(tvn[i] - 1) * psicl(n + 2 * i + 1, n + 2 * L + 2)**j * psicl(n + 2 * i + 2, n + 2 * L + 2)**(tvn[i] - 1 - j) for j in range(tvn[i])]) for i in range(L)] + [sum(
310
[(-psicl(n + 2 * L + 1, n + 2 * L + 2))**j * psicl(n + 2 * L + 2, n + 2 * L + 2)**(t1 - 1 - j) for j in range(t1)])]) # psi class of graph coinciding graphs. Note last one in a is only on one side and to the power of a[-1].
311
result += tautclass([decstratum(graph, poly=psi)], g, n)
312
313
# the case where they are equal
314
if (h == atn[-1][0] and not S):
315
vertices = [atn[0][0]] + [atn[i][0] - atn[i - 1][0] for i in range(1, L)] + [g - atn[-1][0]]
316
labels = [atn[0][1] + [n + 1]] + [list(set(atn[i][1]) - set(atn[i - 1][1])) + [n + 2 * i, n + 2 * i + 1]
317
for i in range(1, L)] + [list(set(range(1, n + 1)) - set(atn[-1][1])) + [n + 2 * L]]
318
involution = [(n + 2 * i + 1, n + 2 * i + 2) for i in range(L)]
319
graph = stgraph(vertices, labels, involution)
320
psi = prod([sum([binomial(tvn[i] - 1, j) * (-1)**(tvn[i] - 1) * psicl(n + 2 * i + 1, n + 2 * L)**j * psicl(n + 2 * i + 2, n + 2 * L)**(tvn[i] - 1 - j) for j in range(tvn[i])])
321
for i in range(L - 1)] + [(-psicl(n + 2 * L - 1, n + 2 * L))**(tvn[-1])] + [sum([(-psicl(n + 2 * L - 1, n + 2 * L))**j * psicl(n + 2 * L, n + 2 * L)**(t1 - 1 - j) for j in range(t1)])])
322
result += tautclass([decstratum(graph, poly=psi)], g, n)
323
324
# The case of the irreducible graph in Sigma:
325
if g - atn[-1][0] > 0:
326
vertices = [atn[0][0]] + [atn[i][0] - atn[i - 1][0] for i in range(1, L)] + [g - atn[-1][0] - 1]
327
labels = [atn[0][1] + [n + 1]] + [list(set(atn[i][1]) - set(atn[i - 1][1])) + [n + 2 * i, n + 2 * i + 1] for i in range(
328
1, L)] + [list(set(range(1, n + 1)) - set(atn[-1][1])) + [n + 2 * L, n + 2 * L + 1, n + 2 * L + 2]]
329
involution = [(n + 2 * i + 1, n + 2 * i + 2) for i in range(L + 1)]
330
graph = stgraph(vertices, labels, involution)
331
psi = prod([sum([binomial(tvn[i] - 1, j) * (-1)**(tvn[i] - 1) * psicl(n + 2 * i + 1, n + 2 * L + 2)**j * psicl(n + 2 * i + 2, n + 2 * L + 2)**(tvn[i] - 1 - j)
332
for j in range(tvn[i])]) for i in range(L)] + [sum([(-psicl(n + 2 * L + 1, n + 2 * L + 2))**j * psicl(n + 2 * L + 2, n + 2 * L + 2)**(t1 - 1 - j) for j in range(t1)])])
333
result += QQ((1, 2)) * tautclass([decstratum(graph, poly=psi)], g, n)
334
return result
335
##
336
##
337
338
339
def generalized_hodge_chern_exp(t, a, g=None, n=None): # The exponential e^C
340
g, n = handle_g_n(g, n)
341
# a.sort(key=operator.itemgetter(1,2)) ## Order a to our convention
342
result = tautclass([], g, n)
343
# loop on Partition of t+1 over elements of ChS, assume a is ordered
344
for tvect in IntegerVectors(t + 1, len(a)):
345
tvn = [tvi for tvi in tvect if tvi != 0]
346
atn = [ai for ai, tvi in zip(a, tvect) if tvi != 0]
347
L = len(tvn)
348
Scomp = list(set(range(1, n + 1)) - set(atn[-1][1]))
349
if all(atn[i][0] <= atn[i + 1][0] and atn[i][1] <= atn[i + 1][1] for i in range(L - 1)) and tvn[-1] > 1:
350
vertices = [atn[0][0]] + [atn[i][0] - atn[i - 1][0] for i in range(1, L)] + [g - atn[-1][0]]
351
labels = [atn[0][1] + [n + 1]] + [list(set(atn[i][1]) - set(atn[i - 1][1])) +
352
[n + 2 * i, n + 2 * i + 1] for i in range(1, L)] + [Scomp + [n + 2 * L]]
353
involution = [(n + 2 * i + 1, n + 2 * i + 2) for i in range(L)]
354
graph = stgraph(vertices, labels, involution)
355
psi = prod([atn[i][2]**tvn[i] * (-1)**(tvn[i] - 1) *
356
sum([binomial(tvn[i] - 1, j) * psicl(n + 2 * i + 1, n + 2 * L)**j * psicl(n + 2 * i + 2, n + 2 * L)**(tvn[i] - 1 - j) for j in range(tvn[i])]) for i in range(L - 1)] +
357
[atn[-1][2]**tvn[-1] * (-1)**(tvn[-1] - 1) *
358
sum([binomial(tvn[-1] - 1, j) * psicl(n + 2 * L - 1, n + 2 * L)**j * psicl(n + 2 * L, n + 2 * L)**(tvn[-1] - 1 - j - 1) for j in range(tvn[-1] - 1)])])
359
result += multinomial(tvn) * tautclass([decstratum(graph, poly=psi)], g, n)
360
return ZZ.one() / ZZ(t + 1).factorial() * result
361
362
363
def generalized_hodge_chern_K(t, l, a, g, n): # The thing with K
364
result = tautclass([], g, n)
365
for alpha in range(t + 2):
366
beta = t + 1 - alpha
367
result += (divided_bernoulli_polynomial(l, beta) / ZZ(alpha).factorial()) * \
368
generalized_hodge_chern_Kin(alpha, beta, a, g, n)
369
return result
370
371
372
def generalized_hodge_chern_S(t, l, d, a, g, n): # The thing with sigma
373
result = tautclass([], g, n)
374
for alpha in range(t + 1):
375
beta = t + 1 - alpha
376
for p in range(1, n + 1):
377
result += sum(((-1)**b * d[p - 1]**(beta - b) * divided_bernoulli_polynomial(l, b) / (ZZ(alpha).factorial() * ZZ(
378
beta - b).factorial())) * generalized_hodge_chern_Sin(alpha, beta, p, a, g, n) for b in range(beta + 1))
379
return result
380
381
382
def generalized_hodge_chern_Kin(alpha, beta, a, g, n):
383
if beta == 0:
384
return ZZ(alpha).factorial() * generalized_hodge_chern_exp(alpha - 1, a, g, n)
385
if alpha == 0:
386
return kappaclass(beta - 1, g, n)
387
result = tautclass([], g, n)
388
# Partition of t+1 over elements of ChS, assume a is ordered
389
for tvect in IntegerVectors(alpha, len(a)):
390
tvn = [tvi for tvi in tvect if tvi != 0]
391
atn = [ai for ai, tvi in zip(a, tvect) if tvi != 0]
392
L = len(tvn)
393
Scomp = list(set(range(1, n + 1)) - set(atn[-1][1]))
394
if all(atn[i][0] <= atn[i + 1][0] and atn[i][1] <= atn[i + 1][1]
395
for i in range(L - 1)):
396
vertices = [atn[0][0]] + [atn[i][0] - atn[i - 1][0] for i in range(1, L)] + [g - atn[-1][0]]
397
labels = [atn[0][1] + [n + 1]] + [list(set(atn[i][1]) - set(atn[i - 1][1])) +
398
[n + 2 * i, n + 2 * i + 1] for i in range(1, L)] + [Scomp + [n + 2 * L]]
399
involution = [(n + 2 * i + 1, n + 2 * i + 2) for i in range(L)]
400
graph = stgraph(vertices, labels, involution)
401
psi = prod([atn[i][2]**tvn[i] * (-1)**(tvn[i] - 1) * sum([binomial(tvn[i] - 1, j) * psicl(n + 2 * i + 1, n + 2 * L)
402
** j * psicl(n + 2 * i + 2, n + 2 * L)**(tvn[i] - 1 - j) for j in range(tvn[i])]) for i in range(L)])
403
kappa = kappacl(L, beta - 1, L + 1, g - atn[-1][0], len(Scomp) + 1)
404
result += multinomial(tvn) * tautclass([decstratum(graph, poly=kappa * psi)], g, n)
405
return result
406
407
408
def generalized_hodge_chern_Sin(alpha, beta, p, a, g, n):
409
if beta == 0:
410
return ZZ(alpha).factorial() * generalized_hodge_chern_exp(alpha - 1, a, g, n)
411
if alpha == 0:
412
return (-psiclass(p, g, n))**(beta - 1)
413
result = tautclass([], g, n)
414
# Partition of t+1 over elements of ChS, assume a is ordered
415
for tvect in IntegerVectors(alpha, len(a)):
416
tvn = [tvi for tvi in tvect if tvi != 0]
417
atn = [ai for ai, tvi in zip(a, tvect) if tvi != 0]
418
L = len(tvn)
419
Scomp = list(set(range(1, n + 1)) - set(atn[-1][1]))
420
if all(atn[i][0] <= atn[i + 1][0] and atn[i][1] <= atn[i + 1][1]
421
for i in range(L - 1)) and p in Scomp:
422
vertices = [atn[0][0]] + [atn[i][0] - atn[i - 1][0] for i in range(1, L)] + [g - atn[-1][0]]
423
labels = [atn[0][1] + [n + 1]] + [list(set(atn[i][1]) - set(atn[i - 1][1])) +
424
[n + 2 * i, n + 2 * i + 1] for i in range(1, L)] + [Scomp + [n + 2 * L]]
425
involution = [(n + 2 * i + 1, n + 2 * i + 2) for i in range(L)]
426
graph = stgraph(vertices, labels, involution)
427
psi = prod([atn[i][2]**tvn[i] * (-1)**(tvn[i] - 1) * sum([binomial(tvn[i] - 1, j) * psicl(n + 2 * i + 1, n + 2 * L)**j * psicl(n + 2 *
428
i + 2, n + 2 * L)**(tvn[i] - 1 - j) for j in range(tvn[i])]) for i in range(L)] + [(-1)**(beta - 1) * psicl(p, n + 2 * L)**(beta - 1)])
429
result += multinomial(tvn) * tautclass([decstratum(graph, poly=psi)], g, n)
430
return result
431
432
433
def twist_div_to_zero(l, d, g=None, n=None):
434
"""
435
INPUT:
436
437
- l -- integer
438
439
- d -- list of integers (d_1,...,d_n)
440
441
EXAMPLES::
442
443
sage: from admcycles import *
444
sage: from admcycles.GRRcomp import *
445
sage: twist_div_to_zero(3,[3,4],2,2)
446
[[0, [1, 2], -10], [1, [1], -9], [1, [1, 2], -16]]
447
"""
448
g, n = handle_g_n(g, n)
449
seprange = ([h, [1] + s] for h in range(g + 1)
450
for s in powerset(range(2, n + 1))
451
if (h != 0 or s) and (h != g or len(s) <= n - 3))
452
a = []
453
for hS0, hS1 in seprange:
454
ahS = -l * (2 * hS0 - 2 + len(hS1) + 1) - sum(d[p - 1] for p in hS1)
455
if ahS != 0:
456
a.append([hS0, hS1, ahS])
457
return a
458
459
460
def generalized_lambda(deg, l, d, a, g=None, n=None):
461
r"""
462
Computes the Chern class c_deg of the derived pushforward of a line
463
bundle \O(D) on the universal curve C_{g,n} over the space Mbar_{g,n} of stable curves.
464
465
A divisor D on C_{g,n} up to pullbacks from Mbar_{g,n} takes the form
466
467
D = l \tilde{K} + sum_{i=1}^n d_i \sigma_i + \sum_{h,S} a_{h,S} C_{h,S}
468
469
where the numbers l, d_i and a_{h,S} are integers, \tilde{K} is the relative canonical
470
class of the morphism C_{g,n} -> Mbar_{g,n}, \sigma_i is the image of the ith section
471
and C_{h,S} is the boundary divisor of C_{g,n} where the moving point lies on a genus h
472
component with markings given by the set S.
473
For such a divisor this function computes the Chern class
474
475
c_deg(R^\bullet \pi_* \O(D))
476
477
of the derived pushforward R^\bullet \pi_* \O(D) using the formula given in
478
[PRvZ20]_. When l=1, d=[0,...,0] and a=[] this coincides with the lambda class.
479
480
NOTE: This formula assumes that the number n of marked points is at least 1.
481
482
INPUT:
483
484
deg : integer
485
degree of the chern class
486
l : integer
487
the coefficient in front of \tilde{K}
488
d : list
489
vector of integers (d_1,...,d_n)
490
a : list
491
list of triples [h,S,a_{h,S}] where a_{h,S} is nonzero (and S is a subset of [1,...,n] )
492
g : integer
493
genus
494
n : integer
495
number of markings, for the formula to work we need n > 0
496
497
498
EXAMPLES::
499
500
sage: from admcycles import *
501
sage: from admcycles.GRRcomp import *
502
sage: l = 1; d = [0]; a = []
503
sage: t = generalized_lambda(1,l,d,a,2,1);t
504
Graph : [2] [[1]] []
505
Polynomial : 1/12*(kappa_1)_0 - 1/12*psi_1
506
<BLANKLINE>
507
Graph : [1] [[3, 4, 1]] [(3, 4)]
508
Polynomial : 1/24
509
<BLANKLINE>
510
Graph : [1, 1] [[3], [1, 4]] [(3, 4)]
511
Polynomial : 1/12
512
sage: t.basis_vector()
513
(1/2, -1/2, -1/2)
514
515
We can verify that this computes the lambda class when l=1, d=[0,...,0] and
516
a=[]. We do this for lambda_2 in \barM_3,1::
517
518
sage: from admcycles import *
519
sage: from admcycles.GRRcomp import *
520
sage: reset_g_n(3, 1)
521
doctest:...: DeprecationWarning: reset_g_n is deprecated. Please use TautologicalRing instead.
522
See https://gitlab.com/modulispaces/admcycles/-/merge_requests/109 for details.
523
sage: l = 1; d = [0]; a = []
524
sage: s = lambdaclass(2)
525
doctest:...: DeprecationWarning: Use of lambdaclass without specifying g,n is deprecated.
526
See https://gitlab.com/modulispaces/admcycles/-/merge_requests/109 for details.
527
sage: t = generalized_lambda(2, l, d, a)
528
sage: (s-t).simplify()
529
0
530
"""
531
g, n = handle_g_n(g, n)
532
533
def chclass(m):
534
return generalized_hodge_chern_single(m, l, d, a, g, n)
535
536
chpoly = chern_char_to_poly(chclass, deg, g, n).degree_part(deg)
537
chpoly.simplify()
538
return chpoly
539
540
541
def DR_phi(g, d):
542
r"""
543
Computes the double ramification cycle DR(g,d) in the case d=[0,...,\pm
544
1,...,\mp 1,...,0] as described in the paper [PRvZ20]_.
545
546
Input:
547
548
g : integer
549
the genus
550
d : vector
551
the vector d
552
553
EXAMPLES::
554
555
sage: from admcycles import *
556
sage: from admcycles.GRRcomp import *
557
sage: DR_phi(1, [1,-1])
558
Graph : [1] [[1, 2]] []
559
Polynomial : -1/12*(kappa_1)_0 + 13/12*psi_1 + 1/12*psi_2
560
<BLANKLINE>
561
Graph : [0] [[4, 5, 1, 2]] [(4, 5)]
562
Polynomial : -1/24
563
<BLANKLINE>
564
Graph : [0, 1] [[1, 2, 4], [5]] [(4, 5)]
565
Polynomial : -1/12
566
567
The different ways of computing the DR cycle coincide when d is of the form
568
[0,...,\pm 1,...,\mp 1,...,0]::
569
570
sage: from admcycles import *
571
sage: from admcycles.GRRcomp import *
572
sage: g = 2; d = [1,-1]
573
sage: (DR_phi(g,d) - DR_cycle(g,d)).is_zero()
574
True
575
576
But not for other values of d::
577
578
sage: from admcycles import *
579
sage: from admcycles.GRRcomp import *
580
sage: g = 1; d = [2,0]
581
sage: (DR_phi(g,d)-DR_cycle(g,d)).FZsimplify()
582
Graph : [1] [[1, 2]] []
583
Polynomial : -(kappa_1)_0 + 4*psi_1
584
585
On the locus of compact type curves we have equality for all vectors d where
586
the entries sum to 0.::
587
588
sage: from admcycles import *
589
sage: from admcycles.GRRcomp import *
590
sage: g = 2; d = [2,-2]
591
sage: (DR_cycle(g,d) - DR_phi(g,d)).basis_vector()
592
(12, -4, 14, 7, -40, -10, -14, -12, 28, -4, 6, -1, 4, 0)
593
sage: (DR_cycle(g,d) - DR_phi(g,d)).toTautbasis(moduli='ct')
594
doctest:...: DeprecationWarning: toTautbasis is deprecated. Please use basis_vector instead.
595
See https://gitlab.com/modulispaces/admcycles/-/merge_requests/109 for details.
596
(0, 0, 0, 0, 0)
597
"""
598
n = len(d)
599
a = twist_div_to_zero(0, d, g, n)
600
return chern_char_to_class(g, -generalized_hodge_chern(0, d, a, g, g, n))
601
602
603
def DR_phi1(g, d):
604
r"""
605
Alternative to DR_phi using chern_char_to_poly, but this takes a lot longer, kept here
606
only for testing purposes.
607
608
TESTS::
609
610
sage: from admcycles.GRRcomp import DR_phi, DR_phi1
611
sage: D1 = DR_phi(2, [1, -1])
612
sage: D2 = DR_phi1(2, [1, -1])
613
sage: (D1 - D2).is_empty()
614
True
615
"""
616
n = len(d)
617
a = twist_div_to_zero(0, d, g, n)
618
619
def chclass(m):
620
temp = generalized_hodge_chern_single(m, 0, d, a, g, n)
621
temp.simplify()
622
return temp
623
624
chpoly = chern_char_to_poly(chclass, g, g, n).degree_part(g)
625
chpoly.simplify()
626
return chpoly
627
628
629
def hodge_chern_class_matrix(char, p, q, g=None, n=None):
630
g, n = handle_g_n(g, n)
631
c = [chern_char_to_class(t, char, g, n) for t in range(q - p + 1, q + p)]
632
return matrix([[c[i + p - 1 - j] for i in range(p)] for j in range(p)])
633
634
635
def generalized_brill_noether_class(r, deg, l, d, a, g=None, n=None):
636
g, n = handle_g_n(g, n)
637
p = r + 1
638
q = g - deg + r
639
char = tautclass([], g, n) + generalized_hodge_chern(l, d, a, q + p - 1, g, n)
640
return hodge_chern_class_matrix(char, p, q, g, n).det()
641
642