Let R = ring F = ring ff, and Rbar = R/(ideal ff). The complex F should admit a system of higher homotopies for the entries of ff, returned by the call makeHomotopies(ff,F).
When the entries of ff form a regular sequence on ring F, the Shamash complex is a resolution.
i1 : x = symbol x o1 = x o1 : Symbol |
i2 : S = ZZ/101[x_0..x_4] o2 = S o2 : PolynomialRing |
i3 : F = res coker vars S 1 5 10 10 5 1 o3 = S <-- S <-- S <-- S <-- S <-- S <-- 0 0 1 2 3 4 5 6 o3 : ChainComplex |
i4 : ff = matrix{{x_0^2,x_1^3}} o4 = | x_0^2 x_1^3 | 1 2 o4 : Matrix S <--- S |
i5 : R = S/(ideal ff) o5 = R o5 : QuotientRing |
i6 : len = 10 o6 = 10 |
i7 : time G = EisenbudShamash(ff,F,len) -- used 7.24191 seconds / S \1 / S \5 / S \12 / S \20 / S \28 / S \36 / S \44 / S \52 / S \60 / S \68 / S \76 o7 = |--------| <-- |--------| <-- |--------| <-- |--------| <-- |--------| <-- |--------| <-- |--------| <-- |--------| <-- |--------| <-- |--------| <-- |--------| | 2 3 | | 2 3 | | 2 3 | | 2 3 | | 2 3 | | 2 3 | | 2 3 | | 2 3 | | 2 3 | | 2 3 | | 2 3 | |(x , x )| |(x , x )| |(x , x )| |(x , x )| |(x , x )| |(x , x )| |(x , x )| |(x , x )| |(x , x )| |(x , x )| |(x , x )| \ 0 1 / \ 0 1 / \ 0 1 / \ 0 1 / \ 0 1 / \ 0 1 / \ 0 1 / \ 0 1 / \ 0 1 / \ 0 1 / \ 0 1 / 0 1 2 3 4 5 6 7 8 9 10 o7 : ChainComplex |
i8 : apply(length G -1, i->prune HH_(i+1) G) o8 = {0, 0, 0, 0, 0, 0, 0, 0, 0} o8 : List |
The complex G has terms that are abstractly G_i = F_i ++ D_1**F_{i-2} ++ D_2**F_{i-4}... where D_i is the i-th divided power of the free module source ff. In fact the term D_i**F_j is the direct sum of copies of F_j, indexed by the basis t^{e} of the divided power, each twisted by the degree of t^{e}. This basis is in 1-1 correspondence with the partitions of c = numcols ff, with i parts, produced by the function expo(c,i), as can be seen in the following:
i9 : betti F 0 1 2 3 4 5 o9 = total: 1 5 10 10 5 1 0: 1 5 10 10 5 1 o9 : BettiTally |
i10 : G5 = (G_5).cache.components / S \1 / S \20 / S \15 o10 = {|--------| , |--------| , |--------| } | 2 3 | | 2 3 | | 2 3 | |(x , x )| |(x , x )| |(x , x )| \ 0 1 / \ 0 1 / \ 0 1 / o10 : List |
Thus, c = 2, so D_i = R^{i+1}, and G5 is the direct sum F_5 ++ R^2**F_3 ++ R^3**F_1. Moreover, D_1 has two exponents,
i11 : expo(numcols ff, 1) o11 = {{1, 0}, {0, 1}} o11 : List |
So G5_1 will have two components, both isomorphic to R**F_3 = R^{10}:
i12 : G51 = (G5_1).cache.components / S \10 / S \10 o12 = {|--------| , |--------| } | 2 3 | | 2 3 | |(x , x )| |(x , x )| \ 0 1 / \ 0 1 / o12 : List |
All the decompositions seem to impose a certain overhead, and in the case where it applies, namely c=1, the routine Shamash is faster:
i13 : S = ZZ/101[a..f] o13 = S o13 : PolynomialRing |
i14 : R = S/ideal"a3,b3" o14 = R o14 : QuotientRing |
i15 : M = coker vars R o15 = cokernel | a b c d e f | 1 o15 : R-module, quotient of R |
i16 : F = res M 1 6 17 32 48 64 80 96 o16 = R <-- R <-- R <-- R <-- R <-- R <-- R <-- R 0 1 2 3 4 5 6 7 o16 : ChainComplex |
i17 : betti F 0 1 2 3 4 5 6 7 o17 = total: 1 6 17 32 48 64 80 96 0: 1 6 15 20 15 6 1 . 1: . . 2 12 30 40 30 12 2: . . . . 3 18 45 60 3: . . . . . . 4 24 o17 : BettiTally |
i18 : ff = matrix"c3" o18 = | c3 | 1 1 o18 : Matrix R <--- R |
i19 : R1 = R/ideal ff o19 = R1 o19 : QuotientRing |
i20 : FF = time Shamash(R1,F,4) -- used 0.155311 seconds 1 6 18 38 66 o20 = R1 <-- R1 <-- R1 <-- R1 <-- R1 0 1 2 3 4 o20 : ChainComplex |
i21 : GG = time EisenbudShamash(ff,F,4) -- used 1.12845 seconds / R\1 / R\6 / R\18 / R\38 / R\66 o21 = |--| <-- |--| <-- |--| <-- |--| <-- |--| | 3| | 3| | 3| | 3| | 3| \c / \c / \c / \c / \c / 0 1 2 3 4 o21 : ChainComplex |
The function also deals correctly with complexes F where min F is not 0:
i22 : GG = time EisenbudShamash(R1,F[2],4) -- used 1.135 seconds 1 6 18 38 66 o22 = R1 <-- R1 <-- R1 <-- R1 <-- R1 -2 -1 0 1 2 o22 : ChainComplex |
The object EisenbudShamash is a method function.