1 | //////////////////////////////////////////////////////////////// |
---|
2 | version = "version chern.lib 4.1.3.0 Apr_2020 "; // $Id$ |
---|
3 | category = "Chern classes"; |
---|
4 | info=" |
---|
5 | LIBRARY: chern.lib Symbolic Computations with Chern classes, |
---|
6 | Computation of Chern classes |
---|
7 | |
---|
8 | AUTHOR: Oleksandr Iena, o.g.yena@gmail.com |
---|
9 | |
---|
10 | OVERVIEW: |
---|
11 | A toolbox for symbolic computations with Chern classes. |
---|
12 | The Aluffi's algorithms for computation of characteristic classes of algebraic varieties |
---|
13 | (Segre, Fulton, Chern-Schwartz-MacPherson classes) are implemented as well. |
---|
14 | |
---|
15 | |
---|
16 | REFERENCES: |
---|
17 | [1] Aluffi, Paolo Computing characteristic classes of projective schemes. |
---|
18 | Journal of Symbolic Computation, 35 (2003), 3-19. |
---|
19 | [2] Iena, Oleksandr, On symbolic computations with Chern classes: |
---|
20 | remarks on the library chern.lib for Singular, |
---|
21 | http://hdl.handle.net/10993/22395, 2015. |
---|
22 | [3] Lascoux, Alain, Classes de Chern d'un produit tensoriel. |
---|
23 | C. R. Acad. Sci., Paris, Ser. A 286, 385-387 (1978). |
---|
24 | [4] Manivel, Laurent Chern classes of tensor products, arXiv 1012.0014, 2010. |
---|
25 | |
---|
26 | PROCEDURES: |
---|
27 | symm(l [,N]); symmetric functions in the entries of l |
---|
28 | symNsym(f, c); symmetric and non-symmetric parts of a polynomial f |
---|
29 | CompleteHomog(N, l); complete homogeneous symmetric functions |
---|
30 | segre(N, c); Segre classes in terms of Chern classes |
---|
31 | chern(N, s); Chern classes in terms of Segre classes |
---|
32 | chNum(N, c); the non-zero Chern numbers in degree N in the entries of c |
---|
33 | chNumbers(N, c); the Chern numbers in degree N in the entries of c |
---|
34 | sum_of_powers(k, l); the sum of k-th powers of the entries of l |
---|
35 | powSumSym(c [,N]); the sums of powers [up to degree N] in terms |
---|
36 | of the elementary symmetric polynomials (entries of l) |
---|
37 | chAll(c [,N]); Chern character in terms of the Chern classes |
---|
38 | chAllInv(c); Chern classes in terms of the Chern character |
---|
39 | chHE(c); the highest term of the Chern character |
---|
40 | ChernRootsSum(a, b); the Chern roots of a direct sum |
---|
41 | chSum(c, C); the Chern classes of a direct sum |
---|
42 | ChernRootsDual(l); the Chern roots of the dual vector bundle |
---|
43 | chDual(c); the Chern classes of the dual vector bundle |
---|
44 | ChernRootsProd(l, L); the Chern roots of a tensor product of vector bundles |
---|
45 | chProd(r, c, R, C [,N]); Chern classes of a tensor product of vector bundles |
---|
46 | chProdE(c, C); Chern classes of a tensor product of vector bundles |
---|
47 | chProdL(r, c, R, C); Chern classes of a tensor product of vector bundles |
---|
48 | chProdLP(r, c, R, C); total Chern class of a tensor product of vector bundles |
---|
49 | chProdM(r, c, R, C); Chern classes of a tensor product of vector bundles |
---|
50 | chProdMP(r, c, R, C); total Chern class of a tensor product of vector bundles |
---|
51 | ChernRootsHom(l, L); the Chern roots of a Hom vector bundle |
---|
52 | chHom(r, c, R, C [,N]); Chern classes of the Hom-vector bundle |
---|
53 | ChernRootsSymm(n, l); the Chern roots of the n-th symmetric power |
---|
54 | of a vector bundle with Chern roots from l |
---|
55 | ChernRootsWedge(n, l); the Chern roots of the n-th exterior power |
---|
56 | of a vector bundle with Chern roots from l |
---|
57 | chSymm(k, r, c [,p]); the rank and the Chern classes of the k-th symmetric power |
---|
58 | of a vector bundle of rank r with Chern classes c |
---|
59 | chSymm2L(r, c); the rank and the Chern classes of the second symmetric power |
---|
60 | of a vector bundle of rank r with Chern classes c |
---|
61 | chSymm2LP(r, c); the total Chern class of the second symmetric power |
---|
62 | of a vector bundle of rank r with Chern classes c |
---|
63 | chWedge(k, r, c [,p]); the rank and the Chern classes of the k-th exterior power |
---|
64 | of a vector bundle of rank r with Chern classes c |
---|
65 | chWedge2L(r, c); the rank and the Chern classes of the second exterior power |
---|
66 | of a vector bundle of rank r with Chern classes c |
---|
67 | chWedge2LP(r, c); the total Chern class of the second exterior power |
---|
68 | of a vector bundle of rank r with Chern classes c |
---|
69 | todd(c [,n]); the Todd class |
---|
70 | toddE(c); the highest term of the Todd class |
---|
71 | Bern(n); the second Bernoulli numbers |
---|
72 | tdCf(n); the coefficients of the Todd class of a line bundle |
---|
73 | tdTerms(n, f); the terms of the Todd class of a line bundle |
---|
74 | corresponding to the Chern root t |
---|
75 | tdFactor(n, t); the Todd class of a line bundle corresponding |
---|
76 | to the Chern root t |
---|
77 | cProj(n); the total Chern class of (the tangent bundle on) |
---|
78 | the projective space P_n |
---|
79 | chProj(n); the Chern character of (the tangent bundle on) |
---|
80 | the projective space P_n |
---|
81 | tdProj(n); the Todd class of (the tangent bundle on) |
---|
82 | the projective space P_n |
---|
83 | eulerChProj(n, r, c); Euler characteristic of a vector bundle on |
---|
84 | the projective space P_n |
---|
85 | via Hirzebruch-Riemann-Roch theorem |
---|
86 | chNumbersProj(n); the Chern numbers of the projective space P_n |
---|
87 | classpoly(l, t); polynomial in t with coefficients from l |
---|
88 | (without constant term) |
---|
89 | chernPoly(l, t); Chern polynomial (constant term 1) |
---|
90 | chernCharPoly(r, l, t); polynomial in t corresponding to the Chern character |
---|
91 | (constant term r) |
---|
92 | toddPoly(td, t); polynomial in t corresponding to the Todd class |
---|
93 | (constant term 1) |
---|
94 | rHRR(N, ch, td); the main ingredient of the right-hand side |
---|
95 | of the Hirzebruch-Riemann-Roch formula |
---|
96 | SchurS(I, S); the Schur polynomial corresponding to partition I |
---|
97 | in terms of the Segre classes S |
---|
98 | SchurCh(I, C); the Schur polynomial corresponding to partition I |
---|
99 | in terms of the Chern classes C |
---|
100 | part(m, n); partitions of integers not exceeding n |
---|
101 | into m non-negative summands |
---|
102 | dualPart(I [,N]); partition dual to I |
---|
103 | PartC(I, m); the complement of a partition with respect to m |
---|
104 | partOver(n, J); partitions over a given partition J with summands not exceeding n |
---|
105 | partUnder(J); partitions under a given partition J |
---|
106 | SegreA(I); Segre class of the projective subscheme defined by I |
---|
107 | FultonA(I); Fulton class of the projective subscheme defined by I |
---|
108 | CSMA(I); Chern-Schwartz-MacPherson class of the |
---|
109 | projective subscheme defined by I |
---|
110 | EulerAff(I); Euler characteristic of the affine subvariety defined by I |
---|
111 | EulerProj(I); Euler characteristic of the projective subvariety defined by I |
---|
112 | "; |
---|
113 | |
---|
114 | LIB "general.lib"; |
---|
115 | LIB "lrcalc.lib"; // needed for chProdM(..) and chProdMP(..) |
---|
116 | //---------------------------------------------------------- |
---|
117 | |
---|
118 | proc symm(list l, list #) |
---|
119 | "USAGE: symm(l [,n]); l a list of polynomials, n integer |
---|
120 | RETURN: list of polynomials |
---|
121 | PURPOSE: computes the list of elementary symmetric functions in the entries of l |
---|
122 | EXAMPLE: example symm; shows an example |
---|
123 | NOTE: makes sense only for a list of polynomials |
---|
124 | " |
---|
125 | { |
---|
126 | int N=size(l); |
---|
127 | int n=size(l); |
---|
128 | if(size(#)!=0) |
---|
129 | { |
---|
130 | if( is_integer(#[1]) ) |
---|
131 | { |
---|
132 | N = #[1]; |
---|
133 | } |
---|
134 | } |
---|
135 | if(n==0) // if the list is empty, return the empty list |
---|
136 | { |
---|
137 | return(list()); |
---|
138 | } |
---|
139 | else |
---|
140 | { |
---|
141 | int i, j; |
---|
142 | list rez=list(1, l[1]); |
---|
143 | for(i=2; i<=n; i++) |
---|
144 | { |
---|
145 | if( i<=N ) |
---|
146 | { |
---|
147 | rez=rez+list(0); |
---|
148 | } |
---|
149 | for(j = min(i, N); j>=1; j--) |
---|
150 | { |
---|
151 | rez[j+1] = rez[j+1] + rez[j]*l[i]; |
---|
152 | } |
---|
153 | } |
---|
154 | return(delete(rez, 1)); |
---|
155 | } |
---|
156 | } |
---|
157 | example |
---|
158 | { |
---|
159 | "EXAMPLE:";echo =2; |
---|
160 | // elementary symmetric functions in x, y, z: |
---|
161 | ring r = 0, (x, y, z), dp; |
---|
162 | list l=(x, y, z); |
---|
163 | print(symm(l)); |
---|
164 | |
---|
165 | //now let us compute only the first two symmetric polynomials in a(1), ... , a(10) |
---|
166 | ring q= 0,(a(1..10)), dp; |
---|
167 | list l=a(1..10); |
---|
168 | print(symm(l, 2)); |
---|
169 | } |
---|
170 | //----------------------------------------------------------------------- |
---|
171 | |
---|
172 | proc symNsym(poly f, list c) |
---|
173 | "USAGE: symNsym(f, c); f polynomial; c list of polynomials |
---|
174 | RETURN: list with 2 poly entries |
---|
175 | PURPOSE: computes a symmetric and a non-symmetric part of f |
---|
176 | in terms of the elementary symmetric functions from c |
---|
177 | as well a non-symmetric remainder |
---|
178 | EXAMPLE: example symNsym; shows an example |
---|
179 | NOTE: constants are not considered symmetric |
---|
180 | " |
---|
181 | { |
---|
182 | ideal V=variables(f); // variables f depends on |
---|
183 | int nV=size(V); // their number |
---|
184 | if(nV==0) |
---|
185 | { |
---|
186 | return(list(f, 0)); |
---|
187 | } |
---|
188 | // now f is non-constant and does depend on some variables |
---|
189 | c=append_by_zeroes(nV, c); // append c by zeroes if it is too short |
---|
190 | def br@=basering; // remember the base ring |
---|
191 | // add additional variables to the base ring |
---|
192 | int ii; |
---|
193 | list l2 = ringlist(basering)[2]; |
---|
194 | for (ii = 1; ii <= nV; ii++) |
---|
195 | { |
---|
196 | l2[size(l2)+1] = "c@("+string(ii)+")"; |
---|
197 | } |
---|
198 | for (ii = 1; ii <= nV; ii++) |
---|
199 | { |
---|
200 | l2[size(l2)+1] = "A@("+string(ii)+")"; |
---|
201 | } |
---|
202 | ring r@ = create_ring(ringlist(basering)[1], l2, "dp", "no_minpoly"); |
---|
203 | ideal V=fetch(br@,V); |
---|
204 | poly f=fetch(br@,f); |
---|
205 | int i; |
---|
206 | for(i=1; i<=nV; i++) |
---|
207 | { |
---|
208 | f=subst(f, V[i], A@(i) ); // rename the variables of f into A@(1..nV) |
---|
209 | } |
---|
210 | int N1=nvars(basering)-nV+1; // the number of variable A@(1) |
---|
211 | poly rez1=0; // to be the expression in c@(i) of the symmetric part of f |
---|
212 | poly rez2=0; // to be the remainder |
---|
213 | poly mon; // monomial in c@(i) |
---|
214 | poly monc; // the corresponding expression in A@(i) |
---|
215 | list l=symm(list(A@(1..nV) )); // symmetric functions in A@(i) |
---|
216 | intvec v=leadexp(f), 0; // the exponent of the leading monomial |
---|
217 | while(v[N1]!=0) |
---|
218 | { |
---|
219 | mon=leadcoef(f); // leading coefficient of f |
---|
220 | monc=mon; |
---|
221 | for(i=1; v[N1+i-1]!=0 ;i++ ) |
---|
222 | { |
---|
223 | mon = mon*c@(i)^( v[N1+i-1]-v[N1+i] ); |
---|
224 | monc = monc*l[i]^( v[N1+i-1]-v[N1+i] ); // has the same leading coefficient as f |
---|
225 | } |
---|
226 | rez1=rez1+mon; // add a monomial |
---|
227 | f=f-monc; // subtract the monomial |
---|
228 | v=leadexp(f), 0; |
---|
229 | } |
---|
230 | while( leadexp(f)!=0 ) |
---|
231 | { |
---|
232 | rez2=rez2+lead(f); |
---|
233 | f=f-lead(f); |
---|
234 | } |
---|
235 | rez1=rez1+f; |
---|
236 | setring br@; // come back to the initial base ring |
---|
237 | // define the specialization homomorphism |
---|
238 | execute("map FF = r@,"+varstr(br@)+",c[1..nV], V[1..nV];"); |
---|
239 | return( list( FF(rez1), FF(rez2) ) ); |
---|
240 | } |
---|
241 | example |
---|
242 | { |
---|
243 | "EXAMPLE:";echo=2; |
---|
244 | ring r=0, (x,y,z, c(1..3)), dp; |
---|
245 | list l=c(1..3); |
---|
246 | // The symmetric part of f = 3x2 + 3y2 + 3z2 + 7xyz + y |
---|
247 | // in terms of the elemenatary symmetric functions c(1), c(2), c(3) |
---|
248 | // and the remainder |
---|
249 | poly f = 3x2 + 3y2 + 3z2 + 7xyz + y; |
---|
250 | print( symNsym(f, l) ); |
---|
251 | // Take a symmetrix polynomial in variables x and z |
---|
252 | f=x2+xz+z2; |
---|
253 | // Express it in terms of the elementary the symmetric functions |
---|
254 | print( symNsym(f, l)[1]); |
---|
255 | } |
---|
256 | //------------------------------------------------------------------------------------------- |
---|
257 | |
---|
258 | proc CompleteHomog(int N, list c) |
---|
259 | "USAGE: CompleteHomog(N, c); N integer, c list of polynomials |
---|
260 | RETURN: list of polynomials |
---|
261 | PURPOSE: computes the list of the complete homogeneous symmetric polynomials |
---|
262 | in terms of the elementary symmetric polynomials (entries of c) |
---|
263 | EXAMPLE: example CompleteHomog; shows an example |
---|
264 | NOTE: |
---|
265 | " |
---|
266 | { |
---|
267 | c=append_by_zeroes(N, c); |
---|
268 | if(N<0) // if N is negative, return the empty list |
---|
269 | { |
---|
270 | return(list()); |
---|
271 | } |
---|
272 | list rez=list(1); // the result will be computed here |
---|
273 | int i, j; |
---|
274 | int sign; |
---|
275 | poly f; |
---|
276 | for(i=1; i<=N; i++) // use the recursive formula |
---|
277 | { |
---|
278 | f=0; |
---|
279 | sign=1; |
---|
280 | for(j=1;j<=i; j++) // compute the next complete homogeneous symmetric polynomial |
---|
281 | { |
---|
282 | f=f+sign*c[j]*rez[i-j+1]; |
---|
283 | sign=-sign; |
---|
284 | } |
---|
285 | rez=rez+( list(f) ); |
---|
286 | } |
---|
287 | return(rez); |
---|
288 | } |
---|
289 | example |
---|
290 | { |
---|
291 | "EXAMPLE:";echo =2; |
---|
292 | ring r = 0, (x(1..3)), dp; |
---|
293 | list l=x(1..3); |
---|
294 | //Complete homogeneous symmetric polynomials up to degree 3 in variables x(1), x(2), x(3) |
---|
295 | print( CompleteHomog(3, l) ); |
---|
296 | } |
---|
297 | //----------------------------------------------------------------------- |
---|
298 | |
---|
299 | proc segre(list c, list #) |
---|
300 | "USAGE: segre(c[, N]); c list of polynomials, N integer |
---|
301 | RETURN: list of polynomials |
---|
302 | PURPOSE: computes the list of the Segre classes up to degree N |
---|
303 | in terms of the Chern classes from c |
---|
304 | EXAMPLE: example segre; shows an example |
---|
305 | NOTE: |
---|
306 | " |
---|
307 | { |
---|
308 | int N; |
---|
309 | if(size(#)>0) |
---|
310 | { |
---|
311 | if( is_integer(#[1]) ) |
---|
312 | { |
---|
313 | N=#[1]; |
---|
314 | } |
---|
315 | } |
---|
316 | else |
---|
317 | { |
---|
318 | N=size(c); |
---|
319 | } |
---|
320 | c=append_by_zeroes(N, c); |
---|
321 | if(N<0) // if N is negative, return the empty list |
---|
322 | { |
---|
323 | return(list()); |
---|
324 | } |
---|
325 | list rez=list(1); // the result will be computed here |
---|
326 | int i, j; |
---|
327 | poly f; |
---|
328 | for(i=1; i<=N; i++) // use the recursive formula |
---|
329 | { |
---|
330 | f=0; |
---|
331 | for(j=1;j<=i; j++) // compute the next Segre class |
---|
332 | { |
---|
333 | f=f-c[j]*rez[i-j+1]; |
---|
334 | } |
---|
335 | rez=rez+( list(f) ); |
---|
336 | } |
---|
337 | return(delete(rez,1)); |
---|
338 | } |
---|
339 | example |
---|
340 | { |
---|
341 | "EXAMPLE:";echo =2; |
---|
342 | ring r = 0, (c(1..3)), dp; |
---|
343 | list l=c(1..3); |
---|
344 | //Segre classes up to degree 5 in Chern classes c(1), c(2), c(3) |
---|
345 | print( segre(l, 5) ); |
---|
346 | } |
---|
347 | //----------------------------------------------------------------------- |
---|
348 | |
---|
349 | proc chern(list s, list #) |
---|
350 | "USAGE: chern(s); s list of polynomials |
---|
351 | RETURN: list of polynomials |
---|
352 | PURPOSE: computes the list of the Chern classes up to degree N |
---|
353 | in terms of the Segre classes from s |
---|
354 | EXAMPLE: example chern; shows an example |
---|
355 | NOTE: |
---|
356 | " |
---|
357 | { |
---|
358 | return( segre(s, #) ); |
---|
359 | } |
---|
360 | example |
---|
361 | { |
---|
362 | "EXAMPLE:"; echo =2; |
---|
363 | ring r = 0, (s(1..3)), dp; |
---|
364 | list l=s(1..3); |
---|
365 | // Chern classes in Segre classes s(1), s(2), s(3) |
---|
366 | print( chern(l) ); |
---|
367 | // This procedure is inverse to segre(...). Indeed: |
---|
368 | print( segre(chern(l), 3) ); |
---|
369 | } |
---|
370 | //----------------------------------------------------------------------- |
---|
371 | |
---|
372 | proc chNum(int N, list c) |
---|
373 | "USAGE: chNum(N, c); N integer, c list |
---|
374 | RETURN: list |
---|
375 | PURPOSE: computes the Chern numbers of a vector bundle with Chern classes c |
---|
376 | on a complex manifold (variety) of dimension N, |
---|
377 | the zeroes corresponding to the higher zero Chern classes are ignored |
---|
378 | EXAMPLE: example chNumbers; shows an example |
---|
379 | NOTE: computes basically the partitions of N |
---|
380 | in summands not greater than the length of c |
---|
381 | " |
---|
382 | { |
---|
383 | int n=size(c); |
---|
384 | if(N<0) |
---|
385 | { |
---|
386 | print(""); |
---|
387 | return( list() ); |
---|
388 | } |
---|
389 | if( (n==0) || (N==0) ) |
---|
390 | { |
---|
391 | return(list(1)); |
---|
392 | } |
---|
393 | if(n==1) // if there is only one entry in the list |
---|
394 | { |
---|
395 | return(list(c[1]^N)); |
---|
396 | } |
---|
397 | int i; |
---|
398 | int j; |
---|
399 | poly f; // the powers of the last variable will be stored here |
---|
400 | list l=delete(c, n); // delete the last variable |
---|
401 | list L; |
---|
402 | list rez=chNum(N, l); // monomials not involving the last variable |
---|
403 | for(i=1;i<=(N div n); i++) // add the monomials involving the last variable |
---|
404 | { |
---|
405 | f=c[n]^i; // the power of the last variable |
---|
406 | // monomials without the last variable that, |
---|
407 | // multiplied by the i-th power of the last variable, |
---|
408 | // give a monomial of the required type |
---|
409 | L=chNum(N-n*i, l); |
---|
410 | for(j=1; j<=size(L) ;j++) // multiply every such monomial |
---|
411 | { |
---|
412 | L[j]=L[j]*f; // by the i-th power of the last variable |
---|
413 | } |
---|
414 | rez=rez+L; // add the monomials involving the i-th power of the last variable |
---|
415 | } |
---|
416 | return(rez); |
---|
417 | } |
---|
418 | example |
---|
419 | { |
---|
420 | "EXAMPLE:";echo=2; |
---|
421 | ring r = 0, (c(1..2)), dp; |
---|
422 | list l=c(1..2); |
---|
423 | // Let c(1) be a variable of degree 1, let c(2) be a variable of degree 2. |
---|
424 | // The monomials in c(1) and c(2) of weighted degree 5 are: |
---|
425 | print( chNum( 5, l ) ); |
---|
426 | |
---|
427 | // Compare the result to the output of chNumbers(...): |
---|
428 | print( chNumbers(5, l) ); |
---|
429 | } |
---|
430 | //---------------------------------------------------------------------------------------- |
---|
431 | |
---|
432 | proc chNumbers(int r, list c) |
---|
433 | "USAGE: chNumbers(r, c); r integer, c list |
---|
434 | RETURN: list |
---|
435 | PURPOSE: computes the Chern numbers of a vector bundle with Chern classes c |
---|
436 | on a complex manifold (variety) of dimension r |
---|
437 | EXAMPLE: example chNumbers; shows an example |
---|
438 | NOTE: computes basically the partitions of r |
---|
439 | " |
---|
440 | { |
---|
441 | if(r<0) |
---|
442 | { |
---|
443 | print("The dimension of a manifold must be a non-negative integer!"); |
---|
444 | return(list()); // return the empty list in this case |
---|
445 | } |
---|
446 | if(r==0) |
---|
447 | { |
---|
448 | return(list(1)); |
---|
449 | } |
---|
450 | //----------------- |
---|
451 | // from now on r>0 |
---|
452 | //---------------- |
---|
453 | int n=size(c); |
---|
454 | c=append_by_zeroes(r, c); |
---|
455 | c=c[1..r]; // throw away redundant data |
---|
456 | return(chNum(r, c)); |
---|
457 | } |
---|
458 | example |
---|
459 | { |
---|
460 | "EXAMPLE:";echo=2; |
---|
461 | ring r = 0, (c(1..3)), dp; |
---|
462 | list l=c(1..3); |
---|
463 | // The Chern numbers of a vector bundle with Chern classes c(1), c(2), c(3) |
---|
464 | // on a 3-fold: |
---|
465 | print( chNumbers( 3, l ) ); |
---|
466 | |
---|
467 | // If the highest Chern class is zero, the Chern numbers are: |
---|
468 | l=c(1..2); |
---|
469 | print( chNumbers( 3, l ) ); |
---|
470 | |
---|
471 | // Compare this to the output of chNum(...): |
---|
472 | print( chNum( 3, l ) ); |
---|
473 | } |
---|
474 | //--------------------------------------------------------------------------------------- |
---|
475 | |
---|
476 | proc sum_of_powers(int k, list l) |
---|
477 | "USAGE: sum_of_powers(k, l); k non-negative integer, l list of polynomials |
---|
478 | RETURN: polynomial |
---|
479 | PURPOSE: computes the sum of k-th powers of the entries of l |
---|
480 | EXAMPLE: example sum_of_powers; shows an example |
---|
481 | NOTE: returns 0 if k is negative |
---|
482 | " |
---|
483 | { |
---|
484 | if(k<0) // return 0 if k is negative |
---|
485 | { |
---|
486 | print("The exponent must be non-negative; 0 has been returned"); |
---|
487 | return(0); |
---|
488 | } |
---|
489 | int i; |
---|
490 | int n=size(l); |
---|
491 | poly rez; // the result will be computed here |
---|
492 | for(i=1;i<=n;i++) // compute the sum of powers |
---|
493 | { |
---|
494 | rez=rez+l[i]^k; |
---|
495 | } |
---|
496 | return(rez); |
---|
497 | } |
---|
498 | example |
---|
499 | { |
---|
500 | "EXAMPLE:";echo =2; |
---|
501 | ring r = 0, (x, y, z), dp; |
---|
502 | list l=x, y, z; |
---|
503 | //sum of 7-th powers of x, y, z |
---|
504 | print( sum_of_powers(7, l) ); |
---|
505 | } |
---|
506 | //----------------------------------------------------------------------- |
---|
507 | |
---|
508 | proc powSumSym(list c, list #) |
---|
509 | "USAGE: powSumSym(l [,N]); l a list of polynomials, N integer |
---|
510 | RETURN: list of polynomials |
---|
511 | PURPOSE: computes the expressions for the sums of powers [up to degree N] |
---|
512 | in terms of the elementary symmetric polynomials (entries of l), |
---|
513 | EXAMPLE: example powSumSym; shows an example |
---|
514 | NOTE: returns the terms of the Chern character |
---|
515 | multiplied by the corresponding factorials |
---|
516 | " |
---|
517 | { |
---|
518 | int n; |
---|
519 | if( size(#) == 0 ) // if there are no optional parameters |
---|
520 | { |
---|
521 | n = size(c); // set n to be the length of c |
---|
522 | } |
---|
523 | else // if there are optional parameters |
---|
524 | { |
---|
525 | if( is_integer(#[1])) // if the first optional parameter is an integer |
---|
526 | { |
---|
527 | n = max( #[1], 0 ); // if the parameter is negative, reset it to be zero |
---|
528 | c = append_by_zeroes(n, c); // if n is greater than the length of c, append c by zeroes |
---|
529 | if( n != 0 ) // if n is non-zero |
---|
530 | { |
---|
531 | c = c[1..n]; // take into account only the first n entries of c |
---|
532 | } |
---|
533 | } |
---|
534 | else // if the optional parameter is not an integer, then |
---|
535 | { |
---|
536 | n=size(c); // ignore it and set n to be the length of c |
---|
537 | } |
---|
538 | } |
---|
539 | list rez; // the result will be computed here |
---|
540 | if(n==0) // return the empty list |
---|
541 | { |
---|
542 | return(rez) |
---|
543 | } |
---|
544 | else // otherwise proceed as follows: |
---|
545 | { |
---|
546 | // first compute the sums of powers of the Chern roots |
---|
547 | // in terms of the Chern classes using the Newton's identities |
---|
548 | int i, j, sign; |
---|
549 | poly f; |
---|
550 | // the first term of the Chern character coincides with the first Chern class, |
---|
551 | // or equivalently with the sum of Chern roots |
---|
552 | rez = rez + list(c[1]); |
---|
553 | // compute the sums of powers of Chern roots recursively using the Newton's identities |
---|
554 | for(j=2; j<=n; j++) |
---|
555 | { |
---|
556 | sign=1; |
---|
557 | f=0; |
---|
558 | for(i=1; i<j; i++) |
---|
559 | { |
---|
560 | f=f + c[i]*sign*rez[j-i]; |
---|
561 | sign = -sign; |
---|
562 | } |
---|
563 | f=f+sign*j*c[j]; |
---|
564 | rez=rez+list(f); // add the newly computed sum of powers of Chern roots to the list |
---|
565 | } |
---|
566 | return(rez); // return the result |
---|
567 | } |
---|
568 | } |
---|
569 | example |
---|
570 | { |
---|
571 | "EXAMPLE:";echo =2; |
---|
572 | // the expressions of the first 3 sums of powers of 3 variables a(1), a(2), a(3) |
---|
573 | // in terms of the elementary symmetric polynomials c(1), c(2), c(3): |
---|
574 | ring r = 0, (c(1..3)), dp; |
---|
575 | list l=(c(1..3)); |
---|
576 | print(powSumSym(l)); |
---|
577 | // The first 5 sums in the same situation |
---|
578 | print(powSumSym(l, 5)); |
---|
579 | } |
---|
580 | //--------------------------------------------------------------------------------- |
---|
581 | |
---|
582 | proc chAll(list c, list #) |
---|
583 | "USAGE: chAll(l [,N]); l a list of polynomials, N integer |
---|
584 | RETURN: list of polynomials |
---|
585 | PURPOSE: computes the list of terms of positive degree [up to degree N] of |
---|
586 | the Chern character, where the entries of l are considered as the Chern classes |
---|
587 | EXAMPLE: example chAll; shows an example |
---|
588 | NOTE: makes sense only for a list of polynomials |
---|
589 | " |
---|
590 | { |
---|
591 | list rez; // to be the result |
---|
592 | rez = powSumSym(c, #); // get the sums of powers of the Chern roots |
---|
593 | int n = size(rez); |
---|
594 | bigint fct=1; |
---|
595 | int i; |
---|
596 | for(i=1;i<=n;i++) // get the terms of the Chern character |
---|
597 | { |
---|
598 | fct=fct*i; |
---|
599 | rez[i]=rez[i]/fct; |
---|
600 | } |
---|
601 | return(rez); // return the result |
---|
602 | } |
---|
603 | example |
---|
604 | { |
---|
605 | "EXAMPLE:";echo =2; |
---|
606 | // Chern character (terms of degree 1, 2, 3) |
---|
607 | // corresponding to the Chern classes c(1), c(2), c(3): |
---|
608 | ring r = 0, (c(1..3)), dp; |
---|
609 | list l=(c(1..3)); |
---|
610 | print(chAll(l)); |
---|
611 | // terms up to degree 5 in the same situation |
---|
612 | print(chAll(l, 5)); |
---|
613 | } |
---|
614 | //--------------------------------------------------------------------------------- |
---|
615 | |
---|
616 | proc chAllInv(list c) |
---|
617 | "USAGE: chAllInv(l); l a list of polynomials |
---|
618 | RETURN: list of polynomials |
---|
619 | PURPOSE: procedure inverse to chAll(), computes the list of Chern classes |
---|
620 | from the list of terms of positive degree of the Chern character |
---|
621 | EXAMPLE: example chAllInv; shows an example |
---|
622 | NOTE: makes sense only for a list of polynomials |
---|
623 | " |
---|
624 | { |
---|
625 | int n = size(c); |
---|
626 | list rez; |
---|
627 | if(n==0) // if the list of terms of Chern character is empty, return the empty list |
---|
628 | { |
---|
629 | return(rez); |
---|
630 | } |
---|
631 | else // otherwise compute the result using the Newton's identities |
---|
632 | { |
---|
633 | int j, i, sign; |
---|
634 | poly f; |
---|
635 | // transform the list of terms of the Chern character |
---|
636 | // to the list of sums of powers of Chern roots |
---|
637 | //bigint fct=1; |
---|
638 | for(i=1; i<=n; i++) |
---|
639 | { |
---|
640 | //fct=fct*i; |
---|
641 | //c[i]=fct*c[i]; |
---|
642 | c[i]=factorial(i)*c[i]; |
---|
643 | } |
---|
644 | // the first Chern class coincides with the first degree term of the Chern character |
---|
645 | rez=rez+list(c[1]); |
---|
646 | // compute the higher Chern classes recursively using the Newton's identities |
---|
647 | for(j=2;j<=n;j++) |
---|
648 | { |
---|
649 | sign=1;f=0; |
---|
650 | for(i=1;i<j;i++) |
---|
651 | { |
---|
652 | f=f+ c[i]*sign*rez[j-i]; |
---|
653 | sign=-sign; |
---|
654 | } |
---|
655 | f=f+sign*c[j]; |
---|
656 | rez=rez+list(f/j); |
---|
657 | } |
---|
658 | return(rez); // return the result |
---|
659 | } |
---|
660 | } |
---|
661 | example |
---|
662 | { |
---|
663 | "EXAMPLE:";echo=2; |
---|
664 | // first 3 Chern classes in terms of the first 3 terms |
---|
665 | // of the Chern character Chern ch(1), ch(2), ch(3): |
---|
666 | ring r = 0, (ch(1..3)), dp; |
---|
667 | list l=(ch(1..3)); |
---|
668 | print(chAllInv(l)); |
---|
669 | // let's see that chAllInv() is inverse to chAll() |
---|
670 | print( chAll( chAllInv(l) ) ); |
---|
671 | } |
---|
672 | //--------------------------------------------------------------------------------- |
---|
673 | |
---|
674 | proc chHE(list c) |
---|
675 | "USAGE: chHE(c); c list of polynomials |
---|
676 | RETURN: polynomial |
---|
677 | PURPOSE: computes the highest relevant term of the Chern character |
---|
678 | EXAMPLE: example chHE; shows an example |
---|
679 | NOTE: uses the elimination and is extremely inefficient, |
---|
680 | is included just for comparison with chAll(c) |
---|
681 | " |
---|
682 | { |
---|
683 | int i; |
---|
684 | // insure that the entries of c are polynomials |
---|
685 | // in order to be able to apply maps |
---|
686 | for(i=1;i<=size(c);i++) |
---|
687 | { |
---|
688 | c[i]=poly(c[i]); |
---|
689 | } |
---|
690 | int n=size(c); |
---|
691 | if(n==0) // in this case return the empty list |
---|
692 | { |
---|
693 | return(list()); |
---|
694 | } |
---|
695 | else // otherwise proceed as follows |
---|
696 | { |
---|
697 | def br@=basering; // remember the base ring |
---|
698 | // add additional variables c@, a@(1..n) to the base ring |
---|
699 | list l3 = "c@"; |
---|
700 | l3 = l3+ ringlist(basering)[2]; |
---|
701 | for (int ii = 1; ii <= n; ii++) |
---|
702 | { |
---|
703 | l3[size(l3)+1] = "a@("+string(ii)+")"; |
---|
704 | } |
---|
705 | ring r@ = create_ring(ringlist(basering)[1], l3, "lp", "no_minpoly"); |
---|
706 | execute( "map F= br@,"+varstr(br@)+";" ); // define the corresponding inclusion of rings |
---|
707 | list c=F(c); // embed c in the bigger ring |
---|
708 | poly rez; |
---|
709 | list A=a@(1..n); |
---|
710 | list sym=symm(A); |
---|
711 | ideal I; |
---|
712 | poly E=1; // to be the product of variables which should be eliminated |
---|
713 | for(i=1;i<=n;i++) |
---|
714 | { |
---|
715 | E=E*a@(i); // compute the product of the variables that must be eliminated |
---|
716 | I=I, c[i]-sym[i]; |
---|
717 | } |
---|
718 | I=I, c@-sum_of_powers(n, A); |
---|
719 | I=simplify(elim(I, E),1); |
---|
720 | rez = -subst(I[1], c@, 0); |
---|
721 | setring br@; // come back to the initial base ring |
---|
722 | execute( "map FF= r@,0,"+varstr(br@)+";" ); // define the specialization homomorphism |
---|
723 | poly rez=FF(rez); // bring the result to the base ring |
---|
724 | return( (1/factorial(n))*rez); |
---|
725 | } |
---|
726 | } |
---|
727 | example |
---|
728 | { |
---|
729 | "EXAMPLE:";echo =2; |
---|
730 | ring r = 0, (c(1..3)), dp; |
---|
731 | list l=c(1..3); |
---|
732 | //the third degree term of the Chern character |
---|
733 | print( chHE(l) ); |
---|
734 | } |
---|
735 | //---------------------------------------------------------------------- |
---|
736 | |
---|
737 | proc ChernRootsSum(list a, list b) |
---|
738 | "USAGE: ChernRootsSum(a, b); a, b lists of polynomials |
---|
739 | RETURN: list of polynomials |
---|
740 | PURPOSE: computes the Chern roots of the direct (Whitney) sum |
---|
741 | of a vector bundle with Chern roots a and a vector bundle with Chern roots b |
---|
742 | EXAMPLE: example ChernRootsSum; shows an example |
---|
743 | NOTE: |
---|
744 | " |
---|
745 | { |
---|
746 | return(a+b); |
---|
747 | } |
---|
748 | example |
---|
749 | { |
---|
750 | "EXAMPLE:";echo =2; |
---|
751 | ring r = 0, (a(1..3), b(1..2)), dp; |
---|
752 | // assume a(1), a(2), a(3) are the Chern roots of a vector bundle E |
---|
753 | // assume b(1), b(2) are the Chern roots of a vector bundle F |
---|
754 | list l=a(1..3); |
---|
755 | list L=b(1..2); |
---|
756 | // the Chern roots of their direct sum is |
---|
757 | print( ChernRootsSum(l, L) ); |
---|
758 | } |
---|
759 | //---------------------------------------------------------------------- |
---|
760 | |
---|
761 | proc chSum(list c, list C) |
---|
762 | "USAGE: chSum(c, C); c, C lists of polynomials |
---|
763 | RETURN: list of polynomials |
---|
764 | PURPOSE: computes the Chern classes of a direct sum of two vector bundles |
---|
765 | EXAMPLE: example chSum; shows an example |
---|
766 | NOTE: |
---|
767 | " |
---|
768 | { |
---|
769 | int N=size(c)+size(C); |
---|
770 | c=append_by_zeroes(N, c); // append by zeroes if necessary |
---|
771 | C=append_by_zeroes(N, C); // append by zeroes if necessary |
---|
772 | list rez; // to be the result |
---|
773 | int i; |
---|
774 | int j; |
---|
775 | poly f; |
---|
776 | for(i=1;i<=N;i++) |
---|
777 | { |
---|
778 | f=c[i]+C[i]; |
---|
779 | for(j=1;j<i;j++) |
---|
780 | { |
---|
781 | f=f+c[j]*C[i-j]; |
---|
782 | } |
---|
783 | rez=rez+list(f); |
---|
784 | } |
---|
785 | return(rez); |
---|
786 | } |
---|
787 | example |
---|
788 | { |
---|
789 | "EXAMPLE:";echo =2; |
---|
790 | ring r = 0, (c(1..3), C(1..2)), dp; |
---|
791 | // Let E be a vector bundle with Chern classes c(1), c(2), c(3). |
---|
792 | // Let F be a vector bundle with Chern classes C(1), C(2). |
---|
793 | list l=c(1..3); |
---|
794 | list L=C(1..2); |
---|
795 | // Then the Chern classes of their direct sum are |
---|
796 | print( chSum(l, L) ); |
---|
797 | } |
---|
798 | //---------------------------------------------------------------------- |
---|
799 | |
---|
800 | proc ChernRootsDual(list l) |
---|
801 | "USAGE: ChernRootsDual(l); l a list of polynomials |
---|
802 | RETURN: list of polynomials |
---|
803 | PURPOSE: computes the Chern roots of the dual vector bundle |
---|
804 | of a vector bundle with Chern roots from l |
---|
805 | EXAMPLE: example ChernRootsDual; shows an example |
---|
806 | NOTE: |
---|
807 | " |
---|
808 | { |
---|
809 | int n=size(l); |
---|
810 | int i; |
---|
811 | for(i=1;i<=n;i++) // change the sign of the entries of a |
---|
812 | { |
---|
813 | l[i]=-l[i]; |
---|
814 | } |
---|
815 | return(l); |
---|
816 | } |
---|
817 | example |
---|
818 | { |
---|
819 | "EXAMPLE:";echo =2; |
---|
820 | ring r = 0, (a(1..3)), dp; |
---|
821 | // assume a(1), a(2), a(3) are the Chern roots of a vector bundle |
---|
822 | list l=a(1..3); |
---|
823 | // the Chern roots of the dual vector bundle |
---|
824 | print( ChernRootsDual(l) ); |
---|
825 | } |
---|
826 | //---------------------------------------------------------------------- |
---|
827 | |
---|
828 | proc chDual(list c) |
---|
829 | "USAGE: chDual(c); c list of polynomials |
---|
830 | RETURN: list of polynomials |
---|
831 | PURPOSE: computes the list of Chern classes of the dual vector bundle |
---|
832 | EXAMPLE: example chDual; shows an example |
---|
833 | NOTE: |
---|
834 | " |
---|
835 | { |
---|
836 | int n=size(c); |
---|
837 | int i; |
---|
838 | for(i=1;i<=n;i=i+2) |
---|
839 | { |
---|
840 | c[i]=-c[i]; |
---|
841 | } |
---|
842 | return(c); |
---|
843 | } |
---|
844 | example |
---|
845 | { |
---|
846 | "EXAMPLE:"; echo=2; |
---|
847 | // Chern classes of a vector bundle that is dual to a vector bundle |
---|
848 | // with Chern classes c(1), c(2), c(3) |
---|
849 | ring r=0, (c(1..3)), dp; |
---|
850 | list l=c(1..3); |
---|
851 | print(chDual(l)); |
---|
852 | } |
---|
853 | //----------------------------------------------------------------------------------------- |
---|
854 | |
---|
855 | proc ChernRootsProd(list a, list b) |
---|
856 | "USAGE: ChernRootsProd(a, b); a, b lists of polynomials |
---|
857 | RETURN: list of polynomials |
---|
858 | PURPOSE: computes the Chern roots of the tensor product of a vector bundle with Chern roots a |
---|
859 | and a vector bundles with Chern roots b |
---|
860 | EXAMPLE: example ChernRootsProd; shows an example |
---|
861 | NOTE: |
---|
862 | " |
---|
863 | { |
---|
864 | int na=size(a); |
---|
865 | int nb=size(b); |
---|
866 | int i; |
---|
867 | int j; |
---|
868 | list rez; // the result will be computed here |
---|
869 | for(i=1;i<=na;i++) // compute the result |
---|
870 | { |
---|
871 | for(j=1;j<=nb;j++) |
---|
872 | { |
---|
873 | rez=rez+list(a[i]+b[j]); |
---|
874 | } |
---|
875 | } |
---|
876 | return(rez); |
---|
877 | } |
---|
878 | example |
---|
879 | { |
---|
880 | "EXAMPLE:"; echo=2; |
---|
881 | ring r=0, (a(1..2), b(1..3)), dp; |
---|
882 | list l=a(1..2); |
---|
883 | list L=b(1..3); |
---|
884 | // Chern roots of the tensor product of a vector bundle with Chern roots a(1), a(2) |
---|
885 | // and a vector bundle with Chern roots b(1), b(2), b(3) |
---|
886 | print(ChernRootsProd(l, L)); |
---|
887 | } |
---|
888 | //----------------------------------------------------------------------------------------- |
---|
889 | |
---|
890 | proc chProd(def r, list c, def R, list C, list #) |
---|
891 | "USAGE: chProd(r, c, R, C [, N]); r, R polynomials (integers); |
---|
892 | c, C lists of polynomials, N integer |
---|
893 | RETURN: list of polynomials |
---|
894 | PURPOSE: computes the list of Chern classes of the product of two vector bundles |
---|
895 | in terms of their ranks and Chern clases [up to degree N] |
---|
896 | EXAMPLE: example chProd; shows an example |
---|
897 | NOTE: |
---|
898 | " |
---|
899 | { |
---|
900 | // check the input data |
---|
901 | if( is_integer(r) ) // if r is an integer |
---|
902 | { |
---|
903 | if(r<=0) // if r is negative or zero return the empty list |
---|
904 | { |
---|
905 | return( list() ); |
---|
906 | } |
---|
907 | //---------------------------- |
---|
908 | //now r is a positive integer |
---|
909 | //---------------------------- |
---|
910 | c=append_by_zeroes(r, c); // append c by zeroes if r is greater than the length of c |
---|
911 | c=c[1..r]; // make c shorter (of length r) if r is smaller than the length of c |
---|
912 | } |
---|
913 | if( is_integer(R) ) // if R is an integer |
---|
914 | { |
---|
915 | if(R<=0) // if R is negative or zero return the empty list |
---|
916 | { |
---|
917 | return( list() ); |
---|
918 | } |
---|
919 | //---------------------------- |
---|
920 | //now R is a positive integer |
---|
921 | //---------------------------- |
---|
922 | C=append_by_zeroes(R, C); // append C by zeroes if R is greater than the length of C |
---|
923 | C=C[1..R]; // make C shorter (of length R) if R is smaller than the length of C |
---|
924 | } |
---|
925 | //---------------------------------------------------------- |
---|
926 | //now r > 0 if it is an integer; R > 0 if it is an integer |
---|
927 | //---------------------------------------------------------- |
---|
928 | int n; |
---|
929 | if( is_integer(r) && is_integer(R) ) // if both r and R are integers |
---|
930 | { |
---|
931 | n=r*R; // set n to be the rank of the product bundle |
---|
932 | } |
---|
933 | else // otherwise define the rank of the product vector bundle by |
---|
934 | { |
---|
935 | n=size(c)*size(C); // looking at the lengths of c and C |
---|
936 | } |
---|
937 | if( size(#) != 0 ) // if there is an optional parameter |
---|
938 | { |
---|
939 | if( is_integer( #[1] ) ) // if this parameter is an integer |
---|
940 | { |
---|
941 | if( #[1]<=0 ) // if it is negative or zero, return the empty list |
---|
942 | { |
---|
943 | return( list() ); |
---|
944 | } |
---|
945 | // now #[1] is positive |
---|
946 | // the product bundle can only have non-zero Chern classes up to degree n |
---|
947 | // so ignore the optional parameter if it is greater than n |
---|
948 | n = min(#[1], n); |
---|
949 | } |
---|
950 | } |
---|
951 | if(n==0) // if n is zero, return the empty list |
---|
952 | { |
---|
953 | return( list() ); |
---|
954 | } |
---|
955 | //----------------------------------------------------------- |
---|
956 | //now n is positive, we can perform the relevant computations |
---|
957 | //----------------------------------------------------------- |
---|
958 | int i, j; |
---|
959 | c=append_by_zeroes(n, c); // append c by zeroes up to degree n |
---|
960 | C=append_by_zeroes(n, C); // append C by zeroes up to degree n |
---|
961 | c=c[1..n]; // throw away the redundant data if needed |
---|
962 | C=C[1..n]; // throw away the redundant data if needed |
---|
963 | // build the list of all terms of the Chern characters: for rank r, and Chern classes c |
---|
964 | list ch = list(r) + chAll(c); |
---|
965 | list CH = list(R) + chAll(C); // do the same for rank R and Chern classes C |
---|
966 | poly f; |
---|
967 | list chP; |
---|
968 | // compute the list of the non-zero degree terms of the Chern character |
---|
969 | // of the tensor product of two vector bundles |
---|
970 | for(i=1;i<=n;i++) // using the multiplicativity of the Chern character |
---|
971 | { |
---|
972 | f=0; |
---|
973 | for(j=0;j<=i;j++) |
---|
974 | { |
---|
975 | f=f+ch[j+1]*CH[i-j+1]; |
---|
976 | } |
---|
977 | chP=chP+list(f); |
---|
978 | } |
---|
979 | return( chAllInv(chP) ); // return the corresponding Chern classes |
---|
980 | } |
---|
981 | example |
---|
982 | { |
---|
983 | "EXAMPLE:"; echo =2; |
---|
984 | ring H = 0, ( r, R, c(1..3), C(1..2) ), dp; |
---|
985 | list l=c(1..3); |
---|
986 | list L=C(1..2); |
---|
987 | // the Chern classes of the tensor product of a vector bundle E of rank 3 |
---|
988 | // with Chern classes c(1), c(2), c(3) |
---|
989 | // and a vector bundle F of rank 2 with Chern classes C(1) and C(2): |
---|
990 | print( chProd(3, l, 2, L) ); |
---|
991 | // the first two Chern classes of the tensor product |
---|
992 | // of a vector bundle E of rank r with Chern classes c(1) and c(2) |
---|
993 | // and a vector bundle G of rank R with Chern classes C(1) and C(2) |
---|
994 | // this gives the Chern classes of a tensor product on a complex surface |
---|
995 | l=c(1..2); |
---|
996 | L=C(1..2); |
---|
997 | print( chProd(r, l, R, L, 2 ) ); |
---|
998 | } |
---|
999 | //--------------------------------------------------------------------------------- |
---|
1000 | |
---|
1001 | proc chProdE(list c, list C) |
---|
1002 | "USAGE: chProdE(c, C); c, C lists of polynomials |
---|
1003 | RETURN: list of polynomials |
---|
1004 | PURPOSE: computes the list of Chern classes of the product |
---|
1005 | of two vector bundles in terms of their Chern clases |
---|
1006 | EXAMPLE: example chProdE; shows an example |
---|
1007 | NOTE: makes sense only for (lists of) polynomials; |
---|
1008 | uses elimination, hence very inefficient; |
---|
1009 | included only for comparison with chProd(...) |
---|
1010 | " |
---|
1011 | { |
---|
1012 | int r=size(c); |
---|
1013 | int R=size(C); |
---|
1014 | // insure that the entries of c and C are polynomials |
---|
1015 | // in order to be able to apply maps |
---|
1016 | int i,j; |
---|
1017 | for(i=1;i<=r;i++) |
---|
1018 | { |
---|
1019 | c[i]=poly(c[i]); |
---|
1020 | } |
---|
1021 | for(i=1;i<=R;i++) |
---|
1022 | { |
---|
1023 | C[i]=poly(C[i]); |
---|
1024 | } |
---|
1025 | if( (r==0) && (R==0) ) // if one of the ranks is 0, |
---|
1026 | { |
---|
1027 | return( list() ); // return the empty list (zero bundles have no Chern classes) |
---|
1028 | } |
---|
1029 | //------------------------------------ |
---|
1030 | //now both r and R are greater than 0 |
---|
1031 | //------------------------------------ |
---|
1032 | int n=r*R; // the rank of the product of two vector bundles |
---|
1033 | def br@=basering; // remember the base ring |
---|
1034 | // add additional variables a@(1..r), b@(1..R), x@ to the base ring |
---|
1035 | int ii; |
---|
1036 | list l4 = "x@"; |
---|
1037 | l4 = l4+ ringlist(basering)[2]; |
---|
1038 | for (ii = 1; ii <= r; ii++) |
---|
1039 | { |
---|
1040 | l4[size(l4)+1] = "a@("+string(ii)+")"; |
---|
1041 | } |
---|
1042 | for (ii = 1; ii <= R; ii++) |
---|
1043 | { |
---|
1044 | l4[size(l4)+1] = "b@("+string(ii)+")"; |
---|
1045 | } |
---|
1046 | ring r@ = create_ring(ringlist(basering)[1], l4, "lp", "no_minpoly"); |
---|
1047 | execute( "map F= br@,"+varstr(br@)+";" ); // define the corresponding inclusion of rings |
---|
1048 | list c=F(c); // embed c in the bigger ring |
---|
1049 | list C=F(C); // embed C in the bigger ring |
---|
1050 | list A=a@(1..r); // list of Chern roots of the first vector bundle |
---|
1051 | list syma = symm(A); // symmetric functions in the Chern roots of the first vector bundles |
---|
1052 | list B=b@(1..R); // list of Chern roots of the second vector bundle |
---|
1053 | list symb=symm(B); // symmetric functions in the Chern roots of the second vector bundles |
---|
1054 | ideal I; |
---|
1055 | // the product of variables (all Chern roots) which should be eliminated |
---|
1056 | poly E=product(A)*product(B); |
---|
1057 | for(i=1; i<=r; i++) |
---|
1058 | { |
---|
1059 | for(j=1; j<=R; j++) |
---|
1060 | { |
---|
1061 | I=I, c[i]-syma[i], C[j]-symb[j]; // add the relations |
---|
1062 | } |
---|
1063 | } |
---|
1064 | // the Chern roots of the tensor product in terms of the Chern roots of the factors |
---|
1065 | list crt=ChernRootsProd(A, B); |
---|
1066 | list Cf=symm(crt); // Chern classes of the product in terms of the Chern roots of the factors |
---|
1067 | list rez; // the result will be computed here |
---|
1068 | ideal J; |
---|
1069 | for(i=1;i<=n;i++) |
---|
1070 | { |
---|
1071 | J = I, x@-Cf[i]; // add the equation for the i-th Chern class to the ideal of relations |
---|
1072 | J = simplify(elim(J, E), 1); // eliminate the Chern roots |
---|
1073 | // get the expression for the i-th Chern class of the product |
---|
1074 | // in terms of the Chern classes of the factors |
---|
1075 | rez = rez + list( -subst(J[1], x@, 0) ); |
---|
1076 | } |
---|
1077 | setring br@; // come back to the initial base ring |
---|
1078 | execute( "map FF= r@, 0,"+varstr(br@)+";" ); // define the specialization homomorphism t@=0 |
---|
1079 | list rez=FF(rez); // bring the result to the base ring |
---|
1080 | return(rez); // return the corresponding Chern classes |
---|
1081 | } |
---|
1082 | example |
---|
1083 | { |
---|
1084 | "EXAMPLE:"; echo =2; |
---|
1085 | ring H = 0, ( c(1..3), C(1..2) ), dp; |
---|
1086 | list l=c(1..3); |
---|
1087 | list L=C(1..2); |
---|
1088 | // the Chern classes of the tensor product of a vector bundle E of rank 3 |
---|
1089 | // with Chern classes c(1), c(2), c(3) |
---|
1090 | // and a vector bundle F of rank 2 with Chern classes C(1) and C(2): |
---|
1091 | print( chProdE(l, L) ); |
---|
1092 | } |
---|
1093 | //------------------------------------------------------------------------------------ |
---|
1094 | |
---|
1095 | proc chProdL(int r, list c, int R, list C) |
---|
1096 | "USAGE: chProdL(r, c, R, C); r, R integers; c, C lists of polynomials |
---|
1097 | RETURN: list |
---|
1098 | PURPOSE: computes the list of Chern classes of the product of two vector bundles |
---|
1099 | in terms of their Chern clases |
---|
1100 | EXAMPLE: example chProdL; shows an example |
---|
1101 | NOTE: Implementation of the formula of Lascoux, the Schur polynomials are computed |
---|
1102 | using the second Jacobi-Trudi formula (in terms of the Chern classes) |
---|
1103 | " |
---|
1104 | { |
---|
1105 | // check the input data |
---|
1106 | if(r<=0) // if r is negative or zero return the empty list |
---|
1107 | { |
---|
1108 | return( list() ); |
---|
1109 | } |
---|
1110 | //---------------------------- |
---|
1111 | //now r is a positive integer |
---|
1112 | //---------------------------- |
---|
1113 | c=append_by_zeroes(r, c); // append c by zeroes if r is greater than the length of c |
---|
1114 | c=c[1..r]; // make c shorter (of length r) if r is smaller than the length of c |
---|
1115 | if(R<=0) // if R is negative or zero return the empty list |
---|
1116 | { |
---|
1117 | return( list() ); |
---|
1118 | } |
---|
1119 | //---------------------------- |
---|
1120 | //now R is a positive integer |
---|
1121 | //---------------------------- |
---|
1122 | C=append_by_zeroes(R, C); // append C by zeroes if R is greater than the length of C |
---|
1123 | C=C[1..R]; // make C shorter (of length R) if R is smaller than the length of C |
---|
1124 | //---------------------------------------------------------- |
---|
1125 | // now r > 0 and R > 0 |
---|
1126 | //---------------------------------------------------------- |
---|
1127 | def br@=basering; // remember the base ring |
---|
1128 | // add additional variables to the base ring |
---|
1129 | int ii; |
---|
1130 | list l5 = ringlist(basering)[2]; |
---|
1131 | l5[size(l5)+1] = "t@"; |
---|
1132 | for (ii = 1; ii <= r; ii++) |
---|
1133 | { |
---|
1134 | l5[size(l5)+1] = "c@("+string(ii)+")"; |
---|
1135 | } |
---|
1136 | for (ii = 1; ii <= R; ii++) |
---|
1137 | { |
---|
1138 | l5[size(l5)+1] = "C@("+string(ii)+")"; |
---|
1139 | } |
---|
1140 | ring r@ = create_ring(ringlist(basering)[1], l5, "dp", "no_minpoly"); |
---|
1141 | execute( "map F= br@,"+varstr(br@)+";" ); // define the corresponding inclusion of rings |
---|
1142 | list c, C; |
---|
1143 | int i; |
---|
1144 | for(i=1;i<=r;i++) |
---|
1145 | { |
---|
1146 | c[i]=c@(i)*t@^i; |
---|
1147 | } |
---|
1148 | for(i=1;i<=R;i++) |
---|
1149 | { |
---|
1150 | C[i]=C@(i)*t@^i; |
---|
1151 | } |
---|
1152 | poly f = chProdLP(r,c,R,C); // get the total Chern class using the Lascoux formula |
---|
1153 | matrix CF = coeffs(f, t@); // get its coefficients in front of the powers of t@ |
---|
1154 | int N=r*R; |
---|
1155 | list rez; // write them in a list |
---|
1156 | for(i=1;i<=N;i++) |
---|
1157 | { |
---|
1158 | rez=rez+list(CF[i+1,1]); |
---|
1159 | } |
---|
1160 | setring br@; // come back to the initial base ring |
---|
1161 | // define the specialization homomorphism |
---|
1162 | execute("map FF = r@,"+varstr(br@)+",0, c[1..r], C[1..R];"); |
---|
1163 | return( FF( rez ) ); // bring the result to the initial ring |
---|
1164 | } |
---|
1165 | example |
---|
1166 | { |
---|
1167 | "EXAMPLE:"; echo =2; |
---|
1168 | // The Chern classes of the tensor product of a vector bundle of rank 3 |
---|
1169 | // with Chern classes c(1), c(2), c(3) and a vector bundle of rank 1 with |
---|
1170 | // Chern class C(1) |
---|
1171 | ring r = 0, ( c(1..3), C(1)), dp; |
---|
1172 | list c=c(1..3); |
---|
1173 | list C=C(1); |
---|
1174 | print( chProdL(3,c,1,C) ); |
---|
1175 | } |
---|
1176 | //--------------------------------------------------------------------------------------- |
---|
1177 | |
---|
1178 | proc chProdLP(int r, list c, int R, list C) |
---|
1179 | "USAGE: chProdLP(r, c, R, C); r, R integers; c, C lists of polynomials |
---|
1180 | RETURN: polynomial |
---|
1181 | PURPOSE: computes the total Chern class of the product of two vector bundles |
---|
1182 | in terms of their ranks and Chern clases |
---|
1183 | EXAMPLE: example chProdLP; shows an example |
---|
1184 | NOTE: Implementation of the formula of Lascoux, the Schur polynomials are computed |
---|
1185 | using the second Jacobi-Trudi formula (in terms of the Chern classes) |
---|
1186 | " |
---|
1187 | { |
---|
1188 | if(r<=0) // if r is negative or zero, return 1 |
---|
1189 | { |
---|
1190 | return( 1 ); |
---|
1191 | } |
---|
1192 | if(R<=0) // if R is negative or zero, return 1 |
---|
1193 | { |
---|
1194 | return( 1 ); |
---|
1195 | } |
---|
1196 | //------------------------------------------- |
---|
1197 | // now r and R are positive |
---|
1198 | //------------------------------------------- |
---|
1199 | c=append_by_zeroes(r, c); |
---|
1200 | C=append_by_zeroes(R, C); |
---|
1201 | c=c[1..r]; |
---|
1202 | C=C[1..R]; |
---|
1203 | list P; |
---|
1204 | P=part(r, R); // compute the partitions of numbers up to R into r summands |
---|
1205 | int sz=size(P); // number of such partitions |
---|
1206 | int szu; |
---|
1207 | int i, j; |
---|
1208 | list T; |
---|
1209 | list PU; |
---|
1210 | list TU; |
---|
1211 | poly rez; // the result will be computed here |
---|
1212 | poly ST; |
---|
1213 | // implement the formula of Lascoux: |
---|
1214 | for(i=1;i<=sz;i++) // run through all the partitions from P |
---|
1215 | { |
---|
1216 | T=P[i]; // the current partition |
---|
1217 | ST= SchurS( PartC(T, R) , C ); // compute the corresponding Schur polynomial |
---|
1218 | PU=partUnder(T); // compute the partitions under T |
---|
1219 | szu=size(PU); // number of such partitions |
---|
1220 | for(j=1;j<=szu;j++) // run through all the partitions lying under T |
---|
1221 | { |
---|
1222 | TU=PU[j]; // for each of them |
---|
1223 | rez=rez+IJcoef(T, TU)* SchurCh(TU, c) *ST; // add the corresponding term to the result |
---|
1224 | } |
---|
1225 | } |
---|
1226 | return(rez); // return the result |
---|
1227 | } |
---|
1228 | example |
---|
1229 | { |
---|
1230 | "EXAMPLE:"; echo =2; |
---|
1231 | // The total Chern class of the tensor product of a vector bundle of rank 3 |
---|
1232 | // with Chern classes c(1), c(2), c(3) and a vector bundle of rank 1 with |
---|
1233 | // Chern class C(1) |
---|
1234 | ring r = 0, ( c(1..3), C(1)), ws(1,2,3, 1); |
---|
1235 | list c=c(1..3); |
---|
1236 | list C=C(1); |
---|
1237 | print( chProdLP(3,c,1,C) ); |
---|
1238 | } |
---|
1239 | //--------------------------------------------------------------------------------------- |
---|
1240 | |
---|
1241 | proc chProdM(int r, list c, int R, list C) |
---|
1242 | "USAGE: chProdM(r, c, R, C); r, R integers; c, C lists of polynomials |
---|
1243 | RETURN: list |
---|
1244 | PURPOSE: computes the list of Chern classes of the product of two vector bundles |
---|
1245 | in terms of their Chern clases |
---|
1246 | EXAMPLE: example chProdM; shows an example |
---|
1247 | NOTE: Implementation of the formula of Manivel |
---|
1248 | " |
---|
1249 | { |
---|
1250 | // check the input data |
---|
1251 | if(r<=0) // if r is negative or zero return the empty list |
---|
1252 | { |
---|
1253 | return( list() ); |
---|
1254 | } |
---|
1255 | //---------------------------- |
---|
1256 | //now r is a positive integer |
---|
1257 | //---------------------------- |
---|
1258 | c=append_by_zeroes(r, c); // append c by zeroes if r is greater than the length of c |
---|
1259 | c=c[1..r]; // make c shorter (of length r) if r is smaller than the length of c |
---|
1260 | if(R<=0) // if R is negative or zero return the empty list |
---|
1261 | { |
---|
1262 | return( list() ); |
---|
1263 | } |
---|
1264 | //---------------------------- |
---|
1265 | //now R is a positive integer |
---|
1266 | //---------------------------- |
---|
1267 | C=append_by_zeroes(R, C); // append C by zeroes if R is greater than the length of C |
---|
1268 | C=C[1..R]; // make C shorter (of length R) if R is smaller than the length of C |
---|
1269 | //---------------------------------------------------------- |
---|
1270 | // now r > 0 and R > 0 |
---|
1271 | //---------------------------------------------------------- |
---|
1272 | def br@=basering; // remember the base ring |
---|
1273 | // add additional variables to the base ring |
---|
1274 | int ii; |
---|
1275 | list l6 = ringlist(basering)[2]; |
---|
1276 | l6[size(l6)+1] = "t@"; |
---|
1277 | for (ii = 1; ii <= r; ii++) |
---|
1278 | { |
---|
1279 | l6[size(l6)+1] = "c@("+string(ii)+")"; |
---|
1280 | } |
---|
1281 | for (ii = 1; ii <= R; ii++) |
---|
1282 | { |
---|
1283 | l6[size(l6)+1] = "C@("+string(ii)+")"; |
---|
1284 | } |
---|
1285 | ring r@ = create_ring(ringlist(basering)[1], l6, "dp", "no_minpoly"); |
---|
1286 | execute( "map F= br@,"+varstr(br@)+";" ); // define the corresponding inclusion of rings |
---|
1287 | list c, C; |
---|
1288 | int i; |
---|
1289 | for(i=1;i<=r;i++) |
---|
1290 | { |
---|
1291 | c[i]=c@(i)*t@^i; |
---|
1292 | } |
---|
1293 | for(i=1;i<=R;i++) |
---|
1294 | { |
---|
1295 | C[i]=C@(i)*t@^i; |
---|
1296 | } |
---|
1297 | poly f = chProdMP(r,c,R,C); // get the total Chern class using the Manivel formula |
---|
1298 | matrix CF = coeffs(f, t@); // get its coefficients in front of the powers of t@ |
---|
1299 | int N=r*R; |
---|
1300 | list rez; // write them in a list |
---|
1301 | for(i=1;i<=N;i++) |
---|
1302 | { |
---|
1303 | rez=rez+list(CF[i+1,1]); |
---|
1304 | } |
---|
1305 | setring br@; // come back to the initial base ring |
---|
1306 | // define the specialization homomorphism |
---|
1307 | execute("map FF = r@,"+varstr(br@)+",0, c[1..r], C[1..R];"); |
---|
1308 | return( FF( rez ) ); // bring the result to the initial ring |
---|
1309 | } |
---|
1310 | example |
---|
1311 | { |
---|
1312 | "EXAMPLE:"; echo = 2; |
---|
1313 | // The Chern classes of the tensor product of a vector bundle of rank 3 |
---|
1314 | // with Chern classes c(1), c(2), c(3) and a vector bundle of rank 1 with |
---|
1315 | // Chern class C(1) |
---|
1316 | ring r = 0, ( c(1..3), C(1)), dp; |
---|
1317 | list c=c(1..3); |
---|
1318 | list C=C(1); |
---|
1319 | print( chProdM(3,c,1,C) ); |
---|
1320 | } |
---|
1321 | //--------------------------------------------------------------------------------------- |
---|
1322 | |
---|
1323 | proc chProdMP(int r, list c, int R, list C) |
---|
1324 | "USAGE: chProdMP(r, c, R, C); r, R integers; c, C lists of polynomials |
---|
1325 | RETURN: polynomial |
---|
1326 | PURPOSE: computes the total Chern class of the product of two vector bundles |
---|
1327 | in terms of their ranks and Chern clases |
---|
1328 | EXAMPLE: example chProdMP; shows an example |
---|
1329 | NOTE: Implementation of the formula of Lascoux, the Schur polynomials are computed |
---|
1330 | using the second Jacobi-Trudi formula (in terms of the Chern classes) |
---|
1331 | " |
---|
1332 | { |
---|
1333 | if(r<=0) // if r is negative or zero, return 1 |
---|
1334 | { |
---|
1335 | return( 1 ); |
---|
1336 | } |
---|
1337 | if(R<=0) // if R is negative or zero, return 1 |
---|
1338 | { |
---|
1339 | return( 1 ); |
---|
1340 | } |
---|
1341 | //------------------------------------------- |
---|
1342 | // now r and R are positive |
---|
1343 | //------------------------------------------- |
---|
1344 | c=append_by_zeroes(r, c); |
---|
1345 | C=append_by_zeroes(R, C); |
---|
1346 | c=c[1..r]; |
---|
1347 | C=C[1..R]; |
---|
1348 | list P; |
---|
1349 | P=part(r, R); // compute the partitions of numbers up to R into r summands |
---|
1350 | int sz=size(P); // number of such partitions |
---|
1351 | int szu; |
---|
1352 | int i, j; |
---|
1353 | list T; |
---|
1354 | list PU; |
---|
1355 | list TU; |
---|
1356 | poly rez; // the result will be computed here |
---|
1357 | poly ST; |
---|
1358 | // implement the formula of Manivel: |
---|
1359 | for(i=1;i<=sz;i++) // run through all the partitions from P |
---|
1360 | { |
---|
1361 | T=P[i]; // the current partition |
---|
1362 | ST= SchurS( PartC(T, R) , C ); // compute the corresponding Schur polynomial |
---|
1363 | PU=partUnder(T); // compute the partitions under T |
---|
1364 | szu=size(PU); // number of such partitions |
---|
1365 | for(j=1;j<=szu;j++) // run through all the partitions lying under T |
---|
1366 | { |
---|
1367 | TU=PU[j]; // for each of them |
---|
1368 | // add the corresponding term to the result |
---|
1369 | rez=rez+Pcoef( TU, PartC(dualPart(T, R), r), r, R )* SchurCh(TU, c) *ST; |
---|
1370 | } |
---|
1371 | } |
---|
1372 | return(rez); // return the result |
---|
1373 | } |
---|
1374 | example |
---|
1375 | { |
---|
1376 | "EXAMPLE:"; echo =2; |
---|
1377 | // The total Chern class of the tensor product of a vector bundle of rank 3 |
---|
1378 | // with Chern classes c(1), c(2), c(3) and a vector bundle of rank 1 with |
---|
1379 | // Chern class C(1) |
---|
1380 | ring r = 0, ( c(1..3), C(1)), ws(1,2,3, 1); |
---|
1381 | list c=c(1..3); |
---|
1382 | list C=C(1); |
---|
1383 | print( chProdMP(3,c,1,C) ); |
---|
1384 | } |
---|
1385 | //--------------------------------------------------------------------------------------- |
---|
1386 | |
---|
1387 | proc ChernRootsHom(list a, list b) |
---|
1388 | "USAGE: ChernRootsHom(a, b); a, b lists of polynomials |
---|
1389 | RETURN: list of polynomials |
---|
1390 | PURPOSE: for a vector bundle E with Chern roots a and a vector bundle F |
---|
1391 | with Chern roots b, computes the Chern roots of Hom(E, F) |
---|
1392 | EXAMPLE: example ChernRootsHom; shows an example |
---|
1393 | NOTE: |
---|
1394 | " |
---|
1395 | { |
---|
1396 | int na=size(a); |
---|
1397 | int nb=size(b); |
---|
1398 | int i; |
---|
1399 | int j; |
---|
1400 | list rez; // the result will be computed here |
---|
1401 | for(i=1;i<=na;i++) // compute the result |
---|
1402 | { |
---|
1403 | for(j=1;j<=nb;j++) |
---|
1404 | { |
---|
1405 | rez=rez+list(-a[i]+b[j]); |
---|
1406 | } |
---|
1407 | } |
---|
1408 | return(rez); |
---|
1409 | } |
---|
1410 | example |
---|
1411 | { |
---|
1412 | "EXAMPLE:"; echo=2; |
---|
1413 | ring r=0, (a(1..2), b(1..3)), dp; |
---|
1414 | list l=a(1..2); |
---|
1415 | list L=b(1..3); |
---|
1416 | // Let E be a vector bundle with Chern roots a(1). a(2), |
---|
1417 | // let F be a vector bundle with CHern roots b(1), b(2), b(3). |
---|
1418 | // Then the Chern roots of Hom(E, F) are |
---|
1419 | print(ChernRootsHom(l, L)); |
---|
1420 | } |
---|
1421 | //----------------------------------------------------------------------------------------- |
---|
1422 | |
---|
1423 | proc chHom(def r, list c, def R, list C, list #) |
---|
1424 | "USAGE: chHom(r, c, R, C [, N]); r, R polynomials (integers); |
---|
1425 | c, C lists of polynomials, N integer |
---|
1426 | RETURN: list of polynomials |
---|
1427 | PURPOSE: computes [up to degree N] the list of Chern classes of the vector bundle Hom(E, F) |
---|
1428 | in terms of the ranks and the Chern classes of E and F |
---|
1429 | EXAMPLE: example chHom; shows an example |
---|
1430 | NOTE: |
---|
1431 | " |
---|
1432 | { |
---|
1433 | return( chProd(r, chDual(c), R, C, # ) ); |
---|
1434 | } |
---|
1435 | example |
---|
1436 | { |
---|
1437 | "EXAMPLE:"; echo=2; |
---|
1438 | ring H = 0, ( r, R, c(1..3), C(1..2) ), dp; |
---|
1439 | list l=c(1..3); |
---|
1440 | list L=C(1..2); |
---|
1441 | // the Chern classes of Hom(E, F) for a vector bundle E of rank 3 |
---|
1442 | // with Chern classes c(1), c(2), c(3) |
---|
1443 | // and a vector bundle F of rank 2 with Chern classes C(1) and C(2): |
---|
1444 | print( chHom(3, l, 2, L) ); |
---|
1445 | // the first two Chern classes of Hom(E, F) for a vector bundle E of rank r |
---|
1446 | // with Chern classes c(1) and c(2) |
---|
1447 | // and a vector bundle G of rank R with Chern classes C(1) and C(2) |
---|
1448 | // this gives the Chern classes of a tensor product on a complex surface |
---|
1449 | l=c(1..2); |
---|
1450 | L=C(1..2); |
---|
1451 | print( chHom(r, l, R, L, 2 ) ); |
---|
1452 | } |
---|
1453 | //--------------------------------------------------------------------------------- |
---|
1454 | |
---|
1455 | proc ChernRootsSymm(int n, list l) |
---|
1456 | "USAGE: ChernRootsSymm(m, l); m integer, l a list of polynomials |
---|
1457 | RETURN: list of polynomials |
---|
1458 | PURPOSE: computes the Chern roots of m-th symmetric power |
---|
1459 | of a vector bundle with Chern roots from l |
---|
1460 | EXAMPLE: example ChernRootsSymm; shows an example |
---|
1461 | NOTE: |
---|
1462 | " |
---|
1463 | { |
---|
1464 | if(n<0) // return the empty list if n is negative |
---|
1465 | { |
---|
1466 | return(list(0)); |
---|
1467 | } |
---|
1468 | int r=size(l); |
---|
1469 | def br@=basering; // remember the base ring |
---|
1470 | ring r@=0, (a@(1..r)), dp; |
---|
1471 | ideal mon = a@(1..r); |
---|
1472 | mon=mon^n; // all monomials of degree n |
---|
1473 | list rez; |
---|
1474 | int i, j; |
---|
1475 | int N = size(mon); |
---|
1476 | intvec v; |
---|
1477 | for(i=1; i<=N; i++) // collect in rez the exponents of the monomials of degree n |
---|
1478 | { |
---|
1479 | v = leadexp(mon[i]); |
---|
1480 | rez = rez + list(v); |
---|
1481 | } |
---|
1482 | setring br@; |
---|
1483 | poly f; |
---|
1484 | list rez1; |
---|
1485 | // run over all exponents and construct the corresponding sums of the Chern roots |
---|
1486 | for(i=1; i<=N; i++) |
---|
1487 | { |
---|
1488 | f=0; |
---|
1489 | for(j=1;j<=r;j++) |
---|
1490 | { |
---|
1491 | f=f+rez[i][j]*l[j]; |
---|
1492 | } |
---|
1493 | rez1=rez1+list(f); |
---|
1494 | } |
---|
1495 | return(rez1); |
---|
1496 | } |
---|
1497 | example |
---|
1498 | { |
---|
1499 | "EXAMPLE:";echo =2; |
---|
1500 | ring r=0, (a(1..3)), dp; |
---|
1501 | list l=a(1..3); |
---|
1502 | // the Chern roots of the second symmetric power of a vector bundle |
---|
1503 | // with Chern roots a(1), a(2), a(3) |
---|
1504 | print( ChernRootsSymm(2, l) ); |
---|
1505 | } |
---|
1506 | //------------------------------------------------------------ |
---|
1507 | |
---|
1508 | proc ChernRootsWedge( int m, list l) |
---|
1509 | "USAGE: ChernRootsWedge(m, l); m integer, l a list of polynomials |
---|
1510 | RETURN: list of polynomials |
---|
1511 | PURPOSE: computes the Chern roots of m-th exterior power |
---|
1512 | of a vector bundle with Chern roots from l |
---|
1513 | EXAMPLE: example ChernRootsWedge; shows an example |
---|
1514 | NOTE: makes sense only for list of polynomials |
---|
1515 | " |
---|
1516 | { |
---|
1517 | int n=size(l); |
---|
1518 | if((m>n)||(m<=0) ) // if m is bigger that n or non-positive |
---|
1519 | { |
---|
1520 | return( list(0) ); // return the list with one zero entry |
---|
1521 | } |
---|
1522 | else |
---|
1523 | { |
---|
1524 | if(m==n) // if m equals n, the only Chern root of the exterior power will be |
---|
1525 | { |
---|
1526 | return( list(sum(l)) ); // the sum of the initial Chern roots |
---|
1527 | } |
---|
1528 | else // otherwise proceed recursively |
---|
1529 | { |
---|
1530 | int i; |
---|
1531 | list rez; |
---|
1532 | list rez1; |
---|
1533 | list l1 = delete(l, 1); // throw away the first element from the list |
---|
1534 | poly f = l[1]; // remember the first entry of l |
---|
1535 | // compute the Chern roots of the (m-1)-th exterior power of the smaller list |
---|
1536 | rez1 = ChernRootsWedge(m-1, l1 ); |
---|
1537 | int s = size( rez1 ); |
---|
1538 | // add the first entry of the bigger list to every entry in the result, |
---|
1539 | // this will give all Chern roots involving f |
---|
1540 | for(i=1; i<=s; i++) |
---|
1541 | { |
---|
1542 | rez1[i] = f+rez1[i]; |
---|
1543 | } |
---|
1544 | // return the union of those Chern roots with f and those without f |
---|
1545 | rez = ChernRootsWedge(m, l1) + rez1; |
---|
1546 | return( rez ); |
---|
1547 | } |
---|
1548 | } |
---|
1549 | } |
---|
1550 | example |
---|
1551 | { |
---|
1552 | "EXAMPLE:";echo =2; |
---|
1553 | ring r=0, (a(1..3)), dp; |
---|
1554 | list l=a(1..3); |
---|
1555 | // the Chern roots of the second exterior power of a vector bundle |
---|
1556 | // with Chern roots a(1), a(2), a(3) |
---|
1557 | print( ChernRootsWedge(2, l) ); |
---|
1558 | } |
---|
1559 | //--------------------------------------------------------------------------------- |
---|
1560 | |
---|
1561 | proc chSymm(int k, int r, list c, list #) |
---|
1562 | "USAGE: chSymm(k, r, c[, pos]); k, r integers, c list of polynomials, pos list of integers |
---|
1563 | RETURN: list with entries: int N, list of polynomials l |
---|
1564 | PURPOSE: computes the rank and the Chern classes of the symmetric power of a vector bundle |
---|
1565 | EXAMPLE: example chSymm; shows an example |
---|
1566 | NOTE: for the second symmetric power chSymm2L(...) could be faster |
---|
1567 | " |
---|
1568 | { |
---|
1569 | // insure that the entries of c are polynomials |
---|
1570 | // in order to be able to apply maps |
---|
1571 | int i; |
---|
1572 | for(i=1;i<=size(c);i++) |
---|
1573 | { |
---|
1574 | c[i]=poly(c[i]); |
---|
1575 | } |
---|
1576 | if(r<0) // if the rank is negative |
---|
1577 | { |
---|
1578 | print("The rank of a vector bundle can non be negative"); |
---|
1579 | return(list()); // return the empty list in this case |
---|
1580 | } |
---|
1581 | if(r==0) // if we deal with the zero bundle |
---|
1582 | { |
---|
1583 | return( list( 0, list() ) ); // return the data corresponding to the zero bundle |
---|
1584 | } |
---|
1585 | //----------------------------------- |
---|
1586 | // from now on we are in the case r>0 |
---|
1587 | //----------------------------------- |
---|
1588 | // if the length n of the list of Chern classes is smaller |
---|
1589 | // than the rank of the vector bundle, |
---|
1590 | // the higher classes are assumed to be zero and the list is appended by zeroes up to length r |
---|
1591 | c=append_by_zeroes(r, c); |
---|
1592 | // if the length of the list of the Chern classes is greater than the rank |
---|
1593 | c=c[1..r]; // throw away the redundant data |
---|
1594 | //----------------------------------- |
---|
1595 | // from now on the length of c is r>0 |
---|
1596 | //----------------------------------- |
---|
1597 | if(k<0) |
---|
1598 | { |
---|
1599 | print("You are trying to compute a negative symmetric power of a vector bundle"); |
---|
1600 | return( list(0, list() ) ); // assume such a power to be just a zero bundle |
---|
1601 | } |
---|
1602 | if(k==0) // the zeroth symmetric power is the trivial line bundle |
---|
1603 | { |
---|
1604 | return( list(1, list(0)) ); |
---|
1605 | } |
---|
1606 | if(k==1) // the first symmetric power is equal to the vector bundle itself |
---|
1607 | { |
---|
1608 | return(list(r, c)); |
---|
1609 | } |
---|
1610 | //----------------------------------- |
---|
1611 | // from now on we are in the case k>2 |
---|
1612 | //----------------------------------- |
---|
1613 | list LM = integer_list(#); |
---|
1614 | int M = LM[2]; // maximum among the optional parameters |
---|
1615 | # = LM[1]; // take into account only the first integer optional parameters that are positive |
---|
1616 | //------------------------------- |
---|
1617 | // Perform the computations now |
---|
1618 | //------------------------------- |
---|
1619 | def br@=basering; // remember the base ring |
---|
1620 | // add additional variables to the base ring |
---|
1621 | int ii; |
---|
1622 | list l7 = "x@"; |
---|
1623 | l7 = l7+ ringlist(basering)[2]; |
---|
1624 | for (ii = 1; ii <= r; ii++) |
---|
1625 | { |
---|
1626 | l7[size(l7)+1] = "a@("+string(ii)+")"; |
---|
1627 | } |
---|
1628 | ring r@ = create_ring(ringlist(basering)[1], l7, "lp", "no_minpoly"); |
---|
1629 | execute( "map F= br@,"+varstr(br@)+";" ); // define the corresponding inclusion of rings |
---|
1630 | list c=F(c); // embed c into the bigger ring |
---|
1631 | list rez; // the Chern classes of the symmetric power are going to be written here |
---|
1632 | poly E = product( list( a@(1..r ) ) ); // product of the Chern roots |
---|
1633 | list ss=ChernRootsSymm(k, list( a@(1..r) ) ); // list of the Chern roots of the symmetric power |
---|
1634 | int N=size(ss); // number of such roots, it equals the rank of the symmetric power |
---|
1635 | // the entries in C will be the Chern classes of the symmetric power |
---|
1636 | // expressed in terms of the Chern roots of the initial vector bundle |
---|
1637 | list C; |
---|
1638 | ideal I, J; |
---|
1639 | // list of the Chern classes of the initial vector bundle expressed in its Chern roots |
---|
1640 | list sym=symm(list(a@(1..r))); |
---|
1641 | if(size(#)==0) // if there are no optional parameters, compute all Chern classes |
---|
1642 | { |
---|
1643 | // the entries here are the Chern classes of the symmetric power |
---|
1644 | // expressed in terms of Chern roots of the initial vector bundle |
---|
1645 | C=symm(ss); |
---|
1646 | for(i=1;i<=N;i++) // eliminate the Chern roots |
---|
1647 | { |
---|
1648 | if(i<= r) // first add all relevant formulas for the Chern classes in terms of Chern roots |
---|
1649 | { |
---|
1650 | I=I, c[i]-sym[i]; |
---|
1651 | } |
---|
1652 | J = I, x@-C[i]; |
---|
1653 | // Notice that elim(...) is from the library "elim.lib", |
---|
1654 | // it is loaded as a result of loading "general.lib" |
---|
1655 | J=simplify(elim(J, E), 1); |
---|
1656 | // get the expression of the next Chern class |
---|
1657 | // in terms of the Chern classes of the initial vector bundle |
---|
1658 | rez=rez+list( -subst( J[1], x@, 0) ); |
---|
1659 | } |
---|
1660 | } |
---|
1661 | else // otherwise compute only the needed Chern classes |
---|
1662 | { |
---|
1663 | C=symm(ss, M); // only the needed Chern classes |
---|
1664 | int j; |
---|
1665 | i=1; |
---|
1666 | // the maximal number of optional parameters to be considered does not exceed N, |
---|
1667 | // i.e., the rank of the symmetric power |
---|
1668 | int NN = min( size(#), N); |
---|
1669 | for(j=1; j <= NN; j++) // process the optional parameters |
---|
1670 | { |
---|
1671 | // process the optional parameters only until they are not bigger than N; |
---|
1672 | // notice they are positive anyway after integer_list(...) |
---|
1673 | if( #[j]<=N ) |
---|
1674 | { |
---|
1675 | for( ; i<=#[j];i++) |
---|
1676 | { |
---|
1677 | if(i<=r) |
---|
1678 | { |
---|
1679 | // add the relevant formulas for the Chern classes in terms of the Chern roots |
---|
1680 | I=I, c[i]-sym[i]; |
---|
1681 | } |
---|
1682 | } |
---|
1683 | J= I, x@-C[ #[j]]; |
---|
1684 | // Notice that elim(...) is from the library "elim.lib", |
---|
1685 | // it is loaded as a result of loading "general.lib" |
---|
1686 | J=simplify(elim(J, E), 1); |
---|
1687 | // get the expression of the next Chern class |
---|
1688 | // in terms of the Chern classes of the initial vector bundle |
---|
1689 | rez=rez+list( -subst( J[1], x@, 0) ); |
---|
1690 | } |
---|
1691 | else // get out from the loop |
---|
1692 | { |
---|
1693 | break; |
---|
1694 | } |
---|
1695 | } |
---|
1696 | } |
---|
1697 | // used because Singular seems not to be able to apply maps to empty lists (see below) |
---|
1698 | if(size(rez)==0) |
---|
1699 | { |
---|
1700 | return(list(N, list())); |
---|
1701 | } |
---|
1702 | setring br@; // come back to the initial base ring |
---|
1703 | // define the specialization homomorphism, |
---|
1704 | // evaluate the formulas for the Chern classes on their given values |
---|
1705 | execute( "map FF = r@,0,"+varstr(br@)+";" ); |
---|
1706 | list rez=FF( rez ); // bring the result back to the initial ring |
---|
1707 | return( list( N, rez ) ); // return the result together with the rank of the symmetric power |
---|
1708 | } |
---|
1709 | example |
---|
1710 | { |
---|
1711 | "EXAMPLE:";echo =2; |
---|
1712 | ring r=0, (c(1..5)), dp; |
---|
1713 | list l=c(1..5); |
---|
1714 | // the rank and the Chern classes of the second symmetric power of a vector bundle of rank 3 |
---|
1715 | print( chSymm(2, 3, l) ); |
---|
1716 | // the rank and the first 3 Chern classes |
---|
1717 | // of the second symmetric power of a vector bundle of rank 5 |
---|
1718 | print( chSymm(2, 5, l, 1, 2, 3) ); |
---|
1719 | } |
---|
1720 | //---------------------------------------------------------------------------------- |
---|
1721 | |
---|
1722 | proc chSymm2L(int r, list c) |
---|
1723 | "USAGE: chSymm2L(r, c); r integer, c list of polynomials |
---|
1724 | RETURN: list of polynomials |
---|
1725 | PURPOSE: computes the Chern classes of the second symmetric power of a vector bundle |
---|
1726 | EXAMPLE: example chSymm2L; shows an example |
---|
1727 | NOTE: Implementation of the formula of Lascoux, the Schur polynomials are computed |
---|
1728 | using the second Jacobi-Trudi formula (in terms of the Chern classes) |
---|
1729 | " |
---|
1730 | { |
---|
1731 | // insure that the entries of c are polynomials |
---|
1732 | // in order to be able to apply maps |
---|
1733 | int i; |
---|
1734 | for(i=1;i<=size(c);i++) |
---|
1735 | { |
---|
1736 | c[i]=poly(c[i]); |
---|
1737 | } |
---|
1738 | if(r<0) // if the rank is negative |
---|
1739 | { |
---|
1740 | print("The rank of a vector bundle can non be negative"); |
---|
1741 | return(list()); // return the empty list in this case |
---|
1742 | } |
---|
1743 | if(r==0) // if we deal with the zero bundle |
---|
1744 | { |
---|
1745 | return( list( 0, list() ) ); // return the data corresponding to the zero bundle |
---|
1746 | } |
---|
1747 | //----------------------------------- |
---|
1748 | // from now on we are in the case r>0 |
---|
1749 | //----------------------------------- |
---|
1750 | c=append_by_zeroes(r, c); |
---|
1751 | c=c[1..r]; |
---|
1752 | def br@=basering; // remember the base ring |
---|
1753 | // add additional variables to the base ring |
---|
1754 | list l8 = ringlist(basering)[2]; |
---|
1755 | l8[size(l8)+1] = "t@"; |
---|
1756 | for (int ii = 1; ii <= r; ii++) |
---|
1757 | { |
---|
1758 | l8[size(l8)+1] = "c@("+string(ii)+")"; |
---|
1759 | } |
---|
1760 | ring r@ = create_ring(ringlist(basering)[1], l8, "dp", "no_minpoly"); |
---|
1761 | execute( "map F= br@,"+varstr(br@)+";" ); // define the corresponding inclusion of rings |
---|
1762 | list c; |
---|
1763 | for(i=1;i<=r;i++) |
---|
1764 | { |
---|
1765 | c[i]=c@(i)*t@^i; |
---|
1766 | } |
---|
1767 | poly f = chSymm2LP(r,c); // get the total Chern class using the formula of Lascoux |
---|
1768 | matrix CF = coeffs(f, t@); |
---|
1769 | int N=r*(r+1) div 2; |
---|
1770 | list rez; // write the coefficients in front of the powers of t@ into a list |
---|
1771 | for(i=1;i<=N;i++) |
---|
1772 | { |
---|
1773 | rez=rez+list(CF[i+1,1]); |
---|
1774 | } |
---|
1775 | setring br@; // come back to the initial base ring |
---|
1776 | execute("map FF = r@,"+varstr(br@)+",0, c[1..r];"); // define the specialization homomorphism |
---|
1777 | return( list(N, FF( rez )) ); // bring the result to the initial ring |
---|
1778 | } |
---|
1779 | example |
---|
1780 | { |
---|
1781 | "EXAMPLE:";echo =2; |
---|
1782 | ring r=0, (c(1..2)), dp; |
---|
1783 | list l=c(1..2); |
---|
1784 | // the Chern classes of the second symmetric power of a vector bundle of rank 2 |
---|
1785 | print( chSymm2L(2, l)); |
---|
1786 | } |
---|
1787 | //--------------------------------------------------------------------------------------- |
---|
1788 | |
---|
1789 | proc chSymm2LP(int r, list c) |
---|
1790 | "USAGE: chSymm2LP(r, c); r integer, c list of polynomials |
---|
1791 | RETURN: poly |
---|
1792 | PURPOSE: computes the total Chern class of the second symmetric power of a vector bundle |
---|
1793 | EXAMPLE: example chSymm2LP; shows an example |
---|
1794 | NOTE: Implementation of the formula of Lascoux, the Schur polynomials are computed |
---|
1795 | using the second Jacobi-Trudi formula (in terms of the Chern classes) |
---|
1796 | " |
---|
1797 | { |
---|
1798 | if(r<0) // if the rank is negative |
---|
1799 | { |
---|
1800 | print("The rank of a vector bundle can non be negative"); |
---|
1801 | return(1); // return 1 in this case |
---|
1802 | } |
---|
1803 | if(r==0) // if we deal with the zero bundle |
---|
1804 | { |
---|
1805 | return( 1 ); // return 1 in this case |
---|
1806 | } |
---|
1807 | //------------------------------------------- |
---|
1808 | // from now on we are in the case r > 0 |
---|
1809 | //------------------------------------------- |
---|
1810 | c=append_by_zeroes(r, c); |
---|
1811 | c=c[1..r]; |
---|
1812 | list I; // the partition (1,2,...,r) will be stored here |
---|
1813 | int i; |
---|
1814 | for(i=1;i<=r;i++) |
---|
1815 | { |
---|
1816 | I=I+list(i); |
---|
1817 | } |
---|
1818 | list PU = partUnder(I); // compute the partitions under I |
---|
1819 | int sz=size(PU); // get their number |
---|
1820 | poly rez; // the result will be computed here |
---|
1821 | list J; |
---|
1822 | poly cf; |
---|
1823 | int ex; |
---|
1824 | // implement the formula of Lascoux |
---|
1825 | for(i=1;i<=sz;i++) |
---|
1826 | { |
---|
1827 | J=PU[i]; |
---|
1828 | ex=sum(J)- r*(r-1) div 2; |
---|
1829 | if(ex>=0) |
---|
1830 | { |
---|
1831 | cf=bigint(2)^ex*IJcoef(I, J); |
---|
1832 | } |
---|
1833 | else |
---|
1834 | { |
---|
1835 | cf=IJcoef(I, J)/bigint(2)^(-ex); |
---|
1836 | } |
---|
1837 | rez = rez + cf * SchurCh(J, c ); |
---|
1838 | } |
---|
1839 | return(rez); |
---|
1840 | } |
---|
1841 | example |
---|
1842 | { |
---|
1843 | "EXAMPLE:";echo =2; |
---|
1844 | ring r=0, (c(1..2)), ws(1, 2); |
---|
1845 | list l=c(1..2); |
---|
1846 | // the total Chern class of the second symmetric power of a vector bundle of rank 2 |
---|
1847 | print( chSymm2LP(2, l)); |
---|
1848 | } |
---|
1849 | //--------------------------------------------------------------------------------------- |
---|
1850 | |
---|
1851 | proc chWedge(int k, int r, list c, list #) |
---|
1852 | "USAGE: chWedge(k, r, c [,pos]); k, r integers, c list of polynomials, pos list of integers |
---|
1853 | RETURN: list with entries: int N, list of polynomials l |
---|
1854 | PURPOSE: computes the rank and the Chern classes of the exterior power of a vector bundle |
---|
1855 | EXAMPLE: example chWedge; shows an example |
---|
1856 | NOTE: for the second exterior power chWedge2L(...) could be faster |
---|
1857 | " |
---|
1858 | { |
---|
1859 | // insure that the entries of c are polynomials |
---|
1860 | // in order to be able to apply maps |
---|
1861 | int i; |
---|
1862 | for(i=1;i<=size(c);i++) |
---|
1863 | { |
---|
1864 | c[i]=poly(c[i]); |
---|
1865 | } |
---|
1866 | if(r<0) // if the rank is negative |
---|
1867 | { |
---|
1868 | print("The rank of a vector bundle can non be negative"); |
---|
1869 | return(list()); // return the empty list in this case |
---|
1870 | } |
---|
1871 | if(r==0) // if we deal with the zero bundle |
---|
1872 | { |
---|
1873 | return( list( 0, list() ) ); // return the data corresponding to the zero bundle |
---|
1874 | } |
---|
1875 | //------------------------------------------- |
---|
1876 | // from now on we are in the case r > 0 |
---|
1877 | //------------------------------------------- |
---|
1878 | if(k<0) |
---|
1879 | { |
---|
1880 | print("You are trying to compute a negative exterior power of a vector bundle"); |
---|
1881 | return( list(0, list() ) ); // assume such a power to be just a zero bundle |
---|
1882 | } |
---|
1883 | if(k==0) // the zeroth exterior power is the trivial line bundle |
---|
1884 | { |
---|
1885 | return( list(1, list(0)) ); |
---|
1886 | } |
---|
1887 | if(k==1) // the first exterior power is equal to the vector bundle itself |
---|
1888 | { |
---|
1889 | c=append_by_zeroes(r, c); |
---|
1890 | c=c[1..r]; |
---|
1891 | return(list(r, c)); |
---|
1892 | } |
---|
1893 | //--------------------------------------- |
---|
1894 | // from now on we are in the case k > 2 |
---|
1895 | //--------------------------------------- |
---|
1896 | // if the length of the list of Chern classes is smaller than the rank of the vector bundle, |
---|
1897 | // the higher classes are assumed to be zero and the list is appended by zeroes up to length r |
---|
1898 | c=append_by_zeroes(r, c); |
---|
1899 | // if the length of the list of the Chern classes is greater than the rank |
---|
1900 | c=c[1..r]; // throw away the redundant data |
---|
1901 | //------------------------------------------ |
---|
1902 | // from now on the length of c is r > 0 |
---|
1903 | //------------------------------------------ |
---|
1904 | if( k>r ) // if k>r, the exterior power is zero |
---|
1905 | { |
---|
1906 | return( list( int(0), list() ) ); |
---|
1907 | } |
---|
1908 | //----------------------------------------------- |
---|
1909 | // from now on we are in the case 0 < k <= r = n |
---|
1910 | //----------------------------------------------- |
---|
1911 | if(k==r) |
---|
1912 | { |
---|
1913 | return(list( int(1), list( c(1) ) ) ); |
---|
1914 | } |
---|
1915 | //----------------------------------------------- |
---|
1916 | // from now on we are in the case 0 < k < r = n |
---|
1917 | //----------------------------------------------- |
---|
1918 | list LM = integer_list(#); |
---|
1919 | int M=LM[2]; // maximum among the optional parameters if there are any, zero otherwise |
---|
1920 | # = LM[1]; // take into account only the first integer optional parameters that are positive |
---|
1921 | //----------------------------- |
---|
1922 | // Let us compute now |
---|
1923 | //----------------------------- |
---|
1924 | def br@=basering; // remember the base ring |
---|
1925 | // add additional variables a@(1..r), x@ to the base ring |
---|
1926 | list l9 = "x@"; |
---|
1927 | l9 = l9+ ringlist(basering)[2]; |
---|
1928 | for (int ii = 1; ii <= r; ii++) |
---|
1929 | { |
---|
1930 | l9[size(l9)+1] = "a@("+string(ii)+")"; |
---|
1931 | } |
---|
1932 | ring r@ = create_ring(ringlist(basering)[1], l9, "lp", "no_minpoly"); |
---|
1933 | execute( "map F= br@,"+varstr(br@)+";" ); // define the corresponding inclusion of rings |
---|
1934 | list c = F(c); // embed c into the bigger ring |
---|
1935 | list rez; // the result should be computed here |
---|
1936 | poly E = product( list( a@(1..r ) ) ); // product of the Chern roots to be eliminaned |
---|
1937 | list ss=ChernRootsWedge(k, list( a@(1..r) )); // list of the Chern roots of the exterior product |
---|
1938 | int N=size(ss); // length of ss, equals the rank of the exterior product |
---|
1939 | // list of the Chern classes of the initial vector bundle in terms of their Chern roots |
---|
1940 | list sym=symm(list(a@(1..r))); |
---|
1941 | // the entries here will be the Chern classes we need |
---|
1942 | // expressed in terms of the Chern roots of the initial vector bundle |
---|
1943 | list C; |
---|
1944 | ideal I, J; |
---|
1945 | if( size(#) == 0 ) // if there are no optional parameters, compute all Chern classes |
---|
1946 | { |
---|
1947 | // the entries here are the Chern classes we need |
---|
1948 | // expressed in terms of the Chern roots of the initial vector bundle |
---|
1949 | C=symm(ss); |
---|
1950 | for(i=1;i<=N;i++) // eliminate the Chern roots |
---|
1951 | { |
---|
1952 | if(i<= r) // first add all relevant formulas for the Chern classes in terms of Chern roots |
---|
1953 | { |
---|
1954 | I=I, c[i]-sym[i]; |
---|
1955 | } |
---|
1956 | J = I, x@-C[i]; |
---|
1957 | // Notice that elim(...) is from the library "elim.lib", |
---|
1958 | // it is loaded as a result of loading "general.lib" |
---|
1959 | J=simplify(elim(J, E), 1); |
---|
1960 | // get the expression of the next Chern class |
---|
1961 | // in terms of the Chern classes of the initial vector bundle |
---|
1962 | rez=rez+list( -subst( J[1], x@, 0) ); |
---|
1963 | } |
---|
1964 | } |
---|
1965 | else // otherwise compute only the needed Chern classes |
---|
1966 | { |
---|
1967 | // the entries here are the Chern classes we need |
---|
1968 | // expressed in terms of the Chern roots of the initial vector bundle |
---|
1969 | C=symm(ss, M); |
---|
1970 | int j; |
---|
1971 | i=1; |
---|
1972 | // the maximal number of optional parameters to be considered |
---|
1973 | // does not exceed N, the rank of the exterior power |
---|
1974 | int NN = min( size(#), N); |
---|
1975 | for(j=1; j <= NN; j++) // process the optional parameters |
---|
1976 | { |
---|
1977 | // process the optional parameters only until they are not bigger than N; |
---|
1978 | // notice they are positive anyway after integer_list(...) |
---|
1979 | if( #[j]<=N ) |
---|
1980 | { |
---|
1981 | for( ; i<=#[j]; i++) |
---|
1982 | { |
---|
1983 | if( i<=r ) |
---|
1984 | { |
---|
1985 | // add the relevant formulas for the Chern classes in terms of the Chern roots |
---|
1986 | I=I, c[i]-sym[i]; |
---|
1987 | } |
---|
1988 | } |
---|
1989 | J= I, x@-C[ #[j]]; |
---|
1990 | // Notice that elim(...) is from the library "elim.lib", |
---|
1991 | // it is loaded as a result of loading "general.lib" |
---|
1992 | J=simplify(elim(J, E), 1); |
---|
1993 | // get the expression of the next Chern class |
---|
1994 | // in terms of the Chern classes of the initial vector bundle |
---|
1995 | rez=rez+list( -subst( J[1], x@, 0) ); |
---|
1996 | } |
---|
1997 | else // get out from the loop |
---|
1998 | { |
---|
1999 | break; |
---|
2000 | } |
---|
2001 | } |
---|
2002 | } |
---|
2003 | // used because Singular seems not to be able to apply maps to empty lists (see below) |
---|
2004 | if(size(rez)==0) |
---|
2005 | { |
---|
2006 | return(list(N, list())); |
---|
2007 | } |
---|
2008 | setring br@; // come back to the initial base ring |
---|
2009 | // define the specialization homomorphism, |
---|
2010 | // evaluate the formulas for the Chern classes on their given values |
---|
2011 | execute( "map FF = r@,0,"+varstr(br@)+";" ); |
---|
2012 | list rez=FF( rez ); // bring the result back to the initial ring |
---|
2013 | return( list( N, rez ) ); //return the rank and the Chern classes of the exterior product |
---|
2014 | } |
---|
2015 | example |
---|
2016 | { |
---|
2017 | "EXAMPLE:";echo =2; |
---|
2018 | ring r=0, (c(1..5)), dp; |
---|
2019 | list l=c(1..5); |
---|
2020 | // the rank and the Chern classes of the second exterior power of a vector bundle of rank 3 |
---|
2021 | print( chWedge(2, 3, l) ); |
---|
2022 | // the rank and the first 3 Chern classes |
---|
2023 | // of the fourth exterior power of a vector bundle of rank 5 |
---|
2024 | print( chWedge(4, 5, l, 1, 2, 3) ); |
---|
2025 | } |
---|
2026 | //--------------------------------------------------------------------------------- |
---|
2027 | |
---|
2028 | proc chWedge2L(int r, list c) |
---|
2029 | "USAGE: chWedge2L(r, c ); r integer, c list of polynomials |
---|
2030 | RETURN: list of polynomials |
---|
2031 | PURPOSE: computes the Chern classes of the second exterior power of a vector bundle |
---|
2032 | EXAMPLE: example chWedge2L; shows an example |
---|
2033 | NOTE: Implementation of the formula of Lascoux, the Schur polynomials are computed |
---|
2034 | using the second Jacobi-Trudi formula (in terms of the Chern classes) |
---|
2035 | " |
---|
2036 | { |
---|
2037 | // insure that the entries of c are polynomials |
---|
2038 | // in order to be able to apply maps |
---|
2039 | int i; |
---|
2040 | for(i=1;i<=size(c);i++) |
---|
2041 | { |
---|
2042 | c[i]=poly(c[i]); |
---|
2043 | } |
---|
2044 | if(r<0) // if the rank is negative |
---|
2045 | { |
---|
2046 | print("The rank of a vector bundle can non be negative"); |
---|
2047 | return(list()); // return the empty list in this case |
---|
2048 | } |
---|
2049 | if(r==0) // if we deal with the zero bundle |
---|
2050 | { |
---|
2051 | return( list( 0, list() ) ); // return the data corresponding to the zero bundle |
---|
2052 | } |
---|
2053 | //------------------------------------------- |
---|
2054 | // from now on we are in the case r > 0 |
---|
2055 | //------------------------------------------- |
---|
2056 | c=append_by_zeroes(r, c); |
---|
2057 | c=c[1..r]; |
---|
2058 | def br@=basering; // remember the base ring |
---|
2059 | // add additional variables to the base ring |
---|
2060 | list l10 = ringlist(basering)[2]; |
---|
2061 | l10[size(l10)+1] = "t@"; |
---|
2062 | for (int ii = 1; ii <= r; ii++) |
---|
2063 | { |
---|
2064 | l10[size(l10)+1] = "c@("+string(ii)+")"; |
---|
2065 | } |
---|
2066 | ring r@ = create_ring(ringlist(basering)[1], l10, "dp", "no_minpoly"); |
---|
2067 | execute( "map F= br@,"+varstr(br@)+";" ); // define the corresponding inclusion of rings |
---|
2068 | list c; |
---|
2069 | for(i=1;i<=r;i++) |
---|
2070 | { |
---|
2071 | c[i]=c@(i)*t@^i; |
---|
2072 | } |
---|
2073 | poly f = chWedge2LP(r,c); // get the total Chern class using the formula of Lascoux |
---|
2074 | matrix CF = coeffs(f, t@); |
---|
2075 | int N=r*(r-1) div 2; |
---|
2076 | list rez; // write its coefficients in front of the powers of t@ to a list |
---|
2077 | for(i=1;i<=N;i++) |
---|
2078 | { |
---|
2079 | rez=rez+list(CF[i+1,1]); |
---|
2080 | } |
---|
2081 | setring br@; // come back to the initial base ring |
---|
2082 | execute("map FF = r@,"+varstr(br@)+",0, c[1..r];"); // define the specialization homomorphism |
---|
2083 | return( list(N, FF( rez )) ); // bring the result to the initial ring |
---|
2084 | } |
---|
2085 | example |
---|
2086 | { |
---|
2087 | "EXAMPLE:";echo =2; |
---|
2088 | ring r=0, (c(1..3)), dp; |
---|
2089 | list l=c(1..3); |
---|
2090 | // the Chern classes of the second exterior power of a vector bundle of rank 3 |
---|
2091 | print(chWedge2L(3, l)); |
---|
2092 | } |
---|
2093 | //--------------------------------------------------------------------------------------- |
---|
2094 | |
---|
2095 | proc chWedge2LP(int r, list c) |
---|
2096 | "USAGE: chWedge2LP(r, c ); r integer, c list of polynomials |
---|
2097 | RETURN: poly |
---|
2098 | PURPOSE: computes the total Chern class of the second exterior power of a vector bundle |
---|
2099 | EXAMPLE: example chWedge2LP; shows an example |
---|
2100 | NOTE: Implementation of the formula of Lascoux, the Schur polynomials are computed |
---|
2101 | using the second Jacobi-Trudi formula (in terms of the Chern classes) |
---|
2102 | " |
---|
2103 | { |
---|
2104 | if(r<0) // if the rank is negative |
---|
2105 | { |
---|
2106 | print("The rank of a vector bundle can non be negative"); |
---|
2107 | return(1); // return 1 in this case |
---|
2108 | } |
---|
2109 | if(r==0) // if we deal with the zero bundle |
---|
2110 | { |
---|
2111 | return( 1 ); // return 1 in this case |
---|
2112 | } |
---|
2113 | //------------------------------------------- |
---|
2114 | // from now on we are in the case r > 0 |
---|
2115 | //------------------------------------------- |
---|
2116 | c=append_by_zeroes(r, c); |
---|
2117 | c=c[1..r]; |
---|
2118 | list I; // the partition (0,1,...,r-1) will be stored here |
---|
2119 | int i; |
---|
2120 | for(i=0;i<=r-1;i++) |
---|
2121 | { |
---|
2122 | I=I+list(i); |
---|
2123 | } |
---|
2124 | list PU = partUnder(I); // compute the partitions under I |
---|
2125 | int sz=size(PU); // get their number |
---|
2126 | poly rez; // the result will be computed here |
---|
2127 | list J; |
---|
2128 | poly cf; |
---|
2129 | // implement the Lascoux formula |
---|
2130 | for(i=1;i<=sz;i++) |
---|
2131 | { |
---|
2132 | J=PU[i]; |
---|
2133 | cf = IJcoef(I,J)/bigint(2)^( r*(r-1) div 2-sum(J) ); |
---|
2134 | rez = rez + cf * SchurCh(J, c ); |
---|
2135 | } |
---|
2136 | return(rez); |
---|
2137 | } |
---|
2138 | example |
---|
2139 | { |
---|
2140 | "EXAMPLE:";echo =2; |
---|
2141 | ring r=0, (c(1..3)), ws(1,2,3); |
---|
2142 | list l=c(1..3); |
---|
2143 | // the total Chern class of the second exterior power of a vector bundle of rank 3 |
---|
2144 | print(chWedge2LP(3, l)); |
---|
2145 | } |
---|
2146 | //--------------------------------------------------------------------------------------- |
---|
2147 | |
---|
2148 | proc todd(list c, list #) |
---|
2149 | "USAGE: todd(l [, n] ); l a list of polynomials, n integer |
---|
2150 | RETURN: list of polynomials |
---|
2151 | PURPOSE: computes [the first n] terms of the Todd class |
---|
2152 | EXAMPLE: example todd; shows an example |
---|
2153 | NOTE: returns an empty list if l is empty |
---|
2154 | " |
---|
2155 | { |
---|
2156 | int i, j, k; |
---|
2157 | // insure that the entries of c are polynomials |
---|
2158 | // in order to be able to apply maps |
---|
2159 | for(i=1;i<=size(c); i++) |
---|
2160 | { |
---|
2161 | c[i]=poly(c[i]); |
---|
2162 | } |
---|
2163 | int n; |
---|
2164 | # = integer_list(#)[1]; // take into account only the first integer entries that are positive |
---|
2165 | if( size(#) == 0 ) // if there are no optional parameters |
---|
2166 | { |
---|
2167 | n = size(c); |
---|
2168 | } |
---|
2169 | else |
---|
2170 | { |
---|
2171 | // set n to be 0, if the parameter is non-positive, |
---|
2172 | // set n to the value of the parameter otherwise |
---|
2173 | n = max( #[1], 0 ); |
---|
2174 | c = append_by_zeroes(n, c); // append c by zeroes if the length of c is smaller than n |
---|
2175 | if(n!=0) // throw away the redundant data if n is positive and smaller than the length of c |
---|
2176 | { |
---|
2177 | c = c[1..n]; |
---|
2178 | } |
---|
2179 | } |
---|
2180 | if(n==0) // return the empty list |
---|
2181 | { |
---|
2182 | return(list()); |
---|
2183 | } |
---|
2184 | else // otherwise proceed as follows |
---|
2185 | { |
---|
2186 | def br@=basering; // remember the base ring |
---|
2187 | // add additional variables to the base ring |
---|
2188 | list l11 = ringlist(basering)[2]; |
---|
2189 | l11[size(l11)+1] = "a@"; |
---|
2190 | for (int ii = 1; ii <= n; ii++) |
---|
2191 | { |
---|
2192 | l11[size(l11)+1] = "c@("+string(ii)+")"; |
---|
2193 | } |
---|
2194 | ring r@ = create_ring(ringlist(basering)[1], l11, "dp", "no_minpoly"); |
---|
2195 | execute( "map F= br@,"+varstr(br@)+";" ); // define the corresponding inclusion of rings |
---|
2196 | list c=F(c); // embed c into the bigger ring |
---|
2197 | list prev; |
---|
2198 | list next; |
---|
2199 | next=tdTerms(n, c@(1)); // the Todd class terms of a line budle |
---|
2200 | list step = tdTerms(n, a@); |
---|
2201 | poly f; |
---|
2202 | list hC=c@(1)-a@; // "old" first Chern class |
---|
2203 | for(k=2;k<=n;k++) // do n-1 iterations |
---|
2204 | { |
---|
2205 | prev=next; |
---|
2206 | next=list(); |
---|
2207 | hC=hC+list( c@(k)-a@*hC[k-1] ); // "old" k-th Chern class |
---|
2208 | for(i=0;i<k;i++) // these terms have already been computed in the previous iterations |
---|
2209 | { |
---|
2210 | next = next + list(prev[i+1]); |
---|
2211 | } |
---|
2212 | for(i=k;i<=n;i++) // new values in terms of "old" Chern classes and the Chern root a |
---|
2213 | { |
---|
2214 | f=0; |
---|
2215 | for(j=0; j<=i; j++) |
---|
2216 | { |
---|
2217 | f=f + step[j+1]*prev[i-j+1]; |
---|
2218 | } |
---|
2219 | // substitute the old values of Chern classes |
---|
2220 | // by their expressions in the new ones and the Chern root a |
---|
2221 | for(j=1;j<k;j++) |
---|
2222 | { |
---|
2223 | f=subst(f, c@(j), hC[j] ); |
---|
2224 | } |
---|
2225 | f=reduce(f, std(hC[k]) ); // eliminate the Chern root |
---|
2226 | next = next + list(f); |
---|
2227 | } |
---|
2228 | } |
---|
2229 | next = delete(next, 1); // throw away the zeroth term which is always equal to 1 |
---|
2230 | setring br@; // come back to the initial base ring |
---|
2231 | execute("map FF = r@,"+varstr(br@)+",0, c[1..n];"); // define the specialization homomorphism |
---|
2232 | return( FF( next ) ); // bring the result to the initial ring |
---|
2233 | } |
---|
2234 | } |
---|
2235 | example |
---|
2236 | { |
---|
2237 | "EXAMPLE:";echo =2; |
---|
2238 | // the terms of the Todd class up to degree 5 |
---|
2239 | // in terms of the Chern classes c(1), c(2), c(3), c(4), c(5) |
---|
2240 | ring r=0, (c(1..5)), dp; |
---|
2241 | list l=c(1..5); |
---|
2242 | print( todd( l ) ); |
---|
2243 | |
---|
2244 | // in the same situation compute only first two terms |
---|
2245 | print( todd(l, 2) ); |
---|
2246 | |
---|
2247 | // compute the first 5 terms corresponding to the Chern classes c(1), c(2) |
---|
2248 | l=c(1..2); |
---|
2249 | print( todd(l, 5) ); |
---|
2250 | } |
---|
2251 | //------------------------------------------------------------------------------------------ |
---|
2252 | |
---|
2253 | proc toddE(list c) |
---|
2254 | "USAGE: toddE(l); l a list of polynomials |
---|
2255 | RETURN: polynomial |
---|
2256 | PURPOSE: computes the highest relevant term of the Todd class |
---|
2257 | EXAMPLE: example toddE; shows an example |
---|
2258 | NOTE: returns an empty list if l is empty, |
---|
2259 | very inefficient because the elimination is used, included for comparison with todd(c) |
---|
2260 | " |
---|
2261 | { |
---|
2262 | int i; |
---|
2263 | for(i=1;i<=size(c);i++) |
---|
2264 | { |
---|
2265 | c[i]=poly( c[i] ); |
---|
2266 | } |
---|
2267 | int n=size(c); |
---|
2268 | if(n==0) // return the empty list if c is empty |
---|
2269 | { |
---|
2270 | return(list()); |
---|
2271 | } |
---|
2272 | else |
---|
2273 | { |
---|
2274 | def br@=basering; // remember the base ring |
---|
2275 | // add additional variables a@(1..n), x@ to the base ring |
---|
2276 | list l12 = "x@"; |
---|
2277 | l12 = l12+ ringlist(basering)[2]; |
---|
2278 | for (int ii = 1; ii <= n; ii++) |
---|
2279 | { |
---|
2280 | l12[size(l12)+1] = "a@("+string(ii)+")"; |
---|
2281 | } |
---|
2282 | ring r@ = create_ring(ringlist(basering)[1], l12, "lp", "no_minpoly"); |
---|
2283 | execute( "map F= br@,"+varstr(br@)+";" ); // define the corresponding inclusion of rings |
---|
2284 | list c=F(c); // embed c into the bigger ring |
---|
2285 | int j; |
---|
2286 | int k; |
---|
2287 | poly E = a@(1); // to be the product of the Chern roots that will be eliminated later |
---|
2288 | list ss=tdTerms( n, a@(1) ); |
---|
2289 | list next; // to be the terms of the Todd class corresponding to the next Chern root |
---|
2290 | for(i=2;i<=n;i++) // compute the terms of the Todd class in terms of the Chern roots |
---|
2291 | { |
---|
2292 | E=E*a@(i); // to compute the product of variables to be eliminated |
---|
2293 | next=tdTerms( n, a@(i) ); |
---|
2294 | for(j=n;j>=1;j--) |
---|
2295 | { |
---|
2296 | for(k=0;k<j;k++) |
---|
2297 | { |
---|
2298 | ss[j+1]=ss[j+1]+ss[k+1]*next[j-k+1]; |
---|
2299 | } |
---|
2300 | } |
---|
2301 | } |
---|
2302 | ideal I=x@ - ss[n+1]; // formula for the highest degree term of the Todd class |
---|
2303 | list sym=symm(list(a@(1..n))); // expressions for the Chern classes in terms of the Chern roots |
---|
2304 | for(i=1;i<=n;i++) |
---|
2305 | { |
---|
2306 | I=I, c[i]-sym[i]; // add the relations |
---|
2307 | } |
---|
2308 | I=simplify(elim(I, E), 1); // eliminate the Chern roots |
---|
2309 | poly rez=-subst(I[1],x@, 0); // get the required formula |
---|
2310 | setring br@; // come back to the initial base ring |
---|
2311 | // define the specialization homomorphism (all added variables are set to zero) |
---|
2312 | execute( "map FF = r@,0, "+varstr(br@)+";" ); |
---|
2313 | poly rez=FF( rez ); // bring the result back to the initial base ring |
---|
2314 | return(rez); |
---|
2315 | } |
---|
2316 | } |
---|
2317 | example |
---|
2318 | { |
---|
2319 | "EXAMPLE:";echo =2; |
---|
2320 | // first 3 terms of the Todd class in terms of the Chern classes c(1), c(2), c(3) |
---|
2321 | ring r=0, (c(1..3)), dp; |
---|
2322 | list l; |
---|
2323 | //first term |
---|
2324 | l=c(1); |
---|
2325 | print( toddE( l ) ); |
---|
2326 | // second term |
---|
2327 | l=c(1..2); |
---|
2328 | print( toddE( l ) ); |
---|
2329 | // third term |
---|
2330 | l=c(1..3); |
---|
2331 | print( toddE( l ) ); |
---|
2332 | } |
---|
2333 | //--------------------------------------------------------------------------------- |
---|
2334 | |
---|
2335 | proc Bern(int n) |
---|
2336 | "USAGE: Bern(n); n non-negative integer |
---|
2337 | RETURN: list of numbers |
---|
2338 | PURPOSE: computes the list of (second) Bernoulli numbers from B(0) to B(n) |
---|
2339 | EXAMPLE: example Bern; shows an example |
---|
2340 | NOTE: needs a base ring to be defined, returns an empty list if n is negative, |
---|
2341 | uses the Akiyama-Tanigawa algorithm |
---|
2342 | " |
---|
2343 | { |
---|
2344 | // the Akiyama-Tanigawa algorithm |
---|
2345 | //could be replaced by a more efficient one |
---|
2346 | list rez, steprez; |
---|
2347 | int i, j; |
---|
2348 | if(n<0) // if n is negative, return the empty list |
---|
2349 | { |
---|
2350 | return(list()); |
---|
2351 | } |
---|
2352 | for(i=0;i<=n;i++) |
---|
2353 | { |
---|
2354 | steprez=steprez+list( 1/number(i+1) ); |
---|
2355 | for(j=i;j>=1;j--) |
---|
2356 | { |
---|
2357 | steprez[j]=j*(steprez[j]-steprez[j+1]); |
---|
2358 | } |
---|
2359 | rez=rez+list(steprez[1]); |
---|
2360 | } |
---|
2361 | return(rez); |
---|
2362 | } |
---|
2363 | example |
---|
2364 | { |
---|
2365 | "EXAMPLE:";echo =2; |
---|
2366 | // first 10 Bernoulli numbers: B(0), ..., B(9) |
---|
2367 | ring r=0,(t), dp; |
---|
2368 | print( Bern(9) ); |
---|
2369 | } |
---|
2370 | //--------------------------------------------------------------------------------- |
---|
2371 | |
---|
2372 | proc tdCf(int n) |
---|
2373 | "USAGE: tdCf(n); n integer |
---|
2374 | RETURN: list of rational numbers |
---|
2375 | PURPOSE: computes up to degree n the coefficients of the Todd class of a line bundle |
---|
2376 | EXAMPLE: example tdCf; shows an example |
---|
2377 | NOTE: |
---|
2378 | " |
---|
2379 | { |
---|
2380 | list rez=Bern(n); // notice that Bern(n) is able to take care of negative n |
---|
2381 | int i; |
---|
2382 | for(i=1;i<=n+1;i++) |
---|
2383 | { |
---|
2384 | rez[i]=rez[i]/factorial(i-1); |
---|
2385 | } |
---|
2386 | return(rez); |
---|
2387 | } |
---|
2388 | example |
---|
2389 | { |
---|
2390 | "EXAMPLE:";echo =2; |
---|
2391 | // first 5 coefficients |
---|
2392 | ring r=0,(t), dp; |
---|
2393 | print( tdCf(4) ); |
---|
2394 | } |
---|
2395 | //--------------------------------------------------------------------------------- |
---|
2396 | |
---|
2397 | proc tdTerms(int n, poly f) |
---|
2398 | "USAGE: tdTerms(n, f); n integer, f polynomial |
---|
2399 | RETURN: list of polynomials |
---|
2400 | PURPOSE: computes the terms of the Todd class of the line bundle with the Chern root f |
---|
2401 | EXAMPLE: example tdTerms; shows an example |
---|
2402 | NOTE: |
---|
2403 | " |
---|
2404 | { |
---|
2405 | list rez=Bern(n); // notice that Bern(n) takes care of negative n |
---|
2406 | int i; |
---|
2407 | for(i=1;i<=n+1;i++) |
---|
2408 | { |
---|
2409 | rez[i]=( rez[i]/factorial(i-1) )* f^(i-1); |
---|
2410 | } |
---|
2411 | return(rez); |
---|
2412 | } |
---|
2413 | example |
---|
2414 | { |
---|
2415 | "EXAMPLE:";echo =2; |
---|
2416 | ring r=0, (t), ls;; |
---|
2417 | // the terms of the Todd class of a line bundle with Chern root t up to degree 4 |
---|
2418 | print( tdTerms(4, t) ); |
---|
2419 | } |
---|
2420 | //--------------------------------------------------------------------------------- |
---|
2421 | |
---|
2422 | proc tdFactor(int n, poly t) |
---|
2423 | "USAGE: tdFactor(n, a); n integer, a polynomial |
---|
2424 | RETURN: polynomial |
---|
2425 | PURPOSE: computes up to degree n the Todd class |
---|
2426 | of the line bundle corresponding to the Chern root t |
---|
2427 | EXAMPLE: example tdFactor; shows an example |
---|
2428 | NOTE: returns 0 if n is negative |
---|
2429 | " |
---|
2430 | { |
---|
2431 | int i; |
---|
2432 | poly rez=0; |
---|
2433 | list l=Bern(n); // get the coefficients |
---|
2434 | for(i=0; i<=n; i++) // form the polynomial |
---|
2435 | { |
---|
2436 | rez=rez+(l[i+1]/factorial(i))*t^i; |
---|
2437 | } |
---|
2438 | return(rez); |
---|
2439 | } |
---|
2440 | example |
---|
2441 | { |
---|
2442 | "EXAMPLE:";echo =2; |
---|
2443 | // the Todd class up do degree 4 |
---|
2444 | ring r=0,(t), ls; |
---|
2445 | print( tdFactor(4, t) ); |
---|
2446 | } |
---|
2447 | //--------------------------------------------------------------------------------- |
---|
2448 | |
---|
2449 | proc cProj(int n) |
---|
2450 | "USAGE: cProj(n); n integer |
---|
2451 | RETURN: list of integers |
---|
2452 | PURPOSE: computes the terms of positive degree of the total Chern class |
---|
2453 | of the tangent bundle on the complex projective space |
---|
2454 | EXAMPLE: example cProj; shows an example |
---|
2455 | NOTE: |
---|
2456 | " |
---|
2457 | { |
---|
2458 | if(n<0) |
---|
2459 | { |
---|
2460 | print("The dimension of the projective space must be non-negative!"); |
---|
2461 | return(list()); // return the empty list in this case |
---|
2462 | } |
---|
2463 | else |
---|
2464 | { |
---|
2465 | list rez; |
---|
2466 | int i; |
---|
2467 | for(i=1;i<=n;i++) |
---|
2468 | { |
---|
2469 | rez=rez+list( binomial(n+1, i) ); |
---|
2470 | } |
---|
2471 | return(rez); |
---|
2472 | } |
---|
2473 | } |
---|
2474 | example |
---|
2475 | { |
---|
2476 | "EXAMPLE:";echo =2; |
---|
2477 | ring r=0, (t), dp; |
---|
2478 | // the coefficients of the total Chern class of the complex projective line |
---|
2479 | print( cProj(1) ); |
---|
2480 | |
---|
2481 | // the coefficients of the total Chern class of the complex projective line |
---|
2482 | print( cProj(2) ); |
---|
2483 | |
---|
2484 | // the coefficients of the total Chern class of the complex projective line |
---|
2485 | print( cProj(3) ); |
---|
2486 | } |
---|
2487 | //------------------------------------------------------------------------------------------ |
---|
2488 | |
---|
2489 | proc chProj(int n) |
---|
2490 | "USAGE: chProj(n); n integer |
---|
2491 | RETURN: list of (rational) numbers |
---|
2492 | PURPOSE: computes the terms of the Chern character of the tangent bundle |
---|
2493 | on the complex projective space |
---|
2494 | EXAMPLE: example chProj; shows an example |
---|
2495 | NOTE: |
---|
2496 | " |
---|
2497 | { |
---|
2498 | if(n<0) |
---|
2499 | { |
---|
2500 | print("The dimension of the projective space must be non-negative!"); |
---|
2501 | return( list() ); // return the empty list in this case |
---|
2502 | } |
---|
2503 | else |
---|
2504 | { |
---|
2505 | list rez=list(number(n)); |
---|
2506 | int i; |
---|
2507 | for(i=1;i<=n;i++) |
---|
2508 | { |
---|
2509 | rez=rez+list( (n+1)/factorial(i) ); |
---|
2510 | } |
---|
2511 | return(rez); |
---|
2512 | } |
---|
2513 | } |
---|
2514 | example |
---|
2515 | { |
---|
2516 | "EXAMPLE:";echo =2; |
---|
2517 | ring r=0, (t), dp; |
---|
2518 | // the coefficients of the Chern character of the complex projective line |
---|
2519 | print( chProj(1) ); |
---|
2520 | |
---|
2521 | // the coefficients of the Chern character of the complex projective plane |
---|
2522 | print( chProj(2) ); |
---|
2523 | |
---|
2524 | // the coefficients of the Chern character of the complex 3-dimentional projectice space |
---|
2525 | print( chProj(3) ); |
---|
2526 | } |
---|
2527 | //------------------------------------------------------------------------------------------ |
---|
2528 | |
---|
2529 | proc tdProj(int n) |
---|
2530 | "USAGE: tdProj(n); n integer |
---|
2531 | RETURN: list of (rational) numbers |
---|
2532 | PURPOSE: computes the terms of the Todd class |
---|
2533 | of the (tangent bundle of the) complex projective space |
---|
2534 | EXAMPLE: example tdProj; shows an example |
---|
2535 | NOTE: |
---|
2536 | " |
---|
2537 | { |
---|
2538 | if(n<0) |
---|
2539 | { |
---|
2540 | print("The dimension of the projective space must be non-negative!"); |
---|
2541 | return( list() ); // return the empty list in this case |
---|
2542 | } |
---|
2543 | else |
---|
2544 | { |
---|
2545 | def br@=basering; // remember the base ring |
---|
2546 | ring r@= 0, t@, lp; // ring with one variable t@ |
---|
2547 | ideal T=std( t@^(n+1) ); |
---|
2548 | poly f= tdFactor(n, t@); |
---|
2549 | f=reduce( f^(n+1), T); |
---|
2550 | matrix C = coeffs(f, t@); |
---|
2551 | list rez; |
---|
2552 | int i; |
---|
2553 | for(i=0;i<=n;i++) |
---|
2554 | { |
---|
2555 | rez=rez+list(C[i+1, 1]); |
---|
2556 | } |
---|
2557 | setring br@; // come back to the initial base ring |
---|
2558 | map FF= r@, 0 ; // define the specialization homomorphism t@=0 |
---|
2559 | return(FF(rez)); // bring the result to the base ring |
---|
2560 | } |
---|
2561 | } |
---|
2562 | example |
---|
2563 | { |
---|
2564 | "EXAMPLE:";echo =2; |
---|
2565 | ring r=0, (t), dp; |
---|
2566 | |
---|
2567 | // the coefficients of the Todd class of the complex projective line |
---|
2568 | print( tdProj(1) ); |
---|
2569 | |
---|
2570 | // the coefficients of the Todd class of the complex projective line |
---|
2571 | print( tdProj(2) ); |
---|
2572 | |
---|
2573 | // the coefficients of the Todd class of the complex projective line |
---|
2574 | print( tdProj(3) ); |
---|
2575 | } |
---|
2576 | //------------------------------------------------------------------------------------------ |
---|
2577 | |
---|
2578 | proc eulerChProj(int n, def r, list c) |
---|
2579 | "USAGE: eulerChProj(n, r, c); n integer, r polynomial (or integer), c list of polynomials |
---|
2580 | RETURN: polynomial |
---|
2581 | PURPOSE: computes the Euler characteristic of a vector bundle on P_n |
---|
2582 | in terms of its rank and Chern classes |
---|
2583 | EXAMPLE: example eulerChProj; shows an example |
---|
2584 | NOTE: |
---|
2585 | " |
---|
2586 | { |
---|
2587 | if(n<0) |
---|
2588 | { |
---|
2589 | print("The dimension of the projective space must be non-negative!"); |
---|
2590 | return(0); // return zero in this case |
---|
2591 | } |
---|
2592 | else |
---|
2593 | { |
---|
2594 | if(n==0) |
---|
2595 | { |
---|
2596 | return(r); |
---|
2597 | } |
---|
2598 | // now n is at least 1 |
---|
2599 | c=append_by_zeroes(n, c); // append c by zeroes if its size is smaller than n |
---|
2600 | c=c[1..n]; // throw away the redundant data |
---|
2601 | // now the size of c is n |
---|
2602 | list td = tdProj(n); // terms of the Todd class of P_n |
---|
2603 | list ch = list(r) + chAll(c); // terms of the Chern character of the vector bundle |
---|
2604 | return( rHRR(n, ch, td) ); |
---|
2605 | } |
---|
2606 | } |
---|
2607 | example |
---|
2608 | { |
---|
2609 | "EXAMPLE:";echo =2; |
---|
2610 | ring h=0, (r, c(1..3)), ws(0,1,2,3); |
---|
2611 | list l=c(1..3); |
---|
2612 | // the Euler characteristic of a vector bundle on the projective line |
---|
2613 | print( eulerChProj(1, r, l) ); |
---|
2614 | |
---|
2615 | // the Euler characteristic of a vector bundle on the projective plane |
---|
2616 | print( eulerChProj(2, r, l) ); |
---|
2617 | |
---|
2618 | // the Euler characteristic of a vector bundle on P_3 |
---|
2619 | print( eulerChProj(3, r, l) ); |
---|
2620 | |
---|
2621 | // assume now that we have a bundle framed at a subplane of P_3 |
---|
2622 | // this implies c(1)=c(2)=0 |
---|
2623 | l= 0, 0, c(3); |
---|
2624 | |
---|
2625 | // the Euler characteristic is |
---|
2626 | print( eulerChProj(3, r, l) ); |
---|
2627 | // which implies that c(3) must be even in this case |
---|
2628 | } |
---|
2629 | //------------------------------------------------------- |
---|
2630 | |
---|
2631 | proc chNumbersProj(int n) |
---|
2632 | "USAGE: chNumbersProj(n); n integer |
---|
2633 | RETURN: list of integers |
---|
2634 | PURPOSE: computes the Chern numbers of the projective space P_n |
---|
2635 | EXAMPLE: example chNumbersProj; shows an example |
---|
2636 | NOTE: |
---|
2637 | " |
---|
2638 | { |
---|
2639 | return( chNumbers( n, cProj(n) ) ); |
---|
2640 | } |
---|
2641 | example |
---|
2642 | { |
---|
2643 | "EXAMPLE:";echo =2; |
---|
2644 | ring h=0, (t), dp; |
---|
2645 | // The Chern numbers of the projective plane P_2: |
---|
2646 | print( chNumbersProj(2) ); |
---|
2647 | |
---|
2648 | // The Chern numbers of P_3: |
---|
2649 | print( chNumbersProj(3) ); |
---|
2650 | } |
---|
2651 | //------------------------------------------------------- |
---|
2652 | |
---|
2653 | proc classpoly(list l, poly t) |
---|
2654 | "USAGE: classpoly(l, t); l list of polynomials, t polynomial |
---|
2655 | RETURN: polynomial |
---|
2656 | PURPOSE: computes the polynomial in t with coefficients being the entries of l |
---|
2657 | EXAMPLE: example classpoly; shows an example |
---|
2658 | NOTE: |
---|
2659 | " |
---|
2660 | { |
---|
2661 | int n=size(l); |
---|
2662 | poly pow=1; // powers of t will be compured here |
---|
2663 | poly rez=0; // result will be computed here |
---|
2664 | int i; |
---|
2665 | for(i=1; i<=n; i++) |
---|
2666 | { |
---|
2667 | pow=pow*t; // compute the required power of t |
---|
2668 | // add the i-th entry of l multiplied by the corresponding power of t to the result |
---|
2669 | rez=rez + l[i]*pow; |
---|
2670 | } |
---|
2671 | return( rez ); |
---|
2672 | } |
---|
2673 | example |
---|
2674 | { |
---|
2675 | "EXAMPLE:";echo=2; |
---|
2676 | ring r=0, (c(1..5), t), ds; |
---|
2677 | list l=c(1..5); |
---|
2678 | // get the polynomial c(1)*t + c(2)*t^2 + ... + c(5)*t^5 |
---|
2679 | print( classpoly(l, t) ); |
---|
2680 | } |
---|
2681 | //---------------------------------------------------------------------------------------- |
---|
2682 | |
---|
2683 | proc chernPoly(list c, poly t) |
---|
2684 | "USAGE: chernPoly(c, t); c list of polynomials, t polynomial |
---|
2685 | RETURN: polynomial |
---|
2686 | PURPOSE: computes the Chern polynomial in t |
---|
2687 | EXAMPLE: example chernPoly; shows an example |
---|
2688 | NOTE: does the same as toddPoly(...) |
---|
2689 | " |
---|
2690 | { |
---|
2691 | return( 1+classpoly(c, t) ); |
---|
2692 | } |
---|
2693 | example |
---|
2694 | { |
---|
2695 | "EXAMPLE:";echo=2; |
---|
2696 | ring r=0, (c(1..5), t), ds; |
---|
2697 | list l=c(1..5); |
---|
2698 | // get the Chern polynomial 1 + c(1)*t + c(2)*t^2 + ... + c(5)*t^5 |
---|
2699 | print( chernPoly(l, t) ); |
---|
2700 | } |
---|
2701 | //---------------------------------------------------------------------------------------- |
---|
2702 | |
---|
2703 | proc chernCharPoly(poly r, list ch, poly t) |
---|
2704 | "USAGE: chernCharPoly(r, ch, t); r polynomial, ch list of polynomials, t polynomial |
---|
2705 | RETURN: polynomial |
---|
2706 | PURPOSE: computes the polynomial in t corresponding to the Chern character |
---|
2707 | EXAMPLE: example chernpoly; shows an example |
---|
2708 | NOTE: |
---|
2709 | " |
---|
2710 | { |
---|
2711 | return( r+classpoly(ch, t) ); |
---|
2712 | } |
---|
2713 | example |
---|
2714 | { |
---|
2715 | "EXAMPLE:";echo=2; |
---|
2716 | ring h=0, (r, ch(1..5), t), ds; |
---|
2717 | list l=ch(1..5); |
---|
2718 | // get the polynomial r + ch(1)*t + ch(2)*t^2 + ... + ch(5)*t^5 |
---|
2719 | print( chernCharPoly(r, l, t) ); |
---|
2720 | } |
---|
2721 | //---------------------------------------------------------------------------------------- |
---|
2722 | |
---|
2723 | proc toddPoly(list td, poly t) |
---|
2724 | "USAGE: toddPoly(td, t); td list of polynomials, t polynomial |
---|
2725 | RETURN: polynomial |
---|
2726 | PURPOSE: computes the polynomial in t corresponding to the Todd class |
---|
2727 | EXAMPLE: example toddPoly; shows an example |
---|
2728 | NOTE: does the same as chernPoly(...) |
---|
2729 | " |
---|
2730 | { |
---|
2731 | return( 1+classpoly(td, t) ); |
---|
2732 | } |
---|
2733 | example |
---|
2734 | { |
---|
2735 | "EXAMPLE:"; echo=2; |
---|
2736 | ring r=0, (td(1..5), c(1..5), t), ds; |
---|
2737 | list l=td(1..5); |
---|
2738 | // get the polynomial 1 + td(1)*t + td(2)*t^2 + ... + td(5)*t^5 |
---|
2739 | print( toddPoly(l, t) ); |
---|
2740 | } |
---|
2741 | //--------------------------------------------------------------------------------------- |
---|
2742 | |
---|
2743 | proc rHRR(int N, list ch, list td) |
---|
2744 | "USAGE: rHRR( N, ch, td); N integer, ch, td lists of polynomials |
---|
2745 | RETURN: polynomial |
---|
2746 | PURPOSE: computes the the main ingredient of the right-hand side |
---|
2747 | of the Hirzebruch-Riemann-Roch formula |
---|
2748 | EXAMPLE: example rHRR; shows an example |
---|
2749 | NOTE: in order to get the right-hand side of the HRR formula |
---|
2750 | one needs to be able to compute the degree of the output of this procedure |
---|
2751 | " |
---|
2752 | { |
---|
2753 | poly rez; // to be the result |
---|
2754 | int i; |
---|
2755 | int nch=size(ch); // length of ch |
---|
2756 | int ntd=size(td); // length of td |
---|
2757 | for(i=1; i<=N+1; i++) // compute the highest degree term of ch.td |
---|
2758 | { |
---|
2759 | if( (i<=nch) && (N-i+2 <= ntd) ) |
---|
2760 | { |
---|
2761 | rez = rez + ch[i]*td[N-i+2]; |
---|
2762 | } |
---|
2763 | } |
---|
2764 | return(rez); |
---|
2765 | } |
---|
2766 | example |
---|
2767 | { |
---|
2768 | "EXAMPLE:"; echo=2; |
---|
2769 | ring r=0, (td(0..3), ch(0..3)), dp; |
---|
2770 | // Let ch(0), ch(1), ch(2), ch(3) be the terms of the Chern character |
---|
2771 | // of a vector bundle E on a 3-fold X. |
---|
2772 | list c = ch(0..3); |
---|
2773 | // Let td(0), td(1), td(2), td(3) be the terms of the Todd class of X. |
---|
2774 | list t = td(0..3); |
---|
2775 | // Then the highest term of the product ch(E).td(X) is: |
---|
2776 | print( rHRR(3, c, t) ); |
---|
2777 | } |
---|
2778 | //--------------------------------------------------------------------------------------- |
---|
2779 | |
---|
2780 | proc SchurS(list I, list S) |
---|
2781 | "USAGE: SchurS(I, S); I list of integers representing a partition, S list of polynomials |
---|
2782 | RETURN: poly |
---|
2783 | PURPOSE: computes the Schur polynomial in the Segre classes S (of the dual vector bundle), |
---|
2784 | i.e., in the complete homogeneous symmetric polynomials, with respect to the partition I |
---|
2785 | EXAMPLE: example SchurS; shows an example |
---|
2786 | NOTE: if S are the Segre classes of the tautological bundle on a grassmanian, |
---|
2787 | this gives the cohomology class of a Schubert cycle |
---|
2788 | " |
---|
2789 | { |
---|
2790 | int m=size(I); // size of I |
---|
2791 | S=list(1)+S; // add the zeroth Segre class |
---|
2792 | int szS=size(S); // size of S |
---|
2793 | int h,k; |
---|
2794 | int in; // variable for the index of the required Segre class |
---|
2795 | // construct the required m x m matrix from the first determinantal (Jacobi-Trudi) formula |
---|
2796 | matrix M[m][m]; |
---|
2797 | for(h=1;h<=m;h++) |
---|
2798 | { |
---|
2799 | for(k=1;k<=m;k++) |
---|
2800 | { |
---|
2801 | in=I[k]+k-h; // compute the index |
---|
2802 | if(in<0) // if it is negative, assume the corresponding Segre class to be zero |
---|
2803 | { |
---|
2804 | M[h,k]=0; |
---|
2805 | } |
---|
2806 | else |
---|
2807 | { |
---|
2808 | if(in>=szS) // if it is bigger than the number of the highest available Segre class in S |
---|
2809 | { |
---|
2810 | M[h, k]=0; // assume the corresponding Segre class is zero |
---|
2811 | } |
---|
2812 | else // otherwise |
---|
2813 | { |
---|
2814 | M[h, k]= S[in+1]; // use a value from S for the corresponding Segre class |
---|
2815 | } |
---|
2816 | } |
---|
2817 | } |
---|
2818 | } |
---|
2819 | return(det(M)); // return the determinant of the computed matrix |
---|
2820 | } |
---|
2821 | example |
---|
2822 | { |
---|
2823 | "EXAMPLE:"; echo=2; |
---|
2824 | // The Schur polynomial corresponding to the partition 1,2,4 |
---|
2825 | // and the Segre classes 1, s(1), s(2),..., s(6) |
---|
2826 | ring r=0,(s(1..6)), dp; |
---|
2827 | list I=1,2,4; |
---|
2828 | list S=s(1..6); |
---|
2829 | print( SchurS(I, S) ); |
---|
2830 | // compare this with the Schur polynomial computed using Chern classes |
---|
2831 | list C=chDual(chern(S)); |
---|
2832 | print( SchurCh(I, C) ); |
---|
2833 | } |
---|
2834 | //--------------------------------------------------------------------------------------- |
---|
2835 | |
---|
2836 | proc SchurCh(list I, list C) |
---|
2837 | "USAGE: SchurCh(I, C); I list of integers representing a partition, C list of polynomials |
---|
2838 | RETURN: poly |
---|
2839 | PURPOSE: computes the Schur polynomial in the Chern classes C, |
---|
2840 | i.e., in the elementary symmetric polynomials, with respect to the partition I |
---|
2841 | EXAMPLE: example SchurCh; shows an example |
---|
2842 | NOTE: if C are the Chern classes of the tautological bundle on a grassmanian, |
---|
2843 | this gives the cohomology class of a Schubert cycle |
---|
2844 | " |
---|
2845 | { |
---|
2846 | I=dualPart(I); // dual partition to I |
---|
2847 | int m=size(I); // size of I |
---|
2848 | C=list(1)+C; // add the zeroth Chern class |
---|
2849 | int szC=size(C); // size of C |
---|
2850 | int h,k; |
---|
2851 | int in; // variable for the index of the required Chern class |
---|
2852 | // construct the required m x m matrix from the second determinantal (Jacobi-Trudi) formula |
---|
2853 | matrix M[m][m]; |
---|
2854 | for(h=1;h<=m;h++) |
---|
2855 | { |
---|
2856 | for(k=1;k<=m;k++) |
---|
2857 | { |
---|
2858 | in=I[k]+k-h; // compute the index |
---|
2859 | if(in<0) // if it is negative, assume the corresponding Chern class to be zero |
---|
2860 | { |
---|
2861 | M[h,k]=0; |
---|
2862 | } |
---|
2863 | else |
---|
2864 | { |
---|
2865 | if(in>=szC) // if it is bigger than the number of the highest available Chern class in C |
---|
2866 | { |
---|
2867 | M[h, k]=0; // assume the corresponding Chern class is zero |
---|
2868 | } |
---|
2869 | else // otherwise |
---|
2870 | { |
---|
2871 | M[h, k]= C[in+1]; // use a value from C for the corresponding Chern class |
---|
2872 | } |
---|
2873 | } |
---|
2874 | } |
---|
2875 | } |
---|
2876 | return(det(M)); // return the determinant of the computed matrix |
---|
2877 | } |
---|
2878 | example |
---|
2879 | { |
---|
2880 | "EXAMPLE:"; echo=2; |
---|
2881 | // The Schur polynomial corresponding to the partition 1,2,4 |
---|
2882 | // and the Chern classes c(1), c(2), c(3) |
---|
2883 | ring r=0,(c(1..3)), dp; |
---|
2884 | list I=1,2,4; |
---|
2885 | list C=c(1..3); |
---|
2886 | print( SchurCh(I, C) ); |
---|
2887 | // Compare this with the Schur polynomial computed using Segre classes |
---|
2888 | list S=segre( chDual( list(c(1..3)) ), 6 ); |
---|
2889 | print(SchurS(I,S)); |
---|
2890 | } |
---|
2891 | //--------------------------------------------------------------------------------------- |
---|
2892 | |
---|
2893 | proc part(int m, int n) |
---|
2894 | "USAGE: part( m, n ); m positive integer, n non-negative integer |
---|
2895 | RETURN: list of lists |
---|
2896 | PURPOSE: computes all partitions of integers not exceeding n into m non-negative summands |
---|
2897 | EXAMPLE: example part; shows an example |
---|
2898 | NOTE: if n is negative or m is non-positive, the list with one empty entry is returned |
---|
2899 | " |
---|
2900 | { |
---|
2901 | if( n<0 ) // if n is negative |
---|
2902 | { |
---|
2903 | return(list(list())); // return the list with one empty entry |
---|
2904 | } |
---|
2905 | if(n==0) // if n equals 0, there is only one partition of 0 into m non-negative summands |
---|
2906 | { |
---|
2907 | return(list(listSame(0,m))); // return the list with one entry consistion of m zeroes |
---|
2908 | } |
---|
2909 | // otherwise proceed recursively |
---|
2910 | list rez=part(m, n-1); // get all partitions for n-1 |
---|
2911 | int i; |
---|
2912 | for(i=1;i<=m;i++) // for every i between 1 and m, add the partitions with exactly |
---|
2913 | { |
---|
2914 | rez=rez + appendToAll( part(m-i, n-1), listSame(n, i) ); // i summands equal to n |
---|
2915 | } |
---|
2916 | return(rez); // return the result |
---|
2917 | } |
---|
2918 | example |
---|
2919 | { |
---|
2920 | "EXAMPLE:"; echo=2; |
---|
2921 | // partitions into 3 summands of numbers not exceeding 1 |
---|
2922 | print( part(3, 1) ); |
---|
2923 | } |
---|
2924 | //--------------------------------------------------------------------------------------- |
---|
2925 | |
---|
2926 | proc dualPart(list I, list #) |
---|
2927 | "USAGE: dualPart( I [,N] ); I list of integers, N integer |
---|
2928 | RETURN: list of integers |
---|
2929 | PURPOSE: computes the partition dual (conjugate) to I |
---|
2930 | EXAMPLE: example dualPart; shows an example |
---|
2931 | NOTE: the result is extended by zeroes to length N if an optional integer |
---|
2932 | parameter N is given and the length of the computed dual partition |
---|
2933 | is smaller than N |
---|
2934 | " |
---|
2935 | { |
---|
2936 | int m= size(I); // size of I |
---|
2937 | if(m==0) // if I is the empty list |
---|
2938 | { |
---|
2939 | print("You are trying to compute the dual of the empty partition!"); |
---|
2940 | print("The partition with one zero is returned."); |
---|
2941 | return(list(0)); |
---|
2942 | } |
---|
2943 | // compute the dual partition |
---|
2944 | list J; // the result will be computed here |
---|
2945 | int i; |
---|
2946 | int j=I[1]; |
---|
2947 | int k; |
---|
2948 | for(k=1;k<=j;k++) |
---|
2949 | { |
---|
2950 | J=list(m)+J; |
---|
2951 | } |
---|
2952 | for(i=2;i<=m;i++) |
---|
2953 | { |
---|
2954 | j=I[i]-I[i-1]; |
---|
2955 | for(k=1;k<=j;k++) |
---|
2956 | { |
---|
2957 | J=list(m-i+1)+J; |
---|
2958 | } |
---|
2959 | } |
---|
2960 | if(size(J)==0) // if the dual partition J is empty (if I consists of zeroes) |
---|
2961 | { |
---|
2962 | J = list(0); // add zero to the result |
---|
2963 | } |
---|
2964 | if(size(#)>0) // if there is an optional parameter N |
---|
2965 | { |
---|
2966 | if( is_integer( #[1] ) ) // if the parameter is an integer, |
---|
2967 | { |
---|
2968 | if( size(J) < #[1] ) // if N is bigger than the length of J, |
---|
2969 | { |
---|
2970 | J=listSame(0, #[1]-size(J))+J; // extend J by zeroes to length N |
---|
2971 | } |
---|
2972 | } |
---|
2973 | } |
---|
2974 | return(J); // return the result |
---|
2975 | } |
---|
2976 | example |
---|
2977 | { |
---|
2978 | "EXAMPLE:"; echo =2; |
---|
2979 | // dual partition to (1, 3, 4): |
---|
2980 | list I = 1, 3, 4; |
---|
2981 | print( dualPart(I) ); |
---|
2982 | } |
---|
2983 | //--------------------------------------------------------------------------------------- |
---|
2984 | |
---|
2985 | proc PartC(list I, int m) |
---|
2986 | "USAGE: PartC( I, m); I list of integers, m integer |
---|
2987 | RETURN: list of integers |
---|
2988 | PURPOSE: computes the complement of a partition with respect to m |
---|
2989 | EXAMPLE: example PartC; shows an example |
---|
2990 | NOTE: returns the zero partition if the maximal element of the partition is smaller than m |
---|
2991 | " |
---|
2992 | { |
---|
2993 | int n=size(I); // size of I |
---|
2994 | if( m<I[n] ) // if m is smaller than the last term of I, |
---|
2995 | { |
---|
2996 | // give a warning |
---|
2997 | print("You are trying to compute a complement of a partition with respect"); |
---|
2998 | print("to a number that is smaller than the maximal summand of the partition!"); |
---|
2999 | print("The zero partition is returned."); |
---|
3000 | return(list(0)); // and return the zero partition |
---|
3001 | } |
---|
3002 | list J; // the result will be computed here |
---|
3003 | int i; |
---|
3004 | for(i=n;i>=1;i--) // invert the order of numbers |
---|
3005 | { |
---|
3006 | J=J+list(m-I[i]); // and substitute them by their complemenst to m |
---|
3007 | } |
---|
3008 | return(J); // return the result |
---|
3009 | } |
---|
3010 | example |
---|
3011 | { |
---|
3012 | "EXAMPLE:"; echo =2; |
---|
3013 | // Complement of the partition (1, 3, 4) with respect to 5 |
---|
3014 | list I = 1, 3, 4; |
---|
3015 | print( PartC(I, 5) ); |
---|
3016 | } |
---|
3017 | //--------------------------------------------------------------------------------------- |
---|
3018 | |
---|
3019 | proc partOver(int n, list J) |
---|
3020 | "USAGE: partOver( n, J); n integer, J list of integers (partition) |
---|
3021 | RETURN: list of lists |
---|
3022 | PURPOSE: computes the partitions over a given one with summands not exceeding n |
---|
3023 | EXAMPLE: example partOver; shows an example |
---|
3024 | NOTE: |
---|
3025 | " |
---|
3026 | { |
---|
3027 | int m=size(J); // size of J |
---|
3028 | if( m==0 ) // if J is an empty list |
---|
3029 | { |
---|
3030 | // give a warning |
---|
3031 | print("You are trying to compute partitions over an empty partition!"); |
---|
3032 | return( list() ); // and return the empty list |
---|
3033 | } |
---|
3034 | if( J[m] > n ) // if the biggest summand of the partition is bigger than n |
---|
3035 | { |
---|
3036 | return( list( ) ); // return the empty list |
---|
3037 | } |
---|
3038 | if( J[m] == 0 ) // if J consists of zeroes |
---|
3039 | { |
---|
3040 | return( part(m,n) ); // return all partitions of n into m summands |
---|
3041 | } |
---|
3042 | // now J is non-empty, contains con-zero summands, has partitions over it |
---|
3043 | list rez1; // the result will be computed here |
---|
3044 | int i,j; |
---|
3045 | if(m==1) // if J has only one element |
---|
3046 | { |
---|
3047 | for(j=J[1]; j<=n; j++) // run through the integers from J[1] to n |
---|
3048 | { |
---|
3049 | rez1=rez1 + list(j); // add the corresponding one element lists to the result |
---|
3050 | } |
---|
3051 | return(rez1); // return the result |
---|
3052 | } |
---|
3053 | // now J has at least two elements |
---|
3054 | // get the partitions over the partition without the last summand |
---|
3055 | list rez = partOver(n, delete(J, m)); |
---|
3056 | int sz=size(rez); // number of such partitions |
---|
3057 | list P; |
---|
3058 | int last; |
---|
3059 | for(i=1; i<=sz; i++) // run trough all such partitions |
---|
3060 | { |
---|
3061 | P=rez[i]; // for each partition P of this type |
---|
3062 | last = max( P[size(P)], J[m] ); |
---|
3063 | for(j = last;j<= n;j++) // run through the integers exceeding the last summands of P and J |
---|
3064 | { |
---|
3065 | // append them to P at the end and add the resulting partition to the result |
---|
3066 | rez1=rez1 + list(P+list(j)); |
---|
3067 | } |
---|
3068 | } |
---|
3069 | return(rez1); // return the result |
---|
3070 | } |
---|
3071 | example |
---|
3072 | { |
---|
3073 | "EXAMPLE:"; echo =2; |
---|
3074 | // Partitions over the partition (3, 3, 4) with summands not exceeding 4 |
---|
3075 | list I = 3, 3, 4; |
---|
3076 | print( partOver(4, I) ); |
---|
3077 | } |
---|
3078 | //--------------------------------------------------------------------------------------- |
---|
3079 | |
---|
3080 | proc partUnder(list J) |
---|
3081 | "USAGE: partUnder(J); J list of integers (partition) |
---|
3082 | RETURN: list of lists |
---|
3083 | PURPOSE: computes the partitions under a given one |
---|
3084 | EXAMPLE: example partUnder; shows an example |
---|
3085 | NOTE: |
---|
3086 | " |
---|
3087 | { |
---|
3088 | int m=size(J); // size of J |
---|
3089 | if(m==0) // if J is empty |
---|
3090 | { |
---|
3091 | return(list()); // return an empty list |
---|
3092 | } |
---|
3093 | list rez1; // the result will be computed here |
---|
3094 | int i; |
---|
3095 | if(m==1) // if J contains only one element |
---|
3096 | { |
---|
3097 | for(i=0; i<=J[1]; i++) |
---|
3098 | { |
---|
3099 | rez1=rez1+list(list(i)); |
---|
3100 | } |
---|
3101 | } |
---|
3102 | // now J contains at least two elements |
---|
3103 | list rez; |
---|
3104 | int Jlast=J[m]; // last element of J |
---|
3105 | rez = partUnder(delete(J, m)); // partitions under J without the last element |
---|
3106 | int j; |
---|
3107 | int sz=size(rez); // their number |
---|
3108 | list P; |
---|
3109 | int last; |
---|
3110 | for(i=1; i<=sz; i++) // for every such partition |
---|
3111 | { |
---|
3112 | P = rez[i]; |
---|
3113 | last = P[size(P)]; |
---|
3114 | for(j = last;j<=Jlast ;j++) // for every number between its last entry and the last entry of J |
---|
3115 | { |
---|
3116 | // append that number to the end of the partition |
---|
3117 | // and append the resulting partition to the final result |
---|
3118 | rez1 = rez1 + list(P+list(j)); |
---|
3119 | } |
---|
3120 | } |
---|
3121 | return(rez1); |
---|
3122 | } |
---|
3123 | example |
---|
3124 | { |
---|
3125 | "EXAMPLE:"; echo =2; |
---|
3126 | // Partitions under the partition (0, 1, 1) |
---|
3127 | list I = 0, 1, 1; |
---|
3128 | print( partUnder(I) ); |
---|
3129 | } |
---|
3130 | //------------------------------------------------------------------------------------------- |
---|
3131 | |
---|
3132 | proc SegreA(ideal I) |
---|
3133 | "USAGE: SegreA(I); I an ideal |
---|
3134 | RETURN: list of integers |
---|
3135 | PURPOSE: computes the Segre classes of the subscheme defined by I |
---|
3136 | EXAMPLE: example SegreA; shows an example |
---|
3137 | NOTE: |
---|
3138 | " |
---|
3139 | { |
---|
3140 | if( !homog(I) ) // if the ideal is not homogeneous |
---|
3141 | { |
---|
3142 | print("You are trying to compute the Segre class of a non-homogeneous ideal!"); |
---|
3143 | print("The ideal must be homogeneous, an empty list is returned."); |
---|
3144 | return( list() ); |
---|
3145 | } |
---|
3146 | // modify the generators of the ideal so that all of them are of the same degree |
---|
3147 | I=equal_deg(I); |
---|
3148 | int degGen=deg(I[1]); // this degree d is stored in this variable |
---|
3149 | int i; |
---|
3150 | list rez; // define the variable for the result |
---|
3151 | int n=nvars(basering)-1; // the dimension of the projective space |
---|
3152 | if(degGen==-1) // if the ideal is zero |
---|
3153 | { |
---|
3154 | for(i=0;i<=n;i++) |
---|
3155 | { |
---|
3156 | rez=rez+ list( int((-1)^i*binomial(n+i, i)) ); |
---|
3157 | } |
---|
3158 | return(rez); |
---|
3159 | } |
---|
3160 | int sz=ncols(I); // the number of new generators is stored here |
---|
3161 | def br@=basering; // remember the base ring |
---|
3162 | // add additional variables t@(1), ... , t@(sz) and u@ to the base ring |
---|
3163 | list l13 = ringlist(basering)[2]; |
---|
3164 | for (int ii = 1; ii <= sz; ii++) |
---|
3165 | { |
---|
3166 | l13[size(l13)+1] = "t@("+string(ii)+")"; |
---|
3167 | } |
---|
3168 | l13[size(l13)+1] = "u@"; |
---|
3169 | ring r@ = create_ring(ringlist(basering)[1], l13, "dp", "no_minpoly"); |
---|
3170 | ideal I=fetch(br@,I); // the ideal generated by I in the new ring |
---|
3171 | ideal J(0..n); // define n+1 ideals J(0), ... , J(n) |
---|
3172 | // compute the ideal of the Rees algebra of the ideal I: |
---|
3173 | for(i=1; i<=sz; i++) // consider the ideal generated by t@(i)-u@*I[i] |
---|
3174 | { |
---|
3175 | J(0)=J(0) + ideal( t@(i)-u@*I[i] ); |
---|
3176 | } |
---|
3177 | J(0)=eliminate(J(0), u@); // and eliminate the variable u@ |
---|
3178 | ideal T=t@(1..sz); // define the ideal generated by the additional variables t@(1), ... , t@(sz) |
---|
3179 | for(i=1;i<=n;i++)// for all i=1, ... n define J(j) as in 3.6 of the Aluffi's paper |
---|
3180 | { |
---|
3181 | // add a random general linear form in variables t@(1), ... , t@(n) to J(i-1) |
---|
3182 | J(i)=sat( random_hypersurf(J(i-1), T) , T)[1]; // and saturate with respect to T |
---|
3183 | } |
---|
3184 | poly prd=product(T); // compute the product of t@(i) |
---|
3185 | poly cl; |
---|
3186 | poly mlt; |
---|
3187 | for(i=0;i<=n;i++) |
---|
3188 | { |
---|
3189 | // eliminate all t@(i) from J(i) |
---|
3190 | // compute the degree of the scheme defined by this ideal |
---|
3191 | // and use it to compute the class corresponding to c(O(d))^n * G\otimes O(d) |
---|
3192 | cl=cl+mult(std(eliminate(J(i), prd)))*u@^i*(1+degGen*u@)^(n-i); |
---|
3193 | // the (n+1)-st power of the inverse of the Chern class of O(d) |
---|
3194 | mlt=mlt+binomial(n+i, i)*(-degGen*u@)^i; |
---|
3195 | } |
---|
3196 | poly resPoly; |
---|
3197 | // compute the Segre class by the Aluffi's formula from Proposition 3.1 as polynomial in u@ |
---|
3198 | resPoly= NF( 1-cl*mlt, u@^(n+1)); |
---|
3199 | matrix cf=coeffs(resPoly, u@); // coefficients of the Segre class |
---|
3200 | rez=list(); // empty the list |
---|
3201 | for(i=0;i<=n;i++) // fill the list with the the Segre classes in positive degrees |
---|
3202 | { |
---|
3203 | if( i < nrows(cf) ) // if i is not bigger than the maximal degree of non-zero Segre classes |
---|
3204 | { |
---|
3205 | rez=rez+list(int(cf[i+1,1])); |
---|
3206 | } |
---|
3207 | else // otherwise fill the list with zeroes |
---|
3208 | { |
---|
3209 | rez=rez+list( int(0) ); |
---|
3210 | } |
---|
3211 | } |
---|
3212 | return(rez); |
---|
3213 | } |
---|
3214 | example |
---|
3215 | { |
---|
3216 | "EXAMPLE:";echo =2; |
---|
3217 | // Consider a 3-dimensional projective space |
---|
3218 | ring r = 0, (x, y, z, w), dp; |
---|
3219 | // Consider 3 non-coplanar lines trough one point and compute the Segre class |
---|
3220 | ideal I=xy, xz, yz; |
---|
3221 | I; |
---|
3222 | SegreA(I); |
---|
3223 | // Now consider 3 coplanar lines trough one point and its Segre class |
---|
3224 | ideal J=w, x*y*(x+y); |
---|
3225 | J; |
---|
3226 | SegreA(J); |
---|
3227 | } |
---|
3228 | //------------------------------------------------------------------------------------------- |
---|
3229 | |
---|
3230 | proc FultonA(ideal I) |
---|
3231 | "USAGE: FultonA(I); I an ideal |
---|
3232 | RETURN: list of integers |
---|
3233 | PURPOSE: computes the Fulton classes of the subscheme defined by I |
---|
3234 | EXAMPLE: example FultonA; shows an example |
---|
3235 | NOTE: |
---|
3236 | " |
---|
3237 | { |
---|
3238 | if( !homog(I) ) // if the ideal is not homogeneous |
---|
3239 | { |
---|
3240 | print("You are trying to compute the Segre class of a non-homogeneous ideal!"); |
---|
3241 | print("The ideal must be homogeneous, an empty list is returned."); |
---|
3242 | return( list() ); |
---|
3243 | } |
---|
3244 | // modify the generators of the ideal so that all of them are of the same degree |
---|
3245 | I=equal_deg(I); |
---|
3246 | int degGen=deg(I[1]); // this degree d is stored in this variable |
---|
3247 | int i; |
---|
3248 | list rez; // define the variable for the result |
---|
3249 | int n=nvars(basering)-1; // the dimension of the projective space |
---|
3250 | if(degGen==-1) // if the ideal is zero |
---|
3251 | { |
---|
3252 | rez=rez+list(int(1)); |
---|
3253 | for(i=1;i<=n;i++) |
---|
3254 | { |
---|
3255 | rez=rez+ list( int(0) ); |
---|
3256 | } |
---|
3257 | return(rez); |
---|
3258 | } |
---|
3259 | int sz=ncols(I); // the number of new generators is stored here |
---|
3260 | def br@=basering; // remember the base ring |
---|
3261 | // add additional variables t@(1), ... , t@(sz) and u@ to the base ring |
---|
3262 | list l14 = ringlist(basering)[2]; |
---|
3263 | for (int ii = 1; ii <= sz; ii++) |
---|
3264 | { |
---|
3265 | l14[size(l14)+1] = "t@("+string(ii)+")"; |
---|
3266 | } |
---|
3267 | l14[size(l14)+1] = "u@"; |
---|
3268 | ring r@ = create_ring(ringlist(basering)[1], l14, "dp", "no_minpoly"); |
---|
3269 | ideal I=fetch(br@,I); // the ideal generated by I in the new ring |
---|
3270 | ideal J(0..n); // define n+1 ideals J(0), ... , J(n) |
---|
3271 | // compute the ideal of the Rees algebra of the ideal I: |
---|
3272 | for(i=1; i<=sz; i++) // consider the ideal generated by t@(i)-u@*I[i] |
---|
3273 | { |
---|
3274 | J(0)=J(0) + ideal( t@(i)-u@*I[i] ); |
---|
3275 | } |
---|
3276 | J(0)=eliminate(J(0), u@); // and eliminate the variable u@ |
---|
3277 | ideal T=t@(1..sz); // define the ideal generated by the additional variables t@(1), ... , t@(sz) |
---|
3278 | for(i=1;i<=n;i++)// for all i=1, ... n define J(j) as in 3.6 of the Aluffi's paper |
---|
3279 | { |
---|
3280 | // add a random general linear form in variables t@(1), ... , t@(n) to J(i-1) |
---|
3281 | J(i)=sat( random_hypersurf(J(i-1), T) , T)[1]; // and saturate with respect to T |
---|
3282 | } |
---|
3283 | poly prd=product(T); // compute the product of t@(i) |
---|
3284 | poly cl; |
---|
3285 | poly mlt; |
---|
3286 | for(i=0;i<=n;i++) |
---|
3287 | { |
---|
3288 | // eliminate all t@(i) from J(i) |
---|
3289 | // compute the degree of the scheme defined by this ideal |
---|
3290 | // the class corresponding to c(O(d))^n * G\otimes O(d) |
---|
3291 | cl=cl+ mult(std( eliminate( J(i), prd) ))*u@^i*(1+degGen*u@)^(n-i); |
---|
3292 | // the (n+1)-st power of the inverse of the Chern class of O(d) |
---|
3293 | mlt=mlt+binomial(n+i, i)*(-degGen*u@)^i; |
---|
3294 | } |
---|
3295 | poly resPoly; |
---|
3296 | // compute the Fulton class using the Aluffi's formula for the Segre class and |
---|
3297 | // multiplying it by the Chern class of the projective space (1+u@)^(n+1) |
---|
3298 | resPoly= NF( (1+u@)^(n+1)*(1-cl*mlt), u@^(n+1) ); |
---|
3299 | matrix cf=coeffs(resPoly, u@); // coefficients of the Fulton class |
---|
3300 | rez=list(); // empty the list |
---|
3301 | for(i=0;i<=n;i++) // fill the list with the the Fulton classes in positive degrees |
---|
3302 | { |
---|
3303 | if( i < nrows(cf) ) // if i is not bigger than the maximal degree of non-zero Fulton classes |
---|
3304 | { |
---|
3305 | rez=rez+list(int(cf[i+1,1])); |
---|
3306 | } |
---|
3307 | else // otherwise fill the list with zeroes |
---|
3308 | { |
---|
3309 | rez=rez+list( int(0) ); |
---|
3310 | } |
---|
3311 | } |
---|
3312 | return(rez); |
---|
3313 | } |
---|
3314 | example |
---|
3315 | { |
---|
3316 | "EXAMPLE:";echo =2; |
---|
3317 | // Consider a 3-dimensional projective space |
---|
3318 | ring r = 0, (x, y, z, w), dp; |
---|
3319 | // Consider 3 non-coplanar lines trough one point and compute the Fulton class |
---|
3320 | ideal I=xy, xz, yz; |
---|
3321 | I; |
---|
3322 | FultonA(I); |
---|
3323 | // Now consider 3 coplanar lines trough one point and its Fulton class |
---|
3324 | ideal J=w, x*y*(x+y); |
---|
3325 | J; |
---|
3326 | FultonA(J); |
---|
3327 | } |
---|
3328 | //------------------------------------------------------------------------------------------- |
---|
3329 | |
---|
3330 | proc CSMA(ideal I) |
---|
3331 | "USAGE: CSMA(I); I an ideal |
---|
3332 | RETURN: list of integers |
---|
3333 | PURPOSE: computes the Chern-Schwartz-MacPherson classes of the variety defined by I |
---|
3334 | EXAMPLE: example CSMA; shows an example |
---|
3335 | NOTE: |
---|
3336 | " |
---|
3337 | { |
---|
3338 | if( !homog(I) ) // if the ideal is not homogeneous |
---|
3339 | { |
---|
3340 | print("You are trying to compute the Chern-Schwartz-MacPherson class."); |
---|
3341 | print("However the input ideal is not homogeneous!"); |
---|
3342 | print("The ideal must be homogeneous, an empty list is returned."); |
---|
3343 | return( list() ); |
---|
3344 | } |
---|
3345 | int sz=ncols(I); |
---|
3346 | int i; |
---|
3347 | int n=nvars(basering)-1; |
---|
3348 | bigintmat REZ[1][n+1]; |
---|
3349 | int j; |
---|
3350 | int szpr; |
---|
3351 | list pr; |
---|
3352 | int sgn=-1; |
---|
3353 | for(i=1;i<=sz;i++) |
---|
3354 | { |
---|
3355 | sgn=-sgn; |
---|
3356 | pr=prds(i,I); |
---|
3357 | szpr=size(pr); |
---|
3358 | for(j=1;j<=szpr;j++) |
---|
3359 | { |
---|
3360 | REZ=REZ+sgn*CSM_hypersurf(pr[j]); |
---|
3361 | } |
---|
3362 | } |
---|
3363 | list rez; |
---|
3364 | for(i=0;i<=n;i++) |
---|
3365 | { |
---|
3366 | rez=rez+list(REZ[1,i+1]); |
---|
3367 | } |
---|
3368 | return(rez); |
---|
3369 | } |
---|
3370 | example |
---|
3371 | { |
---|
3372 | "EXAMPLE:";echo =2; |
---|
3373 | // consider the projective plane with homogeneous coordinates x, y, z |
---|
3374 | ring r = 0, (x, y, z), dp; |
---|
3375 | // the Chern-Schwartz-MacPherson class of a smooth cubic: |
---|
3376 | ideal I=x3+y3+z3; |
---|
3377 | I; |
---|
3378 | CSMA(I); |
---|
3379 | // the Chern-Schwartz-MacPherson class of singular cubic |
---|
3380 | // that is a union of 3 non-collinear lines: |
---|
3381 | ideal J=x*y*z; |
---|
3382 | J; |
---|
3383 | CSMA(J); |
---|
3384 | // the Chern-Schwartz-MacPherson class of singular cubic |
---|
3385 | // that is a union of 3 lines passing through one point |
---|
3386 | ideal K=x*y*(x+y); |
---|
3387 | K; |
---|
3388 | CSMA(K); |
---|
3389 | } |
---|
3390 | //------------------------------------------------------------------------------------------- |
---|
3391 | |
---|
3392 | proc EulerAff(ideal I) |
---|
3393 | "USAGE: EulerAff(I); I an ideal |
---|
3394 | RETURN: integer |
---|
3395 | PURPOSE: computes the Euler characteristic of the affine variety defined by I |
---|
3396 | EXAMPLE: example EulerAff; shows an example |
---|
3397 | NOTE: |
---|
3398 | " |
---|
3399 | { |
---|
3400 | int n=nvars(basering); |
---|
3401 | def br@=basering; // remember the base ring |
---|
3402 | ring r@ = create_ring(ringlist(basering)[1], "("+varstr(basering)+",homvar@)", "dp", "no_minpoly"); |
---|
3403 | ideal I=fetch(br@,I); |
---|
3404 | ideal J=homog(I, homvar@); |
---|
3405 | ideal JJ=J, homvar@; |
---|
3406 | return( CSMA(J)[n+1]-CSMA(JJ)[n+1] ); |
---|
3407 | } |
---|
3408 | example |
---|
3409 | { |
---|
3410 | "EXAMPLE:";echo =2; |
---|
3411 | ring r = 0, (x, y), dp; |
---|
3412 | // compute the Euler characteristic of the affine elliptic curve y^2=x^3+x+1; |
---|
3413 | ideal I=y2-x3-x-1; |
---|
3414 | EulerAff(I); |
---|
3415 | } |
---|
3416 | //------------------------------------------------------------------------------------------- |
---|
3417 | |
---|
3418 | proc EulerProj(ideal I) |
---|
3419 | "USAGE: EulerProj(I); I an ideal |
---|
3420 | RETURN: integer |
---|
3421 | PURPOSE: computes the highest degree term of the Chern-Schwartz-MacPherson class |
---|
3422 | of the variety defined by I, which equals the Euler characteristic |
---|
3423 | EXAMPLE: example EulerProj; shows an example |
---|
3424 | NOTE: uses CSMA(...) |
---|
3425 | " |
---|
3426 | { |
---|
3427 | if( !homog(I) ) // if the ideal is not homogeneous |
---|
3428 | { |
---|
3429 | print("The ideal must be homogeneous, zero is returned."); |
---|
3430 | return( int(0) ); |
---|
3431 | } |
---|
3432 | int n=nvars(basering); |
---|
3433 | return( CSMA(I)[n] ); |
---|
3434 | } |
---|
3435 | example |
---|
3436 | { |
---|
3437 | "EXAMPLE:";echo =2; |
---|
3438 | // consider the projective plane with homogeneous coordinates x, y, z |
---|
3439 | ring r = 0, (x, y, z), dp; |
---|
3440 | // Euler characteristic of a smooth cubic: |
---|
3441 | ideal I=x3+y3+z3; |
---|
3442 | I; |
---|
3443 | EulerProj(I); |
---|
3444 | // Euler characteritic of 3 non-collinear lines: |
---|
3445 | ideal J=x*y*z; |
---|
3446 | J; |
---|
3447 | EulerProj(J); |
---|
3448 | // Euler characteristic of 3 lines passing through one point |
---|
3449 | ideal K=x*y*(x+y); |
---|
3450 | K; |
---|
3451 | EulerProj(K); |
---|
3452 | } |
---|
3453 | //---------------------------------------------------------------------------------------- |
---|
3454 | // The procedures below are for the internal usage only |
---|
3455 | //---------------------------------------------------------------------------------------- |
---|
3456 | |
---|
3457 | static proc append_by_zeroes(int N, list c) |
---|
3458 | "USAGE: append_by_zeroes( N, c); N integer, c a list |
---|
3459 | RETURN: list |
---|
3460 | PURPOSE: appends by zeroes up to the length N |
---|
3461 | EXAMPLE: example append_by_zeroes; shows an example |
---|
3462 | NOTE: |
---|
3463 | " |
---|
3464 | { |
---|
3465 | int n=size(c); |
---|
3466 | if(N>n) // if N is greater than the length of c, append c by zeroes up to the length N |
---|
3467 | { |
---|
3468 | int i; |
---|
3469 | for(i=n+1;i<=N;i++) |
---|
3470 | { |
---|
3471 | c=c+list( poly(0) ); |
---|
3472 | } |
---|
3473 | } |
---|
3474 | return(c); |
---|
3475 | } |
---|
3476 | example |
---|
3477 | { |
---|
3478 | "EXAMPLE:";echo =2; |
---|
3479 | ring r = 0, (x, y, z), dp; |
---|
3480 | list l=(x, y, z); |
---|
3481 | //append the list by two zeroes and get a list of length 5 |
---|
3482 | print( append_by_zeroes(5, l) ); |
---|
3483 | } |
---|
3484 | //----------------------------------------------------------------------- |
---|
3485 | |
---|
3486 | static proc is_integer(def r) |
---|
3487 | "USAGE: is_integer(r); r any type |
---|
3488 | RETURN: 1 or 0 |
---|
3489 | PURPOSE: checks whether r is of type int or bigint |
---|
3490 | EXAMPLE: example is_integer; shows an example |
---|
3491 | NOTE: returns 1 if r is of type int or bigint, otherwise returns 0 |
---|
3492 | " |
---|
3493 | { |
---|
3494 | if( (typeof(r)=="int") || (typeof(r)=="bigint") ) |
---|
3495 | { |
---|
3496 | return(1); |
---|
3497 | } |
---|
3498 | else |
---|
3499 | { |
---|
3500 | return(0); |
---|
3501 | } |
---|
3502 | } |
---|
3503 | example |
---|
3504 | { |
---|
3505 | "EXAMPLE:";echo =2; |
---|
3506 | // test on int, bigint, poly |
---|
3507 | ring r; |
---|
3508 | int i=12; |
---|
3509 | bigint j=16; |
---|
3510 | poly f=x; |
---|
3511 | print( is_integer(i) ); |
---|
3512 | print( is_integer(j) ); |
---|
3513 | print( is_integer(f) ); |
---|
3514 | } |
---|
3515 | //------------------------------------------------------------------------------------ |
---|
3516 | |
---|
3517 | static proc integer_list(list l) |
---|
3518 | "USAGE: integer_list(l); l list |
---|
3519 | RETURN: list |
---|
3520 | PURPOSE: gets the first positive ingerer entries of l, computes their maximum; |
---|
3521 | used for adjusting the lists of optional parameters that are supposed to be integers |
---|
3522 | EXAMPLE: example integer_list; shows an example |
---|
3523 | NOTE: used in chWedge(...) and chSymm(...) |
---|
3524 | " |
---|
3525 | { |
---|
3526 | int M=0; |
---|
3527 | int n=size(l); |
---|
3528 | if(n==0) |
---|
3529 | { |
---|
3530 | return(list(l, M)); |
---|
3531 | } |
---|
3532 | // now n>0 |
---|
3533 | list rez; // the result will be computed here |
---|
3534 | int i=1; |
---|
3535 | while( is_integer( l[i] ) ) // take only the first integer entries of l |
---|
3536 | { |
---|
3537 | if(l[i]>0) // if they are positive |
---|
3538 | { |
---|
3539 | rez=rez+list( l[i] ); |
---|
3540 | if(l[i]>M) // adjust the maximum if necessary |
---|
3541 | { |
---|
3542 | M=l[i]; |
---|
3543 | } |
---|
3544 | i++; |
---|
3545 | } |
---|
3546 | else // otherwise get out from the loop |
---|
3547 | { |
---|
3548 | break; |
---|
3549 | } |
---|
3550 | } |
---|
3551 | return( list( rez, M) ); |
---|
3552 | } |
---|
3553 | example |
---|
3554 | { |
---|
3555 | "EXAMPLE:";echo =2; |
---|
3556 | // the first integer entries of 1,2,3,t are 1,2,3 |
---|
3557 | ring r=0,(t), ls; |
---|
3558 | list l=1,2,3, t; |
---|
3559 | print( integer_list(l) ); |
---|
3560 | } |
---|
3561 | //--------------------------------------------------------------------------------------- |
---|
3562 | |
---|
3563 | static proc appendToAll(list L, list A) |
---|
3564 | "USAGE: appendToAll( L, A ); L list of lists, A list |
---|
3565 | RETURN: list |
---|
3566 | PURPOSE: appends A to every entry of L |
---|
3567 | EXAMPLE: example appendToAll; shows an example |
---|
3568 | NOTE: |
---|
3569 | " |
---|
3570 | { |
---|
3571 | int n=size(L); |
---|
3572 | int i; |
---|
3573 | for(i=1;i<=n;i++) // run through all elements of L |
---|
3574 | { |
---|
3575 | L[i]=L[i]+A; // and append A to each of them |
---|
3576 | } |
---|
3577 | return(L); |
---|
3578 | } |
---|
3579 | example |
---|
3580 | { |
---|
3581 | "EXAMPLE:"; echo=2; |
---|
3582 | // Consider two lists |
---|
3583 | list l1, l2; |
---|
3584 | l1=1,2; |
---|
3585 | l2=3,4; |
---|
3586 | // The first one is |
---|
3587 | print(l1); |
---|
3588 | // The second one is |
---|
3589 | print(l2); |
---|
3590 | // Now consider the list with entries l1 and l2 |
---|
3591 | list L= l1, l2; |
---|
3592 | print(L); |
---|
3593 | // and consider a list A |
---|
3594 | list A = 7,9; |
---|
3595 | print(A); |
---|
3596 | // append A to all entries of L |
---|
3597 | print( appendToAll(L, A) ); |
---|
3598 | } |
---|
3599 | //--------------------------------------------------------------------------------------- |
---|
3600 | |
---|
3601 | static proc listSame(int n, int k) |
---|
3602 | "USAGE: listSame( n, k ); n integer, k non-negative integer |
---|
3603 | RETURN: list |
---|
3604 | PURPOSE: list with k entries each equal to n |
---|
3605 | EXAMPLE: example listSame; shows an example |
---|
3606 | NOTE: if k is negative or zero, the empty list is returned |
---|
3607 | " |
---|
3608 | { |
---|
3609 | list rez; |
---|
3610 | int i; |
---|
3611 | for(i=1;i<=k;i++) // create a list with k entries, each equal to n |
---|
3612 | { |
---|
3613 | rez=rez+list(n); |
---|
3614 | } |
---|
3615 | return(rez); |
---|
3616 | } |
---|
3617 | example |
---|
3618 | { |
---|
3619 | "EXAMPLE:"; echo=2; |
---|
3620 | // list of 5 zeroes |
---|
3621 | print( listSame(0, 5) ); |
---|
3622 | } |
---|
3623 | //--------------------------------------------------------------------------------------- |
---|
3624 | |
---|
3625 | static proc IJcoef(list I, list J) |
---|
3626 | "USAGE: IJcoef( I, J); J, J lists of integers |
---|
3627 | RETURN: bigint |
---|
3628 | PURPOSE: computes the coefficient used in the formula of Lascoux |
---|
3629 | EXAMPLE: example IJcoef; shows an example |
---|
3630 | NOTE: these coefficients are denoted (I, J) in the paper of Lascoux |
---|
3631 | " |
---|
3632 | { |
---|
3633 | int m = size(I); |
---|
3634 | if(m != size(J)) // if the sizes of I and J are different |
---|
3635 | { |
---|
3636 | // give a warning |
---|
3637 | print("The sizes of the partitions are different!"); |
---|
3638 | print("Zero is returned."); |
---|
3639 | return( bigint(0) ); // and return zero |
---|
3640 | } |
---|
3641 | // now the sizes of I and J are equal m |
---|
3642 | int h, k; |
---|
3643 | bigintmat M[m][m]; // construct the required matrix |
---|
3644 | for(h=1; h<=m; h++) |
---|
3645 | { |
---|
3646 | for(k=1; k<=m; k++) |
---|
3647 | { |
---|
3648 | M[h,k] = binomial( I[k]+k-1, J[h]+h-1 ); |
---|
3649 | } |
---|
3650 | } |
---|
3651 | return( det(M) ); // and return its determinant |
---|
3652 | } |
---|
3653 | example |
---|
3654 | { |
---|
3655 | "EXAMPLE:"; echo =2; |
---|
3656 | // The coefficient corresponding to the partitions (1, 3, 4) and (0, 3, 3) |
---|
3657 | list I = 1, 3, 4; |
---|
3658 | list J = 1, 3, 3; |
---|
3659 | print( IJcoef(I, J) ); |
---|
3660 | } |
---|
3661 | //--------------------------------------------------------------------------------------- |
---|
3662 | |
---|
3663 | static proc invertPart(list l) |
---|
3664 | "USAGE: invertPart(I); I list of integers (partition), |
---|
3665 | RETURN: list of integers |
---|
3666 | PURPOSE: inverts the ordering of the elements in the list |
---|
3667 | EXAMPLE: example invertPart; shows an example |
---|
3668 | NOTE: |
---|
3669 | " |
---|
3670 | { |
---|
3671 | list L; |
---|
3672 | int sz=size(l); |
---|
3673 | int i; |
---|
3674 | for(i=sz;i>=1;i--) |
---|
3675 | { |
---|
3676 | L=L+list(l[i]); |
---|
3677 | } |
---|
3678 | return(L); |
---|
3679 | } |
---|
3680 | example |
---|
3681 | { |
---|
3682 | "EXAMPLE:"; echo = 2; |
---|
3683 | // Invert the ordering of elements in (3, 2, 1) |
---|
3684 | list l = 3, 2, 1; |
---|
3685 | print( invertPart(l) ); |
---|
3686 | } |
---|
3687 | //--------------------------------------------------------------------------------------- |
---|
3688 | |
---|
3689 | static proc LRmul(list I, list J) |
---|
3690 | "USAGE: LRmul(x, y); x, y lists of integers (partitions) |
---|
3691 | RETURN: list of lists |
---|
3692 | PURPOSE: computes the partitions z for which the Littlewood-Richardson |
---|
3693 | coefficient c^z_{x,y} is non-zero together with that coefficient; |
---|
3694 | partitions up to length r |
---|
3695 | EXAMPLE: example LRmul; shows an example |
---|
3696 | NOTE: uses LRmult(..) from lrcalc.lib, does the same, |
---|
3697 | only uses the inverted ordering of the elements in the partition |
---|
3698 | " |
---|
3699 | { |
---|
3700 | list rez=LRmult(invertPart(I), invertPart(J)); |
---|
3701 | int sz=size(rez); |
---|
3702 | int i; |
---|
3703 | for(i=1;i<=sz;i++) |
---|
3704 | { |
---|
3705 | rez[i][2]=invertPart(rez[i][2]); |
---|
3706 | } |
---|
3707 | return(rez); |
---|
3708 | } |
---|
3709 | example |
---|
3710 | { |
---|
3711 | "EXAMPLE:"; echo = 2; |
---|
3712 | // Compute the partitions z for which the Littlewood-Richardson coefficient |
---|
3713 | // c^z_{x,y} is non-zero together with that coefficient |
---|
3714 | // for x= (1, 2), y=(1, 2) |
---|
3715 | list x = 1, 2; |
---|
3716 | list y = 1, 2; |
---|
3717 | print( LRmul(x, y) ); |
---|
3718 | } |
---|
3719 | //--------------------------------------------------------------------------------------- |
---|
3720 | |
---|
3721 | static proc hook(list I) |
---|
3722 | "USAGE: hook(I); I list of integers (partition), |
---|
3723 | RETURN: bigint |
---|
3724 | PURPOSE: computes the product of the hook lenhths of the partition I |
---|
3725 | EXAMPLE: example hook; shows an example |
---|
3726 | NOTE: |
---|
3727 | " |
---|
3728 | { |
---|
3729 | bigint rez=1; |
---|
3730 | list dI= invertPart( dualPart(I) ); |
---|
3731 | I=invertPart( I ); |
---|
3732 | int szI=size(I); |
---|
3733 | int szdI=size(dI); |
---|
3734 | int i, j; |
---|
3735 | for(i=1;i<=szI;i++) |
---|
3736 | { |
---|
3737 | for(j=1;j<=I[i];j++) |
---|
3738 | { |
---|
3739 | rez=rez*(I[i]+dI[j]-i-j+1); |
---|
3740 | } |
---|
3741 | } |
---|
3742 | return(rez); |
---|
3743 | } |
---|
3744 | example |
---|
3745 | { |
---|
3746 | "EXAMPLE:"; echo = 2; |
---|
3747 | // compute the product of all hook lengths of the partition (1, 1, 3) |
---|
3748 | list I = 1, 1, 3; |
---|
3749 | print( hook(I) ); |
---|
3750 | } |
---|
3751 | //--------------------------------------------------------------------------------------- |
---|
3752 | |
---|
3753 | static proc apn0_int(int N, list c) |
---|
3754 | "USAGE: apn0_int( N, c); N integer, c list of integers (partition) |
---|
3755 | RETURN: list of integers |
---|
3756 | PURPOSE: appends by integer zeroes up to the length N |
---|
3757 | EXAMPLE: example apn0_int; shows an example |
---|
3758 | NOTE: |
---|
3759 | " |
---|
3760 | { |
---|
3761 | int n=size(c); |
---|
3762 | if(N>n) // if N is greater than the length of c, append c by zeroes up to the length N |
---|
3763 | { |
---|
3764 | int i; |
---|
3765 | for(i=n+1;i<=N;i++) |
---|
3766 | { |
---|
3767 | c=c+list( int(0) ); |
---|
3768 | } |
---|
3769 | } |
---|
3770 | return(c); |
---|
3771 | } |
---|
3772 | example |
---|
3773 | { |
---|
3774 | "EXAMPLE:";echo =2; |
---|
3775 | ring r = 0, (x, y, z), dp; |
---|
3776 | list l=(1, 2, 3); |
---|
3777 | //append the list by two zeroes and get a list of length 5 |
---|
3778 | print( apn0_int(5, l) ); |
---|
3779 | } |
---|
3780 | //--------------------------------------------------------------------------------------- |
---|
3781 | |
---|
3782 | static proc contentPoly(list I, list J, poly e) |
---|
3783 | "USAGE: contentPoly(I, J, e); L, M lists of integers (partitions), |
---|
3784 | e polynomial |
---|
3785 | RETURN: poly |
---|
3786 | PURPOSE: computes the content polynomial of the skew partition corresponding to I>J |
---|
3787 | EXAMPLE: example contentPoly; shows an example |
---|
3788 | NOTE: |
---|
3789 | " |
---|
3790 | { |
---|
3791 | int i, j; |
---|
3792 | int szI=size(I); |
---|
3793 | I=invertPart(I); |
---|
3794 | J=invertPart(J); |
---|
3795 | J=apn0_int(szI, J); |
---|
3796 | poly rez=1; |
---|
3797 | for(i=1; i<=szI; i++) |
---|
3798 | { |
---|
3799 | for(j=J[i]+1; j<=I[i]; j++) |
---|
3800 | { |
---|
3801 | rez = rez*(e- i+j); |
---|
3802 | } |
---|
3803 | } |
---|
3804 | return(rez); |
---|
3805 | } |
---|
3806 | example |
---|
3807 | { |
---|
3808 | "EXAMPLE:"; echo = 2; |
---|
3809 | // compute the content Polynomial of the skew partition |
---|
3810 | // corresponding to (1,2) > (0, 1) with respect to the variable x |
---|
3811 | ring r = 0, (x), dp; |
---|
3812 | list L=1,2; |
---|
3813 | list M=0,1; |
---|
3814 | print( contentPoly(L, M, x) ); |
---|
3815 | } |
---|
3816 | //--------------------------------------------------------------------------------------- |
---|
3817 | |
---|
3818 | static proc Pcoef(list L, list M, poly e, poly f) |
---|
3819 | "USAGE: Pcoef(L, M, e, f); L, M lists of integers (partitions), |
---|
3820 | e, f polynomials |
---|
3821 | RETURN: poly |
---|
3822 | PURPOSE: computes the polynomial P_{L, M}(e, f) from the paper of Manivel |
---|
3823 | EXAMPLE: example Pcoef; shows an example |
---|
3824 | NOTE: |
---|
3825 | " |
---|
3826 | { |
---|
3827 | list P = LRmul(dualPart(L), M); |
---|
3828 | int sz=size(P); |
---|
3829 | poly rez; |
---|
3830 | //poly h; |
---|
3831 | list T, DT; |
---|
3832 | //bigint lrc; |
---|
3833 | int i; |
---|
3834 | for(i=1;i<=sz;i++) |
---|
3835 | { |
---|
3836 | T=P[i][2]; |
---|
3837 | DT=dualPart(T); |
---|
3838 | //lrc=P[i][1]; |
---|
3839 | //h=contentPolyM(DT, L, e)*contentPoly(T, M, f); |
---|
3840 | rez=rez+P[i][1]* contentPoly(DT, L, e)*contentPoly(T, M, f)/hook(DT); |
---|
3841 | } |
---|
3842 | return(rez); |
---|
3843 | } |
---|
3844 | example |
---|
3845 | { |
---|
3846 | "EXAMPLE:"; echo = 2; |
---|
3847 | // compute P_{L, M}(e, f) from the paper of Manivel |
---|
3848 | // for L = (0,1) and M = (1, 1) |
---|
3849 | ring r = 0, (e, f), dp; |
---|
3850 | list L=1,2,3; |
---|
3851 | list M=1,2; |
---|
3852 | print( Pcoef(L, M, e, f) ); |
---|
3853 | } |
---|
3854 | //--------------------------------------------------------------------------------------- |
---|
3855 | |
---|
3856 | static proc max_deg(ideal I) |
---|
3857 | "USAGE: max_deg(I); I an ideal |
---|
3858 | RETURN: integer |
---|
3859 | PURPOSE: computes the maximal degree of the generators of I |
---|
3860 | EXAMPLE: example max_deg; shows an example |
---|
3861 | NOTE: |
---|
3862 | " |
---|
3863 | { |
---|
3864 | int rez=0; |
---|
3865 | int i; |
---|
3866 | int sz = ncols(I); |
---|
3867 | for(i=1;i<=sz;i++) |
---|
3868 | { |
---|
3869 | rez=max(rez, deg(I[i]) ); |
---|
3870 | } |
---|
3871 | return(rez); |
---|
3872 | } |
---|
3873 | example |
---|
3874 | { |
---|
3875 | "EXAMPLE:";echo =2; |
---|
3876 | // the maximal degree of the ideal in k[x, y]: |
---|
3877 | ring r = 0, (x, y), dp; |
---|
3878 | ideal I= x4, y7, x2y3; |
---|
3879 | print(max_deg(I)); |
---|
3880 | } |
---|
3881 | //------------------------------------------------------------------------------------------- |
---|
3882 | |
---|
3883 | static proc var_pow(int n) |
---|
3884 | "USAGE: var_pow(n); n an integer |
---|
3885 | RETURN: ideal |
---|
3886 | PURPOSE: computes the ideal generated by the n-th powers of the variables of the base ring |
---|
3887 | EXAMPLE: example var_pow; shows an example |
---|
3888 | NOTE: |
---|
3889 | " |
---|
3890 | { |
---|
3891 | ideal I=maxideal(1); |
---|
3892 | int sz=ncols(I); |
---|
3893 | int i; |
---|
3894 | ideal J; |
---|
3895 | for(i=1; i<=sz; i++) |
---|
3896 | { |
---|
3897 | J=J+ideal(I[i]^n); |
---|
3898 | } |
---|
3899 | return(J); |
---|
3900 | } |
---|
3901 | example |
---|
3902 | { |
---|
3903 | "EXAMPLE:";echo =2; |
---|
3904 | // the 3-rd powers of the variables in k[x, y]: |
---|
3905 | ring r = 0, (x, y), dp; |
---|
3906 | print(var_pow(3)); |
---|
3907 | } |
---|
3908 | //------------------------------------------------------------------------------------------- |
---|
3909 | |
---|
3910 | static proc equal_deg(ideal I) |
---|
3911 | "USAGE: equal_deg(I); I an ideal |
---|
3912 | RETURN: ideal |
---|
3913 | PURPOSE: computes an ideal generated by elements of the same degree |
---|
3914 | that defines the same projective subscheme as I |
---|
3915 | EXAMPLE: example equal_deg; shows an example |
---|
3916 | NOTE: |
---|
3917 | " |
---|
3918 | { |
---|
3919 | I=simplify(I, 8+2); |
---|
3920 | int sz=ncols(I); |
---|
3921 | int mxd=max_deg(I); |
---|
3922 | int i; |
---|
3923 | ideal J; |
---|
3924 | for(i=1;i<=sz;i++) |
---|
3925 | { |
---|
3926 | J=J+I[i]*var_pow( mxd-deg(I[i]) ); |
---|
3927 | } |
---|
3928 | |
---|
3929 | return(sort( simplify(J, 8+2) )[1]); |
---|
3930 | } |
---|
3931 | example |
---|
3932 | { |
---|
3933 | "EXAMPLE:"; echo=2; |
---|
3934 | // change the ideal (x, y^2) in k[x, y, z]: |
---|
3935 | ring r = 0, (x, y, z), dp; |
---|
3936 | ideal I=x, y*z; |
---|
3937 | // the ideal defines a two points subscheme in the projective plane |
---|
3938 | // and is generated by elements of different degrees |
---|
3939 | print(I); |
---|
3940 | ideal J=equal_deg(I); |
---|
3941 | // now the ideal is generated by elements of degree 2 |
---|
3942 | // and defines the same subscheme in the projective plane |
---|
3943 | J; |
---|
3944 | // notice that both ideals have the same saturation |
---|
3945 | // with respect to the irrelevant ideal (x, y, z) |
---|
3946 | // the saturation of the initial ideal coincides with the ideal itself |
---|
3947 | sat(I, maxideal(1))[1]; |
---|
3948 | // the saturation of the modified ideal |
---|
3949 | sat(J, maxideal(1))[1]; |
---|
3950 | } |
---|
3951 | //------------------------------------------------------------------------------------------- |
---|
3952 | |
---|
3953 | static proc CSM_hypersurf(poly f) |
---|
3954 | "USAGE: CSM_hypersurf(f); f a polynomial |
---|
3955 | RETURN: list of integers |
---|
3956 | PURPOSE: computes the Chern-Schwartz-MacPherson classes of the hypersurface defined by f |
---|
3957 | EXAMPLE: example CSM_hypersurf; shows an example |
---|
3958 | NOTE: |
---|
3959 | " |
---|
3960 | { |
---|
3961 | ideal I=jacob(f); |
---|
3962 | I=simplify(I, 8+2); // ignore repetitions and zero generators |
---|
3963 | I=sort(I)[1]; // sort the generators, it speeds up the computations |
---|
3964 | int degGen=deg(I[1]); // the degree of the generators of the Jacobian ideal |
---|
3965 | int i; |
---|
3966 | int n=nvars(basering)-1; // the dimension of the projective space |
---|
3967 | bigintmat REZ[1][n+1]; |
---|
3968 | if(degGen==-1) // if the Jacobian ideal is zero |
---|
3969 | { |
---|
3970 | for(i=0;i<=n;i++) |
---|
3971 | { |
---|
3972 | REZ[1,i+1]=binomial(n+1,i); |
---|
3973 | } |
---|
3974 | return(REZ); |
---|
3975 | } |
---|
3976 | //TODO need to check the zero ideal and I==1; |
---|
3977 | int sz=ncols(I); |
---|
3978 | def br@=basering; // remember the base ring |
---|
3979 | list l15 = ringlist(basering)[2]; |
---|
3980 | for (int ii = 1; ii <= sz; ii++) |
---|
3981 | { |
---|
3982 | l15[size(l15)+1] = "t@("+string(ii)+")"; |
---|
3983 | } |
---|
3984 | l15[size(l15)+1] = "u@"; |
---|
3985 | ring r@ = create_ring(ringlist(basering)[1], l15, "dp", "no_minpoly"); |
---|
3986 | ideal I=fetch(br@,I); |
---|
3987 | ideal J(0..n); |
---|
3988 | for(i=1; i<=sz; i++) |
---|
3989 | { |
---|
3990 | J(0)=J(0) + ideal( t@(i)-u@*I[i] ); |
---|
3991 | } |
---|
3992 | J(0)=eliminate(J(0), u@); |
---|
3993 | ideal T=t@(1..sz); |
---|
3994 | for(i=1;i<=n;i++) |
---|
3995 | { |
---|
3996 | J(i) = sat( random_hypersurf(J(i-1), T), T )[1]; |
---|
3997 | } |
---|
3998 | poly prd=product(T); |
---|
3999 | poly cl; |
---|
4000 | poly mlt; |
---|
4001 | for(i=0;i<=n;i++) |
---|
4002 | { |
---|
4003 | cl=cl+ mult( std(eliminate( J(i), prd)) ) *(-u@)^i*(1+u@)^(n-i); |
---|
4004 | } |
---|
4005 | cl=(1+u@)^(n+1)-cl; |
---|
4006 | poly resPoly=NF( cl, u@^(n+1) ); |
---|
4007 | matrix cf=coeffs(resPoly, u@); |
---|
4008 | for(i=0;i<=n;i++) |
---|
4009 | { |
---|
4010 | if( i < nrows(cf) ) |
---|
4011 | { |
---|
4012 | REZ[1,i+1]=int(cf[i+1,1]); |
---|
4013 | } |
---|
4014 | else |
---|
4015 | { |
---|
4016 | REZ[1,i+1]=int(0); |
---|
4017 | } |
---|
4018 | } |
---|
4019 | return(REZ); |
---|
4020 | } |
---|
4021 | example |
---|
4022 | { |
---|
4023 | "EXAMPLE:";echo =2; |
---|
4024 | // consider the projective plane with homogeneous coordinates x, y, z |
---|
4025 | ring r = 0, (x, y, z), dp; |
---|
4026 | // the Chern-Schwartz-MacPherson class of a smooth cubic: |
---|
4027 | poly f=x3+y3+z3; |
---|
4028 | f; |
---|
4029 | CSM_hypersurf(f); |
---|
4030 | // the Chern-Schwartz-MacPherson class of singular cubic |
---|
4031 | // that is a union of 3 non-collinear lines: |
---|
4032 | poly g=x*y*z; |
---|
4033 | g; |
---|
4034 | CSM_hypersurf(g); |
---|
4035 | // the Chern-Schwartz-MacPherson class of singular cubic |
---|
4036 | // that is a union of 3 lines passing through one point |
---|
4037 | poly h=x*y*(x+y); |
---|
4038 | h; |
---|
4039 | CSM_hypersurf(h); |
---|
4040 | } |
---|
4041 | //------------------------------------------------------------------------------------------- |
---|
4042 | |
---|
4043 | static proc random_hypersurf(ideal I, ideal V) |
---|
4044 | "USAGE: random_hypersurf(I, V); I, V ideals |
---|
4045 | RETURN: ideal |
---|
4046 | PURPOSE: computes the sum of I with the ideal generated by a random |
---|
4047 | linear combination of the generators of V such that the dimension decreases |
---|
4048 | EXAMPLE: example random_hypersurf; shows an example |
---|
4049 | NOTE: if the ideal I=1 (the whole ring), then I is returned |
---|
4050 | " |
---|
4051 | { |
---|
4052 | ideal H; |
---|
4053 | ideal J; |
---|
4054 | // if(isSubModule(ideal(1), I)) // if I equals 1 (the whole ring); |
---|
4055 | if( is_zero(I) ) |
---|
4056 | { |
---|
4057 | return(I); |
---|
4058 | } |
---|
4059 | // otherwise |
---|
4060 | int ok=0; |
---|
4061 | int ntries; // number of tries |
---|
4062 | while( !ok ) // give two tries for every b in randomid(V, 1, b) |
---|
4063 | { |
---|
4064 | H=randomid(V, 1, ntries div 2 +1); |
---|
4065 | ntries++; // increase by 1 |
---|
4066 | if( isSubModule( quotient(I, ideal(H) ), I) ) |
---|
4067 | { |
---|
4068 | J=I + H; |
---|
4069 | ok=1; |
---|
4070 | } |
---|
4071 | } |
---|
4072 | return(J); |
---|
4073 | } |
---|
4074 | example |
---|
4075 | { |
---|
4076 | "EXAMPLE:";echo =2; |
---|
4077 | // Consider an ideal in k[x, y, z, s, t] and find its intersection with a general hyperplane |
---|
4078 | // given by as+bt=0 |
---|
4079 | ring r = 0, (x, y, z, s, t), dp; |
---|
4080 | ideal I=x2, yz, s+t; |
---|
4081 | I; |
---|
4082 | ideal V= s, t; |
---|
4083 | V; |
---|
4084 | // the ideal of the intersection with the random general hyperplane |
---|
4085 | random_hypersurf(I, V); |
---|
4086 | } |
---|
4087 | //------------------------------------------------------------------------------------------- |
---|
4088 | |
---|
4089 | static proc prds(int n, def l) |
---|
4090 | "USAGE: prds(n, l); n an integer, l list of polynomials or ideal |
---|
4091 | RETURN: list of polynomials |
---|
4092 | PURPOSE: computes all possible products of length n (without repetitions) of the entries of l |
---|
4093 | EXAMPLE: example prds; shows an example |
---|
4094 | NOTE: |
---|
4095 | " |
---|
4096 | { |
---|
4097 | int sz; |
---|
4098 | if(typeof(l)=="ideal") |
---|
4099 | { |
---|
4100 | sz=ncols(l); |
---|
4101 | } |
---|
4102 | else |
---|
4103 | { |
---|
4104 | sz=size(l); |
---|
4105 | } |
---|
4106 | if( (n>sz)||(sz==0)||(n<0) ) |
---|
4107 | { |
---|
4108 | return( list() ); |
---|
4109 | } |
---|
4110 | // otherwise |
---|
4111 | if(n==0) |
---|
4112 | { |
---|
4113 | return( list(int(1)) ); |
---|
4114 | } |
---|
4115 | if(sz==n) |
---|
4116 | { |
---|
4117 | return(product(l)); |
---|
4118 | } |
---|
4119 | list L, LL, ll; |
---|
4120 | ll=l[2..sz]; |
---|
4121 | poly f=l[1]; |
---|
4122 | L=prds(n, ll ); |
---|
4123 | LL=prds(n-1,ll); |
---|
4124 | int i; |
---|
4125 | sz=size(LL); |
---|
4126 | for(i=1;i<=sz;i++) |
---|
4127 | { |
---|
4128 | LL[i]=f*LL[i]; |
---|
4129 | } |
---|
4130 | return(L+LL); |
---|
4131 | } |
---|
4132 | example |
---|
4133 | { |
---|
4134 | "EXAMPLE:";echo =2; |
---|
4135 | ring r = 0, (x, y, z, w), dp; |
---|
4136 | // compute all possible 2-products between the variables x,y,z,w |
---|
4137 | list l=x,y,z,w; |
---|
4138 | prds(2, l); |
---|
4139 | // compute all possible 3-products between the variables x,y,z,w |
---|
4140 | ideal I=x,y,z,w; |
---|
4141 | prds(3, l); |
---|
4142 | } |
---|
4143 | //------------------------------------------------------------------------------------------- |
---|