This is PruneComplex.info, produced by Macaulay2, version 1.20

PruneComplex -- Pruning chain complexes over polynomial and local rings
***********************************************************************

Description
===========

This package includes various methods for pruning chain complexes over
polynomial and local rings. In particular, in the local or graded case the
output is guaranteed to be a minimal free resolution.

Algorithms in this package are also implemented using C++ in
e/mutablecomplex.hpp for speed.

+-----------------------------------------------------------------------------+
|i1 : R = ZZ/32003[vars(0..17)];                                              |
+-----------------------------------------------------------------------------+
|i2 : m1 = genericMatrix(R,a,3,3)                                             |
|                                                                             |
|o2 = | a d g |                                                               |
|     | b e h |                                                               |
|     | c f i |                                                               |
|                                                                             |
|             3       3                                                       |
|o2 : Matrix R  <--- R                                                        |
+-----------------------------------------------------------------------------+
|i3 : m2 = genericMatrix(R,j,3,3)                                             |
|                                                                             |
|o3 = | j m p |                                                               |
|     | k n q |                                                               |
|     | l o r |                                                               |
|                                                                             |
|             3       3                                                       |
|o3 : Matrix R  <--- R                                                        |
+-----------------------------------------------------------------------------+
|i4 : I = ideal(m1*m2-m2*m1)                                                  |
|                                                                             |
|o4 = ideal (d*k + g*l - b*m - c*p, b*j - a*k + e*k + h*l - b*n - c*q, c*j +  |
|     ------------------------------------------------------------------------|
|     f*k - a*l + i*l - b*o - c*r, - d*j + a*m - e*m + d*n + g*o - f*p, - d*k |
|     ------------------------------------------------------------------------|
|     + b*m + h*o - f*q, - d*l + c*m + f*n - e*o + i*o - f*r, - g*j - h*m +   |
|     ------------------------------------------------------------------------|
|     a*p - i*p + d*q + g*r, - g*k - h*n + b*p + e*q - i*q + h*r, - g*l - h*o |
|     ------------------------------------------------------------------------|
|     + c*p + f*q)                                                            |
|                                                                             |
|o4 : Ideal of R                                                              |
+-----------------------------------------------------------------------------+

Here we produce an intentionally nonminimal resolution:

+------------------------------------------------------------------------+
|i5 : C = res(I, FastNonminimal=>true)                                   |
|                                                                        |
|      1      26      108      208      221      132      41      5      |
|o5 = R  <-- R   <-- R    <-- R    <-- R    <-- R    <-- R   <-- R  <-- 0|
|                                                                        |
|     0      1       2        3        4        5        6       7      8|
|                                                                        |
|o5 : ChainComplex                                                       |
+------------------------------------------------------------------------+

Now we prune the resolution above to get a minimal resolution:

+-----------------------------------------------------+
|i6 : D = pruneComplex(C, UnitTest => isScalar)       |
|                                                     |
|      1      8      33      60      61      32      5|
|o6 = R  <-- R  <-- R   <-- R   <-- R   <-- R   <-- R |
|                                                     |
|     0      1      2       3       4       5       6 |
|                                                     |
|o6 : ChainComplex                                    |
+-----------------------------------------------------+
|i7 : isCommutative D.cache.pruningMap                |
|                                                     |
|o7 = true                                            |
+-----------------------------------------------------+
|i8 : betti D == betti res I                          |
|                                                     |
|o8 = true                                            |
+-----------------------------------------------------+

Caveat
======

Only supports localization at prime ideals.

See also
========

  * LocalRings -- Localizations of polynomial rings at
    prime ideals

Authors
=======

  * Mahrud Sayrafi (see http://ocf.berkeley.edu/~mahrud/ )
    <mahrud@berkeley.edu>
  * Mike Stillman (see http://www.math.cornell.edu/~mike/ )
    <mike@math.cornell.edu>

Version
=======

This documentation describes version 1.0 of PruneComplex.

Source code
===========

The source code from which this documentation is derived is in the file
PruneComplex.m2 (see common/share/Macaulay2/PruneComplex.m2 ). The auxiliary
files accompanying it are in the directory PruneComplex/ (see
common/share/Macaulay2/PruneComplex/ ).

Exports
=======

  * Functions and commands
      * isScalar -- check whether a ring element is a scalar
      * pruneComplex -- Prunes a chain complex or list of
        mutable matrices
      * pruneDiff -- Prunes a single differential in a chain
        complex or list of mutable matrices
      * pruneUnit -- Prunes a unit of a differential in a
        list of mutable matrices
      * toChainComplex -- Converts a list of mutable
        matrices into a ChainComplex.
      * toMutableComplex -- Converts a chain complex
        into a list of mutable matrices.
  * Methods
      * "isScalar(RingElement)" -- see isScalar, -- check
        whether a ring element is a scalar
      * "pruneComplex(ChainComplex)" -- see pruneComplex,
        -- Prunes a chain complex or list of mutable matrices
      * "pruneComplex(ChainComplex,ZZ)" -- see pruneComplex,
        -- Prunes a chain complex or list of mutable matrices
      * "pruneComplex(List)" -- see pruneComplex, -- Prunes
        a chain complex or list of mutable matrices
      * "pruneComplex(List,ZZ)" -- see pruneComplex, --
        Prunes a chain complex or list of mutable matrices
      * "pruneDiff(ChainComplex,ZZ)" -- see pruneDiff, --
        Prunes a single differential in a chain complex or list of mutable
        matrices
      * "pruneDiff(ChainComplex,ZZ,List)" -- see pruneDiff, --
        Prunes a single differential in a chain complex or list of mutable
        matrices
      * "pruneDiff(List,ZZ)" -- see pruneDiff, -- Prunes a
        single differential in a chain complex or list of mutable matrices
      * "pruneDiff(List,ZZ,List)" -- see pruneDiff, -- Prunes
        a single differential in a chain complex or list of mutable matrices
      * "pruneUnit(List,ZZ,Sequence,List)" -- see pruneUnit,
        -- Prunes a unit of a differential in a list of mutable matrices
      * "toChainComplex(List)" -- see toChainComplex, --
        Converts a list of mutable matrices into a ChainComplex.
      * "toChainComplex(List,Module)" -- see toChainComplex,
        -- Converts a list of mutable matrices into a
        ChainComplex.
      * "toMutableComplex(ChainComplex)" -- see toMutableComplex,
        -- Converts a chain complex into a list of mutable
        matrices.
  * Symbols
      * Direction -- Determines the direction with which the
        matrices in the complex is pruned
      * PruningMap -- Whether to compute a morphism of
        complexes
      * UnitTest -- Limit which units are to be pruned

For the programmer
==================

The object PruneComplex, is a package (Macaulay2Doc).

Direction -- Determines the direction with which the matrices in the complex is pruned
**************************************************************************************

Description
===========

Possible values:

"left": Prune the differentials from lower indices.

"right": Prune the differentials from higher indices.

"both": Alternate between pruning the lower and higher indices.

"best": Use heuristics to prune the best unit in the whole complex first.

See also
========

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

Functions with optional argument named Direction :
==================================================

  * "pruneComplex(...,Direction=>...)"

For the programmer
==================

The object Direction, is a symbol (Macaulay2Doc).

isScalar -- check whether a ring element is a scalar
****************************************************

Synopsis
========

  * Usage:
        b = isScalar(f)
  * Inputs:
      * f, a ring element (Macaulay2Doc), a ring element
  * Outputs:
      * b, a Boolean value (Macaulay2Doc), true if f is a
        scalar, false otherwise.

Description
===========

A synonym for liftable(f, coefficientRing ring f).

See also
========

  * isUnit (Macaulay2Doc) -- whether a ring element is a unit
  * UnitTest -- Limit which units are to be pruned
  * liftable (Macaulay2Doc) -- whether lifting to another ring
    is possible

Ways to use isScalar :
======================

  * "isScalar(RingElement)"

For the programmer
==================

The object isScalar, is a method function (Macaulay2Doc).

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

Synopsis
========

  * Usage:
        D = pruneComplex C
        D = pruneComplex(C, nsteps)
  * Inputs:
      * C, a chain complex (Macaulay2Doc), or a list of
        mutable matrices defining the differentials of a complex
      * nsteps, an integer (Macaulay2Doc), the number of maps in the
        complex that will be pruned
  * Optional inputs (Macaulay2Doc),:
      * 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 chain complex (Macaulay2Doc), 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 = (res(Ihom, FastNonminimal=>true))[-10];            |
+---------------------------------------------------------------+
|i6 : C = (map(R, S, gens R | {1})) Chom                        |
|                                                               |
|      1      9      15      8      1                           |
|o6 = R  <-- R  <-- R   <-- R  <-- R  <-- 0                     |
|                                                               |
|     10     11     12      13     14     15                    |
|                                                               |
|o6 : ChainComplex                                              |
+---------------------------------------------------------------+

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 : ChainComplex                                              |
+---------------------------------------------------------------+
|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 : ChainComplexMap                                           |
+---------------------------------------------------------------+

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 : ChainComplex                                               |
+----------------------------------------------------------------+
|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 : ChainComplexMap                                           |
+----------------------------------------------------------------+

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 : ChainComplex                                                           |
+-----------------------------------------------------------------------------+
|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 : ChainComplexMap                                                        |
+-----------------------------------------------------------------------------+

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 = res(I, FastNonminimal=>true)                                       |
|                                                                             |
|       1      9      18      14      4                                       |
|o16 = R  <-- R  <-- R   <-- R   <-- R  <-- 0                                 |
|                                                                             |
|      0      1      2       3       4      5                                 |
|                                                                             |
|o16 : ChainComplex                                                           |
+-----------------------------------------------------------------------------+
|i17 : pruneComplex(C, UnitTest => isScalar)                                  |
|                                                                             |
|       1      9      16      9      1                                        |
|o17 = R  <-- R  <-- R   <-- R  <-- R                                         |
|                                                                             |
|      0      1      2       3      4                                         |
|                                                                             |
|o17 : ChainComplex                                                           |
+-----------------------------------------------------------------------------+

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 (Macaulay2Doc)

Ways to use pruneComplex :
==========================

  * "pruneComplex(ChainComplex)"
  * "pruneComplex(ChainComplex,ZZ)"
  * "pruneComplex(List)"
  * "pruneComplex(List,ZZ)"

For the programmer
==================

The object pruneComplex, is a method function with options (Macaulay2Doc).

pruneComplex(...,Strategy=>...) -- Whether to use the methods in the package or C++ algorithms in the engine
************************************************************************************************************

Description
===========

Possible values:

null: use the algorithms written using the Macaulay2 language;

Engine: use the algorithms implemented using C++ in the Engine (version 1.11
and up).

For optional inputs, the Engine algorithms only support PruningMap, "left" or
"right" as Direction, and isUnit or isScalar as UnitTest.

Advanced users can implement their own strategies in packages/PruneComplex.m2
and run pruneComplex using the Strategy => null option.

Further information
===================

  * Default value: Engine (Macaulay2Doc),
  * Function: pruneComplex, -- Prunes a chain complex or
    list of mutable matrices
  * Option key: Strategy (Macaulay2Doc), -- an optional argument

See also
========

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

Functions with optional argument named Strategy :
=================================================

  * "addHook(...,Strategy=>...)" -- see addHook (Macaulay2Doc),
    -- add a hook function to an object for later processing
  * "annihilator(...,Strategy=>...)" -- see annihilator (Saturation),
    -- the annihilator ideal
  * "associatedPrimes(...,Strategy=>...)" -- see associatedPrimes (PrimaryDecomposition),
    -- find associated primes
  * "basis(...,Strategy=>...)" -- see basis (Macaulay2Doc), --
    basis or generating set of all or part of a ring, ideal or module
  * "mingens(...,Strategy=>...)" -- see Complement (Macaulay2Doc),
    -- a Strategy option value
  * "trim(...,Strategy=>...)" -- see Complement (Macaulay2Doc),
    -- a Strategy option value
  * determinant(...,Strategy=>...) (Macaulay2Doc)
    -- choose
    between Bareiss and Cofactor algorithms
  * "dual(MonomialIdeal,List,Strategy=>...)" -- see
    dual(MonomialIdeal,Strategy=>...) (Macaulay2Doc),
  * "dual(MonomialIdeal,RingElement,Strategy=>...)" -- see
    dual(MonomialIdeal,Strategy=>...) (Macaulay2Doc),
  * dual(MonomialIdeal,Strategy=>...) (Macaulay2Doc)
  * exteriorPower(...,Strategy=>...) (Macaulay2Doc)
    -- choose
    between Bareiss and Cofactor algorithms
  * "gb(...,Strategy=>...)" -- see gb (Macaulay2Doc), -- compute a
    Gröbner basis
  * gcdLLL(...,Strategy=>...) (missing documentation)
  * "GF(...,Strategy=>...)" -- see GF (Macaulay2Doc), -- make a finite
    field
  * "groebnerBasis(...,Strategy=>...)" -- see groebnerBasis (Macaulay2Doc),
    -- Gröbner basis, as a matrix
  * hermite(...,Strategy=>...) (missing documentation)
  * "hooks(...,Strategy=>...)" -- see hooks (Macaulay2Doc), -- list
    hooks attached to a key
  * "idealizer(...,Strategy=>...)" -- see idealizer (IntegralClosure),
    -- compute Hom(I,I) as a quotient ring
  * integralClosure(...,Strategy=>...) (IntegralClosure),
    --
    control the algorithm used
  * "intersect(Ideal,Ideal,Strategy=>...)" -- see intersect(Ideal,Ideal) (Macaulay2Doc),
    -- compute an intersection of a
    sequence of ideals or modules
  * "intersect(Module,Module,Strategy=>...)" -- see
    intersect(Ideal,Ideal) (Macaulay2Doc), --
    compute an intersection of a sequence of ideals or modules
  * "intersectInP(...,Strategy=>...)" -- see
    intersectInP(...,BasisElementLimit=>...) (ReesAlgebra),
    --
    Option for intersectInP
  * "isPrimary(...,Strategy=>...)" -- see isPrimary (PrimaryDecomposition),
    -- determine whether a submodule is
    primary
  * "isPrime(Ideal,Strategy=>...)" -- see isPrime(Ideal) (MinimalPrimes),
    -- whether an ideal is prime
  * LLL(...,Strategy=>...) (LLLBases)
    -- choose among
    different algorithms
  * "localize(...,Strategy=>...)" -- see localize (PrimaryDecomposition),
    -- localize an ideal at a prime ideal
  * "match(...,Strategy=>...)" -- see match (Macaulay2Doc), --
    regular expression matching
  * "decompose(Ideal,Strategy=>...)" -- see minimalPrimes (MinimalPrimes),
    -- minimal primes of an ideal
  * "minimalPrimes(...,Strategy=>...)" -- see minimalPrimes (MinimalPrimes),
    -- minimal primes of an ideal
  * minors(...,Strategy=>...) (Macaulay2Doc)
    -- choose
    between Bareiss and Cofactor algorithms
  * "primaryComponent(...,Strategy=>...)" -- see primaryComponent (PrimaryDecomposition),
    -- find a primary component
    corresponding to an associated prime
  * pruneComplex(...,Strategy=>...)
    -- Whether to use the
    methods in the package or C++ algorithms in the engine
  * pushForward(...,Strategy=>...) (missing documentation)
  * quotient(...,Strategy=>...) (Saturation)
  * "radical(...,Strategy=>...)" -- see radical (MinimalPrimes),
    -- the radical of an ideal
  * "radicalContainment(...,Strategy=>...)" -- see radicalContainment (MinimalPrimes),
    -- whether an element is contained in
    the radical of an ideal
  * "analyticSpread(...,Strategy=>...)" -- see
    reesIdeal(...,Strategy=>...) (ReesAlgebra),
    -- Choose a
    strategy for the saturation step
  * "distinguished(...,Strategy=>...)" -- see
    reesIdeal(...,Strategy=>...) (ReesAlgebra),
    -- Choose a
    strategy for the saturation step
  * "isLinearType(...,Strategy=>...)" -- see
    reesIdeal(...,Strategy=>...) (ReesAlgebra),
    -- Choose a
    strategy for the saturation step
  * "isReduction(...,Strategy=>...)" -- see reesIdeal(...,Strategy=>...) (ReesAlgebra),
    -- Choose a
    strategy for the saturation step
  * "minimalReduction(...,Strategy=>...)" -- see
    reesIdeal(...,Strategy=>...) (ReesAlgebra),
    -- Choose a
    strategy for the saturation step
  * "multiplicity(...,Strategy=>...)" -- see
    reesIdeal(...,Strategy=>...) (ReesAlgebra),
    -- Choose a
    strategy for the saturation step
  * "normalCone(...,Strategy=>...)" -- see reesIdeal(...,Strategy=>...) (ReesAlgebra),
    -- Choose a
    strategy for the saturation step
  * "reesAlgebra(...,Strategy=>...)" -- see reesIdeal(...,Strategy=>...) (ReesAlgebra),
    -- Choose a
    strategy for the saturation step
  * reesIdeal(...,Strategy=>...) (ReesAlgebra)
    -- Choose a
    strategy for the saturation step
  * "specialFiber(...,Strategy=>...)" -- see
    reesIdeal(...,Strategy=>...) (ReesAlgebra),
    -- Choose a
    strategy for the saturation step
  * "specialFiberIdeal(...,Strategy=>...)" -- see
    reesIdeal(...,Strategy=>...) (ReesAlgebra),
    -- Choose a
    strategy for the saturation step
  * "regSeqInIdeal(...,Strategy=>...)" -- see regSeqInIdeal (PrimaryDecomposition),
    -- a regular sequence contained in an
    ideal
  * resolution(...,Strategy=>...) (Macaulay2Doc)
  * saturate(...,Strategy=>...) (Saturation)
  * "primaryDecomposition(...,Strategy=>...)" -- see strategies for computing primary decomposition (PrimaryDecomposition),
  * "syz(...,Strategy=>...)" -- see syz(Matrix) (Macaulay2Doc),
    -- compute the syzygy matrix
  * "tangentCone(...,Strategy=>...)" -- see tangentCone(Ideal) (TangentCone),

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

Synopsis
========

  * Usage:
        D = pruneDiff(C, n)
        D = pruneDiff(C, n, M)
  * Inputs:
      * C, a chain complex (Macaulay2Doc), or a list of
        mutable matrices defining the differentials of a complex
      * n, an integer (Macaulay2Doc), the index of the differential
        in C
      * M, a list (Macaulay2Doc), if provided, will initialize the
        map back to the original complex
  * Optional inputs (Macaulay2Doc),:
      * PruningMap, => ..., default value true, Whether to
        compute a morphism of complexes
      * UnitTest, => ..., default value isUnit, Limit which
        units are to be pruned
  * Outputs:
      * D, a chain complex (Macaulay2Doc), or the list of
        modified mutable matrices
      * M, a list (Macaulay2Doc), unless PruningMap is false, will
        contain the map back to the original complex

Description
===========

Completely prunes the n-th differential of the chain complex C by removing unit
elements.

Computing the syzygy over a local ring using liftUp and pruneDiff:

+-------------------------------------------------------------+
|i1 : needsPackage "LocalRings";                              |
+-------------------------------------------------------------+
|i2 : R = ZZ/32003[vars(0..5)];                               |
+-------------------------------------------------------------+
|i3 : I = ideal"abc-def,ab2-cd2-c,-b3+acd";                   |
|                                                             |
|o3 : Ideal of R                                              |
+-------------------------------------------------------------+
|i4 : C = res I;                                              |
+-------------------------------------------------------------+
|i5 : M = ideal gens R;                                       |
|                                                             |
|o5 : Ideal of R                                              |
+-------------------------------------------------------------+
|i6 : RM = localRing(R, M);                                   |
+-------------------------------------------------------------+
|i7 : F = C.dd_2;                                             |
|                                                             |
|             4       6                                       |
|o7 : Matrix R  <--- R                                        |
+-------------------------------------------------------------+
|i8 : FM = F ** RM                                            |
|                                                             |
|o8 = {3} | 0    0    -b3+acd   -abc+def  0       a2c2-b2ef  ||
|     {3} | cef  ac2  ab2-cd2-c 0         abc-def -ac2d+abef ||
|     {3} | -ac2 -b2c 0         ab2-cd2-c -b3+acd -a2bc+b2cd ||
|     {5} | b    d    0         0         0       1          ||
|                                                             |
|              4        6                                     |
|o8 : Matrix RM  <--- RM                                      |
+-------------------------------------------------------------+

This is the process for finding the syzygy of FM:

+-------------------------------------------+
|i9 : f = liftUp FM;                        |
|                                           |
|             4       6                     |
|o9 : Matrix R  <--- R                      |
+-------------------------------------------+
|i10 : g = syz f;                           |
|                                           |
|              6       5                    |
|o10 : Matrix R  <--- R                     |
+-------------------------------------------+
|i11 : h = syz g;                           |
|                                           |
|              5       2                    |
|o11 : Matrix R  <--- R                     |
+-------------------------------------------+
|i12 : C = {g ** RM, h ** RM}/mutableMatrix;|
+-------------------------------------------+

Now we prune the map h, which is the first map from the right:

+----------------------------------------------+
|i13 : C = pruneDiff(C, 1, PruningMap => false)|
|                                              |
|o13 = {| -d d2+1 0   |, 0}                    |
|       | b  -bd  -1  |                        |
|       | 0  ef   -ac |                        |
|       | 0  -ac  b2  |                        |
|       | -c 0    ab  |                        |
|       | 0  -b   d   |                        |
|                                              |
|o13 : List                                    |
+----------------------------------------------+
|i14 : g' = C#0;                               |
+----------------------------------------------+

Scale each row with the common denominator of the corresponding column in FM:

+---------------------------------------------+
|i15 : N = transpose entries FM;              |
+---------------------------------------------+
|i16 : for i from 0 to numcols FM - 1 do      |
|        rowMult(g', i, N_i/denominator//lcm);|
+---------------------------------------------+

The syzygy of FM is:

+--------------------------------------+
|i17 : GM = map(source FM, , matrix g')|
|                                      |
|o17 = {6} | -d d2+1 0   |             |
|      {6} | b  -bd  -1  |             |
|      {6} | 0  ef   -ac |             |
|      {6} | 0  -ac  b2  |             |
|      {6} | -c 0    ab  |             |
|      {7} | 0  -b   d   |             |
|                                      |
|               6        3             |
|o17 : Matrix RM  <--- RM              |
+--------------------------------------+
|i18 : kernel FM == image GM           |
|                                      |
|o18 = true                            |
+--------------------------------------+

Caveat
======

This method does not use the algorithms in the engine, hence it might be slow.

See also
========

  * pruneUnit -- Prunes a unit of a differential in a list of
    mutable matrices
  * pruneComplex -- Prunes a chain complex or list of
    mutable matrices

Ways to use pruneDiff :
=======================

  * "pruneDiff(ChainComplex,ZZ)"
  * "pruneDiff(ChainComplex,ZZ,List)"
  * "pruneDiff(List,ZZ)"
  * "pruneDiff(List,ZZ,List)"

For the programmer
==================

The object pruneDiff, is a method function with options (Macaulay2Doc).

pruneUnit -- Prunes a unit of a differential in a list of mutable matrices
**************************************************************************

Synopsis
========

  * Usage:
        D = pruneUnit(C, n, u, M)
  * Inputs:
      * C, a list (Macaulay2Doc), a list of mutable matrices
        defining the differentials of a complex
      * n, an integer (Macaulay2Doc), the index of the differential
        in C
      * u, a sequence (Macaulay2Doc), the coordinates of the
        unit in the differential
      * M, a list (Macaulay2Doc), if provided, will initialize the
        list of map back to the original complex
  * Optional inputs (Macaulay2Doc),:
      * PruningMap, => ..., default value true, Whether to
        compute a morphism of complexes
      * UnitTest, => ..., default value isUnit, Limit which
        units are to be pruned
  * Outputs:
      * D, a list (Macaulay2Doc), a list of modified mutable
        matrices

Description
===========

Prune the unit in location {u} of the {n}-th differential in chain complex {C}.
Moves the unit to the end, clears row and column, while keeping the neighboring
differentials compatible.

Caveat
======

Currently only works with 1x1 units.

See also
========

  * pruningMap (Macaulay2Doc)
  * pruneDiff -- Prunes a single differential in a chain
    complex or list of mutable matrices

Ways to use pruneUnit :
=======================

  * "pruneUnit(List,ZZ,Sequence,List)"

For the programmer
==================

The object pruneUnit, is a method function with options (Macaulay2Doc).

PruningMap -- Whether to compute a morphism of complexes
********************************************************

Description
===========

When true, the pruning map to the original complex will be stored in
C.cache.pruningMap.

Caveat
======

Setting PruningMap to false will improve performance, but in some cases the
grading of the resulting object may be incorrect.

See also
========

  * pruningMap (Macaulay2Doc)
  * pruneUnit -- Prunes a unit of a differential in a list of
    mutable matrices
  * pruneDiff -- Prunes a single differential in a chain
    complex or list of mutable matrices
  * pruneComplex -- Prunes a chain complex or list of
    mutable matrices

Functions with optional argument named PruningMap :
===================================================

  * "pruneComplex(...,PruningMap=>...)"
  * "pruneDiff(...,PruningMap=>...)"
  * "pruneUnit(...,PruningMap=>...)"

For the programmer
==================

The object PruningMap, is a symbol (Macaulay2Doc).

toChainComplex -- Converts a list of mutable matrices into a ChainComplex.
**************************************************************************

Synopsis
========

  * Usage:
        C = toChainComplex(M, F)
  * Inputs:
      * M, a list (Macaulay2Doc), a list of MutableMatrix type
      * F, a module (Macaulay2Doc), the initial free module in
        the resolution. This is used to calculate the degrees in the maps.
  * Outputs:
      * C, a chain complex (Macaulay2Doc),

Description
===========

+-----------------------------------------------------------------------------+
|i1 : R = ZZ/32003[vars(0..17)];                                              |
+-----------------------------------------------------------------------------+
|i2 : m1 = genericMatrix(R,a,3,3)                                             |
|                                                                             |
|o2 = | a d g |                                                               |
|     | b e h |                                                               |
|     | c f i |                                                               |
|                                                                             |
|             3       3                                                       |
|o2 : Matrix R  <--- R                                                        |
+-----------------------------------------------------------------------------+
|i3 : m2 = genericMatrix(R,j,3,3)                                             |
|                                                                             |
|o3 = | j m p |                                                               |
|     | k n q |                                                               |
|     | l o r |                                                               |
|                                                                             |
|             3       3                                                       |
|o3 : Matrix R  <--- R                                                        |
+-----------------------------------------------------------------------------+
|i4 : I = ideal(m1*m2-m2*m1)                                                  |
|                                                                             |
|o4 = ideal (d*k + g*l - b*m - c*p, b*j - a*k + e*k + h*l - b*n - c*q, c*j +  |
|     ------------------------------------------------------------------------|
|     f*k - a*l + i*l - b*o - c*r, - d*j + a*m - e*m + d*n + g*o - f*p, - d*k |
|     ------------------------------------------------------------------------|
|     + b*m + h*o - f*q, - d*l + c*m + f*n - e*o + i*o - f*r, - g*j - h*m +   |
|     ------------------------------------------------------------------------|
|     a*p - i*p + d*q + g*r, - g*k - h*n + b*p + e*q - i*q + h*r, - g*l - h*o |
|     ------------------------------------------------------------------------|
|     + c*p + f*q)                                                            |
|                                                                             |
|o4 : Ideal of R                                                              |
+-----------------------------------------------------------------------------+
|i5 : C = res I;                                                              |
+-----------------------------------------------------------------------------+
|i6 : D = C[-10]                                                              |
|                                                                             |
|      1      8      33      60      61      32      5                        |
|o6 = R  <-- R  <-- R   <-- R   <-- R   <-- R   <-- R  <-- 0                  |
|                                                                             |
|     10     11     12      13      14      15      16     17                 |
|                                                                             |
|o6 : ChainComplex                                                            |
+-----------------------------------------------------------------------------+
|i7 : MC = toMutableComplex D;                                                |
+-----------------------------------------------------------------------------+
|i8 : MC = first pruneComplex MC;                                             |
+-----------------------------------------------------------------------------+
|i9 : D' = toChainComplex MC                                                  |
|                                                                             |
|      1      8      33      60      61      32      5                        |
|o9 = R  <-- R  <-- R   <-- R   <-- R   <-- R   <-- R                         |
|                                                                             |
|     0      1      2       3       4       5       6                         |
|                                                                             |
|o9 : ChainComplex                                                            |
+-----------------------------------------------------------------------------+
|i10 : assert(betti D == betti D'[-10])                                       |
+-----------------------------------------------------------------------------+

Caveat
======

Since the information about source of target of maps is not available, the
grading may be incorrect for general complexes.

See also
========

  * toMutableComplex -- Converts a chain complex into
    a list of mutable matrices.

Ways to use toChainComplex :
============================

  * "toChainComplex(List)"
  * "toChainComplex(List,Module)"

For the programmer
==================

The object toChainComplex, is a method function (Macaulay2Doc).

toMutableComplex -- Converts a chain complex into a list of mutable matrices.
*****************************************************************************

Synopsis
========

  * Usage:
        M = toMutableComplex C
  * Inputs:
      * C, a chain complex (Macaulay2Doc),
  * Outputs:
      * M, a list (Macaulay2Doc), a list of MutableMatrix type

Description
===========

+-----------------------------------------------------------------------------+
|i1 : needsPackage "LocalRings"                                               |
|                                                                             |
|o1 = LocalRings                                                              |
|                                                                             |
|o1 : Package                                                                 |
+-----------------------------------------------------------------------------+
|i2 : R = ZZ/32003[vars(0..3)]                                                |
|                                                                             |
|o2 = R                                                                       |
|                                                                             |
|o2 : PolynomialRing                                                          |
+-----------------------------------------------------------------------------+
|i3 : I = monomialCurveIdeal(R, {1, 3, 4})                                    |
|                                                                             |
|                        3      2     2    2    3    2                        |
|o3 = ideal (b*c - a*d, c  - b*d , a*c  - b d, b  - a c)                      |
|                                                                             |
|o3 : Ideal of R                                                              |
+-----------------------------------------------------------------------------+
|i4 : C = res I                                                               |
|                                                                             |
|      1      4      4      1                                                 |
|o4 = R  <-- R  <-- R  <-- R  <-- 0                                           |
|                                                                             |
|     0      1      2      3      4                                           |
|                                                                             |
|o4 : ChainComplex                                                            |
+-----------------------------------------------------------------------------+
|i5 : RP = localRing(R, ideal"a,b,c");                                        |
+-----------------------------------------------------------------------------+
|i6 : D = (C ++ C[-5]) ** RP                                                  |
|                                                                             |
|       1       4       4       1             1       4       4       1       |
|o6 = RP  <-- RP  <-- RP  <-- RP  <-- 0 <-- RP  <-- RP  <-- RP  <-- RP  <-- 0 |
|                                                                             |
|     0       1       2       3       4     5       6       7       8       9 |
|                                                                             |
|o6 : ChainComplex                                                            |
+-----------------------------------------------------------------------------+
|i7 : MD = toMutableComplex D                                                 |
|                                                                             |
|o7 = {| bc-ad b3-a2c ac2-b2d c3-bd2 |, | -b2 -ac -bd -c2 |, | d  |, 0, 0, |  |
|                                       | c   d   0   0   |  | -c |           |
|                                       | a   b   -c  -d  |  | -b |           |
|                                       | 0   0   a   b   |  | a  |           |
|     ------------------------------------------------------------------------|
|     -bc+ad -b3+a2c -ac2+b2d -c3+bd2 |, | b2 ac bd c2 |, | -d |, 0, 0}       |
|                                        | -c -d 0  0  |  | c  |              |
|                                        | -a -b c  d  |  | b  |              |
|                                        | 0  0  -a -b |  | -a |              |
|                                                                             |
|o7 : List                                                                    |
+-----------------------------------------------------------------------------+
|i8 : pruneComplex MD                                                         |
|                                                                             |
|o8 = ({| bc-ad c3-bd2 |, | (c3-bd2)/d |, 0, 0, 0, | -bc+ad -c3+bd2 |, |      |
|                         | (-bc+ad)/d |                               |      |
|                                                                             |
|                                                                             |
|     ------------------------------------------------------------------------|
|     (-c3+bd2)/d |, 0, 0, 0}, {| 1 |, | 1 0 |, | 0      |, 0, 0, | 1 |, | 1 0|
|     (bc-ad)/d   |                    | 0 0 |  | 0      |               | 0 0|
|                                      | 0 0 |  | 1      |               | 0 0|
|                                      | 0 1 |  | (-c)/d |               | 0 1|
|     ------------------------------------------------------------------------|
|     |, | 0      |, 0, 0, 0})                                                |
|     |  | 0      |                                                           |
|     |  | 1      |                                                           |
|     |  | (-c)/d |                                                           |
|                                                                             |
|o8 : Sequence                                                                |
+-----------------------------------------------------------------------------+

Caveat
======

The nonzero terms in the chain complex must be in a series, otherwise may not
work correctly.

See also
========

  * toChainComplex -- Converts a list of mutable
    matrices into a ChainComplex.

Ways to use toMutableComplex :
==============================

  * "toMutableComplex(ChainComplex)"

For the programmer
==================

The object toMutableComplex, is a method function (Macaulay2Doc).

UnitTest -- Limit which units are to be pruned
**********************************************

Description
===========

Possible values: isUnit, isScalar

See also
========

  * pruneComplex -- Prunes a chain complex or list of
    mutable matrices
  * pruneDiff -- Prunes a single differential in a chain
    complex or list of mutable matrices
  * pruneUnit -- Prunes a unit of a differential in a list of
    mutable matrices
  * isScalar -- check whether a ring element is a scalar
  * isUnit (Macaulay2Doc) -- whether a ring element is a unit

Functions with optional argument named UnitTest :
=================================================

  * "pruneComplex(...,UnitTest=>...)"
  * "pruneDiff(...,UnitTest=>...)"
  * "pruneUnit(...,UnitTest=>...)"

For the programmer
==================

The object UnitTest, is a symbol (Macaulay2Doc).