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 3.84077 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.0698489 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 0.829837 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 0.811033 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.