--********************************************************************* --* --*This file contains the code implementing the algorithms described --*in my paper "Computing characteristic classes of projective schemes". --*This code can be freely used, provided use is properly acknowledged. --*Please send comments to aluffi@math.fsu.edu --* --*Paolo Aluffi, April 2002 --* --********************************************************************* --********************************************************************* --* --*Minor changes implemented in January 2003: --*extracted a separate routine blup for blow-ups, and replaced a dimension --*check in presegre with a direct verification that an element is not --*a zero-divisor. --* --********************************************************************* --********************************************************************* --* --*Adapted to work with 0.9.95, June 2007 --* --********************************************************************* --********************************************************************* --* --*Adapted to work with 1.1, March 2008 --* --*(avoiding an unnecessary transfer of a local variable, which was --*confusing 1.1) --* --********************************************************************* --********************************************************************* --* --*Rewritten `presegre' using the `multidegree' function, April 2009 --* --*(This speeds up computations considerably) --* --********************************************************************* --********************************************************************* --* --*Fixed an error in presegre, December 2011 --* --********************************************************************* --getrings extracts the ring of the ideal and manufactures --local copies of the coefficient field (kk), the ring (S, assumed --to be a polynomial ring), the dimension, and the ideal itself. getrings := Icenter -> ( S:=ring Icenter; if not (isPolynomialRing S) then <<"Sorry, expecting an ideal defined over a polynomial ring"< ( cr:=0;en:=0; tem:=ideal 0_S; center:=trim substitute(Icenter,S); m:=numgens center; if m!=0 then ( ma:=first max degrees center; ls:=first entries gens center; for i from 0 to m-1 do (en=ls_i,cr=ma-first degree en; for j from 0 to n do tem=tem+ideal(en*((entries vars S)_0_j)^cr)); tem=trim tem); sequence(ma,tem)); --blup computes an ideal for the Rees algebra of the given ideal, --for use in presegre. blup = (I,t) -> ( m := numgens I; S := ring I; kk := coefficientRing S; R := kk[gens S, t_0 .. t_(m-1)]; II := substitute(I,R); J := ideal apply(0..(m-2), i -> apply((i+1)..(m-1), j -> (II_i*t_j-II_j*t_i))); if m==1 then J=ideal 0_R; saturate(J,II_0) ); --presegre applies the previous routines, then computes the shadow --of the blow-up along the given ideal. This is encoded in the sequence --of degrees of the images of suitable loci. The output includes --the max degree of a generator of the ideal. presegre = (kk,S,n,Icenter) -> ( init:=fixideal(S,n,Icenter); center:=init_1; m:=numgens center; T:=kk[v_1 .. v_m]; U:=kk[v_1 .. v_m , gens S ,MonomialOrder => Eliminate m]; irrel:=ideal(v_1 .. v_m); blowup:=substitute(blup(center,v),U); UU:=newRing(U,Degrees => {m:{1,0},(n+1):{0,1}}); Ublowup:=substitute(blowup,UU); if Ublowup==ideal(1_(ring Ublowup)) then ou:=(,splice{n+1:0}) else (li:=(entries transpose (coefficients multidegree Ublowup)_1)_0; for i from 1 to n do li=append(li,0); ou=sequence(init_0,toList apply(0..n, i -> substitute(li_i,ZZ)))); ou ); --segre uses the sequence obtained in presegre, and computes the --push-forward of the Segre class and of the Fulton class. These are --elements of the globally defined ring intringPn, generated by the --hyperplane class H. The global variables segreclass and fultonclass --carry the two classes, available for further manipulations. --segreclass is displayed. segre = Icenter -> ( t:=symbol t; init:=getrings(Icenter); kk:=init_0; S:=init_1; n:=init_2; center:=init_3; init=presegre(kk,S,n,center); ma:=init_0;tem:=init_1; H=symbol H; intringPn=ZZ[H]/(H^(n+1)); poly:=sum(0..n,s->tem#s*H^s*(1+ma*H)^(n-s)); segreclass=1 - poly * sum(0..n,i->binomial(n+i,i)*(-ma*H)^i); <<"Segre class : "< ( init:=getrings(Icenter); kk:=init_0; S:=init_1; n:=init_2; center:=init_3; t:=symbol t; init=presegre(kk,S,n,center); ma:=init_0;tem:=init_1; H=symbol H; intringPn=ZZ[H]/(H^(n+1)); poly:=sum(0..n,s->tem#s*H^s*(1+ma*H)^(n-s)); segreclass=1 - poly * sum(0..n,i->binomial(n+i,i)*(-ma*H)^i); fultonclass=(1+H)^(n+1)*segreclass; <<"Fulton class : "< ( jac:=ideal jacobian ideal hyper; t:= symbol t; tem:=(presegre(kk,S,n,jac))_1; (1+H)^(n+1) - sum(0..n,d->tem#d*(-H)^d*(1+H)^(n-d)) ); --CSM assembles many csm computations to get the Chern-Schwartz-MacPherson --class of an arbitrary ideal. The global variable csmclass carries the --answer. CSM = idea -> ( init:=getrings(idea); kk:=init_0; S:=init_1; n:=init_2; schem:=init_3; H=symbol H; intringPn=ZZ[H]/(H^(n+1)); r:=numgens schem; sset:=new MutableList from {0..r}; psum:=new MutableList from {0..r}; gschem:=(entries gens schem)_0; for s from 1 to r do (--<<";"<csm(kk,S,n,intringPn,product(eq))); psum#s=sum(sset#s)); csmclass=sum(1..r,s->-(-1)^s*psum#s); <<"Chern-Schwartz-MacPherson class : "< ( init:=getrings(Icenter); kk:=init_0; S:=init_1; n:=init_2; center:=init_3; t:=symbol t; init=presegre(kk,S,n,center); ma:=init_0;tem:=init_1; H=symbol H; intringPn=ZZ[H]/(H^(n+1)); poly:=sum(0..n,s->tem#s*H^s*(1+ma*H)^(n-s)); segreclass=1 - poly * sum(0..n,i->binomial(n+i,i)*(-ma*H)^i); fultonclass=(1+H)^(n+1)*segreclass; <<"Fulton class : "<csm(kk,S,n,intringPn,product(eq))); psum#s=sum(sset#s)); csmclass=sum(1..r,s->-(-1)^s*psum#s); <<"Chern-Schwartz-MacPherson class : "< ( enleqn:=homogenize(eqn,(entries vars S)_0_0)*(entries vars S)_0_0; cuteqn:=substitute(enleqn,{(entries vars S)_0_0=>0}); tem:=csm(kk,S,n,W,enleqn)-csm(kk,S,n,W,cuteqn); tem_(H^n)+1 ); --euleraffine computes the Euler characteristic of an affine scheme, --by performing many euleraffinehyp. euleraffine = idea -> ( S:=ring idea; if not (isPolynomialRing S) then <<"Sorry, expecting an ideal defined over a polynomial ring"<euleraffinehyp(kk,S,n,intringPn,product(eq))); psum#s=sum(sset#s)); sum(1..r,s->-(-1)^s*psum#s) ); --* --*********************************************************************