.. _hom-comp:

.. _homology-computation:

Homology Computation
====================

The code computes exclusively reduced homology of the given simplicial
complexes. If you want the non-reduced homology, just add a single free rank to
dimension 0 and let it be generated by any single point in the complex.

.. magma:function:: Homology(X)
   :input_types: SmpCpx
   :output_types: SeqEnum, SeqEnum
   :label: Homology_SmpCpx

.. magma:function:: Homology($\sim$X)
   :input_types: SmpCpx
   :label: Homology_SmpCpx_ref

.. magma:function:: Homology(X,A)
   :input_types: SmpCpx, Rng
   :output_types: SeqEnum, SeqEnum
   :label: Homology_SmpCpx_Rng

.. magma:function:: Homology($\sim$X, A)
   :input_types: SmpCpx, Rng
   :label: Homology_SmpCpx_Rng_ref

   Calculates the reduced homology of a simplicial complex ``X`` with coefficients
   in the ring :math:`A`. The procedural form of this command caches the results of
   the calculation in the simplicial complex object. If no ring is given, then the
   function defaults to integer coefficients.

.. magma:example:: Example: homology
   :label: homology

   The resulting modules are stored in falling dimension, always including the
   dimension :math:`-1` vanishing homology module at the very end.

   .. code-block:: magma

      > circ := Boundary(SimplicialComplex([{1,2,3}]));
      > Homology(circ,Integers());
      [
          Full Quotient RSpace of degree 1 over Integer Ring
          Column moduli:
          [ 0 ],

          Full Quotient RSpace of degree 0 over Integer Ring
          Column moduli:
          [ ],

          Full Quotient RSpace of degree 0 over Integer Ring
          Column moduli:
          [ ]
      ]
      [
          Mapping from: RSpace of degree 3, dimension 1 over Integer Ring to Full 
          Quotient RSpace of degree 1 over Integer Ring
          Column moduli:
          [ 0 ],
          Mapping from: RSpace of degree 3, dimension 2 over Integer Ring to Full 
          Quotient RSpace of degree 0 over Integer Ring
          Column moduli:
          [ ],
          Mapping from: Full RSpace of degree 1 over Integer Ring to Full Quotient 
          RSpace of degree 0 over Integer Ring
          Column moduli:
          [ ]
      ]
      > lens3 := LensSpace(3);
      > Homology(~lens3,Integers());
      > Homology(lens3,Integers())[3];
      Full Quotient RSpace of degree 1 over Integer Ring
      Column moduli:
      [ 3 ]

.. magma:function:: HomologyGroup(X, q)
   :input_types: SmpCpx, RngIntElt
   :output_types: ModRng
   :label: HomologyGroup_SmpCpx_RngIntElt

.. magma:function:: HomologyGroup(X, q, A)
   :input_types: SmpCpx, RngIntElt, Rng
   :output_types: ModRng
   :label: HomologyGroup_SmpCpx_RngIntElt_Rng

   Calculates and returns the :math:`q`\ th homology group of :math:`X` with
   coefficients in :math:`A`. If no ring is given, the function defaults to integer
   coefficients. If the homology is cached in :math:`X`, the cached results are
   returned. This function will not compute the entire homology in order to return
   one homology group.

.. magma:function:: BettiNumber(X,q)
   :input_types: SmpCpx, RngIntElt
   :output_types: RngIntElt
   :label: BettiNumber_SmpCpx_RngIntElt

.. magma:function:: BettiNumber(X,q,A)
   :input_types: SmpCpx, RngIntElt, Rng
   :output_types: RngIntElt
   :label: BettiNumber_SmpCpx_RngIntElt_Rng

   Returns the :math:`q`\ th Betti number, computed as the free rank of the
   :math:`q`-dimensional homology group, with coefficients in :math:`A`. If no ring
   is given, then the function will default to integer coefficients.

   Note that the Betti number computations compensate for the homology computations
   being reduced. Thus, ``BettiNumber(X,0) eq Rank(HomologyGroup(X,0)) + 1``.

.. magma:function:: TorsionCoefficients(X, q)
   :input_types: SmpCpx, RngIntElt
   :output_types: SeqEnum[RngElt]
   :label: TorsionCoefficients_SmpCpx_RngIntElt

.. magma:function:: TorsionCoefficients(X, q, A)
   :input_types: SmpCpx, RngIntElt, Rng
   :output_types: SeqEnum[RngElt]
   :label: TorsionCoefficients_SmpCpx_RngIntElt_Rng

   Returns the torsion coefficients of the :math:`q`\ th homology group of
   :math:`X` with coefficients in :math:`A`. If no ring is given, then the function
   will default to integer coefficients.

.. magma:function:: EulerCharacteristic(X)
   :input_types: SmpCpx
   :output_types: RngIntElt
   :label: EulerCharacteristic_SmpCpx

   Computes the Euler characteristic of the complex. If homology is cached, this is
   used for computation, and else the characteristic is computed using the ranks of
   the chain groups.

.. magma:function:: BoundaryMatrix(X, q, A)
   :input_types: SmpCpx, RngIntElt, Rng
   :output_types: Mtrx
   :label: BoundaryMatrix_SmpCpx_RngIntElt_Rng

   Returns the :math:`q`\ th boundary matrix of the corresponding chain complex to
   the simplicial complex :math:`X` with coefficients in :math:`A`.

.. magma:function:: ChainComplex(X, A)
   :input_types: SmpCpx, Rng
   :output_types: ModCpx
   :label: ChainComplex_SmpCpx_Rng

   Constructs a reduced chain complex of free A-modules corresponding to the
   abstract simplicial complex :math:`X`.

   Note that the produced complex includes one extra rank 1 module on each end,
   with the zero map leading to it, to simulate the maps to and from the zero
   module that would end a chain complex constructed from a simplicial complex in
   ordinary cases.

.. magma:example:: Example: chaincomplex
   :label: chaincomplex

   .. code-block:: magma

      > ChainComplex(SimplicialComplex([{1}]),Integers());
      Chain complex with terms of degree 2 down to -1
      Dimensions of terms: 1 1 1 1
      > BoundaryMaps(ChainComplex(SimplicialComplex([{1}]),Integers()));
      [*
      \    [0],

      \    [-1],

      \    [0]
      *]
      > ChainComplex(SimplicialComplex([{1,2,3}]),GF(3));
      Chain complex with terms of degree 4 down to -1
      Dimensions of terms: 1 1 3 3 1 1
      > BoundaryMaps(ChainComplex(SimplicialComplex([{1,2,3}]),GF(3)));
      [*
      \    [0],

      \    [1 2 2],

      \    [1 0 2]
      \    [0 1 2]
      \    [1 2 0],

      \    [2]
      \    [2]
      \    [2],

      \    [0]
      *]

.. magma:function:: HomologyGenerators(X)
   :input_types: SmpCpx
   :label: HomologyGenerators_SmpCpx

.. magma:function:: HomologyGenerators(X, A)
   :input_types: SmpCpx, Rng
   :label: HomologyGenerators_SmpCpx_Rng

.. magma:function:: HomologyGenerators(H, M, X)
   :input_types: SeqEnum, SeqEnum, SmpCpx
   :label: HomologyGenerators_SeqEnum_SeqEnum_SmpCpx

   Prints generators of the homology groups of the simplicial complex :math:`X`
   with coefficients in :math:`A` together with their order, in order of dimension.
   The latter calling form expects :math:`H,M` to be the result from
   ``H,M := ChainComplex(A,smp);``. This function will recalculate homology each
   time unless the homology is already cached in the simplicial complex using
   ``Homology(A, smp)``.

   If no ring is given, the function defaults to integer coefficients.

.. magma:example:: Example: homologygenerators
   :label: homologygenerators

   This function gives a condensed form of the actual bases of the homology groups,
   as well as mappings back to an actual chain representative for each homology
   class.

   The six found generators are the generators of each of the contained torus
   homology groups.

   Notice that each generator is printed out with a prefix. This gives the order of
   the generator - so that for instance torsion elements of homology may be
   recognized. Thus, we see with the projective plane:

   We can further take this opportunity to verify the claims about ``Cone`` and
   ``Suspension`` with regard to the homology.

   .. code-block:: magma

      > HomologyGenerators(threetorus,Integers());

      *** dimension 2 ***
      inf: { 21, 23, 27 } - { 4, 6, 16 } - { 20, 24, 26 } + { 20, 25, 26 } - 
        { 14, 19, 25 } + { 12, 14, 25 } + { 3, 6, 11 } - { 10, 14, 19 } + 
        { 19, 20, 27 } - { 3, 9, 11 } - { 10, 13, 20 } + { 10, 13, 19 } - 
        { 10, 12, 14 } - { 12, 16, 19 } - { 11, 19, 20 } - { 13, 16, 20 } + 
        { 21, 24, 25 } + { 24, 26, 27 } - { 20, 21, 24 } - { 19, 22, 26 } - 
        { 3, 10, 16 } - { 4, 6, 10 } - { 22, 25, 26 } + { 11, 16, 20 } + 
        { 4, 8, 16 } - { 5, 6, 9 } + { 4, 8, 10 } - { 11, 12, 19 } - { 3, 5, 9 } + 
        { 11, 12, 25 } + { 8, 9, 10 } + { 20, 21, 27 } + { 3, 6, 16 } + 
        { 10, 11, 25 } + { 19, 22, 24 } - { 9, 10, 11 } + { 3, 5, 10 } + 
        { 10, 20, 25 } - { 8, 11, 16 } - { 19, 26, 27 } - { 19, 23, 24 } + 
        { 10, 12, 16 } - { 19, 21, 23 } - { 6, 8, 9 } + { 13, 16, 19 } + 
        { 19, 21, 25 } + { 23, 24, 27 } - { 22, 24, 25 } + { 5, 6, 10 } + 
        { 6, 8, 11 }


      *** dimension 1 ***
      inf: -1*{ 10, 13 } + { 3, 5 } - { 8, 9 } - { 8, 16 } - { 19, 22 } + 
        { 20, 26 } + { 9, 11 } - { 3, 16 } + { 5, 10 } + { 22, 26 } + { 11, 20 } + 
        2*{ 10, 20 } + { 13, 19 } - 2*{ 10, 11 }

      inf: { 3, 9 } - { 3, 5 } - { 9, 11 } - { 5, 10 } + { 10, 11 }

      inf: -1*{ 26, 27 } - { 11, 19 } + 2*{ 19, 22 } - { 20, 26 } - 
        2*{ 22,  26 } + { 11, 20 } + { 19, 21 } - { 21, 27 }

      inf: { 10, 13 } + { 11, 19 } - { 11, 20 } - { 10, 20 } - { 13, 19 }

      inf: -1*{ 11, 19 } + { 19, 22 } - { 20, 26 } - { 22, 26 } + { 11, 20 }

      inf: { 11, 20 } + { 10, 20 } - { 10, 11 }
      > HomologyGenerators(SimplicialProjectivePlane(),Integers());

      *** dimension 1 ***
        2: { 3, 6 } + { 2, 3 } - { 2, 6 }
      > HomologyGenerators(Cone(SimplicialProjectivePlane()),Integers());
      Complex is acyclic.

      > HomologyGenerators(Suspension(SimplicialProjectivePlane()),Integers());

      *** dimension 2 ***
        2: { 1, 5, 7 } - { 1, 4, 7 } + { 1, 2, 5 } + { 1, 5, 8 } - { 2, 3, 8 } - 
        { 3, 5, 7 } - { 1, 2, 8 } + { 5, 6, 8 } + { 1, 4, 5 } - { 4, 6, 8 } + 
        { 3, 4, 7 } + { 2, 3, 5 } - { 4, 5, 6 } - { 3, 4, 8 }
