Moment-angle complexes - Topology

Skip to content
Back to top
View this page
Edit this page

# Moment-angle complexes

AUTHORS:

- Ognjen Petrov (2023-06-25): initial version

class sage.topology.moment_angle_complex.MomentAngleComplex(simplicial_complex)

  Bases: `UniqueRepresentation`, `SageObject`

  A moment-angle complex.

  Given a simplicial complex \(K\), with a set of vertices \(V = \{v_1, v_2, \ldots, v_n\}\), a moment-angle complex over \(K\) is a topological space \(Z\), which is a union of \(X_{\sigma}\), where \(\sigma \in K\), and \(X_{\sigma} = Y_{v_1} \times Y_{v_2} \times \cdots \times Y_{v_n}\) and \(Y_{v_i}\) is a 2-disk (a 2-simplex) if \(v_i \in \sigma\) , or a 1-sphere otherwise.

  \[\begin{split}Y_{v_i} = \begin{cases} D^2, &v_i \in \sigma,\\ S^1, &v_i \notin \sigma. \end{cases}\end{split}\]

  Note

  The mentioned union is not a disjoint union of topological spaces. The unit disks and the unit spheres are considered subsets of \(\CC\), so the union is just a normal union of subsets of \(\CC^n\).

  Here we view moment-angle complexes as cubical complexes and try to compute mostly things which would not require computing the moment-angle complex itself, but rather work with the corresponding simplicial complex.

  Note

  One of the more useful properties will be the `bigraded Betti numbers`, and the underlying theorem which makes this possible is Hochter’s formula, which can be found on page 104 of [BP2014].

  INPUT:

  - `simplicial_complex` – an instance of `SimplicialComplex`, or an object from which an instance of `SimplicialComplex` can be created (e.g., list of facets), which represents the associated simplicial complex over which this moment-angle complex is created

  EXAMPLES:

  Sage

      sage: MomentAngleComplex([[1,2,3], [2,4], [3,4]])
      Moment-angle complex of Simplicial complex with vertex set
      (1, 2, 3, 4) and facets {(2, 4), (3, 4), (1, 2, 3)}
      sage: X = SimplicialComplex([[0,1], [1,2], [1,3], [2,3]])
      sage: Z = MomentAngleComplex(X); Z
      Moment-angle complex of Simplicial complex with vertex set
      (0, 1, 2, 3) and facets {(0, 1), (1, 2), (1, 3), (2, 3)}
      sage: M = MomentAngleComplex([[1], [2]]); M
      Moment-angle complex of Simplicial complex with vertex set
      (1, 2) and facets {(1,), (2,)}

  Python

      >>> from sage.all import *
      >>> MomentAngleComplex([[Integer(1),Integer(2),Integer(3)], [Integer(2),Integer(4)], [Integer(3),Integer(4)]])
      Moment-angle complex of Simplicial complex with vertex set
      (1, 2, 3, 4) and facets {(2, 4), (3, 4), (1, 2, 3)}
      >>> X = SimplicialComplex([[Integer(0),Integer(1)], [Integer(1),Integer(2)], [Integer(1),Integer(3)], [Integer(2),Integer(3)]])
      >>> Z = MomentAngleComplex(X); Z
      Moment-angle complex of Simplicial complex with vertex set
      (0, 1, 2, 3) and facets {(0, 1), (1, 2), (1, 3), (2, 3)}
      >>> M = MomentAngleComplex([[Integer(1)], [Integer(2)]]); M
      Moment-angle complex of Simplicial complex with vertex set
      (1, 2) and facets {(1,), (2,)}

  We can perform a number of operations, such as find the dimension or compute the homology:

  Sage

      sage: M.homology()                                                              # needs sage.modules
      {0: 0, 1: 0, 2: 0, 3: Z}
      sage: Z.dimension()
      6
      sage: Z.homology()                                                              # needs sage.modules
      {0: 0, 1: 0, 2: 0, 3: Z x Z, 4: Z, 5: Z, 6: Z}

  [Python]

      >>> from sage.all import *
      >>> M.homology()                                                              # needs sage.modules
      {0: 0, 1: 0, 2: 0, 3: Z}
      >>> Z.dimension()
      6
      >>> Z.homology()                                                              # needs sage.modules
      {0: 0, 1: 0, 2: 0, 3: Z x Z, 4: Z, 5: Z, 6: Z}

  If the associated simplicial complex is an \(n\)-simplex, then the corresponding moment-angle complex is a polydisc (a complex ball) of complex dimension \(n+1\):

  Sage

      sage: Z = MomentAngleComplex([[0, 1, 2]]); Z
      Moment-angle complex of Simplicial complex with vertex set (0, 1, 2)
      and facets {(0, 1, 2)}

  Python

      >>> from sage.all import *
      >>> Z = MomentAngleComplex([[Integer(0), Integer(1), Integer(2)]]); Z
      Moment-angle complex of Simplicial complex with vertex set (0, 1, 2)
      and facets {(0, 1, 2)}

  This can be seen by viewing the components used in the construction of this moment-angle complex by calling `components()`:

  Sage

      sage: Z.components()
      {(0, 1, 2): [The 2-simplex, The 2-simplex, The 2-simplex]}

  [Python]

      >>> from sage.all import *
      >>> Z.components()
      {(0, 1, 2): [The 2-simplex, The 2-simplex, The 2-simplex]}

  If the associated simplicial complex is a disjoint union of 2 points, then the corresponding moment-angle complex is homeomorphic to a boundary of a 3-sphere:

  Sage

      sage: Z = MomentAngleComplex([[0], [1]]); Z
      Moment-angle complex of Simplicial complex with vertex set
      (0, 1) and facets {(0,), (1,)}
      sage: dict(sorted(Z.components().items()))
      {(0,): [The 2-simplex, Minimal triangulation of the 1-sphere],
       (1,): [Minimal triangulation of the 1-sphere, The 2-simplex]}

  Python

      >>> from sage.all import *
      >>> Z = MomentAngleComplex([[Integer(0)], [Integer(1)]]); Z
      Moment-angle complex of Simplicial complex with vertex set
      (0, 1) and facets {(0,), (1,)}
      >>> dict(sorted(Z.components().items()))
      {(0,): [The 2-simplex, Minimal triangulation of the 1-sphere],
       (1,): [Minimal triangulation of the 1-sphere, The 2-simplex]}

  The moment-angle complex passes all the tests of the test suite relative to its category:

  Sage

      sage: TestSuite(Z).run()

  [Python]

      >>> from sage.all import *
      >>> TestSuite(Z).run()

  betti(dim=None)

    Return the Betti number (or numbers) of `self`.

    The the \(i\)-th Betti number is the rank of the \(i\)-th homology group.

    INPUT:

    - `dim` – (optional) an integer or a list of integers

    OUTPUT:

    If `dim` is an integer or a list of integers, then return a dictionary of Betti numbers for each given dimension, indexed by dimension. Otherwise, return all Betti numbers.

    EXAMPLES:

    Sage

        sage: # needs sage.modules
        sage: Z = MomentAngleComplex([[0,1], [1,2], [2,0], [1,2,3]])
        sage: Z.betti()
        {0: 1, 1: 0, 2: 0, 3: 1, 4: 0, 5: 1, 6: 1, 7: 0}
        sage: Z = MomentAngleComplex([[0,1], [1,2], [2,0], [1,2,3], [3,0]])
        sage: Z.betti(dim=6)
        {6: 2}

    Python

        >>> from sage.all import *
        >>> # needs sage.modules
        >>> Z = MomentAngleComplex([[Integer(0),Integer(1)], [Integer(1),Integer(2)], [Integer(2),Integer(0)], [Integer(1),Integer(2),Integer(3)]])
        >>> Z.betti()
        {0: 1, 1: 0, 2: 0, 3: 1, 4: 0, 5: 1, 6: 1, 7: 0}
        >>> Z = MomentAngleComplex([[Integer(0),Integer(1)], [Integer(1),Integer(2)], [Integer(2),Integer(0)], [Integer(1),Integer(2),Integer(3)], [Integer(3),Integer(0)]])
        >>> Z.betti(dim=Integer(6))
        {6: 2}

  cohomology(dim=None, base_ring=Integer Ring, algorithm='pari', verbose=False, reduced=True)

    The reduced cohomology of `self`.

    This is equivalent to calling the `homology()` method, with `cohomology=True` as an argument.

    See also

    `homology()`.

    EXAMPLES:

    Sage

        sage: X = SimplicialComplex([[0,1],[1,2],[2,3],[3,0]])
        sage: Z = MomentAngleComplex(X)

    Python

        >>> from sage.all import *
        >>> X = SimplicialComplex([[Integer(0),Integer(1)],[Integer(1),Integer(2)],[Integer(2),Integer(3)],[Integer(3),Integer(0)]])
        >>> Z = MomentAngleComplex(X)

    It is known that the previous moment-angle complex is homeomorphic to a product of two 3-spheres (which can be seen by looking at the output of `components()`):

    Sage

        sage: # needs sage.modules
        sage: S3 = simplicial_complexes.Sphere(3)
        sage: product_of_spheres = S3.product(S3)
        sage: Z.cohomology()
        {0: 0, 1: 0, 2: 0, 3: Z x Z, 4: 0, 5: 0, 6: Z}
        sage: Z.cohomology() == product_of_spheres.cohomology()  # long time
        True

    [Python]

        >>> from sage.all import *
        >>> # needs sage.modules
        >>> S3 = simplicial_complexes.Sphere(Integer(3))
        >>> product_of_spheres = S3.product(S3)
        >>> Z.cohomology()
        {0: 0, 1: 0, 2: 0, 3: Z x Z, 4: 0, 5: 0, 6: Z}
        >>> Z.cohomology() == product_of_spheres.cohomology()  # long time
        True

  components()

    Return the dictionary of components of `self`, indexed by facets of the associated simplicial complex.

    OUTPUT:

    A dictionary, whose values are lists, representing spheres and disks described in the construction of the moment-angle complex. `The 2-simplex` represents a 2-disk, and `Minimal triangulation of the 1-sphere` represents a 1-sphere.

    EXAMPLES:

    Sage

        sage: M = MomentAngleComplex([[0, 1, 2]]); M
        Moment-angle complex of Simplicial complex with vertex set
        (0, 1, 2) and facets {(0, 1, 2)}
        sage: M.components()
        {(0, 1, 2): [The 2-simplex, The 2-simplex, The 2-simplex]}
        sage: Z = MomentAngleComplex([[0], [1]]); Z
        Moment-angle complex of Simplicial complex with vertex set
        (0, 1) and facets {(0,), (1,)}
        sage: sorted(Z.components().items())
        [((0,), [The 2-simplex, Minimal triangulation of the 1-sphere]),
         ((1,), [Minimal triangulation of the 1-sphere, The 2-simplex])]

    Python

        >>> from sage.all import *
        >>> M = MomentAngleComplex([[Integer(0), Integer(1), Integer(2)]]); M
        Moment-angle complex of Simplicial complex with vertex set
        (0, 1, 2) and facets {(0, 1, 2)}
        >>> M.components()
        {(0, 1, 2): [The 2-simplex, The 2-simplex, The 2-simplex]}
        >>> Z = MomentAngleComplex([[Integer(0)], [Integer(1)]]); Z
        Moment-angle complex of Simplicial complex with vertex set
        (0, 1) and facets {(0,), (1,)}
        >>> sorted(Z.components().items())
        [((0,), [The 2-simplex, Minimal triangulation of the 1-sphere]),
         ((1,), [Minimal triangulation of the 1-sphere, The 2-simplex])]

    We interpret the output of this method by taking the product of all the elements in each list, and then taking the union of all products. From the previous example, we have \(\mathcal{Z} = S^1 \times D^2 \cup D^2 \times S^1 = \partial (D^2 \times D^2) = \partial D^4 = S^3\):

    Sage

        sage: Z = MomentAngleComplex([[0,1], [1,2], [2,3], [3,0]])
        sage: sorted(Z.components().items())
        [((0, 1),
          [The 2-simplex,
           The 2-simplex,
           Minimal triangulation of the 1-sphere,
           Minimal triangulation of the 1-sphere]),
         ((0, 3),
          [The 2-simplex,
           Minimal triangulation of the 1-sphere,
           Minimal triangulation of the 1-sphere,
           The 2-simplex]),
         ((1, 2),
          [Minimal triangulation of the 1-sphere,
           The 2-simplex,
           The 2-simplex,
           Minimal triangulation of the 1-sphere]),
         ((2, 3),
          [Minimal triangulation of the 1-sphere,
           Minimal triangulation of the 1-sphere,
           The 2-simplex,
           The 2-simplex])]

    [Python]

        >>> from sage.all import *
        >>> Z = MomentAngleComplex([[Integer(0),Integer(1)], [Integer(1),Integer(2)], [Integer(2),Integer(3)], [Integer(3),Integer(0)]])
        >>> sorted(Z.components().items())
        [((0, 1),
          [The 2-simplex,
           The 2-simplex,
           Minimal triangulation of the 1-sphere,
           Minimal triangulation of the 1-sphere]),
         ((0, 3),
          [The 2-simplex,
           Minimal triangulation of the 1-sphere,
           Minimal triangulation of the 1-sphere,
           The 2-simplex]),
         ((1, 2),
          [Minimal triangulation of the 1-sphere,
           The 2-simplex,
           The 2-simplex,
           Minimal triangulation of the 1-sphere]),
         ((2, 3),
          [Minimal triangulation of the 1-sphere,
           Minimal triangulation of the 1-sphere,
           The 2-simplex,
           The 2-simplex])]

    It is not that difficult to prove that the previous moment-angle complex is homeomorphic to a product of two 3-spheres. We can look at the cohomologies to try and validate whether this makes sense:

    Sage

        sage: S3 = simplicial_complexes.Sphere(3)
        sage: product_of_spheres = S3.product(S3)
        sage: Z.cohomology()                                                        # needs sage.modules
        {0: 0, 1: 0, 2: 0, 3: Z x Z, 4: 0, 5: 0, 6: Z}
        sage: Z.cohomology() == product_of_spheres.cohomology()  # long time        # needs sage.modules
        True

    Python

        >>> from sage.all import *
        >>> S3 = simplicial_complexes.Sphere(Integer(3))
        >>> product_of_spheres = S3.product(S3)
        >>> Z.cohomology()                                                        # needs sage.modules
        {0: 0, 1: 0, 2: 0, 3: Z x Z, 4: 0, 5: 0, 6: Z}
        >>> Z.cohomology() == product_of_spheres.cohomology()  # long time        # needs sage.modules
        True

  cubical_complex()

    Return the cubical complex that represents `self`.

    This method returns returns a cubical complex which is derived by explicitly computing products and unions in the definition of a moment-angle complex.

    Warning

    The construction can be very slow, it is not recommended unless the corresponding simplicial complex has 5 or less vertices.

    EXAMPLES:

    Sage

        sage: Z = MomentAngleComplex([[0,1,2], [1,3]]); Z
        Moment-angle complex of Simplicial complex with vertex set
        (0, 1, 2, 3) and facets {(1, 3), (0, 1, 2)}
        sage: Z.cubical_complex()
        Cubical complex with 256 vertices and 6409 cubes
        sage: dim(Z.cubical_complex()) == dim(Z)
        True
        sage: Z = MomentAngleComplex([[0,1], [1,2], [2,0], [1,3]]); Z
        Moment-angle complex of Simplicial complex with vertex set
        (0, 1, 2, 3) and facets {(0, 1), (0, 2), (1, 2), (1, 3)}
        sage: Z.betti() == Z.cubical_complex().betti()  # long time
        True

    Python

        >>> from sage.all import *
        >>> Z = MomentAngleComplex([[Integer(0),Integer(1),Integer(2)], [Integer(1),Integer(3)]]); Z
        Moment-angle complex of Simplicial complex with vertex set
        (0, 1, 2, 3) and facets {(1, 3), (0, 1, 2)}
        >>> Z.cubical_complex()
        Cubical complex with 256 vertices and 6409 cubes
        >>> dim(Z.cubical_complex()) == dim(Z)
        True
        >>> Z = MomentAngleComplex([[Integer(0),Integer(1)], [Integer(1),Integer(2)], [Integer(2),Integer(0)], [Integer(1),Integer(3)]]); Z
        Moment-angle complex of Simplicial complex with vertex set
        (0, 1, 2, 3) and facets {(0, 1), (0, 2), (1, 2), (1, 3)}
        >>> Z.betti() == Z.cubical_complex().betti()  # long time
        True

    We can now work with moment-angle complexes as concrete cubical complexes. Though, it can be very slow, due to the size of the complex. However, for some smaller moment-angle complexes, this may be possible:

    Sage

        sage: Z = MomentAngleComplex([[0], [1]]); Z
        Moment-angle complex of Simplicial complex with vertex set
        (0, 1) and facets {(0,), (1,)}
        sage: Z.cubical_complex().f_vector()
        [1, 16, 32, 24, 8]

    [Python]

        >>> from sage.all import *
        >>> Z = MomentAngleComplex([[Integer(0)], [Integer(1)]]); Z
        Moment-angle complex of Simplicial complex with vertex set
        (0, 1) and facets {(0,), (1,)}
        >>> Z.cubical_complex().f_vector()
        [1, 16, 32, 24, 8]

  dimension()

    The dimension of `self`.

    The dimension of a moment-angle complex is the dimension of the constructed (cubical) complex. It is not difficult to see that this turns out to be \(m+n+1\), where \(m\) is the number of vertices and \(n\) is the dimension of the associated simplicial complex.

    EXAMPLES:

    Sage

        sage: Z = MomentAngleComplex([[0,1], [1,2,3]])
        sage: Z.dimension()
        7
        sage: Z = MomentAngleComplex([[0, 1, 2]])
        sage: Z.dimension()
        6
        sage: dim(Z)
        6

    Python

        >>> from sage.all import *
        >>> Z = MomentAngleComplex([[Integer(0),Integer(1)], [Integer(1),Integer(2),Integer(3)]])
        >>> Z.dimension()
        7
        >>> Z = MomentAngleComplex([[Integer(0), Integer(1), Integer(2)]])
        >>> Z.dimension()
        6
        >>> dim(Z)
        6

    We can construct the cubical complex and compare whether the dimensions coincide:

    Sage

        sage: dim(Z) == dim(Z.cubical_complex())
        True

    [Python]

        >>> from sage.all import *
        >>> dim(Z) == dim(Z.cubical_complex())
        True

  euler_characteristic()

    Return the Euler characteristic of `self`.

    The Euler characteristic is defined as the alternating sum of the Betti numbers of `self`.

    The Euler characteristic of a moment-angle complex is 0 if the associated simplicial complex is not a simplex.

    EXAMPLES:

    Sage

        sage: # needs sage.modules
        sage: X = SimplicialComplex([[0,1,2,3,4,5], [0,1,2,3,4,6],
        ....:                        [0,1,2,3,5,7], [0,1,2,3,6,8,9]])
        sage: M = MomentAngleComplex(X)
        sage: M.euler_characteristic()  # long time
        0
        sage: Z = MomentAngleComplex([[0,1,2,3,4]])
        sage: Z.euler_characteristic()
        1

    Python

        >>> from sage.all import *
        >>> # needs sage.modules
        >>> X = SimplicialComplex([[Integer(0),Integer(1),Integer(2),Integer(3),Integer(4),Integer(5)], [Integer(0),Integer(1),Integer(2),Integer(3),Integer(4),Integer(6)],
        ...                        [Integer(0),Integer(1),Integer(2),Integer(3),Integer(5),Integer(7)], [Integer(0),Integer(1),Integer(2),Integer(3),Integer(6),Integer(8),Integer(9)]])
        >>> M = MomentAngleComplex(X)
        >>> M.euler_characteristic()  # long time
        0
        >>> Z = MomentAngleComplex([[Integer(0),Integer(1),Integer(2),Integer(3),Integer(4)]])
        >>> Z.euler_characteristic()
        1

  has_trivial_lowest_deg_massey_product()

    Return whether `self` has a non-trivial lowest degree triple Massey product.

    This is the Massey product in the cohomology of this moment-angle complex. This relies on the theorem which was proven in [GL2019].

    ALGORITHM:

    We obtain the one-skeleton from the associated simplicial complex, which we consider to be a graph. We then perform `subgraph_search`, searching for any subgraph isomorphic to one of the 8 obstruction graphs listed in the mentioned paper.

    EXAMPLES:

    A simplex will not have a trivial triple lowest-degree Massey product, because its one-skeleton certainly does contain a subcomplex isomorphic to one of the 8 mentioned in the paper:

    Sage

        sage: Z = MomentAngleComplex([[1,2,3,4,5,6]])
        sage: Z.has_trivial_lowest_deg_massey_product()
        False

    Python

        >>> from sage.all import *
        >>> Z = MomentAngleComplex([[Integer(1),Integer(2),Integer(3),Integer(4),Integer(5),Integer(6)]])
        >>> Z.has_trivial_lowest_deg_massey_product()
        False

    The following is one of the 8 obstruction graphs:

    Sage

        sage: Z = MomentAngleComplex([[1, 2], [1, 4], [2, 3], [3, 5],
        ....:                         [5, 6], [4, 5], [1, 6]])
        sage: Z.has_trivial_lowest_deg_massey_product()
        False

    [Python]

        >>> from sage.all import *
        >>> Z = MomentAngleComplex([[Integer(1), Integer(2)], [Integer(1), Integer(4)], [Integer(2), Integer(3)], [Integer(3), Integer(5)],
        ...                         [Integer(5), Integer(6)], [Integer(4), Integer(5)], [Integer(1), Integer(6)]])
        >>> Z.has_trivial_lowest_deg_massey_product()
        False

    A hexagon is not isomorphic to any of the 8 obstruction graphs:

    Sage

        sage: Z = MomentAngleComplex([[0,1], [1,2], [2,3],
        ....:                         [3,4], [4,5], [5,0]])
        sage: Z.has_trivial_lowest_deg_massey_product()
        True

    Python

        >>> from sage.all import *
        >>> Z = MomentAngleComplex([[Integer(0),Integer(1)], [Integer(1),Integer(2)], [Integer(2),Integer(3)],
        ...                         [Integer(3),Integer(4)], [Integer(4),Integer(5)], [Integer(5),Integer(0)]])
        >>> Z.has_trivial_lowest_deg_massey_product()
        True

  homology(dim=None, base_ring=Integer Ring, cohomology=False, algorithm='pari', verbose=False, reduced=True)

    The (reduced) homology of `self`.

    INPUT:

    - `dim` – integer or a list of integers; represents the homology (or homologies) we want to compute

    - `base_ring` – commutative ring (default: `ZZ`); must be `ZZ` or a field

    - `cohomology` – boolean (default: `False`); if `True`, compute cohomology rather than homology

    - `algorithm` – string (default: `'pari'`); the options are `'auto'`, `'dhsw'`, or `'pari'`; see `cell_complex.GenericCellComplex.homology()` documentation for a description of what they mean

    - `verbose` – boolean (default: `False`); if `True`, print some messages as the homology is computed

    - `reduced` – boolean (default: `True`); if `True`, return the reduced homology

    ALGORITHM:

    This algorithm is adopted from Theorem 4.5.8 of [BP2014].

    The (co)homology of the moment-angle complex is closely related to the (co)homologies of certain full subcomplexes of the associated simplicial complex. More specifically, we know that:

    \[H_l(\mathcal{Z}_\mathcal{K}) \cong \bigoplus_{J \subseteq [m]} \widetilde{H}_{l-|J|-1}(\mathcal{K}_J),\]

    where \(\mathcal{Z}_\mathcal{K}\) denotes the moment-angle complex associated to a simplicial complex \(\mathcal{K}\), on the set of vertices \(\{1, 2, 3, \ldots, m\} =: [m]\). \(\mathcal{K}_J\) denotes the full subcomplex of \(\mathcal{K}\), generated by a set of vertices \(J\). The same formula holds true for cohomology groups as well.

    See also

    `cell_complex.GenericCellComplex.homology()`

    EXAMPLES:

         sage: # needs sage.modules
         sage: Z = MomentAngleComplex([[0,1,2], [1,2,3], [3,0]]); Z
         Moment-angle complex of Simplicial complex with vertex set
         (0, 1, 2, 3) and facets {(0, 3), (0, 1, 2), (1, 2, 3)}
         sage: Z = MomentAngleComplex([[0,1,2], [1,2,3], [3,0]])
         sage: Z.homology()
         {0: 0, 1: 0, 2: 0, 3: 0, 4: 0, 5: Z x Z, 6: Z, 7: 0}
         sage: Z.homology(base_ring=GF(2))
         {0: Vector space of dimension 0 over Finite Field of size 2,
          1: Vector space of dimension 0 over Finite Field of size 2,
          2: Vector space of dimension 0 over Finite Field of size 2,
          3: Vector space of dimension 0 over Finite Field of size 2,
          4: Vector space of dimension 0 over Finite Field of size 2,
          5: Vector space of dimension 2 over Finite Field of size 2,
          6: Vector space of dimension 1 over Finite Field of size 2,
          7: Vector space of dimension 0 over Finite Field of size 2}
        sage: RP = simplicial_complexes.RealProjectivePlane()
        sage: Z = MomentAngleComplex(RP)
        sage: Z.homology()
        {0: 0, 1: 0, 2: 0, 3: 0, 4: 0, 5: Z^10, 6: Z^15, 7: Z^6, 8: C2, 9: 0}

    This yields the same result as creating a cubical complex from this moment-angle complex, and then computing its (co)homology, but that is incomparably slower and is really only possible when the associated simplicial complex is very small:

    Sage

        sage: Z = MomentAngleComplex([[0,1], [1,2], [2,0]]); Z
        Moment-angle complex of Simplicial complex with vertex set
        (0, 1, 2) and facets {(0, 1), (0, 2), (1, 2)}
        sage: Z.cubical_complex()
        Cubical complex with 64 vertices and 729 cubes
        sage: Z.cubical_complex().homology() == Z.homology()                        # needs sage.modules
        True

    Python

        >>> from sage.all import *
        >>> Z = MomentAngleComplex([[Integer(0),Integer(1)], [Integer(1),Integer(2)], [Integer(2),Integer(0)]]); Z
        Moment-angle complex of Simplicial complex with vertex set
        (0, 1, 2) and facets {(0, 1), (0, 2), (1, 2)}
        >>> Z.cubical_complex()
        Cubical complex with 64 vertices and 729 cubes
        >>> Z.cubical_complex().homology() == Z.homology()                        # needs sage.modules
        True

    Meanwhile, the homology computation used here is quite efficient and works well even with significantly larger underlying simplicial complexes:

    Sage

        sage: # needs sage.modules
        sage: Z = MomentAngleComplex([[0,1,2,3,4,5], [0,1,2,3,4,6],
        ....:                         [0,1,2,3,5,7], [0,1,2,3,6,8,9]])
        sage: Z.homology()  # long time
        {0: 0,
         1: 0,
         2: 0,
         3: Z^9,
         4: Z^17,
         5: Z^12,
         6: Z x Z x Z,
         7: 0,
         8: 0,
         9: 0,
         10: 0,
         11: 0,
         12: 0,
         13: 0,
         14: 0,
         15: 0,
         16: 0,
         17: 0}
        sage: Z = MomentAngleComplex([[0,1,2,3], [0,1,2,4], [0,1,3,5],
        ....:                         [0,1,4,5], [0,2,3,6], [0,2,4,6]])
        sage: Z.homology(dim=range(5), reduced=True)
        {0: 0, 1: 0, 2: 0, 3: Z x Z x Z x Z, 4: Z x Z}
        sage: Z.homology(dim=range(5), reduced=False)
        {0: Z, 1: 0, 2: 0, 3: Z x Z x Z x Z, 4: Z x Z}
        sage: all(Z.homology(i,reduced=True) == Z.homology(i,reduced=False)
        ....:     for i in range(1, dim(Z)))
        True
        sage: all(Z.homology(i,reduced=True) == Z.homology(i,reduced=False)
        ....:     for i in range(dim(Z)))
        False

    [Python]

        >>> from sage.all import *
        >>> # needs sage.modules
        >>> Z = MomentAngleComplex([[Integer(0),Integer(1),Integer(2),Integer(3),Integer(4),Integer(5)], [Integer(0),Integer(1),Integer(2),Integer(3),Integer(4),Integer(6)],
        ...                         [Integer(0),Integer(1),Integer(2),Integer(3),Integer(5),Integer(7)], [Integer(0),Integer(1),Integer(2),Integer(3),Integer(6),Integer(8),Integer(9)]])
        >>> Z.homology()  # long time
        {0: 0,
         1: 0,
         2: 0,
         3: Z^9,
         4: Z^17,
         5: Z^12,
         6: Z x Z x Z,
         7: 0,
         8: 0,
         9: 0,
         10: 0,
         11: 0,
         12: 0,
         13: 0,
         14: 0,
         15: 0,
         16: 0,
         17: 0}
        >>> Z = MomentAngleComplex([[Integer(0),Integer(1),Integer(2),Integer(3)], [Integer(0),Integer(1),Integer(2),Integer(4)], [Integer(0),Integer(1),Integer(3),Integer(5)],
        ...                         [Integer(0),Integer(1),Integer(4),Integer(5)], [Integer(0),Integer(2),Integer(3),Integer(6)], [Integer(0),Integer(2),Integer(4),Integer(6)]])
        >>> Z.homology(dim=range(Integer(5)), reduced=True)
        {0: 0, 1: 0, 2: 0, 3: Z x Z x Z x Z, 4: Z x Z}
        >>> Z.homology(dim=range(Integer(5)), reduced=False)
        {0: Z, 1: 0, 2: 0, 3: Z x Z x Z x Z, 4: Z x Z}
        >>> all(Z.homology(i,reduced=True) == Z.homology(i,reduced=False)
        ...     for i in range(Integer(1), dim(Z)))
        True
        >>> all(Z.homology(i,reduced=True) == Z.homology(i,reduced=False)
        ...     for i in range(dim(Z)))
        False

  product(other)

    Return the product of `self` with `other`.

    It is known that the product of two moment-angle complexes is a moment-angle complex over the join of the two corresponding simplicial complexes. This result can be found on page 138 of [BP2014].

    OUTPUT: a moment-angle complex which is the product of the parsed moment-angle complexes

    EXAMPLES:

    Sage

        sage: X = SimplicialComplex([[0,1,2,3], [1,4], [3,2,4]])
        sage: Y = SimplicialComplex([[1,2,3],[1,2,4],[3,5],[4,5]])
        sage: Z = MomentAngleComplex(X)
        sage: M = MomentAngleComplex(Y)
        sage: Z.product(M)
        Moment-angle complex of Simplicial complex with
        10 vertices and 12 facets
        sage: Z.product(M) == MomentAngleComplex(X*Y)
        True

    Python

        >>> from sage.all import *
        >>> X = SimplicialComplex([[Integer(0),Integer(1),Integer(2),Integer(3)], [Integer(1),Integer(4)], [Integer(3),Integer(2),Integer(4)]])
        >>> Y = SimplicialComplex([[Integer(1),Integer(2),Integer(3)],[Integer(1),Integer(2),Integer(4)],[Integer(3),Integer(5)],[Integer(4),Integer(5)]])
        >>> Z = MomentAngleComplex(X)
        >>> M = MomentAngleComplex(Y)
        >>> Z.product(M)
        Moment-angle complex of Simplicial complex with
        10 vertices and 12 facets
        >>> Z.product(M) == MomentAngleComplex(X*Y)
        True

  simplicial_complex()

    Return the simplicial complex that defines `self`.

    EXAMPLES:

    Sage

        sage: RP2 = simplicial_complexes.RealProjectivePlane()
        sage: Z = MomentAngleComplex(RP2)
        sage: Z.simplicial_complex()
        Simplicial complex with vertex set (0, 1, 2, 3, 4, 5) and 10 facets
        sage: Z = MomentAngleComplex([[0], [1], [2]])
        sage: Z.simplicial_complex()
        Simplicial complex with vertex set (0, 1, 2)
        and facets {(0,), (1,), (2,)}

    Python

        >>> from sage.all import *
        >>> RP2 = simplicial_complexes.RealProjectivePlane()
        >>> Z = MomentAngleComplex(RP2)
        >>> Z.simplicial_complex()
        Simplicial complex with vertex set (0, 1, 2, 3, 4, 5) and 10 facets
        >>> Z = MomentAngleComplex([[Integer(0)], [Integer(1)], [Integer(2)]])
        >>> Z.simplicial_complex()
        Simplicial complex with vertex set (0, 1, 2)
        and facets {(0,), (1,), (2,)}