There are several ways to define a DGAlgebra. One can start by defining one 'from scratch'. One does this by specifying the ring over which the DGAlgebra is defined and the degrees of the generators. The name of the generators of the DGAlgebra by default is $T_i$, but one may change this by specifying the optional (string) argument 'Variable'.
i1 : R = ZZ/101[a,b,c,d]/ideal{a^3,b^3,c^3,d^3} o1 = R o1 : QuotientRing |
i2 : A = freeDGAlgebra(R,{{1,1},{1,1},{1,1},{1,1}}) o2 = {Ring => R } Underlying algebra => R[T ..T ] 1 4 Differential => null o2 : DGAlgebra |
The command freeDGAlgebra only defines the underlying algebra of A, and not the differential. To set the differential of A, one uses the command setDiff.
i3 : setDiff(A, gens R) o3 = {Ring => R } Underlying algebra => R[T ..T ] 1 4 Differential => {a, b, c, d} o3 : DGAlgebra |
Note that the above is the (graded) Koszul complex on a set of generators of R. A much easier way to define this is to use the function koszulComplexDGA.
i4 : B = koszulComplexDGA(R, Variable=>"S") o4 = {Ring => R } Underlying algebra => R[S ..S ] 1 4 Differential => {a, b, c, d} o4 : DGAlgebra |
One can compute the homology algebra of a DGAlgebra using the homology (or HH) command.
i5 : HB = HH B Finding easy relations : -- used 0.0320486 seconds o5 = HB o5 : PolynomialRing, 4 skew commutative variables |
i6 : describe HB ZZ o6 = ---[X ..X , Degrees => {4:{1}}, Heft => {1, 0}, MonomialOrder => {MonomialSize => 32}, DegreeRank => 2, SkewCommutative => {0, 1, 2, 3}] 101 1 4 {3} {GRevLex => {4:1} } {Position => Up } |
i7 : degrees HB o7 = {{1, 3}, {1, 3}, {1, 3}, {1, 3}} o7 : List |
Note that since R is a complete intersection, its Koszul homology algebra is an exterior algebra, which is a free graded commutative algebra. Note that the internal degree is preserved in the computation of the homology algebra of B.
One can also adjoin variables to kill cycles in homology. The command killCycles looks for the first positive degree nonzero homology (say i), and adjoins variables in homological degree i+1 that differentiate to a minimal generating set of this homology, so that the resulting DGAlgebra now only has homology in degree greater than i (note of course this could introduce new homology in higher degrees). The command adjoinVariables allows finer control over this procedure. See adjoinVariables for an example.
i8 : HB.cache.cycles 2 2 2 2 o8 = {a S , b S , c S , d S } 1 2 3 4 o8 : List |
i9 : C = adjoinVariables(B,{first HB.cache.cycles}) o9 = {Ring => R } Underlying algebra => R[T ..T ] 1 5 2 Differential => {a, b, c, d, a T } 1 o9 : DGAlgebra |
i10 : homologyAlgebra(C,GenDegreeLimit=>4,RelDegreeLimit=>4) Finding easy relations : -- used 0.0310609 seconds ZZ o10 = ---[X ..X ] 101 1 3 o10 : PolynomialRing, 3 skew commutative variables |
i11 : C = killCycles(B) o11 = {Ring => R } Underlying algebra => R[T ..T ] 1 8 2 2 2 2 Differential => {a, b, c, d, a T , b T , c T , d T } 1 2 3 4 o11 : DGAlgebra |
i12 : homologyAlgebra(C,GenDegreeLimit=>4,RelDegreeLimit=>4) ZZ o12 = --- 101 o12 : QuotientRing |
Again, note that since R is a complete intersection, once we adjoin the variables in homological degree two to kill the cycles in degree one, we obtain a minimal DG Algebra resolution of the residue field of R. Also, note that since C has generators in even degree, one must specify the optional arguments GenDegreeLimit and RelDegreeLimit to specify the max degree of the computation. To do this, one uses the homologyAlgebra command rather than the HH command.
This computation could have also been done with the command acyclicClosure. The command acyclicClosure performs the command killCycles sequentially to ensure that the result has homology in higher and higher degrees, thereby computing (part of) a minimal DG Algebra resolution of the residue field. acyclicClosure has an optional argument EndDegree that allows the user to specify the maximum homological degree with which to perform this adjunction of variables. The default value of this is 3, since if there are any variables of degree 3 that need to be added, then each subsequent homological degree will require some variables to be adjoined (Halperin's rigidity theorem).
i13 : D = acyclicClosure R o13 = {Ring => R } Underlying algebra => R[T ..T ] 1 8 2 2 2 2 Differential => {a, b, c, d, a T , b T , c T , d T } 1 2 3 4 o13 : DGAlgebra |
i14 : R' = ZZ/101[x,y,z]/ideal{x^2,y^2,z^2,x*y*z} o14 = R' o14 : QuotientRing |
i15 : E = acyclicClosure(R',EndDegree=>5) o15 = {Ring => R' } Underlying algebra => R'[T ..T ] 1 56 2 2 2 2 2 2 Differential => {x, y, z, x*T , y*T , z*T , y*z*T , y*z*T , -y*z*T T , -y*z*T T , -y*z*T T , -y*z*T T , y*z*T T , y*z*T T , y*z*T T , -y*z*T T T , -y*z*T , -y*z*T T , -y*z*T T , y*z*T T T , y*z*T T T , y*z*T T T , y*z*T T T , -y*z*T T T , -y*z*T T T , -y*z*T T T , -y*z*T T , y*z*T T T , y*z*T T T , y*z*T T , y*z*T T T , y*z*T T , -y*z*T T , -y*z*T T , -y*z*T T , -y*z*T T T , -y*z*T T T , -y*z*T T T , -y*z*T T T , -y*z*T T T , -y*z*T T T , y*z*T T T T , y*z*T T T T , -y*z*T T T T , y*z*T T , -y*z*T T T , -y*z*T T T , -y*z*T T T , - y*z*T T T T - y*z*T T T , -y*z*T T T , y*z*T T T , y*z*T T T , -y*z*T T T , -y*z*T T T , -y*z*T T T , y*z*T T T T } 1 2 3 1 4 1 3 1 2 1 5 1 6 3 4 2 4 1 4 1 2 3 4 4 5 4 6 1 3 5 1 2 5 1 3 6 1 2 6 2 3 4 1 3 4 1 2 4 4 7 1 3 7 1 2 7 1 5 1 5 6 1 6 3 4 2 4 1 4 3 4 5 2 4 5 1 4 5 3 4 6 2 4 6 1 4 6 1 2 3 5 1 2 3 6 1 2 3 4 4 8 1 3 8 1 3 9 1 2 8 1 2 3 7 1 2 9 1 2 10 1 5 7 1 6 7 3 4 7 2 4 7 1 4 7 1 2 3 7 o15 : DGAlgebra |
i16 : tally degrees E.natural o16 = Tally{{1, 1} => 3 } {2, 2} => 3 {2, 3} => 1 {3, 4} => 3 {4, 5} => 6 {5, 6} => 10 {5, 7} => 3 {6, 7} => 15 {6, 8} => 12 o16 : Tally |
As you can see, since R' is not a complete intersection, the acyclic closure of E requires infinitely many variables; we display the degrees of the first 6 here. The tally that is displayed gives the deviations of the ring R. One can compute the deviations directly from any minimal free resolution of the residue field of R', so that using the one provided by res coker vars R is faster. To do this, use the command deviations.
i17 : deviations(R,DegreeLimit=>6) o17 = HashTable{(1, {1}) => 4} (2, {3}) => 4 o17 : HashTable |
i18 : deviations(R',DegreeLimit=>6) o18 = HashTable{(1, {1}) => 3 } (2, {2}) => 3 (2, {3}) => 1 (3, {4}) => 3 (4, {5}) => 6 (5, {6}) => 10 (5, {7}) => 3 (6, {7}) => 15 (6, {8}) => 12 o18 : HashTable |
As a brief warning, the command poincareN which is used in deviations uses the symbols S and T internally, and may cause problems accessing such rings with the user interface.