source: git/Singular/LIB/chern.lib @ 27a5b3

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