Beispiel #1
0
    def homology(self, n):
        r"""
        Return the ``n``'th homology group of the kenzo chain complex

        INPUT:

        - ``n`` -- the dimension in which compute the homology

        OUTOUT:

        - An homology group.

        EXAMPLES::

                sage: from sage.interfaces.kenzo import Sphere   # optional - kenzo
                sage: s2 = Sphere(2)                             # optional - kenzo
                sage: s2                                         # optional - kenzo
                [K1 Simplicial-Set]
                sage: s2.homology(2)                             # optional - kenzo
                Z
        """
        echcm1 = echcm(self._kenzo)
        m1 = chcm_mat(echcm1, n)
        m2 = chcm_mat(echcm1, n + 1)
        homology = homologie(m1, m2)
        lhomomology = [i for i in EclListIterator(homology)]
        res = []
        for component in lhomomology:
            pair = [i for i in EclListIterator(component)]
            res.append(pair[0].python())
        return HomologyGroup(len(res), ZZ, res)
Beispiel #2
0
    def homology(self,
                 dim=None,
                 base_ring=ZZ,
                 subcomplex=None,
                 generators=False,
                 cohomology=False,
                 algorithm='pari',
                 verbose=False,
                 reduced=True,
                 **kwds):
        r"""
        The (reduced) homology of this cell complex.

        :param dim: If None, then return the homology in every
           dimension.  If ``dim`` is an integer or list, return the
           homology in the given dimensions.  (Actually, if ``dim`` is
           a list, return the homology in the range from ``min(dim)``
           to ``max(dim)``.)
        :type dim: integer or list of integers or None; optional,
           default None
        :param base_ring: commutative ring, must be ZZ or a field.
        :type base_ring: optional, default ZZ
        :param subcomplex: a subcomplex of this simplicial complex.
           Compute homology relative to this subcomplex.
        :type subcomplex: optional, default empty
        :param generators: If ``True``, return generators for the homology
           groups along with the groups.  NOTE: Since :trac:`6100`, the result
           may not be what you expect when not using CHomP since its return
           is in terms of the chain complex.
        :type generators: boolean; optional, default False
        :param cohomology: If True, compute cohomology rather than homology.
        :type cohomology: boolean; optional, default False
        :param algorithm: The options are 'auto', 'dhsw', 'pari' or 'no_chomp'.
           See below for a description of what they mean.
        :type algorithm: string; optional, default 'pari'
        :param verbose: If True, print some messages as the homology is
           computed.
        :type verbose: boolean; optional, default False
        :param reduced: If ``True``, return the reduced homology.
        :type reduced: boolean; optional, default ``True``

        ALGORITHM:

        If ``algorithm`` is set to 'auto', then use
        CHomP if available.  (CHomP is available at the web page
        http://chomp.rutgers.edu/.  It is also an optional package
        for Sage.)

        CHomP computes homology, not cohomology, and only works over
        the integers or finite prime fields.  Therefore if any of
        these conditions fails, or if CHomP is not present, or if
        ``algorithm`` is set to 'no_chomp', go to plan B: if this complex
        has a ``_homology`` method -- each simplicial complex has
        this, for example -- then call that.  Such a method implements
        specialized algorithms for the particular type of cell
        complex.

        Otherwise, move on to plan C: compute the chain complex of
        this complex and compute its homology groups.  To do this: over a
        field, just compute ranks and nullities, thus obtaining
        dimensions of the homology groups as vector spaces.  Over the
        integers, compute Smith normal form of the boundary matrices
        defining the chain complex according to the value of
        ``algorithm``.  If ``algorithm`` is 'auto' or 'no_chomp', then
        for each relatively small matrix, use the standard Sage
        method, which calls the Pari package.  For any large matrix,
        reduce it using the Dumas, Heckenbach, Saunders, and Welker
        elimination algorithm: see
        :func:`sage.homology.matrix_utils.dhsw_snf` for details.

        Finally, ``algorithm`` may also be 'pari' or 'dhsw', which
        forces the named algorithm to be used regardless of the size
        of the matrices and regardless of whether CHomP is available.

        As of this writing, ``'pari'`` is the fastest standard option.
        The optional CHomP package may be better still.

        EXAMPLES::

            sage: P = delta_complexes.RealProjectivePlane()
            sage: P.homology()
            {0: 0, 1: C2, 2: 0}
            sage: P.homology(reduced=False)
            {0: Z, 1: C2, 2: 0}
            sage: P.homology(base_ring=GF(2))
            {0: Vector space of dimension 0 over Finite Field of size 2,
             1: Vector space of dimension 1 over Finite Field of size 2,
             2: Vector space of dimension 1 over Finite Field of size 2}
            sage: S7 = delta_complexes.Sphere(7)
            sage: S7.homology(7)
            Z
            sage: cubical_complexes.KleinBottle().homology(1, base_ring=GF(2))
            Vector space of dimension 2 over Finite Field of size 2

        If CHomP is installed, Sage can compute generators of homology
        groups::

            sage: S2 = simplicial_complexes.Sphere(2)
            sage: S2.homology(dim=2, generators=True, base_ring=GF(2))  # optional - CHomP
            (Vector space of dimension 1 over Finite Field of size 2, [(0, 1, 2) + (0, 1, 3) + (0, 2, 3) + (1, 2, 3)])

        When generators are computed, Sage returns a pair for each
        dimension: the group and the list of generators.  For
        simplicial complexes, each generator is represented as a
        linear combination of simplices, as above, and for cubical
        complexes, each generator is a linear combination of cubes::

            sage: S2_cub = cubical_complexes.Sphere(2)
            sage: S2_cub.homology(dim=2, generators=True)  # optional - CHomP
            (Z, [-[[0,1] x [0,1] x [0,0]] + [[0,1] x [0,1] x [1,1]] - [[0,0] x [0,1] x [0,1]] - [[0,1] x [1,1] x [0,1]] + [[0,1] x [0,0] x [0,1]] + [[1,1] x [0,1] x [0,1]]])
        """
        from sage.interfaces.chomp import have_chomp, homcubes, homsimpl
        from sage.homology.cubical_complex import CubicalComplex
        from sage.homology.simplicial_complex import SimplicialComplex
        from sage.modules.all import VectorSpace
        from sage.homology.homology_group import HomologyGroup

        if dim is not None:
            if isinstance(dim, (list, tuple, range)):
                low = min(dim) - 1
                high = max(dim) + 2
            else:
                low = dim - 1
                high = dim + 2
            dims = range(low, high)
        else:
            dims = None

        # try to use CHomP if computing homology (not cohomology) and
        # working over Z or F_p, p a prime.
        if (algorithm == 'auto' and cohomology is False
                and (base_ring == ZZ or
                     (base_ring.is_prime_field() and base_ring != QQ))):
            # homcubes, homsimpl seems fastest if all of homology is computed.
            H = None
            if isinstance(self, CubicalComplex):
                if have_chomp('homcubes'):
                    H = homcubes(self,
                                 subcomplex,
                                 base_ring=base_ring,
                                 verbose=verbose,
                                 generators=generators)
            elif isinstance(self, SimplicialComplex):
                if have_chomp('homsimpl'):
                    H = homsimpl(self,
                                 subcomplex,
                                 base_ring=base_ring,
                                 verbose=verbose,
                                 generators=generators)

            # now pick off the requested dimensions
            if H:
                answer = {}
                if not dims:
                    dims = range(self.dimension() + 1)
                for d in dims:
                    answer[d] = H.get(d, HomologyGroup(0, base_ring))
                if dim is not None:
                    if not isinstance(dim, (list, tuple, range)):
                        answer = answer.get(dim, HomologyGroup(0, base_ring))
                return answer

        # Derived classes can implement specialized algorithms using a
        # _homology_ method.  See SimplicialComplex for one example.
        # Those may allow for other arguments, so we pass **kwds.
        if hasattr(self, '_homology_'):
            return self._homology_(dim,
                                   subcomplex=subcomplex,
                                   cohomology=cohomology,
                                   base_ring=base_ring,
                                   verbose=verbose,
                                   algorithm=algorithm,
                                   reduced=reduced,
                                   **kwds)

        C = self.chain_complex(cochain=cohomology,
                               augmented=reduced,
                               dimensions=dims,
                               subcomplex=subcomplex,
                               base_ring=base_ring,
                               verbose=verbose)
        answer = C.homology(base_ring=base_ring,
                            generators=generators,
                            verbose=verbose,
                            algorithm=algorithm)
        if dim is None:
            dim = range(self.dimension() + 1)
        zero = HomologyGroup(0, base_ring)
        if isinstance(dim, (list, tuple, range)):
            return dict([d, answer.get(d, zero)] for d in dim)
        return answer.get(dim, zero)