-- -*- coding: utf-8 -*-
newPackage ("TangentCone",
       	Version => "1.0", 
    	Date => "June 27, 2006",
    	Authors => {
	     {Name => "Craig Huneke", Email => "huneke@math.ku.edu"},
	     {Name => "David Eisenbud", Email => "de@msri.org"}
	     },
    	Headline => "tangent cones",
	Keywords => {"Commutative Algebra"},
    	DebuggingMode => false
    	)

export { "tangentCone" }

tangentCone = method(TypicalValue => Ideal, 
     Options => { 
	  Strategy => Local 				    -- or Global
	  } )

tangentCone Ideal := (opts) -> (i) -> (
     R := ring i;
     n := numgens R;
     k := coefficientRing R;
     if opts.Strategy === Local then (
	  M := monoid [Variables=>n,MonomialOrder=>Weights=>splice{n:-1},Global=>false];
	  SS := k M;
	  toSS := map(SS, R, vars SS);
	  fromSS := map(R, SS, vars R);
	  ideal mingens fromSS ideal leadTerm(1, gens gb toSS i))
     else if opts.Strategy === Global then (
	  M = monoid [Variables=>n+1,MonomialOrder=>{1,n}];
	  SS = k M;
	  toSS = map(SS, R, (vars SS)_{1..n});
	  fromSS = map(R, SS, 1_R|vars R);
	  ideal mingens fromSS ideal leadTerm(1, gens gb homogenize(toSS i, SS_0)))
     else error "expected Strategy option to be Local or Global")

beginDocumentation()

document {
     Key => "TangentCone",
     Headline => "tangent cones",
     "This package provides a single function that computes the tangent cone at a point."
     }

document {
     Key => {(tangentCone, Ideal), tangentCone, [tangentCone, Strategy]},
     Usage => "tangentCone I",
     Inputs => { "I",
	  Strategy => { TT "Local", " or ", TT "Global" }
	  },
     Outputs => {{ "the ideal of the tangent cone of the subvariety defined by ", TT "I", " at the point defined by the variables of the ring, with a minimal 
	       set of generators" }},
     PARA {
	  "The tangent cone is the ideal that defines ", TT "gr(R/I)", ", where ", TT "R", " is the ring containing ", TT "I", ", and ", TT "gr", " is
	  the associated graded ring formed with respect to maximal ideal generated by the variables."
	  },
     PARA {
	  "The algorithm follows the method of Proposition 15.28 in the book ", EM "Commutative Algebra
	  with a View Toward Algebraic Geometry", " by David Eisenbud (Springer, Graduate Texts in Mathematics, volume 150)."
	  },
     EXAMPLE lines ///
	  R = QQ[x,y,z]
	  tangentCone ideal "xz-y3,yz-x4,z2-x3y2"
	  tangentCone ideal "z2-x5,zx-y3"
	  tangentCone ideal "x3+x2z2,x2y+xz3+z5"
	  betti oo
     ///
     }

TEST ///
	  R = QQ[x,y,z]
	  tangentCone ideal "xz-y3,yz-x4,z2-x3y2"
     	  assert( oo === ideal (z^2,y*z,x*z,y^4))
	  tangentCone ideal "z2-x5,zx-y3"
     	  assert( oo === ideal (z^2,x*z,y^3*z,y^6))
	  tangentCone ideal "x3+x2z2,x2y+xz3+z5"
     	  assert( oo === ideal (x^2*y,x^3,x^2*z^3,2*x*y*z^5-x*z^6,x*z^7,y*z^9))
///

-- Local Variables:
-- compile-command: "make -C $M2BUILDDIR/Macaulay2/packages PACKAGES=TangentCone pre-install"
-- End:
