Ticket #6099: 6099-2.patch

File 6099-2.patch, 29.7 KB (added by bantieau, 10 years ago)
  • sage/categories/category_types.py

    # HG changeset patch
    # User Benjamin Antieau <antieau@math.uic.edu>
    # Date 1245132753 25200
    # Node ID efea4b77a992f954989491b42823261d4885acd7
    # Parent  5e63080e334f90780fdc0ed2f10e139e8dc09d20
    Second patch for trac #6099; implemented chain complex morphisms.
    
    diff -r 5e63080e334f -r efea4b77a992 sage/categories/category_types.py
    a b  
    13051305    GroupAlgebras          : [MonoidAlgebras, Algebras, Sets],\
    13061306    MatrixAlgebras         : [Algebras, Sets],\
    13071307    RingModules            : [AbelianGroups, Sets],\
     1308    ChainComplexes         : [],\
    13081309    FreeModules            : [RingModules, AbelianGroups, Sets],\
    13091310    VectorSpaces           : [FreeModules, RingModules, AbelianGroups, Sets],\
    13101311    HeckeModules           : [FreeModules, RingModules, AbelianGroups, Sets],\
  • sage/categories/homset.py

    diff -r 5e63080e334f -r efea4b77a992 sage/categories/homset.py
    a b  
    159159        from sage.homology.simplicial_complex_homset import SimplicialComplexHomset
    160160        H = SimplicialComplexHomset(X,Y)
    161161
     162    elif cat._is_subclass(category_types.ChainComplexes):
     163
     164        from sage.homology.chain_complex_homspace import ChainComplexHomspace
     165        H = ChainComplexHomspace(X,Y)
     166
    162167    else:  # default
    163168        if hasattr(X, '_base') and X._base is not X and X._base is not None:
    164169            H = HomsetWithBase(X, Y, cat)
  • sage/homology/all.py

    diff -r 5e63080e334f -r efea4b77a992 sage/homology/all.py
    a b  
    11from chain_complex import ChainComplex
    22
     3from chain_complex_morphism import ChainComplexMorphism
     4
    35from simplicial_complex import SimplicialComplex
    46
    57from simplicial_complex_morphism import SimplicialComplexMorphism
  • sage/homology/chain_complex.py

    diff -r 5e63080e334f -r efea4b77a992 sage/homology/chain_complex.py
    a b  
    338338    EXAMPLES::
    339339
    340340        sage: ChainComplex()
    341         Chain complex with at most 0 nonzero terms over Integer Ring.
     341        Chain complex with at most 0 nonzero terms over Integer Ring
    342342        sage: C = ChainComplex({0: matrix(ZZ, 2, 3, [3, 0, 0, 0, 0, 0])})
    343343        sage: C
    344         Chain complex with at most 2 nonzero terms over Integer Ring.
     344        Chain complex with at most 2 nonzero terms over Integer Ring
    345345        sage: D = ChainComplex([matrix(ZZ, 2, 2, [0, 1, 0, 0]), matrix(ZZ, 2, 2, [0, 1, 0, 0])], base_ring=GF(2)); D
    346         Chain complex with at most 3 nonzero terms over Finite Field of size 2.
     346        Chain complex with at most 3 nonzero terms over Finite Field of size 2
    347347        sage: D == loads(dumps(D))
    348348        True
    349349
     
    361361    Defining the base ring implicitly::
    362362
    363363        sage: ChainComplex([matrix(QQ, 3, 1), matrix(ZZ, 4, 3)])
    364         Chain complex with at most 2 nonzero terms over Rational Field.
     364        Chain complex with at most 2 nonzero terms over Rational Field
    365365        sage: ChainComplex([matrix(GF(125, 'a'), 3, 1), matrix(ZZ, 4, 3)])
    366         Chain complex with at most 2 nonzero terms over Finite Field in a of size 5^3.
     366        Chain complex with at most 2 nonzero terms over Finite Field in a of size 5^3
    367367
    368368    If the matrices are defined over incompatible rings, an error results::
    369369
     
    389389        EXAMPLES::
    390390
    391391            sage: C = ChainComplex(); C
    392             Chain complex with at most 0 nonzero terms over Integer Ring.
     392            Chain complex with at most 0 nonzero terms over Integer Ring
    393393            sage: D = ChainComplex({0: matrix(ZZ, 2, 3, [3, 0, 0, 0, 0, 0])})
    394394            sage: D
    395             Chain complex with at most 2 nonzero terms over Integer Ring.
     395            Chain complex with at most 2 nonzero terms over Integer Ring
    396396        """
    397397        try:
    398398            deg = grading_group(degree)
     
    882882
    883883            sage: C = ChainComplex({0: matrix(ZZ, 2, 3, [3, 0, 0, 0, 0, 0])})
    884884            sage: C._repr_()
    885             'Chain complex with at most 2 nonzero terms over Integer Ring.'
     885            'Chain complex with at most 2 nonzero terms over Integer Ring'
    886886        """
    887887        diffs = filter(lambda mat: mat.nrows() + mat.ncols() > 0,
    888888                       self._diff.values())
    889889        string1 = "Chain complex with at most"
    890         string2 = " %s nonzero terms over %s." % (len(diffs),
     890        string2 = " %s nonzero terms over %s" % (len(diffs),
    891891                                                  self._base_ring)
    892892        return string1 + string2
    893893
  • new file sage/homology/chain_complex_homspace.py

    diff -r 5e63080e334f -r efea4b77a992 sage/homology/chain_complex_homspace.py
    - +  
     1r"""
     2Homspaces between chain complexes
     3
     4Note that some significant functionality is lacking. Namely, the homspaces
     5are not actually modules over the base ring. It will be necessary to
     6enrich some of the structure of chain complexes for this to be naturally
     7available. On other hand, there are various overloaded operators. __mul__
     8acts as composition. one can __add__, and one can __mul__ with a ring element
     9on the right.
     10
     11EXAMPLES::
     12
     13    sage: S = simplicial_complexes.Sphere(2)
     14    sage: T = simplicial_complexes.Torus()
     15    sage: C = S.chain_complex(augmented=True,cochain=True)
     16    sage: D = T.chain_complex(augmented=True,cochain=True)
     17    sage: G = Hom(C,D)
     18    sage: G
     19    Set of Morphisms from Chain complex with at most 4 nonzero terms over Integer Ring to Chain complex with at most 4 nonzero terms over Integer Ring in Category of chain complexes over Integer Ring
     20
     21    sage: S = simplicial_complexes.ChessboardComplex(3,3)
     22    sage: H = Hom(S,S)
     23    sage: i = H.identity()
     24    sage: x = i.associated_chain_complex_morphism(augmented=True)
     25    sage: x
     26    Chain complex morphism from Chain complex with at most 4 nonzero terms over Integer Ring to Chain complex with at most 4 nonzero terms over Integer Ring
     27    sage: x._mat
     28    x._mathematica_       x._mathematica_init_  x._matrix_dictionary 
     29    sage: x._matrix_dictionary
     30
     31    {-1: [1],
     32     0: [1 0 0 0 0 0 0 0 0]
     33    [0 1 0 0 0 0 0 0 0]
     34    [0 0 1 0 0 0 0 0 0]
     35    [0 0 0 1 0 0 0 0 0]
     36    [0 0 0 0 1 0 0 0 0]
     37    [0 0 0 0 0 1 0 0 0]
     38    [0 0 0 0 0 0 1 0 0]
     39    [0 0 0 0 0 0 0 1 0]
     40    [0 0 0 0 0 0 0 0 1],
     41     1: [1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
     42    [0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
     43    [0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
     44    [0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
     45    [0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0]
     46    [0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0]
     47    [0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0]
     48    [0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0]
     49    [0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0]
     50    [0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0]
     51    [0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0]
     52    [0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0]
     53    [0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0]
     54    [0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0]
     55    [0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0]
     56    [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0]
     57    [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0]
     58    [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1],
     59     2: [1 0 0 0 0 0]
     60
     61    sage: S = simplicial_complexes.Sphere(2)
     62    sage: A = Hom(S,S)
     63    sage: i = A.identity()
     64    sage: x = i.associated_chain_complex_morphism()
     65    sage: x
     66    Chain complex morphism from Chain complex with at most 3 nonzero terms over Integer Ring to Chain complex with at most 3 nonzero terms over Integer Ring
     67    sage: y = x*4
     68    sage: z = y*y
     69    sage: (y+z)
     70    Chain complex morphism from Chain complex with at most 3 nonzero terms over Integer Ring to Chain complex with at most 3 nonzero terms over Integer Ring
     71    sage: f = x._matrix_dictionary
     72    sage: C = S.chain_complex()
     73    sage: G = Hom(C,C)
     74    sage: w = G(f)
     75    sage: w==x
     76    True
     77
     78"""
     79
     80#*****************************************************************************
     81# Copyright (C) 2009 D. Benjamin Antieau <d.ben.antieau@gmail.com>
     82#
     83#  Distributed under the terms of the GNU General Public License (GPL)
     84#
     85#    This code is distributed in the hope that it will be useful,
     86#    but WITHOUT ANY WARRANTY; without even the implied warranty
     87#    of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
     88#
     89#  See the GNU General Public License for more details; the full text
     90#  is available at:
     91#
     92#                  http://www.gnu.org/licenses/
     93#
     94#*****************************************************************************
     95
     96import sage.categories.homset
     97import sage.homology.chain_complex as chain_complex
     98import sage.homology.chain_complex_morphism as chain_complex_morphism
     99
     100def is_ChainComplexHomset(x):
     101    """
     102    Returns True if and only if x is a morphism of chain complexes.
     103    """
     104    return isinstance(x,ChainComplexHomset)
     105
     106class ChainComplexHomspace(sage.categories.homset.Homset):
     107    """
     108    Class of homspaces of chain complex morphisms.
     109   
     110    EXAMPLES::
     111
     112        sage: T = SimplicialComplex(17,[[1,2,3,4],[7,8,9]])
     113        sage: C = T.chain_complex(augmented=True,cochain=True)
     114        sage: G = Hom(C,C)
     115        sage: G
     116        Set of Morphisms from Chain complex with at most 5 nonzero terms over Integer Ring to Chain complex with at most 5 nonzero terms over Integer Ring in Category of chain complexes over Integer Ring
     117
     118    """
     119    def __call__(self, f):
     120        """
     121        f is a dictionary of matrices in the basis of the chain complex.
     122
     123        EXAMPLES::
     124
     125            sage: S = simplicial_complexes.Sphere(5)
     126            sage: H = Hom(S,S)
     127            sage: i = H.identity()
     128            sage: C = S.chain_complex()
     129            sage: G = Hom(C,C)
     130            sage: x = i.associated_chain_complex_morphism()
     131            sage: f = x._matrix_dictionary
     132            sage: y = G(f)
     133            sage: x==y
     134            True
     135
     136        """
     137        return chain_complex_morphism.ChainComplexMorphism(f, self.domain(), self.codomain())
  • new file sage/homology/chain_complex_morphism.py

    diff -r 5e63080e334f -r efea4b77a992 sage/homology/chain_complex_morphism.py
    - +  
     1r"""
     2Morphisms of chain complexes
     3
     4AUTHORS:
     5
     6- D. Benjamin Antieau <d.ben.antieau@gmail.com> (2009.06)
     7
     8This module implements morphisms of simplicial complexes. The input is a dictionary whose
     9keys are in the grading group of the chain complex and whose values are matrix morphisms.
     10
     11EXAMPLES::
     12
     13    from sage.matrix.constructor import zero_matrix
     14    sage: S
     15    Simplicial complex with vertex set (0, 1, 2) and facets {(1, 2), (0, 2), (0, 1)}
     16    sage: C = S.chain_complex()
     17    sage: C.differential()
     18    {0: [], 1: [ 1  1  0]
     19    [ 0 -1 -1]
     20    [-1  0  1]}
     21    sage: f = {0:zero_matrix(ZZ,3,3),1:zero_matrix(ZZ,3,3)}
     22    sage: G = Hom(C,C)
     23    sage: x = G(f)
     24    sage: x
     25    Chain complex morphism from Chain complex with at most 2 nonzero terms over Integer Ring to Chain complex with at most 2 nonzero terms over Integer Ring
     26    sage: x._matrix_dictionary
     27    {0: [0 0 0]
     28    [0 0 0]
     29    [0 0 0], 1: [0 0 0]
     30    [0 0 0]
     31    [0 0 0]}
     32
     33"""
     34
     35#*****************************************************************************
     36# Copyright (C) 2009 D. Benjamin Antieau <d.ben.antieau@gmail.com>
     37#
     38#  Distributed under the terms of the GNU General Public License (GPL)
     39#
     40#    This code is distributed in the hope that it will be useful,
     41#    but WITHOUT ANY WARRANTY; without even the implied warranty
     42#    of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
     43#
     44#  See the GNU General Public License for more details; the full text
     45#  is available at:
     46#
     47#                  http://www.gnu.org/licenses/
     48#
     49#*****************************************************************************
     50
     51import sage.homology.simplicial_complex as simplicial_complex
     52import sage.matrix.all as matrix
     53import sage.categories.category_types as category_types
     54from sage.rings.integer_ring import ZZ
     55
     56def is_ChainComplexMorphism(x):
     57    """
     58    Returns True if and only if x is a chain complex morphism.
     59
     60    EXAMPLES::
     61
     62        sage: S = simplicial_complexes.Sphere(14)
     63        sage: H = Hom(S,S)
     64        sage: i = H.identity()
     65        sage: S = simplicial_complexes.Sphere(6)
     66        sage: H = Hom(S,S)
     67        sage: i = H.identity()
     68        sage: x = i.associated_chain_complex_morphism()
     69        sage: from sage.homology.chain_complex_morphism import is_ChainComplexMorphism
     70        sage: is_ChainComplexMorphism(x)
     71        True
     72
     73    """
     74    return isinstance(x,ChainComplexMorphism)
     75
     76class ChainComplexMorphism(category_types.SageObject):
     77    """
     78    An element of this class is a morphism of chain complexes.
     79    """
     80    def __init__(self,matrices,C,D):
     81        """
     82        Create a morphism from a dictionary of matrices.
     83
     84        EXAMPLES::
     85
     86            from sage.matrix.constructor import zero_matrix
     87            sage: S
     88            Simplicial complex with vertex set (0, 1, 2) and facets {(1, 2), (0, 2), (0, 1)}
     89            sage: C = S.chain_complex()
     90            sage: C.differential()
     91            {0: [], 1: [ 1  1  0]
     92            [ 0 -1 -1]
     93            [-1  0  1]}
     94            sage: f = {0:zero_matrix(ZZ,3,3),1:zero_matrix(ZZ,3,3)}
     95            sage: G = Hom(C,C)
     96            sage: x = G(f)
     97            sage: x
     98            Chain complex morphism from Chain complex with at most 2 nonzero terms over Integer Ring to Chain complex with at most 2 nonzero terms over Integer Ring
     99            sage: x._matrix_dictionary
     100            {0: [0 0 0]
     101            [0 0 0]
     102            [0 0 0], 1: [0 0 0]
     103            [0 0 0]
     104            [0 0 0]}
     105
     106        """
     107        if C._grading_group != ZZ:
     108            raise NotImplementedError, "Chain complex morphisms are not implemented over gradings other than ZZ."
     109        d = C._degree
     110        if d != D._degree:
     111            raise ValueError, "Chain complex morphisms are not defined for chain complexes of different degrees."
     112        if d != -1 and d != 1:
     113            raise NotImplementedError, "Chain complex morphisms are not implemented for degrees besides -1 and 1."
     114        dim_min = min(min(C.differential().keys()),min(D.differential().keys()))
     115        dim_max = max(max(C.differential().keys()),max(D.differential().keys()))
     116        if not C.base_ring()==D.base_ring():
     117            raise NotImplementedError, "Chain complex morphisms between chain complexes of different base rings are not implemented."
     118        for i in range(dim_min,dim_max):
     119            try:
     120                matrices[i]
     121            except KeyError:
     122                matrices[i] = matrix.zero_matrix(C.base_ring(),D.differential()[i].ncols(),C.differential()[i].ncols(),sparse=True)
     123            try:
     124                matrices[i+1]
     125            except KeyError:
     126                matrices[i+1] = matrix.zero_matrix(C.base_ring(),D.differential()[i+1].ncols(),C.differential()[i+1].ncols(),sparse=True)
     127            if d==-1:
     128                if (i+1) in C.differential().keys() and (i+1) in D.differential().keys():
     129                    if not matrices[i]*C.differential()[i+1]==D.differential()[i+1]*matrices[i+1]:
     130                        raise ValueError, "Matrices must define a chain complex morphism."
     131                elif (i+1) in C.differential().keys():
     132                    if not matrices[i]*C.differential()[i+1].is_zero():
     133                        raise ValueError, "Matrices must define a chain complex morphism."
     134                elif (i+1) in D.differential().keys():
     135                    if not D.differential()[i+1]*matrices[i+1].is_zero():
     136                        raise ValueError, "Matrices must define a chain complex morphism."
     137            else:
     138                if i in C.differential().keys() and i in D.differential().keys():
     139                    if not matrices[i+1]*C.differential()[i]==D.differential()[i]*matrices[i]:
     140                        raise ValueError, "Matrices must define a chain complex morphism."
     141                elif i in C.differential().keys():
     142                    if not matrices[i+1]*C.differential()[i].is_zero():
     143                        raise ValueError, "Matrices must define a chain complex morphism."
     144                elif i in D.differential().keys():
     145                    if not D.differential()[i]*matrices[i].is_zero():
     146                        raise ValueError, "Matrices must define a chain complex morphism."
     147        self._matrix_dictionary = matrices
     148        self._domain = C
     149        self._codomain = D
     150 
     151    def __neg__(self):
     152        """
     153        Returns -x.
     154
     155        EXAMPLES::
     156
     157            sage: S = simplicial_complexes.Sphere(2)
     158            sage: H = Hom(S,S)
     159            sage: i = H.identity()
     160            sage: x = i.associated_chain_complex_morphism()
     161            sage: w = -x
     162            sage: w._matrix_dictionary
     163            {0: [-1  0  0  0]
     164            [ 0 -1  0  0]
     165            [ 0  0 -1  0]
     166            [ 0  0  0 -1],
     167             1: [-1  0  0  0  0  0]
     168            [ 0 -1  0  0  0  0]
     169            [ 0  0 -1  0  0  0]
     170            [ 0  0  0 -1  0  0]
     171            [ 0  0  0  0 -1  0]
     172            [ 0  0  0  0  0 -1],
     173             2: [-1  0  0  0]
     174            [ 0 -1  0  0]
     175            [ 0  0 -1  0]
     176            [ 0  0  0 -1]}
     177       
     178        """
     179        f = dict()
     180        for i in self._matrix_dictionary.keys():
     181            f[i] = -self._matrix_dictionary[i]
     182        return ChainComplexMorphism(f,self._domain,self._codomain)
     183
     184    def __add__(self,x):
     185        """
     186        Returns self+x.
     187
     188        EXAMPLES::
     189
     190            sage: S = simplicial_complexes.Sphere(2)
     191            sage: H = Hom(S,S)
     192            sage: i = H.identity()
     193            sage: x = i.associated_chain_complex_morphism()
     194            sage: z = x+x
     195            sage: z._matrix_dictionary
     196            {0: [2 0 0 0]
     197            [0 2 0 0]
     198            [0 0 2 0]
     199            [0 0 0 2],
     200             1: [2 0 0 0 0 0]
     201            [0 2 0 0 0 0]
     202            [0 0 2 0 0 0]
     203            [0 0 0 2 0 0]
     204            [0 0 0 0 2 0]
     205            [0 0 0 0 0 2],
     206             2: [2 0 0 0]
     207            [0 2 0 0]
     208            [0 0 2 0]
     209            [0 0 0 2]}
     210
     211        """
     212        if not isinstance(x,ChainComplexMorphism) or self._codomain != x._codomain or self._domain != x._domain or self._matrix_dictionary.keys() != x._matrix_dictionary.keys():
     213            raise TypeError, "Unsupported operation."
     214        f = dict()
     215        for i in self._matrix_dictionary.keys():
     216            f[i] = self._matrix_dictionary[i] + x._matrix_dictionary[i]
     217        return ChainComplexMorphism(f,self._domain,self._codomain)
     218
     219    def __mul__(self,x):
     220        """
     221        Returns self*x if self and x are composable morphisms or if x is an element of the base_ring.
     222
     223        EXAMPLES::
     224            sage: S = simplicial_complexes.Sphere(2)
     225            sage: H = Hom(S,S)
     226            sage: i = H.identity()
     227            sage: x = i.associated_chain_complex_morphism()
     228            sage: y = x*2
     229            sage: y._matrix_dictionary
     230            {0: [2 0 0 0]
     231            [0 2 0 0]
     232            [0 0 2 0]
     233            [0 0 0 2],
     234             1: [2 0 0 0 0 0]
     235            [0 2 0 0 0 0]
     236            [0 0 2 0 0 0]
     237            [0 0 0 2 0 0]
     238            [0 0 0 0 2 0]
     239            [0 0 0 0 0 2],
     240             2: [2 0 0 0]
     241            [0 2 0 0]
     242            [0 0 2 0]
     243            [0 0 0 2]}
     244            sage: z = y*y
     245            sage: z._matrix_dictionary
     246            {0: [4 0 0 0]
     247            [0 4 0 0]
     248            [0 0 4 0]
     249            [0 0 0 4],
     250             1: [4 0 0 0 0 0]
     251            [0 4 0 0 0 0]
     252            [0 0 4 0 0 0]
     253            [0 0 0 4 0 0]
     254            [0 0 0 0 4 0]
     255            [0 0 0 0 0 4],
     256             2: [4 0 0 0]
     257            [0 4 0 0]
     258            [0 0 4 0]
     259            [0 0 0 4]}
     260
     261        """
     262        if not isinstance(x,ChainComplexMorphism) or self._codomain != x._domain:
     263            try:
     264                y = self._domain.base_ring()(x)
     265            except TypeError:
     266                raise TypeError, "Multiplication is not defined."
     267            f = dict()
     268            for i in self._matrix_dictionary.keys():
     269                f[i] = y * self._matrix_dictionary[i]
     270            return ChainComplexMorphism(f,self._domain,self._codomain)
     271        f = dict()
     272        for i in self._matrix_dictionary.keys():
     273            f[i] = x._matrix_dictionary[i]*self._matrix_dictionary[i]
     274        return ChainComplexMorphism(f,self._domain,x._codomain)
     275
     276    def __sub__(self,x):
     277        """
     278        Returns self-x.
     279
     280        EXAMPLES::
     281
     282            sage: S = simplicial_complexes.Sphere(2)
     283            sage: H = Hom(S,S)
     284            sage: i = H.identity()
     285            sage: x = i.associated_chain_complex_morphism()
     286            sage: y = x-x
     287            sage: y._matrix_dictionary
     288            {0: [0 0 0 0]
     289            [0 0 0 0]
     290            [0 0 0 0]
     291            [0 0 0 0],
     292             1: [0 0 0 0 0 0]
     293            [0 0 0 0 0 0]
     294            [0 0 0 0 0 0]
     295            [0 0 0 0 0 0]
     296            [0 0 0 0 0 0]
     297            [0 0 0 0 0 0],
     298             2: [0 0 0 0]
     299            [0 0 0 0]
     300            [0 0 0 0]
     301            [0 0 0 0]}
     302
     303        """   
     304        return self + (-x)
     305
     306    def __eq__(self,x):
     307        """
     308        Returns True if and only if self==x.
     309
     310        EXAMPLES::
     311
     312            sage: S = SimplicialComplex(3)
     313            sage: H = Hom(S,S)
     314            sage: i = H.identity()
     315            sage: x = i.associated_chain_complex_morphism()
     316            sage: x
     317            Chain complex morphism from Chain complex with at most 0 nonzero terms over Integer Ring to Chain complex with at most 0 nonzero terms over Integer Ring
     318            sage: f = x._matrix_dictionary
     319            sage: C = S.chain_complex()
     320            sage: G = Hom(C,C)
     321            sage: y = G(f)
     322            sage: x==y
     323            True
     324
     325        """
     326        if not isinstance(x,ChainComplexMorphism) or self._codomain != x._codomain or self._domain != x._domain or self._matrix_dictionary != x._matrix_dictionary:
     327            return False
     328        else:
     329            return True
     330
     331    def _repr_(self):
     332        """
     333        Returns the string representation of self.
     334
     335        EXAMPLES::
     336
     337            sage: S = SimplicialComplex(3)
     338            sage: H = Hom(S,S)
     339            sage: i = H.identity()
     340            sage: x = i.associated_chain_complex_morphism()
     341            sage: x
     342            Chain complex morphism from Chain complex with at most 0 nonzero terms over Integer Ring to Chain complex with at most 0 nonzero terms over Integer Ring
     343        """
     344        return "Chain complex morphism from " + self._domain._repr_() + " to " + self._codomain._repr_()
  • sage/homology/simplicial_complex_morphism.py

    diff -r 5e63080e334f -r efea4b77a992 sage/homology/simplicial_complex_morphism.py
    a b  
    9292import sage.homology.simplicial_complex as simplicial_complex
    9393import sage.matrix.all as matrix
    9494import sage.categories.category_types as category_types
     95from sage.rings.integer_ring import ZZ
     96from sage.homology.chain_complex_morphism import ChainComplexMorphism
    9597
    9698def is_SimplicialComplexMorphism(x):
    9799    return isinstance(x,SimplicialComplexMorphism)
     
    221223        """
    222224        return "Simplicial complex morphism " + str(self._vertex_dictionary) + " from " + self._domain._repr_() + " to " + self._codomain._repr_()
    223225
    224 #    This is going to be implemented in the near future.
    225 #
    226 #    def associated_chain_complex_morphism(self,base_ring=ZZ,augmented=False,cochain=False):
    227 #        max_dim = max(self._domain.dimension(),self._codomain.dimension())
    228 #        min_dim = min(self._domain.dimension(),self._codomain.dimension())
    229 #        matrices={}
    230 #        if augmented is True:
    231 #            m=matrix.Matrix(base_ring,1,1,1)
    232 #            if not cochain:
    233 #                matrices[-1] = m
    234 #            else:
    235 #                matrices[-1] = m.transpose()
    236 #        for dim in range(min_dim+1):
    237 #            X_faces = list(self._domain.faces()[dim])
    238 #            Y_faces = list(self._codomain.faces()[dim])
    239 #            num_faces_X = len(X_faces)
    240 #            num_faces_Y = len(Y_faces)
    241 #            mval = [0 for i in range(num_faces_X*num_faces_Y)]
    242 #            for i in X_faces:
    243 #                y=self(i)
    244 #                if y.dimension() < dim:
    245 #                    pass
    246 #                else:
    247 #                    mval[X_faces.index(i)+(Y_faces.index(y)*num_faces_X)] = 1
    248 #            m = matrix.Matrix(base_ring,num_faces_Y,num_faces_X,mval,sparse=True)
    249 #            if not cochain:
    250 #                matrices[dim] = m
    251 #            else:
    252 #                matrices[dim] = m.transpose()
    253 #        for dim in range(min_dim+1,max_dim+1):
    254 #            m = zero_matrix(base_ring,len(self._codomain.faces()[dim]),len(self._domain.faces()[dim]),sparse=True)
    255 #            if not cochain:
    256 #                matrices[dim] = m
    257 #            else:
    258 #                matrices[dim] = m.transpose()
    259 #        if not cochain:
    260 #            return ChainComplexMorphism(matrices,self._domain.chain_complex(base_ring=base_ring,augmented=augmented,cochain=cochain),self._codomain.chain_complex(base_ring=base_ring,augmented=augmented,cochain=cochain))
    261 #        else:
    262 #            return ChainComplexMorphism(matrices,self._codomain.chain_complex(base_ring=base_ring,augmented=augmented,cochain=cochain),self._domain.chain_complex(base_ring=base_ring,augmented=augmented,cochain=cochain))
     226    def associated_chain_complex_morphism(self,base_ring=ZZ,augmented=False,cochain=False):
     227        """
     228        Returns the associated chain complex morphism of self.
     229
     230        EXAMPLES::
     231
     232            sage: S = simplicial_complexes.Sphere(1)
     233            sage: T = simplicial_complexes.Sphere(2)
     234            sage: H = Hom(S,T)
     235            sage: f = {0:0,1:1,2:2}
     236            sage: x = H(f)
     237            sage: x
     238            Simplicial complex morphism {0: 0, 1: 1, 2: 2} from Simplicial complex with vertex set (0, 1, 2) and facets {(1, 2), (0, 2), (0, 1)} to Simplicial complex with vertex set (0, 1, 2, 3) and facets {(0, 2, 3), (0, 1, 2), (1, 2, 3), (0, 1, 3)}
     239            sage: a = x.associated_chain_complex_morphism()
     240            sage: a
     241            Chain complex morphism from Chain complex with at most 2 nonzero terms over Integer Ring to Chain complex with at most 3 nonzero terms over Integer Ring
     242            sage: a._matrix_dictionary
     243            {0: [0 0 0]
     244            [0 1 0]
     245            [0 0 1]
     246            [1 0 0],
     247             1: [0 0 0]
     248            [0 1 0]
     249            [0 0 0]
     250            [1 0 0]
     251            [0 0 0]
     252            [0 0 1],
     253             2: []}
     254            sage: x.associated_chain_complex_morphism(augmented=True)
     255            Chain complex morphism from Chain complex with at most 3 nonzero terms over Integer Ring to Chain complex with at most 4 nonzero terms over Integer Ring
     256            sage: x.associated_chain_complex_morphism(cochain=True)
     257            Chain complex morphism from Chain complex with at most 3 nonzero terms over Integer Ring to Chain complex with at most 2 nonzero terms over Integer Ring
     258            sage: x.associated_chain_complex_morphism(augmented=True,cochain=True)
     259            Chain complex morphism from Chain complex with at most 4 nonzero terms over Integer Ring to Chain complex with at most 3 nonzero terms over Integer Ring
     260            sage: x.associated_chain_complex_morphism(base_ring=GF(11))
     261            Chain complex morphism from Chain complex with at most 2 nonzero terms over Finite Field of size 11 to Chain complex with at most 3 nonzero terms over Finite Field of size 11
     262
     263        """
     264        max_dim = max(self._domain.dimension(),self._codomain.dimension())
     265        min_dim = min(self._domain.dimension(),self._codomain.dimension())
     266        matrices = {}
     267        if augmented is True:
     268            m = matrix.Matrix(base_ring,1,1,1)
     269            if not cochain:
     270                matrices[-1] = m
     271            else:
     272                matrices[-1] = m.transpose()
     273        for dim in range(min_dim+1):
     274            X_faces = list(self._domain.faces()[dim])
     275            Y_faces = list(self._codomain.faces()[dim])
     276            num_faces_X = len(X_faces)
     277            num_faces_Y = len(Y_faces)
     278            mval = [0 for i in range(num_faces_X*num_faces_Y)]
     279            for i in X_faces:
     280                y = self(i)
     281                if y.dimension() < dim:
     282                    pass
     283                else:
     284                    mval[X_faces.index(i)+(Y_faces.index(y)*num_faces_X)] = 1
     285            m = matrix.Matrix(base_ring,num_faces_Y,num_faces_X,mval,sparse=True)
     286            if not cochain:
     287                matrices[dim] = m
     288            else:
     289                matrices[dim] = m.transpose()
     290        for dim in range(min_dim+1,max_dim+1):
     291            try:
     292                l1 = len(self._codomain.faces()[dim])
     293            except KeyError:
     294                l1 = 0
     295            try:
     296                l2 = len(self._domain.faces()[dim])
     297            except KeyError:
     298                l2 = 0
     299            m = matrix.zero_matrix(base_ring,l1,l2,sparse=True)
     300            if not cochain:
     301                matrices[dim] = m
     302            else:
     303                matrices[dim] = m.transpose()
     304        if not cochain:
     305            return ChainComplexMorphism(matrices,\
     306                    self._domain.chain_complex(base_ring=base_ring,augmented=augmented,cochain=cochain),\
     307                    self._codomain.chain_complex(base_ring=base_ring,augmented=augmented,cochain=cochain))
     308        else:
     309            return ChainComplexMorphism(matrices,\
     310                    self._codomain.chain_complex(base_ring=base_ring,augmented=augmented,cochain=cochain),\
     311                    self._domain.chain_complex(base_ring=base_ring,augmented=augmented,cochain=cochain))
    263312       
    264313    def image(self):
    265314        """