Description
A simplicial R-module is a presheaf on the so-called Simplex Category, with values in the category of R-modules. Concretely, such objects can be viewed as nonnegatively graded R-modules equipped with certain face and degeneracy operators satisfying the simplicial identities. As an example, every R-module M can be converted into a simplicial R-module whose degree n piece is equal to M for all n, and with face/degeneracy operators simply given by the identity.
i1 : S = simplicialModule(ZZ^2,3,Degeneracy => true) --the integer 3 specifies a top degree, the option Degeneracy specifies whether or not to compute degeneracy maps
2 2 2 2
o1 = ZZ <-- ZZ <-- ZZ <-- ZZ <-- ...
0 1 2 3
o1 : SimplicialModule
|
The output string for a simplicial module is meant to indicate that this object is infinite in general, and the user can only compute a finite snapshot of the object. The face/degeneracy maps can be accessed using the keys dd and ss, respectively. In order to verify that the resulting face/degeneracy maps satisfy the simplicial identities, one can use the isSimplicialModule command.
i2 : S.dd
2 2
o2 = (0, 0) : ZZ <----------- ZZ : (1, 0)
| 1 0 |
| 0 1 |
2 2
(0, 1) : ZZ <----------- ZZ : (1, 1)
| 1 0 |
| 0 1 |
2 2
(1, 0) : ZZ <----------- ZZ : (2, 0)
| 1 0 |
| 0 1 |
2 2
(1, 1) : ZZ <----------- ZZ : (2, 1)
| 1 0 |
| 0 1 |
2 2
(1, 2) : ZZ <----------- ZZ : (2, 2)
| 1 0 |
| 0 1 |
2 2
(2, 0) : ZZ <----------- ZZ : (3, 0)
| 1 0 |
| 0 1 |
2 2
(2, 1) : ZZ <----------- ZZ : (3, 1)
| 1 0 |
| 0 1 |
2 2
(2, 2) : ZZ <----------- ZZ : (3, 2)
| 1 0 |
| 0 1 |
2 2
(2, 3) : ZZ <----------- ZZ : (3, 3)
| 1 0 |
| 0 1 |
o2 : SimplicialModuleMap
|
i3 : S.ss
2 2
o3 = (1, 0) : ZZ <----------- ZZ : (0, 0)
| 1 0 |
| 0 1 |
2 2
(2, 0) : ZZ <----------- ZZ : (1, 0)
| 1 0 |
| 0 1 |
2 2
(2, 1) : ZZ <----------- ZZ : (1, 1)
| 1 0 |
| 0 1 |
2 2
(3, 0) : ZZ <----------- ZZ : (2, 0)
| 1 0 |
| 0 1 |
2 2
(3, 1) : ZZ <----------- ZZ : (2, 1)
| 1 0 |
| 0 1 |
2 2
(3, 2) : ZZ <----------- ZZ : (2, 2)
| 1 0 |
| 0 1 |
o3 : SimplicialModuleMap
|
i4 : assert isSimplicialModule S
|
In general, simplicial objects are infinite objects. Because of this, the user can specify a top degree for the resulting simplicial object. If no top degree is specified, then the default top degree is determined by the input object.
The Dold-Kan Correspondence
The category of simplicial R-modules is equivalent to the category of nonnegatively graded chain complexes via an equivalence known as the Dold-Kan correspondence.
This means that there is a functor that converts a chain complex into a simplicial object, known as the Dold-Kan functor. In practice, the image of the Dold-Kan functor is highly nontrivial to compute by hand. However, this package uses an algorithm of Kock-Sakuranath to compute Dold-Kan images quite efficiently by using the simplicialModule command:
i5 : R = ZZ/101[x_1..x_3];
|
i6 : K = koszulComplex vars R
1 3 3 1
o6 = R <-- R <-- R <-- R
0 1 2 3
o6 : Complex
|
i7 : simplicialModule(K) --defaults to top degree 3
1 4 10 20
o7 = R <-- R <-- R <-- R <-- ...
0 1 2 3
o7 : SimplicialModule
|
i8 : elapsedTime simplicialModule(K,6) --specify top degree 6
-- .0642295s elapsed
1 4 10 20 35 56 84
o8 = R <-- R <-- R <-- R <-- R <-- R <-- R <-- ...
0 1 2 3 4 5 6
o8 : SimplicialModule
|
i9 : elapsedTime S' = simplicialModule(K,6, Degeneracy => true)
-- .193831s elapsed
1 4 10 20 35 56 84
o9 = R <-- R <-- R <-- R <-- R <-- R <-- R <-- ...
0 1 2 3 4 5 6
o9 : SimplicialModule
|
i10 : isWellDefined S' --this method checks the simplicial identities as well as many other basic checks
o10 = true
|
The other piece of the Dold-Kan correspondence is the functor that converts a simplicial module into a chain complex. This functor is often referred to as the normalization functor, and is also implemented as the command normalize. If a simplicial R-module is computed as the Dold-Kan image of some complex, then this complex is cached and the normalize command returns this cached complex. If the user wants the normalization to be computed without accessing this cached value, one can use the CheckComplex => false option. By default, the normalization function does not prune the output, so the user should use prune to get a nicer looking output.
i11 : R = ZZ/101[x_1..x_3];
|
i12 : K = koszulComplex vars R
1 3 3 1
o12 = R <-- R <-- R <-- R
0 1 2 3
o12 : Complex
|
i13 : Kn = normalize(simplicialModule(K,4), CheckComplex => false)
1
o13 = R <-- image {0} | 0 0 0 | <-- image {0} | 0 0 0 | <-- image {0} | 0 |
{1} | 1 0 0 | {1} | 0 0 0 | {1} | 0 |
0 {1} | 0 1 0 | {1} | 0 0 0 | {1} | 0 |
{1} | 0 0 1 | {1} | 0 0 0 | {1} | 0 |
{1} | 0 0 0 | {1} | 0 |
1 {1} | 0 0 0 | {1} | 0 |
{1} | 0 0 0 | {1} | 0 |
{2} | 1 0 0 | {1} | 0 |
{2} | 0 1 0 | {1} | 0 |
{2} | 0 0 1 | {1} | 0 |
{2} | 0 |
2 {2} | 0 |
{2} | 0 |
{2} | 0 |
{2} | 0 |
{2} | 0 |
{2} | 0 |
{2} | 0 |
{2} | 0 |
{3} | 1 |
3
o13 : Complex
|
i14 : Kn.dd
1
o14 = 0 : R <------------------- image {0} | 0 0 0 | : 1
| x_1 x_2 x_3 | {1} | 1 0 0 |
{1} | 0 1 0 |
{1} | 0 0 1 |
1 : image {0} | 0 0 0 | <-------------------------- image {0} | 0 0 0 | : 2
{1} | 1 0 0 | {1} | -x_2 -x_3 0 | {1} | 0 0 0 |
{1} | 0 1 0 | {1} | x_1 0 -x_3 | {1} | 0 0 0 |
{1} | 0 0 1 | {1} | 0 x_1 x_2 | {1} | 0 0 0 |
{1} | 0 0 0 |
{1} | 0 0 0 |
{1} | 0 0 0 |
{2} | 1 0 0 |
{2} | 0 1 0 |
{2} | 0 0 1 |
2 : image {0} | 0 0 0 | <---------------- image {0} | 0 | : 3
{1} | 0 0 0 | {2} | x_3 | {1} | 0 |
{1} | 0 0 0 | {2} | -x_2 | {1} | 0 |
{1} | 0 0 0 | {2} | x_1 | {1} | 0 |
{1} | 0 0 0 | {1} | 0 |
{1} | 0 0 0 | {1} | 0 |
{1} | 0 0 0 | {1} | 0 |
{2} | 1 0 0 | {1} | 0 |
{2} | 0 1 0 | {1} | 0 |
{2} | 0 0 1 | {1} | 0 |
{2} | 0 |
{2} | 0 |
{2} | 0 |
{2} | 0 |
{2} | 0 |
{2} | 0 |
{2} | 0 |
{2} | 0 |
{2} | 0 |
{3} | 1 |
o14 : ComplexMap
|
i15 : K == prune Kn
o15 = true
|
As the above example shows, applying the normalization to the Dold-Kan image recovers the original complex.
Canonical Extensions of Functors to the Category of Chain Complexes
One of the main utilities of the Dold-Kan correspondence from the perspective of a commutative algebraist is as a method of canonically extending any endofunctor of R-modules to an endofunctor of nonnegatively chain complexes. This is because endofunctors of R-modules naturally extend to endofunctors of simplicial R-modules by just applying the functor degree-wise. Since any nonnegatively graded chain complex can be converted into a simplicial R-module (and vice versa) this yields a canonical way to extend endofunctors of R-modules to chain complexes in a way that preserves homotopy equivalence.
This extension is often called the Dold-Puppe extension, and was introduced in pioneering work on the theory of derived nonlinear functors. In general, the Dold-Puppe extension of a functor looks quite different from the classically defined functor, and in most cases may not be quasi-isomorphic over arbitrary base rings!
i16 : Q = ZZ/101[x_1,x_2];
|
i17 : K1 = complex {matrix{{x_1}}};
|
i18 : K2 = complex {matrix{{x_2}}};
|
i19 : T1 = K1**K2
1 2 1
o19 = Q <-- Q <-- Q
0 1 2
o19 : Complex
|
i20 : T1.dd
1 2
o20 = 0 : Q <--------------- Q : 1
| x_2 x_1 |
2 1
1 : Q <---------------- Q : 2
{1} | x_1 |
{1} | -x_2 |
o20 : ComplexMap
|
i21 : T2 = prune simplicialTensor({K1,K2})
1 3 2
o21 = Q <-- Q <-- Q
0 1 2
o21 : Complex
|
i22 : T2.dd
1 3
o22 = 0 : Q <---------------------- Q : 1
| x_2 x_1 x_1x_2 |
3 2
1 : Q <--------------------- Q : 2
{1} | -x_1 -x_1 |
{1} | x_2 0 |
{2} | 0 1 |
o22 : ComplexMap
|
i23 : phi1 = extend(T1,T2,id_(T1_0))
1 1
o23 = 0 : Q <--------- Q : 0
| 1 |
2 3
1 : Q <------------------- Q : 1
{1} | 1 0 0 |
{1} | 0 1 x_2 |
1 2
2 : Q <----------------- Q : 2
{2} | -1 -1 |
o23 : ComplexMap
|
i24 : phi2 = extend(T2,T1,id_(T1_0))
1 1
o24 = 0 : Q <--------- Q : 0
| 1 |
3 2
1 : Q <--------------- Q : 1
{1} | 1 0 |
{1} | 0 1 |
{2} | 0 0 |
2 1
2 : Q <-------------- Q : 2
{2} | -1 |
{2} | 0 |
o24 : ComplexMap
|
i25 : phi1*phi2 == id_T1
o25 = true
|
i26 : isNullHomotopic(phi2*phi1 - id_T2)
o26 = true
|
The above example allows us to directly verify that the classically defined tensor product is homotopy equivalent to the Dold-Kan version. This is true over arbitrary base rings, but there are other functors such as the symmetric/exterior power functors that have classical definitions for chain complexes that are not necessarily homotopy equivalent to the Dold-Puppe extensions:
i27 : needsPackage "ChainComplexOperations"
o27 = ChainComplexOperations
o27 : Package
|
i28 : Q = ZZ/2[x_1..x_3];
|
i29 : K = koszulComplex vars Q;
|
i30 : W1 = wedge2 K --the classical "naively" defined exterior power functor
3 6 10 6 3
o30 = 0 <-- Q <-- Q <-- Q <-- Q <-- Q <-- 0
0 1 2 3 4 5 6
o30 : Complex
|
i31 : W2 = prune extPower(2,K) --the simplicial version of the exterior power functor
6 33 73 81 45 10
o31 = Q <-- Q <-- Q <-- Q <-- Q <-- Q
1 2 3 4 5 6
o31 : Complex
|
i32 : prune HH W1
1
o32 = cokernel {1} | x_2 0 x_3 | <-- cokernel {2} | x_2 x_1 0 x_3 0 0 0 x_3 | <-- cokernel {3} | x_3 x_2 x_1 0 | <-- 0 <-- Q
{1} | x_1 x_3 0 | {2} | 0 0 x_3 x_2 x_1 0 0 0 | {4} | 0 0 0 x_3^2 |
{1} | 0 x_2 x_1 | {2} | 0 0 0 0 0 x_3 x_2 x_1 | {4} | 0 0 0 x_2^2 | 4 5
{4} | 0 0 0 x_1^2 |
1 2
3
o32 : Complex
|
i33 : prune HH W2
o33 = cokernel {1} | x_1 0 x_2 0 0 x_3 | <-- cokernel {2} | x_2 x_1 0 x_3 0 0 0 x_3 | <-- cokernel {3} | x_3 x_2 x_1 |
{1} | 0 x_2 x_1 0 x_3 0 | {2} | 0 0 x_3 x_2 x_1 0 0 0 |
{1} | 0 0 0 x_3 x_2 x_1 | {2} | 0 0 0 0 0 x_3 x_2 x_1 | 3
1 2
o33 : Complex
|
Notice that the two definitions of exterior power yield complexes that are not even quasi-isomorphic, and hence certainly not homotopy equivalent. Moreover, the "naive" definition yields a complex that does not even have finite length homology, while the Dold-Puppe extension applied to a complex with finite length homology is guaranteed to have finite length homology. This preservation of "good behavior" for Dold-Puppe extensions of functors was the main motivation of the authors of CITE for using simplicial techniques to prove the Total Rank Conjecture in characteristic 2. The extPower command along with Schur functors in general have also been implemented in a functorial way and can take morphisms of chain complexes as inputs:
i34 : Q=ZZ/101[x_1,x_2];
|
i35 : K = koszulComplex vars Q;
|
i36 : F = complex res ((ideal vars Q)^2);
|
i37 : phi = extend(K,F,id_(K_0))
1 1
o37 = 0 : Q <--------- Q : 0
| 1 |
2 3
1 : Q <----------------------- Q : 1
{1} | x_1 x_2 0 |
{1} | 0 0 x_2 |
1 2
2 : Q <----------------- Q : 2
{2} | 0 x_2 |
o37 : ComplexMap
|
i38 : e2phi = prune extPower(2,phi) --induced map on the exterior powers of these complexes
3 6
o38 = 1 : Q <-------------------------------------- Q : 1
{1} | x_1 x_2 0 0 0 0 |
{1} | 0 0 0 x_2 0 0 |
{2} | 0 0 0 0 x_1x_2 x_2^2 |
9 24
2 : Q <-------------------------------------------------------------------------------------------------------------------------------- Q : 2
{2} | 0 0 x_1^2 2x_1x_2 x_2^2 x_1x_2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 |
{2} | 0 0 0 0 0 0 x_1x_2 x_2^2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 |
{2} | 0 0 0 0 0 0 0 0 x_2^2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 |
{2} | 0 0 0 0 0 0 0 0 0 x_1x_2 x_2^2 0 0 0 0 0 0 0 0 0 0 0 0 0 |
{2} | 0 x_2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 |
{3} | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 x_1x_2 x_2^2 0 0 0 0 0 |
{3} | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 x_2^2 0 0 0 0 |
{3} | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 x_1x_2 x_2^2 0 0 |
{3} | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 x_2^2 0 |
9 30
3 : Q <-------------------------------------------------------------------------------------------------------------------------- Q : 3
{3} | 0 0 0 0 0 0 0 0 0 x_1x_2 x_2^2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 |
{3} | 0 0 0 0 0 0 0 0 0 0 0 x_2^2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 |
{3} | 0 0 0 0 0 0 0 0 0 0 0 0 x_1x_2 x_2^2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 |
{3} | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 x_2^2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 |
{3} | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 x_1x_2 x_2^2 0 0 0 0 0 0 0 0 0 0 0 0 0 |
{3} | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 x_2^2 0 0 0 0 0 0 0 0 0 0 0 0 |
{4} | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 x_2^2 0 0 0 0 0 0 0 0 0 |
{4} | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 x_2^2 0 0 0 |
{4} | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 x_2^2 0 |
3 12
4 : Q <----------------------------------------------- Q : 4
{4} | 0 0 0 0 0 0 0 x_2^2 0 0 0 0 |
{4} | 0 0 0 0 0 0 0 0 0 x_2^2 0 0 |
{4} | 0 0 0 0 0 0 0 0 0 0 0 x_2^2 |
o38 : ComplexMap
|
i39 : assert isCommutative e2phi
|
i40 : ephi = prune extPower(3,phi,TopDegree => 4); --the TopDegree option specifies how many homological degrees to compute
|
i41 : assert isCommutative ephi;
|
i42 : ephi_1
o42 = {2} | 0 x_1x_2 x_2^2 0 |
1 4
o42 : Matrix Q <-- Q
|
i43 : ephi_2;
18 76
o43 : Matrix Q <-- Q
|
i44 : prune schurMap({2},phi) --the second symmetric power
1 1
o44 = 0 : Q <--------- Q : 0
| 1 |
5 9
1 : Q <------------------------------------------------------------- Q : 1
{1} | x_1 x_2 0 0 0 0 0 0 0 |
{1} | 0 0 x_2 0 0 0 0 0 0 |
{2} | 0 0 0 x_1^2 x_1x_2 0 x_2^2 0 0 |
{2} | 0 0 0 0 0 x_1x_2 0 x_2^2 0 |
{2} | 0 0 0 0 0 0 0 0 x_2^2 |
10 26
2 : Q <---------------------------------------------------------------------------------------------------------------------------------- Q : 2
{2} | 0 x_2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 |
{2} | 0 0 0 x_1x_2 x_2^2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 |
{2} | 0 0 0 0 0 x_1^2 x_1x_2 0 x_2^2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 |
{2} | 0 0 0 0 0 0 0 x_1x_2 0 x_2^2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 |
{2} | 0 0 0 0 0 0 0 0 0 0 x_2^2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 |
{3} | 0 0 0 0 0 0 0 0 0 0 0 0 x_1x_2 0 x_2^2 0 0 0 0 0 0 0 0 0 0 0 |
{3} | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 x_2^2 0 0 0 0 0 0 0 0 0 |
{3} | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 x_1x_2 0 x_2^2 0 0 0 0 0 |
{3} | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 x_2^2 0 0 0 |
{4} | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 x_2^2 |
9 30
3 : Q <-------------------------------------------------------------------------------------------------------------------------- Q : 3
{3} | 0 x_1x_2 0 x_2^2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 |
{3} | 0 0 0 0 0 x_2^2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 |
{3} | 0 0 0 0 0 0 0 x_1x_2 0 0 0 x_2^2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 |
{3} | 0 0 0 0 0 0 0 0 0 x_1x_2 0 0 0 x_2^2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 |
{3} | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 x_2^2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 |
{3} | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 x_2^2 0 0 0 0 0 0 0 0 0 0 0 0 |
{4} | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 x_2^2 0 0 0 0 0 0 0 |
{4} | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 x_2^2 0 0 0 |
{4} | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 x_2^2 |
3 12
4 : Q <----------------------------------------------- Q : 4
{4} | 0 0 x_2^2 0 0 0 0 0 0 0 0 0 |
{4} | 0 0 0 0 0 0 0 x_2^2 0 0 0 0 |
{4} | 0 0 0 0 0 0 0 0 0 0 0 x_2^2 |
o44 : ComplexMap
|
i45 : sphi = schurMap({2,1},phi,TopDegree => 3); --schur functor corresponding to partition {2,1} applied to phi
|
i46 : sphi_1
o46 = {1} | x_1 0 0 0 x_2 0 0 0 0 0 0 0 0
{2} | 0 x_1^2 x_1x_2 0 0 x_1x_2 x_2^2 0 0 0 0 0 0
{2} | 0 0 0 x_1x_2 0 0 0 x_2^2 0 0 0 0 0
{1} | 0 0 0 0 0 0 0 0 0 0 0 x_2 0
{2} | 0 0 0 0 0 0 0 0 0 0 0 0 x_1x_2
{2} | 0 0 0 0 0 0 0 0 0 0 0 0 0
{3} | 0 0 0 0 0 0 0 0 0 0 0 0 0
{3} | 0 0 0 0 0 0 0 0 0 0 0 0 0
-----------------------------------------------------------------------
0 0 0 0 0 0 0 |
0 0 0 0 0 0 0 |
0 0 0 0 0 0 0 |
0 0 0 0 0 0 0 |
x_2^2 0 0 0 0 0 0 |
0 x_2^2 0 0 0 0 0 |
0 0 x_1^2x_2 x_1x_2^2 0 x_2^3 0 |
0 0 0 0 x_1x_2^2 0 x_2^3 |
8 20
o46 : Matrix Q <-- Q
|
This package thus lays the groundwork for computing with Dold-Puppe extensions of nonlinear functors, deriving nonlinear functors, and also allows any endofunctor of R-modules implemented in Macaulay2 to immediately be canonically extended to an endofunctor at the level of chain complexes. Moreover, almost all methods are implemented with an eye toward user accessibility and comprehension of the outputs. This is illustrated in many of the documentation nodes below.
Getting started:
Contributors
The following people have generously contributed code or improved existing code:
Acknowledgments
This package began its life during the 2023 Macaulay2 workshop in Minneapolis. Many documentation nodes for the basic constructors not specific to the SimplicialModule type have been repurposed from existing documentation coming from the Complexes package.