1 | //////////////////////////////////////////////////////////////// |
---|
2 | version = "version goettsche.lib 0.931 Feb_2019 "; //$Id$ |
---|
3 | info=" |
---|
4 | LIBRARY: goettsche.lib Drezet's formula for the Betti numbers of the moduli space |
---|
5 | of Kronecker modules; |
---|
6 | Goettsche's formula for the Betti numbers of the Hilbert scheme |
---|
7 | of points on a surface; |
---|
8 | Nakajima's and Yoshioka's formula for the Betti numbers |
---|
9 | of the punctual Quot-schemes on a plane or, equivalently, |
---|
10 | of the moduli spaces of the framed torsion-free planar sheaves; |
---|
11 | Macdonald's formula for the symmetric product |
---|
12 | |
---|
13 | AUTHOR: Oleksandr Iena, o.g.yena@gmail.com |
---|
14 | |
---|
15 | REFERENCES: |
---|
16 | [1] Drezet, Jean-Marc Cohomologie des varie'te's de modules de hauter nulle. |
---|
17 | Mathematische Annalen: 281, 43-85, (1988). |
---|
18 | |
---|
19 | [2] Goettsche, Lothar, The Betti numbers of the Hilbert scheme of points |
---|
20 | on a smooth projective surface. |
---|
21 | Mathematische Annalen: 286, 193-208, (1990). |
---|
22 | |
---|
23 | [3] Macdonald, I. G., The Poincare polynomial of a symmetric product, |
---|
24 | Mathematical proceedings of the Cambridge Philosophical Society: |
---|
25 | 58, 563-568, (1962). |
---|
26 | |
---|
27 | [4] Nakajima, Hiraku; Lectures on instanton counting, CRM Proceedings and Lecture Notes, |
---|
28 | Yoshioka, Kota Volume 88, 31-101, (2004). |
---|
29 | |
---|
30 | PROCEDURES: |
---|
31 | GoettscheF(z, t, n, b); The Goettsche's formula up to n-th degree |
---|
32 | PPolyH(z, n, b); Poincare Polynomial of the Hilbert scheme of n points on a surface |
---|
33 | BettiNumsH(n, b); Betti numbers of the Hilbert scheme of n points on a surface |
---|
34 | NakYoshF(z, t, r, n); The Nakajima-Yoshioka formula up to n-th degree |
---|
35 | PPolyQp(z, n, b); Poincare Polynomial of the punctual Quot-scheme |
---|
36 | of rank r on n planar points |
---|
37 | BettiNumsQp(n, b); Betti numbers of the punctual Quot-scheme |
---|
38 | of rank r on n planar points |
---|
39 | MacdonaldF(z, t, n, b); The Macdonald's formula up to n-th degree |
---|
40 | PPolyS(z, n, b); Poincare Polynomial of the n-th symmetric power of a variety |
---|
41 | BettiNumsS(n, b); Betti numbers of the n-th symmetric power of a variety |
---|
42 | PPolyN(t, q, m, n); Poincare Polynomial of the moduli space |
---|
43 | of Kronecker modules N (q; m, n) |
---|
44 | BettiNumsN(q, m, n); Betti numbers of the moduli space |
---|
45 | of Kronecker modules N (q; m, n) |
---|
46 | |
---|
47 | KEYWORDS: Betty number; Goettsche's formula; Macdonald's formula; |
---|
48 | Kronecker module; Hilbert scheme; Quot-scheme; |
---|
49 | framed sheaves; symmetric product |
---|
50 | "; |
---|
51 | //---------------------------------------------------------- |
---|
52 | |
---|
53 | proc GoettscheF(poly z, poly t, int n, list b) |
---|
54 | "USAGE: GoettscheF(z, t, n, b); z, t polynomials, n integer, b list of non-negative integers |
---|
55 | RETURN: polynomial in z and t |
---|
56 | PURPOSE: computes the Goettsche's formula up to degree n in t |
---|
57 | EXAMPLE: example GoettscheF; shows an example |
---|
58 | NOTE: zero is returned if n<0 or b is not a list of non-negative integers |
---|
59 | or if there are not enough Betti numbers |
---|
60 | " |
---|
61 | { |
---|
62 | // check the input data |
---|
63 | if( !checkBetti(b) ) |
---|
64 | { |
---|
65 | print("the Betti numbers must be non-negative integers"); |
---|
66 | print("zero polynomial is returned"); |
---|
67 | return( poly(0) ); |
---|
68 | } |
---|
69 | if(n<0) |
---|
70 | { |
---|
71 | print("the number of points must be non-negative"); |
---|
72 | print("zero polynomial is returned"); |
---|
73 | return( poly(0) ); |
---|
74 | } |
---|
75 | // now n is non-negative and b is a list of non-negative integers |
---|
76 | if(size(b) < 5) // if there are not enough Betti numbers |
---|
77 | { |
---|
78 | print("a surface must habe 5 Betti numbers b_0, b_1, b_2, b_3, b_4"); |
---|
79 | print("zero polynomial is returned"); |
---|
80 | return( poly(0) ); |
---|
81 | } |
---|
82 | // now there are at least 5 non-negative Betti numbers b_0, b_1, b_2, b_3, b_4 |
---|
83 | def br@=basering; // remember the base ring |
---|
84 | // add additional variables z@, t@ to the base ring |
---|
85 | ring r@ = create_ring(ring_list(basering)[1],"("+varstr(basering)+", z@, t@)","dp","no_minpoly"); |
---|
86 | execute( "map F= br@,"+varstr(br@)+";" ); // define the corresponding inclusion of rings |
---|
87 | // compute the generating function by the Goettsche's formula up to degree n in t@ |
---|
88 | poly rez=1; |
---|
89 | int k,i; |
---|
90 | ideal I=std(t@^(n+1)); |
---|
91 | for(k=1;k<=n;k++) |
---|
92 | { |
---|
93 | for(i=0;i<=4;i++) |
---|
94 | { |
---|
95 | rez=NF( rez*generFactor( z@^(2*k-2+i)*t@^k, k, i, b[i+1], n), I); |
---|
96 | } |
---|
97 | } |
---|
98 | setring br@; // come back to the initial base ring |
---|
99 | // define the specialization homomorphism z@=z, t@=t |
---|
100 | execute( "map FF= r@,"+varstr(br@)+", z, t;" ); |
---|
101 | poly rez=FF(rez); // bring the result to the base ring |
---|
102 | return(rez); |
---|
103 | } |
---|
104 | example |
---|
105 | { |
---|
106 | "EXAMPLE:"; echo=2; |
---|
107 | ring r=0, (t, z), ls; |
---|
108 | // consider the projective plane with Betti numbers 1,0,1,0,1 |
---|
109 | list b=1,0,1,0,1; |
---|
110 | // get the Goettsche's formula up to degree 3 |
---|
111 | print( GoettscheF(z, t, 3, b) ); |
---|
112 | } |
---|
113 | //---------------------------------------------------------- |
---|
114 | |
---|
115 | proc PPolyH(poly z, int n, list b) |
---|
116 | "USAGE: PPolyH(z, n, b); z polynomial, n integer, b list of non-negative integers |
---|
117 | RETURN: polynomial in z |
---|
118 | PURPOSE: computes the Poincare polynomial of the Hilbert scheme |
---|
119 | of n points on a surface with Betti numbers b |
---|
120 | EXAMPLE: example PPolyH; shows an example |
---|
121 | NOTE: zero is returned if n<0 or b is not a list of non-negative integers |
---|
122 | or if there are not enough Betti numbers |
---|
123 | " |
---|
124 | { |
---|
125 | // check the input data |
---|
126 | if( !checkBetti(b) ) |
---|
127 | { |
---|
128 | print("the Betti numbers must be non-negative integers"); |
---|
129 | print("zero polynomial is returned"); |
---|
130 | return( poly(0) ); |
---|
131 | } |
---|
132 | if(n<0) |
---|
133 | { |
---|
134 | print("the number of points must be non-negative"); |
---|
135 | print("zero polynomial is returned"); |
---|
136 | return( poly(0) ); |
---|
137 | } |
---|
138 | // now n is non-negative and b is a list of non-negative integers |
---|
139 | if(size(b) < 5) // if there are not enough Betti numbers |
---|
140 | { |
---|
141 | print("a surface must habe 5 Betti numbers b_0, b_1, b_2, b_3, b_4"); |
---|
142 | print("zero polynomial is returned"); |
---|
143 | return( poly(0) ); |
---|
144 | } |
---|
145 | // now there are at least 5 non-negative Betti numbers b_0, b_1, b_2, b_3, b_4 |
---|
146 | def br@=basering; // remember the base ring |
---|
147 | // add additional variables z@, t@ to the base ring |
---|
148 | ring r@ = create_ring(ring_list(basering)[1], "("+varstr(basering)+",z@, t@)","dp","no_minpoly"); |
---|
149 | execute( "map F= br@,"+varstr(br@)+";" ); // define the corresponding inclusion of rings |
---|
150 | // compute the generating function by the Goettsche's formula up to degree n in t@ |
---|
151 | poly rez=1; |
---|
152 | int k,i; |
---|
153 | ideal I=std(t@^(n+1)); |
---|
154 | for(k=1;k<=n;k++) |
---|
155 | { |
---|
156 | for(i=0;i<=4;i++) |
---|
157 | { |
---|
158 | rez=NF(rez*generFactor( z@^(2*k-2+i)*t@^k, k, i, b[i+1], n), I); |
---|
159 | } |
---|
160 | } |
---|
161 | rez= coeffs(rez, t@)[n+1, 1]; // take the coefficient of the n-th power of t@ |
---|
162 | setring br@; // come back to the initial base ring |
---|
163 | // define the specialization homomorphism z@=z, t@=0 |
---|
164 | execute( "map FF= r@,"+varstr(br@)+",z, 0;" ); |
---|
165 | poly rez=FF(rez); // bring the result to the base ring |
---|
166 | return(rez); |
---|
167 | } |
---|
168 | example |
---|
169 | { |
---|
170 | "EXAMPLE:"; echo=2; |
---|
171 | ring r=0, (z), ls; |
---|
172 | // consider the projective plane P_2 with Betti numbers 1,0,1,0,1 |
---|
173 | list b=1,0,1,0,1; |
---|
174 | // get the Poincare polynomial of the Hilbert scheme of 3 points on P_2 |
---|
175 | print( PPolyH(z, 3, b) ); |
---|
176 | } |
---|
177 | //---------------------------------------------------------- |
---|
178 | |
---|
179 | proc BettiNumsH(int n, list b) |
---|
180 | "USAGE: BettiNumsH(n, b); n integer, b list of non-negative integers |
---|
181 | RETURN: list of non-negative integers |
---|
182 | PURPOSE: computes the Betti numbers of the Hilbert scheme |
---|
183 | of n points on a surface with Betti numbers b |
---|
184 | EXAMPLE: example BettiNumsH; shows an example |
---|
185 | NOTE: an empty list is returned if n<0 or b is not a list of non-negative integers |
---|
186 | or if there are not enough Betti numbers |
---|
187 | " |
---|
188 | { |
---|
189 | // check the input data |
---|
190 | if( !checkBetti(b) ) |
---|
191 | { |
---|
192 | print("the Betti numbers must be non-negative integers"); |
---|
193 | print("an empty list is returned"); |
---|
194 | return( list() ); |
---|
195 | } |
---|
196 | if(n<0) |
---|
197 | { |
---|
198 | print("the number of points must be non-negative"); |
---|
199 | print("an empty list is returned"); |
---|
200 | return(list()); |
---|
201 | } |
---|
202 | // now n is non-negative and b is a list of non-negative integers |
---|
203 | if(size(b) < 5) // if there are not enough Betti numbers |
---|
204 | { |
---|
205 | print("a surface must habe 5 Betti numbers b_0, b_1, b_2, b_3, b_4"); |
---|
206 | print("an empty list is returned"); |
---|
207 | return( list() ); |
---|
208 | } |
---|
209 | // now there are at least 5 non-negative Betti numbers b_0, b_1, b_2, b_3, b_4 |
---|
210 | def br@=basering; // remember the base ring |
---|
211 | // add additional variables z@, t@ to the base ring |
---|
212 | ring r@ = create_ring(ring_list(basering)[1],"("+varstr(basering)+", z@, t@)","dp","no_minpoly"); |
---|
213 | execute( "map F= br@,"+varstr(br@)+";" ); // define the corresponding inclusion of rings |
---|
214 | poly rez=1; |
---|
215 | int k,i; |
---|
216 | ideal I=std(t@^(n+1)); |
---|
217 | for(k=1;k<=n;k++) |
---|
218 | { |
---|
219 | for(i=0;i<=4;i++) |
---|
220 | { |
---|
221 | rez=NF(rez*generFactor( z@^(2*k-2+i)*t@^k, k, i, b[i+1], n), I); |
---|
222 | } |
---|
223 | } |
---|
224 | rez= coeffs(rez, t@)[n+1, 1]; // take the coefficient of the n-th power of t@ |
---|
225 | matrix CF=coeffs(rez, z@); // take the matrix of the coefficients |
---|
226 | list res; // and transform it to a list |
---|
227 | int d=size(CF); |
---|
228 | for(i=1; i<=d; i++) |
---|
229 | { |
---|
230 | res=res+ list(int(CF[i, 1])) ; |
---|
231 | } |
---|
232 | setring br@; // come back to the initial base ring |
---|
233 | return(res); |
---|
234 | } |
---|
235 | example |
---|
236 | { |
---|
237 | "EXAMPLE:"; echo=2; |
---|
238 | ring r=0, (z), ls; |
---|
239 | // consider the projective plane P_2 with Betti numbers 1,0,1,0,1 |
---|
240 | list b=1,0,1,0,1; |
---|
241 | // get the Betti numbers of the Hilbert scheme of 3 points on P_2 |
---|
242 | print( BettiNumsH(3, b) ); |
---|
243 | } |
---|
244 | //---------------------------------------------------------- |
---|
245 | |
---|
246 | proc NakYoshF(poly z, poly t, int r, int n) |
---|
247 | "USAGE: NakYoshF(z, t, r, n); z, t polynomials, r, n integers |
---|
248 | RETURN: polynomial in z and t |
---|
249 | PURPOSE: computes the formula of Nakajima and Yoshioka |
---|
250 | up to degree n in t |
---|
251 | EXAMPLE: example NakYoshF; shows an example |
---|
252 | NOTE: zero is returned if n<0 or r<=0 |
---|
253 | " |
---|
254 | { |
---|
255 | // check the input data |
---|
256 | if(n<0) |
---|
257 | { |
---|
258 | print("the number of points must be non-negative"); |
---|
259 | print("zero polynomial is returned"); |
---|
260 | return( poly(0) ); |
---|
261 | } |
---|
262 | if(r<=0) |
---|
263 | { |
---|
264 | print("r must be positive"); |
---|
265 | print("zero polynomial is returned"); |
---|
266 | return( poly(0) ); |
---|
267 | } |
---|
268 | // now n is non-negative and r is positive |
---|
269 | def br@=basering; // remember the base ring |
---|
270 | // add additional variables z@, t@ to the base ring |
---|
271 | ring r@ = create_ring(ring_list(basering)[1],"("+varstr(basering)+", z@, t@)","dp","no_minpoly"); |
---|
272 | execute( "map F= br@,"+varstr(br@)+";" ); // define the corresponding inclusion of rings |
---|
273 | // compute the generating function by the Nakajima-Yoshioka formula up to degree n in t@ |
---|
274 | poly rez=1; |
---|
275 | int k,i; |
---|
276 | ideal I=std(t@^(n+1)); |
---|
277 | for(k=1;k<=n;k++) |
---|
278 | { |
---|
279 | for(i=1;i<=r;i++) |
---|
280 | { |
---|
281 | rez=NF( rez*generFactor( z@^(2*(r*k-i))*t@^k, k, 0, 1, n), I); |
---|
282 | } |
---|
283 | } |
---|
284 | setring br@; // come back to the initial base ring |
---|
285 | // define the specialization homomorphism z@=z, t@=t |
---|
286 | execute( "map FF= r@,"+varstr(br@)+", z, t;" ); |
---|
287 | poly rez=FF(rez); // bring the result to the base ring |
---|
288 | return(rez); |
---|
289 | } |
---|
290 | example |
---|
291 | { |
---|
292 | "EXAMPLE:"; echo=2; |
---|
293 | ring r=0, (t, z), ls; |
---|
294 | // get the Nakajima-Yoshioka formula for r=1 up to degree 3, i.e., |
---|
295 | // the generating function for the Poincare polynomials of the |
---|
296 | // punctual Hilbert schemes of n planar points |
---|
297 | print( NakYoshF(z, t, 1, 3) ); |
---|
298 | } |
---|
299 | //---------------------------------------------------------- |
---|
300 | |
---|
301 | proc PPolyQp(poly z, int r, int n) |
---|
302 | "USAGE: PPolyQp(z, r, n); z polynomial, r, n integers |
---|
303 | RETURN: polynomial in z |
---|
304 | PURPOSE: computes the Poincare polynomial of the punctual Quot-scheme |
---|
305 | of rank r on n planar points |
---|
306 | EXAMPLE: example PPolyQp; shows an example |
---|
307 | NOTE: zero is returned if n<0 or r<=0 |
---|
308 | " |
---|
309 | { |
---|
310 | // check the input data |
---|
311 | if(n<0) |
---|
312 | { |
---|
313 | print("the number of points must be non-negative"); |
---|
314 | print("zero polynomial is returned"); |
---|
315 | return( poly(0) ); |
---|
316 | } |
---|
317 | if(r<=0) |
---|
318 | { |
---|
319 | print("r must be positive"); |
---|
320 | print("zero polynomial is returned"); |
---|
321 | return( poly(0) ); |
---|
322 | } |
---|
323 | // now n is non-negative and r is positive |
---|
324 | def br@=basering; // remember the base ring |
---|
325 | // add additional variables z@, t@ to the base ring |
---|
326 | ring r@ = create_ring(ring_list(basering)[1],"("+varstr(basering)+", z@, t@)","dp","no_minpoly"); |
---|
327 | execute( "map F= br@,"+varstr(br@)+";" ); // define the corresponding inclusion of rings |
---|
328 | // compute the generating function by the Nakajima-Yoshioka formula up to degree n in t@ |
---|
329 | poly rez=1; |
---|
330 | int k,i; |
---|
331 | ideal I=std(t@^(n+1)); |
---|
332 | for(k=1;k<=n;k++) |
---|
333 | { |
---|
334 | for(i=1;i<=r;i++) |
---|
335 | { |
---|
336 | rez=NF(rez*generFactor( z@^(2*(r*k-i))*t@^k, k, 0, 1, n), I); |
---|
337 | } |
---|
338 | } |
---|
339 | rez= coeffs(rez, t@)[n+1, 1]; // take the coefficient of the n-th power of t@ |
---|
340 | setring br@; // come back to the initial base ring |
---|
341 | // define the specialization homomorphism z@=z, t@=0 |
---|
342 | execute( "map FF= r@,"+varstr(br@)+",z, 0;" ); |
---|
343 | poly rez=FF(rez); // bring the result to the base ring |
---|
344 | return(rez); |
---|
345 | } |
---|
346 | example |
---|
347 | { |
---|
348 | "EXAMPLE:"; echo=2; |
---|
349 | ring r=0, (z), ls; |
---|
350 | // get the Poincare polynomial of the punctual Hilbert scheme (r=1) |
---|
351 | // of 3 planar points |
---|
352 | print( PPolyQp(z, 1, 3) ); |
---|
353 | } |
---|
354 | //---------------------------------------------------------- |
---|
355 | |
---|
356 | proc BettiNumsQp(int r, int n) |
---|
357 | "USAGE: BettiNumsQp(r, n); n, r integers |
---|
358 | RETURN: list of non-negative integers |
---|
359 | PURPOSE: computes the Betti numbers of the punctual Quot-scheme |
---|
360 | of rank r on n points on a plane |
---|
361 | EXAMPLE: example BettiNumsQp; shows an example |
---|
362 | NOTE: an empty list is returned if n<0 or r<=0 |
---|
363 | " |
---|
364 | { |
---|
365 | // check the input data |
---|
366 | if(n<0) |
---|
367 | { |
---|
368 | print("the number of points must be non-negative"); |
---|
369 | print("zero polynomial is returned"); |
---|
370 | return( poly(0) ); |
---|
371 | } |
---|
372 | if(r<=0) |
---|
373 | { |
---|
374 | print("r must be positive"); |
---|
375 | print("zero polynomial is returned"); |
---|
376 | return( poly(0) ); |
---|
377 | } |
---|
378 | // now n is non-negative and r is positive |
---|
379 | def br@=basering; // remember the base ring |
---|
380 | // add additional variables z@, t@ to the base ring |
---|
381 | ring r@ = create_ring(ring_list(basering)[1],"("+varstr(basering)+", z@, t@)","dp","no_minpoly"); |
---|
382 | execute( "map F= br@,"+varstr(br@)+";" ); // define the corresponding inclusion of rings |
---|
383 | poly rez=1; |
---|
384 | int k,i; |
---|
385 | ideal I=std(t@^(n+1)); |
---|
386 | for(k=1;k<=n;k++) |
---|
387 | { |
---|
388 | for(i=1;i<=r;i++) |
---|
389 | { |
---|
390 | rez=NF(rez*generFactor( z@^(2*(r*k-i))*t@^k, k, 0, 1, n), I); |
---|
391 | } |
---|
392 | } |
---|
393 | rez= coeffs(rez, t@)[n+1, 1]; // take the coefficient of the n-th power of t@ |
---|
394 | matrix CF=coeffs(rez, z@); // take the matrix of the coefficients |
---|
395 | list res; // and transform it to a list |
---|
396 | int d=size(CF); |
---|
397 | for(i=1; i<=d; i++) |
---|
398 | { |
---|
399 | res=res+ list(int(CF[i, 1])) ; |
---|
400 | } |
---|
401 | setring br@; // come back to the initial base ring |
---|
402 | return(res); |
---|
403 | } |
---|
404 | example |
---|
405 | { |
---|
406 | "EXAMPLE:"; echo=2; |
---|
407 | ring r=0, (z), ls; |
---|
408 | // get the Betti numbers of the punctual Hilbert scheme (r=1) |
---|
409 | // of 3 points on a plane |
---|
410 | print( BettiNumsQp(1, 3) ); |
---|
411 | } |
---|
412 | //---------------------------------------------------------- |
---|
413 | |
---|
414 | proc MacdonaldF(poly z, poly t, int n, list b) |
---|
415 | "USAGE: MacdonaldF(z, t, n, b); z, t polynomials, n integer, b list of non-negative integers |
---|
416 | RETURN: polynomial in z and t with integer coefficients |
---|
417 | PURPOSE: computes the Macdonalds's formula up to degree n in t |
---|
418 | EXAMPLE: example MacdonaldF; shows an example |
---|
419 | NOTE: zero is returned if n<0 or b is not a list of non-negative integers |
---|
420 | " |
---|
421 | { |
---|
422 | // check the input data |
---|
423 | if( !checkBetti(b) ) |
---|
424 | { |
---|
425 | print("the Betti numbers must be non-negative integers"); |
---|
426 | print("zero polynomial is returned"); |
---|
427 | return( poly(0) ); |
---|
428 | } |
---|
429 | if(n<0) |
---|
430 | { |
---|
431 | print("the exponent of the symmetric power must be non-negative"); |
---|
432 | print("zero polynomial is returned"); |
---|
433 | return( poly(0) ); |
---|
434 | } |
---|
435 | int d=size(b); |
---|
436 | def br@=basering; // remember the base ring |
---|
437 | // add additional variables z@, t@ to the base ring |
---|
438 | ring r@ = create_ring(ring_list(basering)[1],"("+varstr(basering)+", z@, t@)","dp","no_minpoly"); |
---|
439 | execute( "map F= br@,"+varstr(br@)+";" ); // define the corresponding inclusion of rings |
---|
440 | poly rez=1; |
---|
441 | int i; |
---|
442 | ideal I=std(t@^(n+1)); |
---|
443 | for(i=0;i<d;i++) |
---|
444 | { |
---|
445 | rez=NF(rez*generFactor( z@^i*t@, 1, i, b[i+1], n), I); |
---|
446 | } |
---|
447 | setring br@; // come back to the initial base ring |
---|
448 | // define the specialization homomorphism z@=z, t@=t |
---|
449 | execute( "map FF= r@,"+varstr(br@)+",z, t;" ); |
---|
450 | poly rez=FF(rez); // bring the result to the base ring |
---|
451 | return(rez); |
---|
452 | } |
---|
453 | example |
---|
454 | { |
---|
455 | "EXAMPLE:"; echo=2; |
---|
456 | ring r=0, (t, z), ls; |
---|
457 | // consider the projective plane with Betti numbers 1,0,1,0,1 |
---|
458 | list b=1,0,1,0,1; |
---|
459 | // get the Macdonald's formula up to degree 3 |
---|
460 | print( MacdonaldF(z, t, 3, b) ); |
---|
461 | } |
---|
462 | //---------------------------------------------------------- |
---|
463 | |
---|
464 | proc PPolyS(poly z, int n, list b) |
---|
465 | "USAGE: PPolyS(z, n, b); z polynomial, n integer, b list of non-negative integers |
---|
466 | RETURN: polynomial in z with integer coefficients |
---|
467 | PURPOSE: computes the Poincare polynomial of the n-th symmetric power |
---|
468 | of a variety with Betti numbers b |
---|
469 | EXAMPLE: example PPolyS; shows an example |
---|
470 | NOTE: zero is returned if n<0 or b is not a list of non-negative integers |
---|
471 | " |
---|
472 | { |
---|
473 | // check the input data |
---|
474 | if( !checkBetti(b) ) |
---|
475 | { |
---|
476 | print("the Betti numbers must be non-negative integers"); |
---|
477 | print("zero polynomial is returned"); |
---|
478 | return( poly(0) ); |
---|
479 | } |
---|
480 | if(n<0) |
---|
481 | { |
---|
482 | print("the exponent of the symmetric power must be non-negative"); |
---|
483 | print("zero polynomial is returned"); |
---|
484 | return( poly(0) ); |
---|
485 | } |
---|
486 | int d=size(b); |
---|
487 | def br@=basering; // remember the base ring |
---|
488 | // add additional variables z@, t@ to the base ring |
---|
489 | ring r@ = create_ring(ring_list(basering)[1],"("+varstr(basering)+", z@, t@)","dp","no_minpoly"); |
---|
490 | execute( "map F= br@,"+varstr(br@)+";" ); // define the corresponding inclusion of rings |
---|
491 | poly rez=1; |
---|
492 | int i; |
---|
493 | ideal I=std(t@^(n+1)); |
---|
494 | for(i=0;i<d;i++) |
---|
495 | { |
---|
496 | rez=NF(rez*generFactor( z@^i*t@, 1, i, b[i+1], n), I); |
---|
497 | } |
---|
498 | rez= coeffs(rez, t@)[n+1, 1]; // take the coefficient of the n-th power of t@ |
---|
499 | setring br@; // come back to the initial base ring |
---|
500 | // define the specialization homomorphism z@=z, t@=0 |
---|
501 | execute( "map FF= r@,"+varstr(br@)+",z, 0;" ); |
---|
502 | poly rez=FF(rez); // bring the result to the base ring |
---|
503 | return(rez); |
---|
504 | } |
---|
505 | example |
---|
506 | { |
---|
507 | "EXAMPLE:"; echo=2; |
---|
508 | ring r=0, (z), ls; |
---|
509 | // consider the projective plane P_2 with Betti numbers 1,0,1,0,1 |
---|
510 | list b=1,0,1,0,1; |
---|
511 | // get the Poincare polynomial of the third symmetric power of P_2 |
---|
512 | print( PPolyS(z, 3, b) ); |
---|
513 | } |
---|
514 | //---------------------------------------------------------- |
---|
515 | |
---|
516 | proc BettiNumsS(int n, list b) |
---|
517 | "USAGE: BettiNumsS(n, b); n integer, b list of non-negative integers |
---|
518 | RETURN: list of non-negative integers |
---|
519 | PURPOSE: computes the Betti numbers of the n-th symmetric power of a variety with Betti numbers b |
---|
520 | EXAMPLE: example BettiNumsS; shows an example |
---|
521 | NOTE: an empty list is returned if n<0 or b is not a list of non-negative integers |
---|
522 | " |
---|
523 | { |
---|
524 | // check the input data |
---|
525 | if( !checkBetti(b) ) |
---|
526 | { |
---|
527 | print("the Betti numbers must be non-negative integers"); |
---|
528 | print("an empty list is returned"); |
---|
529 | return( list() ); |
---|
530 | } |
---|
531 | if(n<0) |
---|
532 | { |
---|
533 | print("the exponent of the symmetric power must be non-negative"); |
---|
534 | print("an empty list is returned"); |
---|
535 | return(list()); |
---|
536 | } |
---|
537 | int d=size(b); |
---|
538 | def br@=basering; // remember the base ring |
---|
539 | // add additional variables z@, t@ to the base ring |
---|
540 | ring r@ = create_ring(ring_list(basering)[1],"("+varstr(basering)+", z@, t@)","dp","no_minpoly"); |
---|
541 | execute( "map F= br@,"+varstr(br@)+";" ); // define the corresponding inclusion of rings |
---|
542 | poly rez=1; |
---|
543 | int i; |
---|
544 | ideal I=std(t@^(n+1)); |
---|
545 | for(i=0;i<d;i++) |
---|
546 | { |
---|
547 | rez=NF(rez*generFactor( z@^i*t@, 1, i, b[i+1], n), I); |
---|
548 | } |
---|
549 | rez= coeffs(rez, t@)[n+1, 1]; // take the coefficient of the n-th power of t@ |
---|
550 | matrix CF=coeffs(rez, z@); // take the matrix of the coefficients |
---|
551 | list res; // and transform it to a list |
---|
552 | d=size(CF); |
---|
553 | for(i=1; i<=d; i++) |
---|
554 | { |
---|
555 | res=res+ list(int(CF[i, 1])) ; |
---|
556 | } |
---|
557 | setring br@; // come back to the initial base ring |
---|
558 | return(res); |
---|
559 | } |
---|
560 | example |
---|
561 | { |
---|
562 | "EXAMPLE:"; echo=2; |
---|
563 | ring r=0, (z), ls; |
---|
564 | // consider a complex torus T (elliptic curve) with Betti numbers 1,2,1 |
---|
565 | list b=1,2,1; |
---|
566 | // get the Betti numbers of the second symmetric power of T |
---|
567 | print( BettiNumsS(2, b) ); |
---|
568 | // consider a projective plane P_2 with Betti numbers 1,0,1,0,1 |
---|
569 | b=1,0,1,0,1; |
---|
570 | // get the Betti numbers of the third symmetric power of P_2 |
---|
571 | print( BettiNumsS(3, b) ); |
---|
572 | } |
---|
573 | //---------------------------------------------------------- |
---|
574 | |
---|
575 | proc PPolyN(poly t, int q, int m, int n) |
---|
576 | "USAGE: PPolyN(t, q, m, n); t polynomial, q, m, n integers |
---|
577 | RETURN: polynomial in t |
---|
578 | PURPOSE: computes the Poincare polynomial of the moduli space |
---|
579 | of Kronecker modules N(q; m, n) |
---|
580 | EXAMPLE: example PPolyN; shows an example |
---|
581 | NOTE: if m and n are not coprime, the result does not necessary make sense |
---|
582 | " |
---|
583 | { |
---|
584 | int d=dimKron(q, m, n); |
---|
585 | if(d<0) |
---|
586 | { |
---|
587 | return(0); |
---|
588 | } |
---|
589 | if(gcd(m, n)!=1) |
---|
590 | { |
---|
591 | "You are trying to compute the Poincare polynomial"; |
---|
592 | "of the moduli space of Kronecker modules N("+string(q)+"; "+string(m)+", "+string(n)+")."; |
---|
593 | "Notice that gcd(m,n)=1 is expected to get the correct Poincare polynomial"; |
---|
594 | "of the moduli space N(q; m, n)!"; |
---|
595 | } |
---|
596 | def br@=basering; // remember the base ring |
---|
597 | // add additional variable t@ to the base ring |
---|
598 | ring r@ = create_ring(ring_list(basering)[1], "("+varstr(basering)+", t@)", "dp", "no_minpoly"); |
---|
599 | execute( "map F= br@,"+varstr(br@)+";" ); // define the corresponding inclusion of rings |
---|
600 | poly rez=(1-t@^2)*PPolyW(q, m, n, t@, d); |
---|
601 | ideal I=t@^(2*d+1); |
---|
602 | rez=NF(rez, I); |
---|
603 | setring br@; // come back to the initial base ring |
---|
604 | // define the specialization homomorphism t@=t |
---|
605 | execute( "map FF= r@,"+varstr(br@)+", t;" ); |
---|
606 | poly rez=FF(rez); // bring the result to the base ring |
---|
607 | return(rez); |
---|
608 | } |
---|
609 | example |
---|
610 | { |
---|
611 | "EXAMPLE:"; echo=2; |
---|
612 | ring r=0, (t), ls; |
---|
613 | // get the Poincare polynomial of N(3; 2, 3) |
---|
614 | print( PPolyN(t, 3, 2, 3) ); |
---|
615 | } |
---|
616 | //---------------------------------------------------------- |
---|
617 | |
---|
618 | proc BettiNumsN(int q, int m, int n) |
---|
619 | "USAGE: BettiNumsN(q, m, n); q, m, n integers |
---|
620 | RETURN: list of integers |
---|
621 | PURPOSE: computes the Betti numbers of the moduli space |
---|
622 | of Kronecker modules N(q; m, n) |
---|
623 | EXAMPLE: example BettiNumsN; shows an example |
---|
624 | NOTE: if m and n are not coprime, the result does not necessary make sense |
---|
625 | " |
---|
626 | { |
---|
627 | int d=dimKron(q, m, n); |
---|
628 | if(d<0) |
---|
629 | { |
---|
630 | return(0); |
---|
631 | } |
---|
632 | if(gcd(m, n)!=1) |
---|
633 | { |
---|
634 | "You are trying to compute the Poincare polynomial"; |
---|
635 | "of the moduli space of Kronecker modules N("+string(q)+"; "+string(m)+", "+string(n)+")."; |
---|
636 | "Notice that gcd(m,n)=1 is expected to get the correct Poincare polynomial"; |
---|
637 | "of the moduli space N(q; m, n)!"; |
---|
638 | } |
---|
639 | def br@=basering; // remember the base ring |
---|
640 | // add additional variable t@ to the base ring |
---|
641 | ring r@ = create_ring(ring_list(basering)[1], "("+varstr(basering)+", t@)", "dp", "no_minpoly"); |
---|
642 | execute( "map F= br@,"+varstr(br@)+";" ); // define the corresponding inclusion of rings |
---|
643 | poly rez=(1-t@^2)*PPolyW(q, m, n, t@, d); |
---|
644 | ideal I=t@^(2*d+1); |
---|
645 | rez=NF(rez, I); |
---|
646 | matrix CF=coeffs(rez, t@); // take the matrix of the coefficients |
---|
647 | list res; // and transform it to a list |
---|
648 | d=size(CF); |
---|
649 | int i; |
---|
650 | for(i=1; i<=d; i++) |
---|
651 | { |
---|
652 | res=res + list(int(CF[i, 1])) ; |
---|
653 | } |
---|
654 | setring br@; // come back to the initial base ring |
---|
655 | return(res); |
---|
656 | } |
---|
657 | example |
---|
658 | { |
---|
659 | "EXAMPLE:"; echo=2; |
---|
660 | ring r=0, (t), dp; |
---|
661 | // get the Betti numbers of N(3; 2, 3) |
---|
662 | print( BettiNumsN(3, 2, 3) ); |
---|
663 | } |
---|
664 | //---------------------------------------------------------------------------------------- |
---|
665 | // The procedures below are for the internal usage only |
---|
666 | //---------------------------------------------------------------------------------------- |
---|
667 | |
---|
668 | static proc checkBetti(list b) |
---|
669 | "USAGE: checkBetti(b); b list of integers |
---|
670 | RETURN: integer 1 or 0 |
---|
671 | PURPOSE: checks whether all entries of b are non-negative integers |
---|
672 | EXAMPLE: example checkBetti; shows an example |
---|
673 | NOTE: |
---|
674 | " |
---|
675 | { |
---|
676 | int i; |
---|
677 | int sz=size(b); |
---|
678 | for(i=1;i<=sz;i++) |
---|
679 | { |
---|
680 | if( typeof(b[i])!="int" ) |
---|
681 | { |
---|
682 | return(int(0)); |
---|
683 | } |
---|
684 | if( b[i]<0 ) |
---|
685 | { |
---|
686 | return(int(0)); |
---|
687 | } |
---|
688 | } |
---|
689 | return(int(1)); |
---|
690 | } |
---|
691 | example |
---|
692 | { |
---|
693 | "EXAMPLE:"; echo=2; |
---|
694 | ring r=0, (t), dp; |
---|
695 | // not all entries are integers |
---|
696 | list b=1,0,t,0,1; |
---|
697 | print(checkBetti(b)); |
---|
698 | // all entries are integers but not all are non-negative |
---|
699 | list b=1,0,-1,0,1; |
---|
700 | print(checkBetti(b)); |
---|
701 | // all entries are non-negative integers |
---|
702 | list b=1,0,1,0,1; |
---|
703 | print(checkBetti(b)); |
---|
704 | } |
---|
705 | //---------------------------------------------------------- |
---|
706 | |
---|
707 | static proc generFactor(poly X, int k, int i, int b, int n) |
---|
708 | "USAGE: generFactor; X polynomial, k, b, n integers |
---|
709 | RETURN: polynomial |
---|
710 | PURPOSE: computes the corresponding factor from Goettsche's formula |
---|
711 | EXAMPLE: example generFactor; shows an example |
---|
712 | NOTE: |
---|
713 | " |
---|
714 | { |
---|
715 | poly rez=0; |
---|
716 | int j; |
---|
717 | int pow; |
---|
718 | pow=(-1)^(i+1)*b; |
---|
719 | if(pow > 0) |
---|
720 | { |
---|
721 | rez=(1+X)^pow; |
---|
722 | } |
---|
723 | else |
---|
724 | { |
---|
725 | int m=n div k + 1; |
---|
726 | for(j=0;j<m;j++) |
---|
727 | { |
---|
728 | rez=rez+ X^j; |
---|
729 | } |
---|
730 | rez=rez^(-pow); |
---|
731 | } |
---|
732 | return(rez); |
---|
733 | } |
---|
734 | example |
---|
735 | { |
---|
736 | "EXAMPLE:"; echo=2; |
---|
737 | ring r=0, (t), ds; |
---|
738 | // get the polynomial expansion of 1/(1-t)^2 |
---|
739 | // using the Taylor expansion of 1/(1-t) up to degree 11 |
---|
740 | // and assuming that the degree of t is 3 |
---|
741 | print( generFactor(t, 3, 0, 2, 11) ); |
---|
742 | } |
---|
743 | //---------------------------------------------------------------------------------------- |
---|
744 | // The procedures below are related to the Kronecker modules |
---|
745 | //---------------------------------------------------------------------------------------- |
---|
746 | |
---|
747 | static proc PPolyW(int q, int m, int n, poly t, int d, list #) |
---|
748 | { |
---|
749 | // without loss of generality assume that m >= n |
---|
750 | int N; |
---|
751 | int M; |
---|
752 | if(n>m) |
---|
753 | { |
---|
754 | M = n; |
---|
755 | N = m; |
---|
756 | } |
---|
757 | else |
---|
758 | { |
---|
759 | M = m; |
---|
760 | N = n; |
---|
761 | } |
---|
762 | // now M >= N; |
---|
763 | int i; |
---|
764 | int j; |
---|
765 | list plg;// will be the matrix-list with all the data |
---|
766 | list newPlg;// will be used for computation of new entries of plg |
---|
767 | // initial initialization of plg, M entries |
---|
768 | for(i=1;i<=M;i++) |
---|
769 | { |
---|
770 | plg = plg + list( list() ); |
---|
771 | } |
---|
772 | int ii; |
---|
773 | int jj; |
---|
774 | int st; |
---|
775 | list P; |
---|
776 | list PP; |
---|
777 | int c; |
---|
778 | int sz; |
---|
779 | int pow; |
---|
780 | poly pterm; |
---|
781 | poly rez;// to be the result |
---|
782 | ideal I=t^(2*d+1); |
---|
783 | // starting in the bottom row, moving from left to right and from the bottom upwards |
---|
784 | for(j=0;j<=N;j++) |
---|
785 | { |
---|
786 | for(i=max(j, 1);i<=M;i++) |
---|
787 | { |
---|
788 | // for each entry compute the relevant data inductively |
---|
789 | // add the trivial polygon |
---|
790 | newPlg = list( list( list( list(int(0), int(0)), list(i, j)) , poly(0), int(0) ) ); |
---|
791 | // first summand in the Drezet's formula |
---|
792 | if(j==0)// if in the bottom row |
---|
793 | { |
---|
794 | if(i==1) |
---|
795 | { |
---|
796 | rez=geomS(t^2, d); |
---|
797 | } |
---|
798 | else |
---|
799 | { |
---|
800 | rez=plg[i-1][1][1][2]*geomS(t^(2*i), d div i ); |
---|
801 | } |
---|
802 | } |
---|
803 | else// otherwise use the values from the bottom row |
---|
804 | { |
---|
805 | rez=plg[i][1][1][2]*plg[j][1][1][2]; |
---|
806 | } |
---|
807 | rez=NF(rez, I);// throw away the higher powers |
---|
808 | //inductively compute the polygons |
---|
809 | for(ii = 0; ii <= i; ii++) |
---|
810 | { |
---|
811 | st= ((j*ii) div i) + 1; |
---|
812 | for(jj = st; jj <= j; jj++) |
---|
813 | { |
---|
814 | PP=list();// to be the list of polygons that will be added |
---|
815 | P = plg[i-ii][j-jj+1];// list of smaller polygons |
---|
816 | sz=size(P); |
---|
817 | for(c=1;c<=sz;c++)// for every smaller polygon |
---|
818 | { |
---|
819 | if( jj*P[c][1][2][1]-P[c][1][2][2]*ii > 0 )// if the slopes fit |
---|
820 | { |
---|
821 | pow = P[c][3]+ jj*( q*(i-ii)-(j-jj) )-ii*(i-ii);// get the corresponding power |
---|
822 | // and the corresponding product |
---|
823 | pterm = NF(P[c][2]* plg[max(ii,jj)][min(ii,jj)+1][1][2], I); |
---|
824 | // and add the data to PP |
---|
825 | PP = PP + list(list(list(list(int(0),int(0))) + shift(P[c][1],ii,jj),pterm,pow)); |
---|
826 | // throw away the summands from the polygons with non-admissible slopes and pow<0 |
---|
827 | if(pterm!=0) |
---|
828 | { |
---|
829 | rez=rez-t^(2*pow) * pterm;// add the next summand |
---|
830 | } |
---|
831 | } |
---|
832 | } |
---|
833 | newPlg=newPlg + PP;// add the new polygons to the list |
---|
834 | } |
---|
835 | } |
---|
836 | rez=NF(rez, I);// throw away the higher powers |
---|
837 | newPlg[1][2]=rez;// set the polynomial corresponding to the trivial polygon |
---|
838 | plg[i]=plg[i]+list(newPlg);// add the new data |
---|
839 | // now all the data for (i, j) have been computed |
---|
840 | } |
---|
841 | } |
---|
842 | if(size(#)==0)// if there are no optional parameters |
---|
843 | { |
---|
844 | return(plg[M][N+1][1][2]);// return the polynomial of the upper right entry |
---|
845 | } |
---|
846 | else// otherwise return all the computed data |
---|
847 | { |
---|
848 | return(plg); |
---|
849 | } |
---|
850 | } |
---|
851 | //---------------------------------------------------------- |
---|
852 | |
---|
853 | static proc dimKron(int q, int m, int n) |
---|
854 | { |
---|
855 | if( (q<3)||(m<0)||(n<0) ) |
---|
856 | { |
---|
857 | "Check the input data!"; |
---|
858 | "It is expected that for the moduli space of Kronecker modules N(q; m, n)"; |
---|
859 | "q >= 3, m >= 0, n >= 0."; |
---|
860 | return(int(-1)); |
---|
861 | } |
---|
862 | int ph=m^2+n^2-q*m*n; |
---|
863 | if(ph<0) |
---|
864 | { |
---|
865 | return(1-ph); |
---|
866 | } |
---|
867 | int g=gcd(m, n); |
---|
868 | if(g==0) |
---|
869 | { |
---|
870 | return(int(-1)); |
---|
871 | } |
---|
872 | m = m div g; |
---|
873 | n = n div g; |
---|
874 | ph = m^2+n^2-q*m*n; |
---|
875 | if(ph==1) |
---|
876 | { |
---|
877 | return(int(0)); |
---|
878 | } |
---|
879 | else |
---|
880 | { |
---|
881 | return(int(-1)); |
---|
882 | } |
---|
883 | } |
---|
884 | //---------------------------------------------------------- |
---|
885 | |
---|
886 | static proc shift(list l, int a, int b) |
---|
887 | { |
---|
888 | int sz=size(l); |
---|
889 | int i; |
---|
890 | for(i=1;i<=sz;i++) |
---|
891 | { |
---|
892 | l[i][1]=l[i][1]+a; |
---|
893 | l[i][2]=l[i][2]+b; |
---|
894 | } |
---|
895 | return(l); |
---|
896 | } |
---|
897 | //---------------------------------------------------------- |
---|
898 | |
---|
899 | static proc geomS(poly t, int d) |
---|
900 | { |
---|
901 | poly rez=1; |
---|
902 | int i; |
---|
903 | for(i=1;i<=d;i++) |
---|
904 | { |
---|
905 | rez=rez+t^i; |
---|
906 | } |
---|
907 | return(rez); |
---|
908 | } |
---|
909 | //---------------------------------------------------------- |
---|