buildModule=method() buildModule(Module, RingElement):=(N,g)->( ---Input : A module over a graded complete intersection and a --- polynomial from another polynomial ring that will --- help define the support set of the module that we --- wish to construct ---Output: A Module defined over the graded complete intersection --- whose support set ideal may contain the input polynomial ---Notes: Eisoplist are the decompositions of the n-2 products. --- fnMatrix1 is the even constructed matrix. --- fnMatrix2 is the odd constructed matrix. --- theMatrix is the mapping that we need to take the cokernel of. --- This method is used below by buildModule(Module, List) theGuy := coker vars ring N; gDegree := degree g; if (isHomogeneous(g) != true) then ( << "Must input a homogenous polynomial." << endl; ) else ( if (gDegree != -infinity) then ( if (gDegree#0 == 0) then ( << "Must input a polynomial that is zero or positive degree." << endl; ) else ( --- get a List for the generators of the ring of g varsList := gens ring g; --- get a List for the terms of g termList := terms g; --- take the resolution out to n n := (2 * gDegree#0) + 1; Nres := res (N, LengthLimit => n); --- construct the Eisenbud Operators Eisoplist = getEisopList(Nres,n); i := 0; j := 0; k := 0; fnMatrix1 := matrix{{0}}; tempMatrix1 := matrix{{0}}; fnMatrix2 := matrix{{0}}; tempMatrix2 := matrix{{0}}; tempQuo := 0; tempRem := 0; tempMono := 0; --- at this point we have our list of Eisenbud operators --- and may start to build the module we are looking for. --- the below loop calculates the two matrices that represent --- the degree 2d+1 and 2d support set maps. --- from the above Eisoplist, Eisoplist#i#0 represents the first --- generator of the ideal, Eisoplist#i#1 the second and so on. --- we compose maps in increasing fashion so that for example --- x^2 is Eisoplist#0#0*Eisoplist#2#0 for the first map and --- Eisoplist#1#0*Eisoplist#3#0 for the second. Just increase the --- first index by 2 for each factor in the term. --- This loop iterates over the terms in the input polynomial --- and produces the maps described above. Since the --- input polynomial is homogeneous, we may add them at the --- end and get the map that represents the polynomial. while (i < #termList) do ( j = 0; k = 0; tempQuo = termList#i; tempRem = 0; --- this loop iterates over the variables to get the correct --- matrices to multiply together to represent the --- input polynomial while (j < #varsList) do ( tempMono = tempQuo; tempQuo = tempMono // varsList#j; tempRem = tempMono % varsList#j; while((tempMono % varsList#j) == 0) do ( if (k == 0) then ( tempMatrix1 = Eisoplist#k#j; tempMatrix2 = Eisoplist#(k+1)#j; k = k + 2; ) else ( tempMatrix1 = tempMatrix1 * Eisoplist#k#j; tempMatrix2 = tempMatrix2 * Eisoplist#(k+1)#j; k = k + 2; ); tempMono = tempQuo; tempQuo = tempMono // varsList#j; tempRem = tempMono % varsList#j; ); tempQuo = tempRem; j = j + 1; ); --- take the coefficient that is left over and multiply it --- by the tempMatrix scalar := lift(tempQuo, coefficientRing(ring tempQuo)); scalar = scalar_(ring tempMatrix1); tempMatrix1 = scalar * tempMatrix1; tempMatrix2 = scalar * tempMatrix2; if (i == 0) then ( fnMatrix1 = tempMatrix1; fnMatrix2 = tempMatrix2; ) else ( fnMatrix1 = fnMatrix1 + tempMatrix1; fnMatrix2 = fnMatrix2 + tempMatrix2; ); i = i + 1; ); --- at this point, fnMatrix1 represents the degree 2d --- support set map and fnMatrix2 the degree 2d+1 map. --- now in order to get the matrix we are actually after, we --- must get the syzygy matrices from the computed matrices --- and compose the maps sigma1, Nres.dd_n and the --- splitting map of sigma0. sigma1 := syz fnMatrix2; sigma0 := syz fnMatrix1; ident := id_(target sigma0); split := ident // sigma0; theMatrix := split*Nres.dd_n*sigma1; --- take the cokernel and return! theGuy = cokernel theMatrix ) ) else ( theGuy ) ) ) buildModule(Module, List):=(N,h)->( ---Input : A module over a graded complete intersection and a --- list of polynomials from another polynomial ring that --- will help define the support set of the module that we --- wish to construct ---Output: A Module defined over the graded complete intersection --- whose support set ideal may contain the input polynomials ---Method: Iterate through the list of ringElements and --- call buildModule(N, h_0) for the first --- one. Take the output of that and call buildModule again --- with the next polynomial in the list, until you have done --- all of the polynomials. i := 0; loopMod = buildModule(N, h_i); i = i + 1; while (i < #h) do ( loopMod = buildModule(loopMod, h_i); i = i + 1; ); loopMod ) getEisopList=method() getEisopList(ChainComplex, ZZ):=(Nres,n)->( ---Input : A free resolution of a module over a graded complete --- intersection and an integer indicating how far the --- Eisenbud operators should be constructed. ---Output: A List of Lists of Matrices, which contain the Eisenbud --- operators t_(ij). --- get the module that the ChainComplex is a resolution of N := cokernel Nres.dd_1; --- get the ring that the module is over B := ring N; --- get the ring that R is a quotient of A := ambient B; --- n is the highest degree for which the Eisenbud operators --- are constructed firstMatrList := {}; i := 1; --- the below loop builds a list of matrices which have entries --- in A and are the liftings of differentials of the resolution while (i <= n) do ( firstMatrList = firstMatrList | {lift(Nres.dd_i, A)}; i = i + 1; ); secondMatrList := {}; i = 0; --- the below loop takes the entries of firstMatrList and composes --- the maps pairwise. Using the n above, this creates a list of --- length n-1. while (i < n-1) do ( secondMatrList = secondMatrList | {firstMatrList#i * firstMatrList#(i+1)}; i = i + 1; ); --- create a groebner basis for the ideal that we are modding out --- in the ring of our module N I := ideal B; --- must use ChangeMatrix => true for division to be used Igb := gb(I, ChangeMatrix => true); i = 0; Eisoplist := {}; --- the below loop builds a list of lists of matrices. Each --- entry in Eisoplist is a list of matrices whose length is --- as long as the regular sequence we are modding out by. --- Since each product matrix is congruent to zero mod the f's, --- we are able to represent the entries in terms of the generators --- of the ideal. We decompose each matrix to the form --- (matrix_1)f1 * ... * (matrix_c)fc, where c is the length --- of the regular sequence we are modding out by. Thus, when you --- see Eisoplist#i#j below, it represents t_(i+2,j+1), the f_jth component --- of the ith matrix in the above secondMatrList while (i < n-1) do ( j := 0; --- had to be a Mutable List to access and change elements tempMatrList := new MutableList from {}; while (j < numgens target secondMatrList#i) do ( tempRow := secondMatrList#i^{j}; --- the below command inputs a row of a matrix and --- outputs a matrix whose columns are the components --- of the elements of the input matrix in the original --- basis of I. tempCoef := tempRow // Igb; --- if we are on the first row, we need to insert the --- matrix in the list, otherwise, just append to the --- one that we're on. l := 0; --- tensor t_(ij) with B ( = ring N) tempCoef = substitute(tempCoef, ring N); while (l < numgens I) do ( if (j == 0) then ( tempMatrList = append(tempMatrList, tempCoef^{l}); ) else ( tempMatrList#l = tempMatrList#l || tempCoef^{l}; ); l = l + 1; ); j = j + 1; ); i = i + 1; Eisoplist = Eisoplist | {toList(tempMatrList)}; ); Eisoplist )