Skip to content
This repository has been archived by the owner on Jan 30, 2023. It is now read-only.

Commit

Permalink
Merge #31680
Browse files Browse the repository at this point in the history
  • Loading branch information
mkoeppe committed Apr 23, 2021
2 parents 186707b + 30271af commit adac07a
Show file tree
Hide file tree
Showing 5 changed files with 499 additions and 1 deletion.
2 changes: 2 additions & 0 deletions src/doc/en/reference/manifolds/manifold.rst
Expand Up @@ -21,3 +21,5 @@ Topological Manifolds
sage/manifolds/topological_submanifold

vector_bundle

sage/manifolds/family
18 changes: 17 additions & 1 deletion src/sage/graphs/digraph.py
Expand Up @@ -3317,12 +3317,28 @@ def layout_acyclic_dummy(self, heights=None, rankdir='up', **options):
...
ValueError: `self` should be an acyclic graph
TESTS:
:trac:`31681` is fixed::
sage: H = DiGraph({0: [1], 'X': [1]}, format='dict_of_lists')
sage: pos = H.layout_acyclic_dummy(rankdir='up')
sage: pos['X'][1] == 0 and pos[0][1] == 0
True
sage: pos[1][1] == 1
True
"""
if heights is None:
if not self.is_directed_acyclic():
raise ValueError("`self` should be an acyclic graph")
levels = self.level_sets()
levels = [sorted(z) for z in levels]
# Sort vertices in each level in best effort mode
for i in range(len(levels)):
try:
l = sorted(levels[i])
levels[i] = l
except:
continue
if rankdir=='down' or rankdir=='left':
levels.reverse()
heights = {i: levels[i] for i in range(len(levels))}
Expand Down
236 changes: 236 additions & 0 deletions src/sage/manifolds/family.py
@@ -0,0 +1,236 @@
r"""
Families of Manifold Objects
The class :class:`ManifoldObjectFiniteFamily` is a subclass of :class:`FiniteFamily`
that provides an associative container of manifold objects, indexed by their
``_name`` attributes.
:class:`ManifoldObjectFiniteFamily` instances are totally ordered according
to their lexicographically ordered element names.
The subclass :class:`ManifoldSubsetFiniteFamily` customizes the print
representation further.
"""
#*****************************************************************************
# Copyright (C) 2021 Matthias Koeppe <mkoeppe@math.ucdavis.edu>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 2 of the License, or
# (at your option) any later version.
# http://www.gnu.org/licenses/
#*****************************************************************************

from functools import total_ordering
from sage.sets.family import FiniteFamily

@total_ordering
class ManifoldObjectFiniteFamily(FiniteFamily):

r"""
Finite family of manifold objects, indexed by their names.
The class :class:`ManifoldObjectFiniteFamily` inherits from
:class:`FiniteFamily`. Therefore it is an associative container.
It provides specialized ``__repr__`` and ``_latex_`` methods.
:class:`ManifoldObjectFiniteFamily` instances are totally ordered
according to their lexicographically ordered element names.
EXAMPLES::
sage: from sage.manifolds.family import ManifoldObjectFiniteFamily
sage: M = Manifold(2, 'M', structure='topological')
sage: A = M.subset('A')
sage: B = M.subset('B')
sage: C = B.subset('C')
sage: F = ManifoldObjectFiniteFamily([A, B, C]); F
Set {A, B, C} of objects of the 2-dimensional topological manifold M
sage: latex(F)
\{A, B, C\}
sage: F['B']
Subset B of the 2-dimensional topological manifold M
All objects must have the same base manifold::
sage: N = Manifold(2, 'N', structure='topological')
sage: ManifoldObjectFiniteFamily([M, N])
Traceback (most recent call last):
...
TypeError: all objects must have the same manifold
"""
def __init__(self, objects=(), keys=None):
r"""
Initialize a new instance of :class:`ManifoldObjectFiniteFamily`.
TESTS:
sage: from sage.manifolds.family import ManifoldObjectFiniteFamily
sage: M = Manifold(2, 'M', structure='topological')
sage: A = M.subset('A')
sage: B = M.subset('B')
sage: C = B.subset('C')
sage: F = ManifoldObjectFiniteFamily([A, B, C]); F
Set {A, B, C} of objects of the 2-dimensional topological manifold M
sage: TestSuite(F).run(skip='_test_elements')
Like ``frozenset``, it can be created from any iterable::
sage: from sage.manifolds.family import ManifoldSubsetFiniteFamily
sage: M = Manifold(2, 'M', structure='topological')
sage: I = M.subset('I')
sage: gen = (subset for subset in (M, I, M, I, M, I)); gen
<generator object ...>
sage: ManifoldSubsetFiniteFamily(gen)
Set {I, M} of subsets of the 2-dimensional topological manifold M
"""
if isinstance(objects, dict):
dictionary = objects
else:
dictionary = {object._name: object for object in objects}
if keys is None:
keys = sorted(dictionary.keys())
FiniteFamily.__init__(self, dictionary, keys)
names_and_latex_names = sorted((object._name, object._latex_name)
for object in self)
self._name = '{' + ', '.join(keys) + '}'
latex_names = (latex_name for name, latex_name in names_and_latex_names)
self._latex_name = r'\{' + ', '.join(latex_names) + r'\}'
try:
object_iter = iter(self)
self._manifold = next(object_iter)._manifold
except StopIteration:
self._manifold = None
else:
if not all(object._manifold == self._manifold for object in object_iter):
raise TypeError(f'all {self._repr_object_type()} must have the same manifold')

def _repr_object_type(self):
r"""
String that describes the type of the elements (plural).
TESTS::
sage: from sage.manifolds.family import ManifoldObjectFiniteFamily
sage: M = Manifold(2, 'M', structure='topological')
sage: A = M.subset('A')
sage: B = M.subset('B')
sage: ManifoldObjectFiniteFamily([A, B]).__repr__() # indirect doctest
'Set {A, B} of objects of the 2-dimensional topological manifold M'
"""
return "objects"

def __lt__(self, other):
r"""
Implement the total order on instances of :class:`ManifoldObjectFiniteFamily`.
TESTS::
sage: from sage.manifolds.family import ManifoldSubsetFiniteFamily
sage: M = Manifold(2, 'M', structure='topological')
sage: A = M.subset('A')
sage: B = M.subset('B')
sage: sorted([ManifoldSubsetFiniteFamily([A, B]), ManifoldSubsetFiniteFamily([]),
....: ManifoldSubsetFiniteFamily([B]), ManifoldSubsetFiniteFamily([A])])
[{},
Set {A} of subsets of the 2-dimensional topological manifold M,
Set {A, B} of subsets of the 2-dimensional topological manifold M,
Set {B} of subsets of the 2-dimensional topological manifold M]
"""
if not isinstance(other, ManifoldSubsetFiniteFamily):
return NotImplemented
return self.keys() < other.keys()

def __repr__(self):
r"""
String representation of the object.
TESTS::
sage: from sage.manifolds.family import ManifoldObjectFiniteFamily
sage: ManifoldObjectFiniteFamily().__repr__()
'{}'
sage: M = Manifold(2, 'M', structure='topological')
sage: A = M.subset('A')
sage: B = M.subset('B')
sage: ManifoldObjectFiniteFamily([A, B]).__repr__()
'Set {A, B} of objects of the 2-dimensional topological manifold M'
"""
if self:
return "Set {} of {} of the {}".format(self._name, self._repr_object_type(), self._manifold)
else:
return "{}"

def _latex_(self):
r"""
LaTeX representation of ``self``.
TESTS::
sage: from sage.manifolds.family import ManifoldSubsetFiniteFamily
sage: M = Manifold(2, 'M', structure='topological')
sage: A = M.subset('A')
sage: B = M.subset('B')
sage: ManifoldSubsetFiniteFamily([B, A])._latex_()
'\\{A, B\\}'
"""
return self._latex_name

class ManifoldSubsetFiniteFamily(ManifoldObjectFiniteFamily):

r"""
Finite family of subsets of a topological manifold, indexed by their names.
The class :class:`ManifoldSubsetFiniteFamily` inherits from
:class:`ManifoldObjectFiniteFamily`. It provides an associative
container with specialized ``__repr__`` and ``_latex_`` methods.
:class:`ManifoldSubsetFiniteFamily` instances are totally ordered according
to their lexicographically ordered element (subset) names.
EXAMPLES::
sage: from sage.manifolds.family import ManifoldSubsetFiniteFamily
sage: M = Manifold(2, 'M', structure='topological')
sage: A = M.subset('A')
sage: B = M.subset('B')
sage: C = B.subset('C')
sage: ManifoldSubsetFiniteFamily([A, B, C])
Set {A, B, C} of subsets of the 2-dimensional topological manifold M
sage: latex(_)
\{A, B, C\}
All subsets must have the same base manifold::
sage: N = Manifold(2, 'N', structure='topological')
sage: ManifoldSubsetFiniteFamily([M, N])
Traceback (most recent call last):
...
TypeError: all... subsets must have the same manifold
"""

def _repr_object_type(self):
r"""
String that describes the type of the elements (plural).
TESTS::
sage: from sage.manifolds.family import ManifoldSubsetFiniteFamily
sage: M = Manifold(2, 'M', structure='topological')
sage: A = M.subset('A')
sage: B = M.subset('B')
sage: ManifoldSubsetFiniteFamily([A, B]).__repr__() # indirect doctest
'Set {A, B} of subsets of the 2-dimensional topological manifold M'
"""
if all(subset.is_open() for subset in self):
return "open subsets"
else:
return "subsets"

0 comments on commit adac07a

Please sign in to comment.