Macaulay2 » Documentation
Packages » PruneComplex :: pruneComplex
next | previous | forward | backward | up | index | toc

# pruneComplex -- Prunes a chain complex or list of mutable matrices

- Usage:
    `D = pruneComplex C`
    `D = pruneComplex(C, nsteps)`
- Inputs:
  - C, a complex, or a list of mutable matrices defining the differentials of a complex
  - nsteps, an integer, the number of maps in the complex that will be pruned
- Optional inputs:
  - Direction => ..., default value "left", Determines the direction with which the matrices in the complex is pruned
  - PruningMap => ..., default value true, Whether to compute a morphism of complexes
  - Strategy => ..., default value Engine, Whether to use the methods in the package or C++ algorithms in the engine
  - UnitTest => ..., default value isUnit, Limit which units are to be pruned
- Outputs:
  - D, a complex, or the list of modified mutable matrices
- Consequences:
  - Unless PruningMap is false, D.cache.pruningMap will be updated to a chain complex map {f: C <-- D}.

## Description

Prune a chain complex C by removing unit elements from the differentials.

If C is a free resolution for an R-module M, the output will remain a free resolution of M. In particular, if M is homogeneous or R is a local ring, the output is guaranteed to be a minimal free resolution of M.

    i1 : R = ZZ/32003[a..f]

    o1 = R

    o1 : PolynomialRing

    i2 : I = ideal"abc-def,ab2-cd2-c,acd-b3-1"

                                  2      2         3
    o2 = ideal (a*b*c - d*e*f, a*b  - c*d  - c, - b  + a*c*d - 1)

    o2 : Ideal of R

Here we produce an intentionally non-minimal resolution from a inhomogeneous ideal:

    i3 : S = (coefficientRing R)(monoid [gens R, local h]);

    i4 : Ihom = ideal homogenize(sub(gens gb I, S), S_(numgens R));

    o4 : Ideal of S

    i5 : Chom = (freeResolution(Ihom, Strategy => Nonminimal))[-10];

    i6 : C = (map(R, S, gens R | {1})) Chom

          1      9      15      8      1
    o6 = R  <-- R  <-- R   <-- R  <-- R

         10     11     12      13     14

    o6 : Complex

Now we use pruneComplex to prune the resolution above:

    i7 : D = pruneComplex C

          1      3      3      1
    o7 = R  <-- R  <-- R  <-- R

         10     11     12     13

    o7 : Complex

    i8 : D.dd

               1                                      3
    o8 = 10 : R  <---------------------------------- R  : 11
                    | ab2-cd2-c b3-acd+1 abc-def |

               3                                             3
         11 : R  <----------------------------------------- R  : 12
                    {3} | -abc+def  -b3+acd-1 0         |
                    {3} | 0         ab2-cd2-c abc-def   |
                    {3} | ab2-cd2-c 0         -b3+acd-1 |

               3                         1
         12 : R  <--------------------- R  : 13
                    {6} | b3-acd+1  |
                    {6} | -abc+def  |
                    {6} | ab2-cd2-c |

    o8 : ComplexMap

One way of improving performance is to turn off computation of the pruning map. Note, however, that this may result in incorrect degrees in the graded case:

    i9 : D1 = pruneComplex(C, PruningMap => false)

          1      3      3      1
    o9 = R  <-- R  <-- R  <-- R

         10     11     12     13

    o9 : Complex

    i10 : D1.dd

                1                                      3
    o10 = 10 : R  <---------------------------------- R  : 11
                     | ab2-cd2-c b3-acd+1 abc-def |

                3                                             3
          11 : R  <----------------------------------------- R  : 12
                     {3} | -abc+def  -b3+acd-1 0         |
                     {3} | 0         ab2-cd2-c abc-def   |
                     {3} | ab2-cd2-c 0         -b3+acd-1 |

                3                         1
          12 : R  <--------------------- R  : 13
                     {6} | b3-acd+1  |
                     {6} | -abc+def  |
                     {6} | ab2-cd2-c |

    o10 : ComplexMap

Another method is to use a different pruning strategy. Note that in general there is no well-defined notion of minimality for chain complexes, so different strategies can lead to different results. See the page linked in the optional inputs section above for information on available strategies.

As an example, we can alternate between pruning the lower and higher indices:

    i11 : D2 = pruneComplex(C, Strategy => null, Direction => "both")

           1      4      4      1
    o11 = R  <-- R  <-- R  <-- R

          10     11     12     13

    o11 : Complex

    i12 : D2.dd

                1                                                        4
    o12 = 10 : R  <---------------------------------------------------- R  : 11
                     | c2d2-bdef+c2 b3-acd+1 abc-def a2cd-bcd2-bc-a |

                4                                                          4
          11 : R  <------------------------------------------------------ R  : 12
                     {4} | abd       b3-acd+1      -ad2ef+ab    -b2   |
                     {3} | bcd2+bc+a -c2d2+bdef-c2 -cd3ef-cdef  -def  |
                     {3} | -ab2d     0             abd2ef-cd2-c acd-1 |
                     {4} | b3+1      0             -b2def       -bc   |

                4                                       1
          12 : R  <----------------------------------- R  : 13
                     {7} | -bc2d2+b2def-bc2        |
                     {7} | -b2cd2+ad2ef-b2c-ab     |
                     {9} | b3-acd+1                |
                     {6} | -b3cd2+abd2ef-b3c-cd2-c |

    o12 : ComplexMap

For pruning chain complexes over local rings, pruning scalars by setting UnitTest => isScalar and then pruning other units using UnitTest => isUnit can improve speed. For homogeneous chain complexes (that is, when all maps are homogeneous), since all units are scalars, setting UnitTest => isScalar is always faster:

    i13 : R = ZZ/32003[vars(0..8)]

    o13 = R

    o13 : PolynomialRing

    i14 : M = genericMatrix(R,3,3)

    o14 = | a d g |
          | b e h |
          | c f i |

                  3      3
    o14 : Matrix R  <-- R

    i15 : I = minors(2, M)

    o15 = ideal (- b*d + a*e, - c*d + a*f, - c*e + b*f, - b*g + a*h, - c*g + a*i,
          -----------------------------------------------------------------------
          - c*h + b*i, - e*g + d*h, - f*g + d*i, - f*h + e*i)

    o15 : Ideal of R

    i16 : C = freeResolution(I, Strategy => Nonminimal)

           1      9      18      14      4
    o16 = R  <-- R  <-- R   <-- R   <-- R

          0      1      2       3       4

    o16 : Complex

    i17 : pruneComplex(C, UnitTest => isScalar)

           1      9      16      9      1
    o17 = R  <-- R  <-- R   <-- R  <-- R

          0      1      2       3      4

    o17 : Complex

## Caveat

For inhomogeneous input the resulting complex is not guaranteed to be minimal, particularly because minimality is not well-defined in that case.

If PruningMap is false and the input is not the resolution of a graded ideal, the grading of the resulting complex may be incorrect.

## See also

- pruneDiff -- Prunes a single differential in a chain complex or list of mutable matrices
- pruningMap

## Ways to use pruneComplex:

- `pruneComplex(Complex)`
- `pruneComplex(Complex,ZZ)`
- `pruneComplex(List)`
- `pruneComplex(List,ZZ)`
- pruneComplex(ChainComplex) (missing documentation)
- pruneComplex(ChainComplex,ZZ) (missing documentation)

## For the programmer

The object pruneComplex is a method function with options.

The source of this document is in /build/macaulay2-88fgJW/macaulay2-1.25.11+ds/M2/Macaulay2/packages/PruneComplex/doc.m2:114:0.