# Ticket #9122: trac_9122-cubical-simplicial.patch

File trac_9122-cubical-simplicial.patch, 12.2 KB (added by John Palmieri, 12 years ago)
• ## sage/homology/cubical_complex.py

# HG changeset patch
# User J. H. Palmieri <palmieri@math.washington.edu>
# Date 1275517397 25200
# Node ID 7993564c6cb70b65d2f637b7017566e585d7f094
diff -r 3a18981812ff -r 7993564c6cb7 sage/homology/cubical_complex.py
 a return (insert_self, insert_other, translate) def _triangulation_(self): r""" Triangulate this cube by "pulling vertices," as described by Hetyei.  Return a list of simplices which triangulate self. ALGORITHM: If the cube is given by .. math:: C = [i_1, j_1] \times [i_2, j_2] \times ... \times [i_k, j_k] let v_1 be the "upper" corner of C: v is the point (j_1, ..., j_k).  Choose a coordinate n where the interval [i_n, j_n] is non-degenerate and form v_2 by replacing j_n by i_n; repeat to define v_3, etc.  The last vertex so defined will be (i_1, ..., i_k).  These vertices define a simplex, as do the vertices obtained by making different choices at each stage.  Return the list of such simplices; thus if C is n-dimensional, then it is subdivided into n! simplices. REFERENCES: - G. Hetyei, "On the Stanley ring of a cubical complex", Discrete Comput. Geom. 14 (1995), 305-330. EXAMPLES:: sage: from sage.homology.cubical_complex import Cube sage: C = Cube([[1,2], [3,4]]); C [1,2] x [3,4] sage: C._triangulation_() [((1, 3), (1, 4), (2, 4)), ((1, 3), (2, 3), (2, 4))] sage: C = Cube([[1,2], [3,4], [8,9]]) sage: len(C._triangulation_()) 6 """ from sage.homology.simplicial_complex import Simplex if self.dimension() < 0: # the empty cube return [Simplex(())] # the empty simplex v = tuple([max(j) for j in self.tuple()]) if self.dimension() == 0: # just v return [Simplex((v,))] simplices = [] for i in range(self.dimension()): for S in self.face(i, upper=False)._triangulation_(): simplices.append(S.join(Simplex((v,)), rename_vertices=False)) return simplices def __cmp__(self, other): """ Return True iff this cube is the same as other: that is, class :class:Cube, or lists or tuples suitable for conversion to cubes.  These cubes are the maximal cubes in the complex. In addition, maximal_faces may be a cubical complex, in which case that complex is returned.  Also, maximal_faces may instead be any object which has a _cubical_ method (e.g., a simplicial complex); then that method is used to convert the object to a cubical complex. If maximality_check is True, check that each maximal face is, in fact, maximal. In this case, when producing the internal representation of the cubical complex, omit those that are not. sage: X.homology() {0: Z x Z x Z x Z, 1: Z^5} Converting a simplicial complex to a cubical complex:: sage: S2 = simplicial_complexes.Sphere(2) sage: C2 = CubicalComplex(S2) sage: all([C2.homology(n) == S2.homology(n) for n in range(3)]) True You can get the set of maximal cells or a dictionary of all cells:: sage: X.maximal_cells() """ maximality_check = kwds.get('maximality_check', True) C = None if isinstance(maximal_faces, CubicalComplex): C = maximal_faces try: C = maximal_faces._cubical_() except AttributeError: pass if C is not None: self._facets = copy(C._facets) self._cells = copy(C._cells) self._complex = copy(C._complex) return good_faces = [] maximal_cubes = [Cube(f) for f in maximal_faces] for face in maximal_cubes: s += "\n" return s def _simplicial_(self): r""" Simplicial complex constructed from self. ALGORITHM: This is constructed as described by Hetyei: choose a total ordering of the vertices of the cubical complex.  Then for each maximal face .. math:: C = [i_1, j_1] \times [i_2, j_2] \times ... \times [i_k, j_k] let v_1 be the "upper" corner of C: v is the point (j_1, ..., j_k).  Choose a coordinate n where the interval [i_n, j_n] is non-degenerate and form v_2 by replacing j_n by i_n; repeat to define v_3, etc.  The last vertex so defined will be (i_1, ..., i_k).  These vertices define a simplex, and do the vertices obtained by making different choices at each stage.  Thus each n-cube is subdivided into n! simplices. REFERENCES: - G. Hetyei, "On the Stanley ring of a cubical complex", Discrete Comput. Geom. 14 (1995), 305-330. EXAMPLES:: sage: T = cubical_complexes.Torus(); T Cubical complex with 16 vertices and 64 cubes sage: len(T.maximal_cells()) 16 When this is triangulated, each maximal 2-dimensional cube gets turned into a pair of triangles.  Since there were 16 maximal cubes, this results in 32 facets in the simplicial complex:: sage: Ts = T._simplicial_(); Ts Simplicial complex with 16 vertices and 32 facets sage: T.homology() == Ts.homology() True Each n-dimensional cube produces n! n-simplices:: sage: S4 = cubical_complexes.Sphere(4) sage: len(S4.maximal_cells()) 10 sage: SimplicialComplex(S4) # calls S4._simplicial_() Simplicial complex with 32 vertices and 240 facets """ from sage.homology.simplicial_complex import SimplicialComplex simplices = [] for C in self.maximal_cells(): simplices.extend(C._triangulation_()) return SimplicialComplex(simplices) def _string_constants(self): """ Tuple containing the name of the type of complex, and the
diff -r 3a18981812ff -r 7993564c6cb7 sage/homology/simplicial_complex.py
 a #  should + have any meaning? #  cohomology: compute cup products (and Massey products?) from copy import copy from sage.homology.cell_complex import GenericCellComplex from sage.structure.sage_object import SageObject from sage.rings.integer import Integer sage: SimplicialComplex([[0,2], [0,3], [0,6]]) Simplicial complex with vertex set (0, 2, 3, 6) and facets {(0, 6), (0, 2), (0, 3)} Finally, if vertex_set is the only argument and it is a simplicial complex, return that complex.  If it is an object with a built-in conversion to simplicial complexes (via a _simplicial_ method), then the resulting simplicial complex is returned:: sage: S = SimplicialComplex([[0,2], [0,3], [0,6]]) sage: SimplicialComplex(S) == S True sage: Tc = cubical_complexes.Torus(); Tc Cubical complex with 16 vertices and 64 cubes sage: Ts = SimplicialComplex(Tc); Ts Simplicial complex with 16 vertices and 32 facets sage: Ts.homology() {0: 0, 1: Z x Z, 2: Z} TESTS:: sage: S = SimplicialComplex(['a', 'b', 'c'], (('a', 'b'), ('a', 'c'), ('b', 'c'))) # 'maximal_faces', and use the union of all of the vertices for # 'vertex_set'. if maximal_faces == []: C = None if isinstance(vertex_set, (list, tuple)) and isinstance(vertex_set[0], (list, tuple, Simplex)): maximal_faces = vertex_set vertex_set = reduce(union, vertex_set) elif isinstance(vertex_set, SimplicialComplex): C = vertex_set else: try: C = vertex_set._simplicial_() except AttributeError: pass if C is not None: self._vertex_set = copy(C.vertices()) self._facets = list(C.facets()) self._faces = copy(C._faces) self._gen_dict = copy(C._gen_dict) self._complex = copy(C._complex) self.__contractible = copy(C.__contractible) self.__enlarged = copy(C.__enlarged) self._graph = copy(C._graph) self._numeric = C._numeric self._numeric_translation = copy(C._numeric_translation) return if sort_facets: try:  # vertex_set is an iterable vertices = Simplex(sorted(vertex_set)) vertex_check=False, sort_facets=False) self.__enlarged[subcomplex] = L return L def _cubical_(self): r""" Cubical complex constructed from self. ALGORITHM: The algorithm comes from a paper by Shtan'ko and Shtogrin, as reported by Bukhshtaber and Panov.  Let I^m denote the unit m-cube, viewed as a cubical complex.  Let [m] = \{1, 2, ..., m\}; then each face of I^m has the following form, for subsets I \subset J \subset [m]: .. math:: F_{I \subset J} = \{ (y_1,...,y_m) \in I^m \,:\, y_i =0 \text{ for } i \in I, y_j = 1 \text{ for } j \not \in J\}. If K is a simplicial complex on vertex set [m] and if I \subset [m], write I \in K if I is a simplex of K. Then we associate to K the cubical subcomplex of I^m with faces .. math:: \{F_{I \subset J} \,:\, J \in K, I \neq \emptyset \} The geometric realization of this cubical complex is homeomorphic to the geometric realization of the original simplicial complex. REFERENCES: - V. M. Bukhshtaber and T. E. Panov, "Moment-angle complexes and combinatorics of simplicial manifolds," *Uspekhi Mat. Nauk* 55 (2000), 171--172. - M. A. Shtan'ko and and M. I. Shtogrin, "Embedding cubic manifolds and complexes into a cubic lattice", *Uspekhi Mat. Nauk* 47 (1992), 219-220. EXAMPLES:: sage: T = simplicial_complexes.Torus() sage: T.homology() {0: 0, 1: Z x Z, 2: Z} sage: Tc = T._cubical_() sage: Tc Cubical complex with 42 vertices and 168 cubes sage: Tc.homology() {0: 0, 1: Z x Z, 2: Z} """ from sage.homology.cubical_complex import Cube, CubicalComplex V = self.vertices() embed = V.dimension() + 1 # dictionary to translate vertices to the numbers 1, ..., embed vd = dict(zip(V, range(1, embed + 1))) cubes = [] for JJ in self.facets(): J = [vd[i] for i in JJ] for i in J: # loop over indices from 1 to embed.  if equal to i, # set to 0. if not in J, set to 1.  Otherwise, range # from 0 to 1 cube = [] for n in range(1, embed+1): if n == i: cube.append([0,]) elif n not in J: cube.append([1,]) else: cube.append([0,1]) cubes.append(cube) return CubicalComplex(cubes) def category(self): """