From 77b801c6de17159081eea9a1c3fdc4952bf4288a Mon Sep 17 00:00:00 2001 From: Travis Scrimshaw Date: Sun, 12 Apr 2015 11:36:02 -0400 Subject: [PATCH 1/4] Inital stubs --- src/sage/categories/groups.py | 29 +++++ src/sage/categories/lie_groups.py | 73 ++++++++++++ src/sage/categories/manifolds.py | 98 ++++++++++++++++ src/sage/categories/metric_spaces.py | 114 ++++++++++++++++++ src/sage/categories/sets_cat.py | 13 +++ src/sage/categories/topological_spaces.py | 136 ++++++++++++++++++++++ 6 files changed, 463 insertions(+) create mode 100644 src/sage/categories/lie_groups.py create mode 100644 src/sage/categories/manifolds.py create mode 100644 src/sage/categories/metric_spaces.py create mode 100644 src/sage/categories/topological_spaces.py diff --git a/src/sage/categories/groups.py b/src/sage/categories/groups.py index 785d81afc12..27bc4a0755a 100644 --- a/src/sage/categories/groups.py +++ b/src/sage/categories/groups.py @@ -18,6 +18,7 @@ from sage.categories.algebra_functor import AlgebrasCategory from sage.categories.cartesian_product import CartesianProductsCategory, cartesian_product from sage.categories.finite_enumerated_sets import FiniteEnumeratedSets +from sage.categories.topological_spaces import TopologicalSpacesCategory class Groups(CategoryWithAxiom): """ @@ -479,6 +480,7 @@ def conjugacy_class(self): return self.parent().conjugacy_class(self) Finite = LazyImport('sage.categories.finite_groups', 'FiniteGroups') + Lie = LazyImport('sage.categories.lie_groups', 'LieGroups', 'Lie') #Algebras = LazyImport('sage.categories.group_algebras', 'GroupAlgebras') class Commutative(CategoryWithAxiom): @@ -945,3 +947,30 @@ def lift(i, gen): for i,G in enumerate(F)]) return Family(gens_prod, lift, name="gen") + class Topological(TopologicalSpacesCategory): + """ + Category of topological groups. + + A topological group `G` is a group which has a topology such that + multiplication and taking inverses are continuous functions. + + REFERENCES: + + - :wikipedia:`Topological_group` + """ + def additional_structure(self): + r""" + Return ``None``. + + Indeed, the category of topolgocial groups defines no new + structure: a morphism of groups and of topological spaces + between two topological groups is a topological group morphism. + + .. SEEALSO:: :meth:`Category.additional_structure` + + EXAMPLES:: + + sage: Groups().Topological().additional_structure() + """ + return None + diff --git a/src/sage/categories/lie_groups.py b/src/sage/categories/lie_groups.py new file mode 100644 index 00000000000..2713286cba6 --- /dev/null +++ b/src/sage/categories/lie_groups.py @@ -0,0 +1,73 @@ +r""" +Lie Groups +""" +#***************************************************************************** +# Copyright (C) 2015 Travis Scrimshaw +# +# Distributed under the terms of the GNU General Public License (GPL) +# http://www.gnu.org/licenses/ +#****************************************************************************** + +from sage.misc.abstract_method import abstract_method +from sage.misc.cachefunc import cached_method +from sage.misc.lazy_attribute import lazy_attribute +from sage.misc.lazy_import import LazyImport +from sage.categories.category import Category +from sage.categories.category_types import Category_over_base_ring +from sage.categories.sets_cat import Sets + +class Manifolds(Category_over_base_ring): + r""" + The category of Lie groups. + + A Lie group is a topological group with a smooth differentiable + manifold structure. + + INPUT: + + - ``k`` -- (default: ``RR``) the field `k` + + EXAMPLES:: + + sage: from sage.categories.lie_groups import LieGroups + sage: C = LieGroups(); C + Category of manifolds over Real Field + sage: C.super_categories() + [Category of additive commutative additive associative additive unital distributive magmas and additive magmas, + Category of modules over Integer Ring] + sage: C = LieGroups(CC); C + Category of manifolds over Complex Field + + TESTS:: + + sage: TestSuite(C).run() + """ + @cached_method + def super_categories(self): + """ + EXAMPLES:: + + sage: from sage.categories.lie_groups import LieGroups + sage: LieGroups().super_categories() + """ + R = self.base_ring() + # TODO: Make this smooth differentiable manifolds + return [Groups().Topological(), Manifolds(R)] + + def additional_structure(self): + r""" + Return ``None``. + + Indeed, the category of Lie groups defines no new + structure: a morphism of topological spaces and of smooth + differentiable manifolds is a morphism as Lie groups. + + .. SEEALSO:: :meth:`Category.additional_structure` + + EXAMPLES:: + + sage: from sage.categories.lie_groups import LieGroups + sage: LieGroups().additional_structure() + """ + return None + diff --git a/src/sage/categories/manifolds.py b/src/sage/categories/manifolds.py new file mode 100644 index 00000000000..56dbde629e9 --- /dev/null +++ b/src/sage/categories/manifolds.py @@ -0,0 +1,98 @@ +r""" +Manifolds +""" +#***************************************************************************** +# Copyright (C) 2015 Travis Scrimshaw +# +# Distributed under the terms of the GNU General Public License (GPL) +# http://www.gnu.org/licenses/ +#****************************************************************************** + +from sage.misc.abstract_method import abstract_method +from sage.misc.cachefunc import cached_method +from sage.misc.lazy_attribute import lazy_attribute +from sage.misc.lazy_import import LazyImport +from sage.categories.category import Category +from sage.categories.category_types import Category_over_base_ring +from sage.categories.sets_cat import Sets +from sage.categories.fields import Fields +from sage.rings.all import RR + +class Manifolds(Category_over_base_ring): + r""" + The category of maniolds. + + Let `k` be a field. A `d`-dimensional `k`-*manifold* `M` is a + second countable Hausdorff space such that the neighborhood + of any point `x \in M` is homeomorphic to `k^d`. + + INPUT: + + - ``k`` -- (default: ``RR``) the field `k` + + EXAMPLES:: + + sage: from sage.categories.manifolds import Manifolds + sage: C = Manifolds(); C + Category of manifolds over Real Field + sage: C.super_categories() + [Category of additive commutative additive associative additive unital distributive magmas and additive magmas, + Category of modules over Integer Ring] + sage: C = Manifolds(CC); C + Category of manifolds over Complex Field + + TESTS:: + + sage: TestSuite(C).run() + """ + def __init__(self, k=RR): + """ + Initialize ``self``. + """ + if k not in Fields(): + raise ValueError("must be defined over a field") + Category_over_base_ring.__init__(self, k) + + @cached_method + def super_categories(self): + """ + EXAMPLES:: + + sage: from sage.categories.magmatic_algebras import MagmaticAlgebras + sage: MagmaticAlgebras(ZZ).super_categories() + [Category of additive commutative additive associative additive unital distributive magmas and additive magmas, Category of modules over Integer Ring] + + sage: from sage.categories.additive_semigroups import AdditiveSemigroups + sage: MagmaticAlgebras(ZZ).is_subcategory((AdditiveSemigroups() & Magmas()).Distributive()) + True + """ + return [Sets().Topological()] + + def additional_structure(self): + r""" + Return ``None``. + + Indeed, the category of manifolds defines no new + structure: a morphism of metric spaces between manifolds + is a manifold morphism. + + .. SEEALSO:: :meth:`Category.additional_structure` + + EXAMPLES:: + + sage: from sage.categories.manifolds import Manifolds + sage: Manifolds().additional_structure() + """ + return None + + class Connected: + """ + The category of connected manifolds. + """ + class ParentMethods: + @abstract_method + def dimension(self): + """ + Return the dimension of ``self``. + """ + diff --git a/src/sage/categories/metric_spaces.py b/src/sage/categories/metric_spaces.py new file mode 100644 index 00000000000..6b4dec93de3 --- /dev/null +++ b/src/sage/categories/metric_spaces.py @@ -0,0 +1,114 @@ +r""" +Topological Spaces +""" +#***************************************************************************** +# Copyright (C) 2015 Travis Scrimshaw +# +# Distributed under the terms of the GNU General Public License (GPL) +# http://www.gnu.org/licenses/ +#****************************************************************************** + +from sage.misc.abstract_method import abstract_method +from sage.categories.category import Category +from sage.categories.covariant_functorial_construction import RegressiveCovariantConstructionCategory + +class MetricSpaces(RegressiveCovariantConstructionCategory): + r""" + The category of metric spaces. + + A *metric* on a set `S` is a function `d : S \times S \to \RR` + such that: + + - `d(a, b) \geq 0`, + - `d(a, b) = 0` if and only if `a = b`. + + A metric space is a set `S` with a distinguished metric. + """ + + _functor_category = "Metric" + + @classmethod + def default_super_categories(cls, category): + """ + Return the default super categories of ``category.Metric()``. + + Mathematical meaning: if `A` is a metric space in the + category `C`, then `A` is also a topological space. + + INPUT: + + - ``cls`` -- the class ``MetricSpaces`` + - ``category`` -- a category `Cat` + + OUTPUT: + + A (join) category + + In practice, this returns ``category.Subquotients()``, joined + together with the result of the method + :meth:`RegressiveCovariantConstructionCategory.default_super_categories() + ` + (that is the join of ``category`` and ``cat.Metric()`` for + each ``cat`` in the super categories of ``category``). + + EXAMPLES: + + Consider ``category=Groups()``, which has ``cat=Monoids()`` as + super category. Then, a subgroup of a group `G` is + simultaneously a subquotient of `G`, a group by itself, and a + submonoid of `G`:: + + sage: Groups().Subobjects().super_categories() + [Category of groups, Category of subquotients of monoids, Category of subobjects of sets] + + Mind the last item above: there is indeed currently nothing + implemented about submonoids. + + This resulted from the following call:: + + sage: sage.categories.subobjects.SubobjectsCategory.default_super_categories(Groups()) + Join of Category of groups and Category of subquotients of monoids and Category of subobjects of sets + """ + return Category.join([category.Topological(), + super(MetricSpaces, cls).default_super_categories(category)]) + + class ParentMethods: + def _test_metric(self, **options): + r""" + Test that this metric space has a properly implemented metric. + + INPUT:: + + - ``options`` -- any keyword arguments accepted + by :meth:`_tester` + """ + tester = self._tester(**options) + S = tester.some_elements() + dist = self.metric() + for a in S: + for b in S: + d = dist(a, b) + if a != b: + tester.assertGreater(d, 0) + else: + tester.assertEqual(d, 0) + + def metric(self): + """ + Return the metric of ``self``. + """ + return lambda a,b: self.dist(a, b) + + @abstract_method + def dist(self, a, b): + """ + Return the distance between ``a`` and ``b`` in ``self``. + """ + + class ElementMethods: + def dist(self, b): + """ + Return the distance between ``self`` and ``b``. + """ + return self.parent().dist(self, b) + diff --git a/src/sage/categories/sets_cat.py b/src/sage/categories/sets_cat.py index b773014c8f0..1542235b364 100644 --- a/src/sage/categories/sets_cat.py +++ b/src/sage/categories/sets_cat.py @@ -649,6 +649,18 @@ def IsomorphicObjects(self): """ return IsomorphicObjectsCategory.category_of(self) + @cached_method + def Topological(self): + """ + Return the subcategory of the topological objects of ``self``. + + TESTS:: + + sage: TestSuite(Sets().Topological()).run() + """ + from sage.categories.topological_spaces import TopologicalSpacesCategory + return TopologicalSpacesCategory.category_of(self) + @cached_method def Algebras(self, base_ring): """ @@ -1555,6 +1567,7 @@ def cartesian_product(*elements): Facade = LazyImport('sage.categories.facade_sets', 'FacadeSets') Finite = LazyImport('sage.categories.finite_sets', 'FiniteSets', at_startup=True) + Topological = LazyImport('sage.categories.topological_spaces', 'TopologicalSpaces') class Infinite(CategoryWithAxiom): diff --git a/src/sage/categories/topological_spaces.py b/src/sage/categories/topological_spaces.py new file mode 100644 index 00000000000..c4ab000dd48 --- /dev/null +++ b/src/sage/categories/topological_spaces.py @@ -0,0 +1,136 @@ +r""" +Topological Spaces +""" +#***************************************************************************** +# Copyright (C) 2015 Travis Scrimshaw +# +# Distributed under the terms of the GNU General Public License (GPL) +# http://www.gnu.org/licenses/ +#****************************************************************************** + +from sage.misc.cachefunc import cached_method +from sage.misc.lazy_attribute import lazy_class_attribute +from sage.categories.category import Category +from sage.categories.covariant_functorial_construction import RegressiveCovariantConstructionCategory +from sage.categories.sets_cat import Sets + +class TopologicalSpacesCategory(RegressiveCovariantConstructionCategory): + + _functor_category = "Topological" + + # Currently no use case for this + @lazy_class_attribute + def _base_category_class(cls): + """ + Recover the class of the base category. + + OUTPUT: + + A *tuple* whose first entry is the base category class. + + .. WARNING:: + + This is only used for graded categories that are not + implemented as nested classes, and won't work otherwise. + + .. SEEALSO:: :meth:`__classcall__` + + EXAMPLES:: + + sage: GradedModules._base_category_class + (,) + sage: GradedAlgebrasWithBasis._base_category_class + (,) + + The reason for wrapping the base category class in a tuple is + that, often, the base category class implements a + :meth:`__classget__` method which would get in the way upon + attribute access:: + + sage: F = GradedAlgebrasWithBasis + sage: F._foo = F._base_category_class[0] + sage: F._foo + Traceback (most recent call last): + ... + AssertionError: base category class for <...AlgebrasWithBasis'> mismatch; + expected <...Algebras'>, got <...GradedAlgebrasWithBasis'> + """ + module_name = cls.__module__.replace("topological_","") + import sys + name = cls.__name__.replace("Topological","") + __import__(module_name) + module = sys.modules[module_name] + return (module.__dict__[name],) + + @staticmethod + def __classcall__(cls, category=None, *args): + """ + Magic support for putting topological categories in their own file. + + EXAMPLES:: + + sage: TopologicalSpaces() # indirect doctest + Category of graded modules over Integer Ring + sage: Sets().Topological() + Category of graded modules over Integer Ring + sage: TopologicalSpaces() is Sets().Topological() + True + + .. TODO:: + + Generalize this support for all other functorial + constructions if at some point we have a category ``Blah`` for + which we want to implement the construction ``Blah.Foo`` in a + separate file like we do for e.g. :class:`GradedModules`, + :class:`GradedAlgebras`, ... + + .. SEEALSO:: :meth:`_base_category_class` + """ + base_category_class = cls._base_category_class[0] + if isinstance(category, base_category_class): + return super(TopologicalSpacesCategory, cls).__classcall__(cls, category, *args) + else: + return base_category_class(category, *args).Topological() + + def _repr_object_names(self): + """ + EXAMPLES:: + + sage: Groups().Topological() # indirect doctest + Category of graded algebras with basis over Rational Field + """ + return "topological {}".format(self.base_category()._repr_object_names()) + +class TopologicalSpaces(TopologicalSpacesCategory): + """ + The category of topological spaces. + + EXAMPLES:: + + sage: Sets().Topological() + Category of topological spaces + sage: Sets().Topological().super_categories() + [Category of modules over Integer Ring] + + The category of topological spaces defines the topological structure, + which shall be preserved by morphisms:: + + sage: Sets().Topological().additional_structure() + Category of topological spaces + + TESTS:: + + sage: TestSuite(Sets().Topological()).run() + """ + # We must override the general object because the names don't match + _base_category_class = (Sets,) + + def _repr_object_names(self): + """ + EXAMPLES:: + + sage: Sets().Topological() # indirect doctest + Category of topological spaces + """ + return "topological spaces" + From bdb08fb0e246e3d9937ca67762dde3baa4d43725 Mon Sep 17 00:00:00 2001 From: Travis Scrimshaw Date: Sun, 12 Apr 2015 12:28:19 -0400 Subject: [PATCH 2/4] Some cleanup and getting category stubs ready. --- src/sage/categories/groups.py | 15 ----- src/sage/categories/lie_groups.py | 11 +++- src/sage/categories/topological_spaces.py | 74 ----------------------- 3 files changed, 10 insertions(+), 90 deletions(-) diff --git a/src/sage/categories/groups.py b/src/sage/categories/groups.py index 27bc4a0755a..1acde422a69 100644 --- a/src/sage/categories/groups.py +++ b/src/sage/categories/groups.py @@ -958,19 +958,4 @@ class Topological(TopologicalSpacesCategory): - :wikipedia:`Topological_group` """ - def additional_structure(self): - r""" - Return ``None``. - - Indeed, the category of topolgocial groups defines no new - structure: a morphism of groups and of topological spaces - between two topological groups is a topological group morphism. - - .. SEEALSO:: :meth:`Category.additional_structure` - - EXAMPLES:: - - sage: Groups().Topological().additional_structure() - """ - return None diff --git a/src/sage/categories/lie_groups.py b/src/sage/categories/lie_groups.py index 2713286cba6..c2af33196b1 100644 --- a/src/sage/categories/lie_groups.py +++ b/src/sage/categories/lie_groups.py @@ -15,8 +15,11 @@ from sage.categories.category import Category from sage.categories.category_types import Category_over_base_ring from sage.categories.sets_cat import Sets +from sage.categories.groups import Groups +from sage.categories.manifolds import Manifolds +from sage.rings.all import RR -class Manifolds(Category_over_base_ring): +class LieGroups(Category_over_base_ring): r""" The category of Lie groups. @@ -42,6 +45,12 @@ class Manifolds(Category_over_base_ring): sage: TestSuite(C).run() """ + def __init__(self, R=RR): + """ + Initialize ``self``. + """ + Category_over_base_ring.__init__(self, RR) + @cached_method def super_categories(self): """ diff --git a/src/sage/categories/topological_spaces.py b/src/sage/categories/topological_spaces.py index c4ab000dd48..80e31857508 100644 --- a/src/sage/categories/topological_spaces.py +++ b/src/sage/categories/topological_spaces.py @@ -18,80 +18,6 @@ class TopologicalSpacesCategory(RegressiveCovariantConstructionCategory): _functor_category = "Topological" - # Currently no use case for this - @lazy_class_attribute - def _base_category_class(cls): - """ - Recover the class of the base category. - - OUTPUT: - - A *tuple* whose first entry is the base category class. - - .. WARNING:: - - This is only used for graded categories that are not - implemented as nested classes, and won't work otherwise. - - .. SEEALSO:: :meth:`__classcall__` - - EXAMPLES:: - - sage: GradedModules._base_category_class - (,) - sage: GradedAlgebrasWithBasis._base_category_class - (,) - - The reason for wrapping the base category class in a tuple is - that, often, the base category class implements a - :meth:`__classget__` method which would get in the way upon - attribute access:: - - sage: F = GradedAlgebrasWithBasis - sage: F._foo = F._base_category_class[0] - sage: F._foo - Traceback (most recent call last): - ... - AssertionError: base category class for <...AlgebrasWithBasis'> mismatch; - expected <...Algebras'>, got <...GradedAlgebrasWithBasis'> - """ - module_name = cls.__module__.replace("topological_","") - import sys - name = cls.__name__.replace("Topological","") - __import__(module_name) - module = sys.modules[module_name] - return (module.__dict__[name],) - - @staticmethod - def __classcall__(cls, category=None, *args): - """ - Magic support for putting topological categories in their own file. - - EXAMPLES:: - - sage: TopologicalSpaces() # indirect doctest - Category of graded modules over Integer Ring - sage: Sets().Topological() - Category of graded modules over Integer Ring - sage: TopologicalSpaces() is Sets().Topological() - True - - .. TODO:: - - Generalize this support for all other functorial - constructions if at some point we have a category ``Blah`` for - which we want to implement the construction ``Blah.Foo`` in a - separate file like we do for e.g. :class:`GradedModules`, - :class:`GradedAlgebras`, ... - - .. SEEALSO:: :meth:`_base_category_class` - """ - base_category_class = cls._base_category_class[0] - if isinstance(category, base_category_class): - return super(TopologicalSpacesCategory, cls).__classcall__(cls, category, *args) - else: - return base_category_class(category, *args).Topological() - def _repr_object_names(self): """ EXAMPLES:: From 68b85e9898949b1d9707f5d62c467e7fa2467da9 Mon Sep 17 00:00:00 2001 From: Travis Scrimshaw Date: Sun, 12 Apr 2015 16:48:58 -0400 Subject: [PATCH 3/4] Adding some more stubs for categories. --- src/sage/categories/all.py | 3 +- src/sage/categories/category_types.py | 29 +-- src/sage/categories/category_with_axiom.py | 1 + src/sage/categories/cw_complexes.py | 162 ++++++++++++++++ src/sage/categories/graphs.py | 61 ++++++ src/sage/categories/lie_groups.py | 49 ++--- src/sage/categories/manifolds.py | 179 ++++++++++++++---- src/sage/categories/metric_spaces.py | 44 +++-- src/sage/categories/sets_cat.py | 16 +- src/sage/categories/simplicial_complexes.py | 78 ++++++++ src/sage/categories/topological_spaces.py | 52 ++++- src/sage/homology/simplicial_complex.py | 8 +- .../homology/simplicial_complex_homset.py | 4 +- 13 files changed, 576 insertions(+), 110 deletions(-) create mode 100644 src/sage/categories/cw_complexes.py create mode 100644 src/sage/categories/graphs.py create mode 100644 src/sage/categories/simplicial_complexes.py diff --git a/src/sage/categories/all.py b/src/sage/categories/all.py index 233ea32ce9e..e00d5000b7e 100644 --- a/src/sage/categories/all.py +++ b/src/sage/categories/all.py @@ -3,10 +3,11 @@ from category_types import( Elements, Sequences, - SimplicialComplexes, ChainComplexes, ) +from sage.categories.simplicial_complexes import SimplicialComplexes + from tensor import tensor from cartesian_product import cartesian_product diff --git a/src/sage/categories/category_types.py b/src/sage/categories/category_types.py index 8ef0b0a216e..cca4855a982 100644 --- a/src/sage/categories/category_types.py +++ b/src/sage/categories/category_types.py @@ -599,34 +599,7 @@ def __call__(self, v): return v return self.ring().ideal(v) -############################################################# -# TODO: make those two into real categories (with super_category, ...) - -# SimplicialComplex -############################################################# -class SimplicialComplexes(Category): - """ - The category of simplicial complexes. - - EXAMPLES:: - - sage: SimplicialComplexes() - Category of simplicial complexes - - TESTS:: - - sage: TestSuite(SimplicialComplexes()).run() - """ - - def super_categories(self): - """ - EXAMPLES:: - - sage: SimplicialComplexes().super_categories() - [Category of objects] - """ - return [Objects()] # anything better? - +# TODO: make this into a better category ############################################################# # ChainComplex ############################################################# diff --git a/src/sage/categories/category_with_axiom.py b/src/sage/categories/category_with_axiom.py index 84031ba8f30..aa249c87d49 100644 --- a/src/sage/categories/category_with_axiom.py +++ b/src/sage/categories/category_with_axiom.py @@ -1675,6 +1675,7 @@ class ``Sets.Finite``), or in a separate file (typically in a class all_axioms = AxiomContainer() all_axioms += ("Flying", "Blue", + "Compact", "Complex", "Differentiable", "Smooth", "Facade", "Finite", "Infinite", "FiniteDimensional", "Connected", "WithBasis", "Irreducible", diff --git a/src/sage/categories/cw_complexes.py b/src/sage/categories/cw_complexes.py new file mode 100644 index 00000000000..764fac8b896 --- /dev/null +++ b/src/sage/categories/cw_complexes.py @@ -0,0 +1,162 @@ +r""" +CW Complexes +""" +#***************************************************************************** +# Copyright (C) 2015 Travis Scrimshaw +# +# Distributed under the terms of the GNU General Public License (GPL) +# http://www.gnu.org/licenses/ +#****************************************************************************** + +from sage.misc.abstract_method import abstract_method +from sage.misc.cachefunc import cached_method +from sage.categories.category_singleton import Category_singleton +from sage.categories.category_with_axiom import CategoryWithAxiom +from sage.categories.sets_cat import Sets + +class CWComplexes(Category_singleton): + r""" + The category of CW complexes. + + A CW complex is a Closure-finite cell complex in the Weak toplogy. + + REFERENCES: + + - :wikipedia:`CW_complex` + + EXAMPLES:: + + sage: from sage.categories.cw_complexes import CWComplexes + sage: C = CWComplexes(); C + Category of CW complexes + + TESTS:: + + sage: TestSuite(C).run() + """ + @cached_method + def super_categories(self): + """ + EXAMPLES:: + + sage: from sage.categories.cw_complexes import CWComplexes + sage: CWComplexes().super_categories() + [Category of topological spaces] + """ + return [Sets().Topological()] + + def _repr_object_names(self): + """ + EXAMPLES:: + + sage: from sage.categories.cw_complexes import CWComplexes + sage: CWComplexes() + Category of CW complexes + """ + return "CW complexes" + + class SubcategoryMethods: + @cached_method + def Connected(self): + """ + Return the full subcategory of the connected objects of ``self``. + + EXAMPLES:: + + sage: from sage.categories.cw_complexes import CWComplexes + sage: CWComplexes().Connected() + Category of connected CW complexes + + TESTS:: + + sage: TestSuite(CWComplexes().Connected()).run() + sage: CWComplexes().Connected.__module__ + 'sage.categories.cw_complexes' + """ + return self._with_axiom('Connected') + + @cached_method + def FiniteDimensional(self): + """ + Return the full subcategory of the finite dimensional + objects of ``self``. + + EXAMPLES:: + + sage: from sage.categories.cw_complexes import CWComplexes + sage: C = CWComplexes().FiniteDimensional(); C + Category of finite dimensional CW complexes + + TESTS:: + + sage: from sage.categories.cw_complexes import CWComplexes + sage: C = CWComplexes().FiniteDimensional() + sage: TestSuite(C).run() + sage: CWComplexes().Connected().FiniteDimensional.__module__ + 'sage.categories.cw_complexes' + """ + return self._with_axiom('FiniteDimensional') + + class Connected(CategoryWithAxiom): + """ + The category of connected CW complexes. + """ + + class FiniteDimensional(CategoryWithAxiom): + """ + Category of finite dimensional CW complexes. + """ + + class Finite(CategoryWithAxiom): + """ + Category of finite CW complexes. + """ + def extra_super_categories(self): + """ + Return the extra super categories of ``self``. + + A finite CW complex is a compact finite-dimensional CW complex. + """ + return [CWComplexes().FiniteDimensional(), Sets().Topological().Compact()] + + class ParentMethods: + @cached_method + def dimension(self): + """ + Return the dimension of ``self``. + """ + return max(c.dimension() for c in self.cells()) + + def Compact_extra_super_categories(self): + """ + Return extraneous super categories for ``CWComplexes().Compact()``. + + A compact CW complex is finite, see Proposition A.1 in [Hat]_. + + .. TODO:: + + Fix the name of finite CW complexes. + + EXAMPLES:: + + sage: from sage.categories.cw_complexes import CWComplexes + sage: CWComplexes().Compact() + Category of finite finite dimensional CW complexes + sage: CWComplexes().Compact() is CWComplexes().Finite() + True + """ + return (Sets().Finite(),) + + class ParentMethods: + @abstract_method + def dimension(self): + """ + Return the dimension of ``self``. + """ + + @abstract_method(optional=True) + def cells(self): + """ + Return the cells of ``self``. + """ + diff --git a/src/sage/categories/graphs.py b/src/sage/categories/graphs.py new file mode 100644 index 00000000000..275bec76808 --- /dev/null +++ b/src/sage/categories/graphs.py @@ -0,0 +1,61 @@ +""" +Graphs +""" +#***************************************************************************** +# Copyright (C) 2015 Travis Scrimshaw +# +# Distributed under the terms of the GNU General Public License (GPL) +# http://www.gnu.org/licenses/ +#****************************************************************************** + +#from sage.misc.abstract_method import abstract_method +from sage.misc.cachefunc import cached_method +from sage.categories.category_singleton import Category_singleton +from sage.categories.simplicial_complexes import SimplicialComplexes + +class Graphs(Category_singleton): + r""" + The category of graphs. + + EXAMPLES:: + + sage: from sage.categories.graphs import Graphs + sage: C = Graphs(); C + Category of graphs + + TESTS:: + + sage: TestSuite(C).run() + """ + @cached_method + def super_categories(self): + """ + EXAMPLES:: + + sage: from sage.categories.graphs import Graphs + sage: Graphs().super_categories() + [Category of simplicial complexes] + """ + return [SimplicialComplexes()] + + class ParentMethods: + def dimension(self): + """ + Return the dimension of ``self`` as a CW complex. + """ + if self.edges(): + return 1 + return 0 + + def facets(self): + """ + Return the facets of ``self``. + """ + return self.edges() + + def faces(self): + """ + Return the faces of ``self``. + """ + return set(self.edges()).union(self.vertices()) + diff --git a/src/sage/categories/lie_groups.py b/src/sage/categories/lie_groups.py index c2af33196b1..eb9e31abb2a 100644 --- a/src/sage/categories/lie_groups.py +++ b/src/sage/categories/lie_groups.py @@ -8,49 +8,28 @@ # http://www.gnu.org/licenses/ #****************************************************************************** -from sage.misc.abstract_method import abstract_method +#from sage.misc.abstract_method import abstract_method from sage.misc.cachefunc import cached_method -from sage.misc.lazy_attribute import lazy_attribute -from sage.misc.lazy_import import LazyImport -from sage.categories.category import Category -from sage.categories.category_types import Category_over_base_ring -from sage.categories.sets_cat import Sets +from sage.categories.category_singleton import Category_singleton from sage.categories.groups import Groups from sage.categories.manifolds import Manifolds -from sage.rings.all import RR -class LieGroups(Category_over_base_ring): +class LieGroups(Category_singleton): r""" The category of Lie groups. - A Lie group is a topological group with a smooth differentiable - manifold structure. - - INPUT: - - - ``k`` -- (default: ``RR``) the field `k` + A Lie group is a topological group with a smooth manifold structure. EXAMPLES:: sage: from sage.categories.lie_groups import LieGroups sage: C = LieGroups(); C - Category of manifolds over Real Field - sage: C.super_categories() - [Category of additive commutative additive associative additive unital distributive magmas and additive magmas, - Category of modules over Integer Ring] - sage: C = LieGroups(CC); C - Category of manifolds over Complex Field + Category of Lie groups TESTS:: sage: TestSuite(C).run() """ - def __init__(self, R=RR): - """ - Initialize ``self``. - """ - Category_over_base_ring.__init__(self, RR) - @cached_method def super_categories(self): """ @@ -58,10 +37,9 @@ def super_categories(self): sage: from sage.categories.lie_groups import LieGroups sage: LieGroups().super_categories() + [Category of topological groups, Category of smooth manifolds] """ - R = self.base_ring() - # TODO: Make this smooth differentiable manifolds - return [Groups().Topological(), Manifolds(R)] + return [Groups().Topological(), Manifolds().Smooth()] def additional_structure(self): r""" @@ -69,7 +47,7 @@ def additional_structure(self): Indeed, the category of Lie groups defines no new structure: a morphism of topological spaces and of smooth - differentiable manifolds is a morphism as Lie groups. + manifolds is a morphism as Lie groups. .. SEEALSO:: :meth:`Category.additional_structure` @@ -80,3 +58,14 @@ def additional_structure(self): """ return None + # Because Lie is a name that deserves to be capitalized + def _repr_object_names(self): + """ + EXAMPLES:: + + sage: from sage.categories.lie_groups import LieGroups + sage: LieGroups() # indirect doctest + Category of Lie groups + """ + return "Lie groups" + diff --git a/src/sage/categories/manifolds.py b/src/sage/categories/manifolds.py index 56dbde629e9..fa8ce5ff6d0 100644 --- a/src/sage/categories/manifolds.py +++ b/src/sage/categories/manifolds.py @@ -13,58 +13,39 @@ from sage.misc.lazy_attribute import lazy_attribute from sage.misc.lazy_import import LazyImport from sage.categories.category import Category -from sage.categories.category_types import Category_over_base_ring +from sage.categories.category_singleton import Category_singleton +from sage.categories.category_with_axiom import CategoryWithAxiom from sage.categories.sets_cat import Sets from sage.categories.fields import Fields -from sage.rings.all import RR -class Manifolds(Category_over_base_ring): +class Manifolds(Category_singleton): r""" - The category of maniolds. + The category of manifolds over any field. - Let `k` be a field. A `d`-dimensional `k`-*manifold* `M` is a - second countable Hausdorff space such that the neighborhood - of any point `x \in M` is homeomorphic to `k^d`. - - INPUT: - - - ``k`` -- (default: ``RR``) the field `k` + Let `k` be a field. A `k`-*manifold* `M` is a second countable + Hausdorff space such that the neighborhood of any point `x \in M` + is homeomorphic to `k^d` for some `d`. EXAMPLES:: sage: from sage.categories.manifolds import Manifolds sage: C = Manifolds(); C - Category of manifolds over Real Field + Category of manifolds sage: C.super_categories() - [Category of additive commutative additive associative additive unital distributive magmas and additive magmas, - Category of modules over Integer Ring] - sage: C = Manifolds(CC); C - Category of manifolds over Complex Field + [Category of topological spaces] TESTS:: sage: TestSuite(C).run() """ - def __init__(self, k=RR): - """ - Initialize ``self``. - """ - if k not in Fields(): - raise ValueError("must be defined over a field") - Category_over_base_ring.__init__(self, k) - @cached_method def super_categories(self): """ EXAMPLES:: - sage: from sage.categories.magmatic_algebras import MagmaticAlgebras - sage: MagmaticAlgebras(ZZ).super_categories() - [Category of additive commutative additive associative additive unital distributive magmas and additive magmas, Category of modules over Integer Ring] - - sage: from sage.categories.additive_semigroups import AdditiveSemigroups - sage: MagmaticAlgebras(ZZ).is_subcategory((AdditiveSemigroups() & Magmas()).Distributive()) - True + sage: from sage.categories.manifolds import Manifolds + sage: Manifolds().super_categories() + [Category of topological spaces] """ return [Sets().Topological()] @@ -85,7 +66,84 @@ def additional_structure(self): """ return None - class Connected: + class SubcategoryMethods: + @cached_method + def Connected(self): + """ + Return the full subcategory of the connected objects of ``self``. + + EXAMPLES:: + + sage: from sage.categories.manifolds import Manifolds + sage: Manifolds().Connected() + Category of connected manifolds + + TESTS:: + + sage: TestSuite(Manifolds().Connected()).run() + sage: Manifolds().Connected.__module__ + 'sage.categories.manifolds' + """ + return self._with_axiom('Connected') + + @cached_method + def Differentiable(self): + """ + Return the subcategory of the differentiable objects of ``self``. + + EXAMPLES:: + + sage: from sage.categories.manifolds import Manifolds + sage: Manifolds().Differentiable() + Category of differentiable manifolds + + TESTS:: + + sage: TestSuite(Manifolds().Differentiable()).run() + sage: Manifolds().Differentiable.__module__ + 'sage.categories.manifolds' + """ + return self._with_axiom('Differentiable') + + @cached_method + def Smooth(self): + """ + Return the subcategory of the smooth objects of ``self``. + + EXAMPLES:: + + sage: from sage.categories.manifolds import Manifolds + sage: Manifolds().Smooth() + Category of smooth manifolds + + TESTS:: + + sage: TestSuite(Manifolds().Smooth()).run() + sage: Manifolds().Smooth.__module__ + 'sage.categories.manifolds' + """ + return self._with_axiom('Smooth') + + @cached_method + def Complex(self): + """ + Return the full subcategory of the complex objects of ``self``. + + EXAMPLES:: + + sage: from sage.categories.manifolds import Manifolds + sage: Manifolds().Complex() + Category of complex manifolds + + TESTS:: + + sage: TestSuite(Manifolds().Complex()).run() + sage: Manifolds().Complex.__module__ + 'sage.categories.manifolds' + """ + return self._with_axiom('Complex') + + class Connected(CategoryWithAxiom): """ The category of connected manifolds. """ @@ -96,3 +154,60 @@ def dimension(self): Return the dimension of ``self``. """ + class SubcategoryMethods: + @cached_method + def FiniteDimensional(self): + """ + Return the full subcategory of the finite dimensional + objects of ``self``. + + EXAMPLES:: + + sage: from sage.categories.manifolds import Manifolds + sage: C = Manifolds().Connected().FiniteDimensional(); C + Category of finite dimensional connected manifolds + + TESTS:: + + sage: from sage.categories.manifolds import Manifolds + sage: C = Manifolds().Connected().FiniteDimensional() + sage: TestSuite(C).run() + sage: Manifolds().Connected().FiniteDimensional.__module__ + 'sage.categories.manifolds' + """ + return self._with_axiom('FiniteDimensional') + + class FiniteDimensional(CategoryWithAxiom): + """ + Category of finite dimensional (connected) manifolds. + """ + + class Differentiable(CategoryWithAxiom): + """ + The category of differentiable manifolds. + """ + + class Smooth(CategoryWithAxiom): + """ + The category of smooth manifolds. + """ + def extra_super_categories(self): + """ + Return the extra super categories of ``self``. + + A smooth manifold is differentiable. + + EXAMPLES:: + + sage: from sage.categories.manifolds import Manifolds + sage: Manifolds().Smooth().super_categories() # indirect doctest + [Category of differentiable manifolds] + """ + return [Manifolds().Differentiable()] + + class Complex(CategoryWithAxiom): + r""" + The category of complex manifolds, i.e., the underlying vector + space is `\CC^d`. + """ + diff --git a/src/sage/categories/metric_spaces.py b/src/sage/categories/metric_spaces.py index 6b4dec93de3..d01c992fe4f 100644 --- a/src/sage/categories/metric_spaces.py +++ b/src/sage/categories/metric_spaces.py @@ -12,18 +12,7 @@ from sage.categories.category import Category from sage.categories.covariant_functorial_construction import RegressiveCovariantConstructionCategory -class MetricSpaces(RegressiveCovariantConstructionCategory): - r""" - The category of metric spaces. - - A *metric* on a set `S` is a function `d : S \times S \to \RR` - such that: - - - `d(a, b) \geq 0`, - - `d(a, b) = 0` if and only if `a = b`. - - A metric space is a set `S` with a distinguished metric. - """ +class MetricSpacesCategory(RegressiveCovariantConstructionCategory): _functor_category = "Metric" @@ -72,6 +61,37 @@ def default_super_categories(cls, category): return Category.join([category.Topological(), super(MetricSpaces, cls).default_super_categories(category)]) + # We currently don't have a use for this, but we probably will + def _repr_object_names(self): + """ + EXAMPLES:: + + sage: Groups().Metric() # indirect doctest + Category of metric groups + """ + return "metric {}".format(self.base_category()._repr_object_names()) + +class MetricSpaces(MetricSpacesCategory): + r""" + The category of metric spaces. + + A *metric* on a set `S` is a function `d : S \times S \to \RR` + such that: + + - `d(a, b) \geq 0`, + - `d(a, b) = 0` if and only if `a = b`. + + A metric space is a set `S` with a distinguished metric. + """ + def _repr_object_names(self): + """ + EXAMPLES:: + + sage: Sets().Metric() # indirect doctest + Category of metric spaces + """ + return "metric spaces" + class ParentMethods: def _test_metric(self, **options): r""" diff --git a/src/sage/categories/sets_cat.py b/src/sage/categories/sets_cat.py index 1542235b364..55435b11f80 100644 --- a/src/sage/categories/sets_cat.py +++ b/src/sage/categories/sets_cat.py @@ -661,6 +661,18 @@ def Topological(self): from sage.categories.topological_spaces import TopologicalSpacesCategory return TopologicalSpacesCategory.category_of(self) + @cached_method + def Metric(self): + """ + Return the subcategory of the metric objects of ``self``. + + TESTS:: + + sage: TestSuite(Sets().Metric()).run() + """ + from sage.categories.metric_spaces import MetricSpaces + return MetricSpaces.category_of(self) + @cached_method def Algebras(self, base_ring): """ @@ -1567,7 +1579,9 @@ def cartesian_product(*elements): Facade = LazyImport('sage.categories.facade_sets', 'FacadeSets') Finite = LazyImport('sage.categories.finite_sets', 'FiniteSets', at_startup=True) - Topological = LazyImport('sage.categories.topological_spaces', 'TopologicalSpaces') + Topological = LazyImport('sage.categories.topological_spaces', + 'TopologicalSpaces', 'Topological') + Metric = LazyImport('sage.categories.metric_spaces', 'MetricSpaces', 'Mertic') class Infinite(CategoryWithAxiom): diff --git a/src/sage/categories/simplicial_complexes.py b/src/sage/categories/simplicial_complexes.py new file mode 100644 index 00000000000..81121e68920 --- /dev/null +++ b/src/sage/categories/simplicial_complexes.py @@ -0,0 +1,78 @@ +""" +Simplicial Complexes +""" +#***************************************************************************** +# Copyright (C) 2015 Travis Scrimshaw +# +# Distributed under the terms of the GNU General Public License (GPL) +# http://www.gnu.org/licenses/ +#****************************************************************************** + +from sage.misc.abstract_method import abstract_method +from sage.misc.cachefunc import cached_method +from sage.categories.category_singleton import Category_singleton +from sage.categories.category_with_axiom import CategoryWithAxiom +#from sage.categories.cw_complexes import CWComplexes +from sage.categories.sets_cat import Sets + +class SimplicialComplexes(Category_singleton): + r""" + The category of abstract simplicial complexes. + + An abstract simplicial complex `A` is a collection of sets `X` + such that: + + - `\emptyset \in A`, + - if `X \subset Y \in A`, then `X \in A`. + + .. TODO:: + + Implement the category of simplicial complexes considered + as :class:`CW complexes `. + + EXAMPLES:: + + sage: from sage.categories.simplicial_complexes import SimplicialComplexes + sage: C = SimplicialComplexes(); C + Category of simplicial complexes + + TESTS:: + + sage: TestSuite(C).run() + """ + @cached_method + def super_categories(self): + """ + EXAMPLES:: + + sage: from sage.categories.simplicial_complexes import SimplicialComplexes + sage: SimplicialComplexes().super_categories() + [Category of sets] + """ + return [Sets()] + + class Finite(CategoryWithAxiom): + """ + Category of finite simplicial complexes. + """ + class ParentMethods: + @cached_method + def dimension(self): + """ + Return the dimension of ``self``. + """ + return max(c.dimension() for c in self.facets()) + + class ParentMethods: + @abstract_method + def facets(self): + """ + Return the facets of ``self``. + """ + + @abstract_method + def faces(self): + """ + Return the faces of ``self``. + """ + diff --git a/src/sage/categories/topological_spaces.py b/src/sage/categories/topological_spaces.py index 80e31857508..f279509fb5b 100644 --- a/src/sage/categories/topological_spaces.py +++ b/src/sage/categories/topological_spaces.py @@ -11,6 +11,7 @@ from sage.misc.cachefunc import cached_method from sage.misc.lazy_attribute import lazy_class_attribute from sage.categories.category import Category +from sage.categories.category_with_axiom import CategoryWithAxiom from sage.categories.covariant_functorial_construction import RegressiveCovariantConstructionCategory from sage.categories.sets_cat import Sets @@ -23,7 +24,7 @@ def _repr_object_names(self): EXAMPLES:: sage: Groups().Topological() # indirect doctest - Category of graded algebras with basis over Rational Field + Category of topological groups """ return "topological {}".format(self.base_category()._repr_object_names()) @@ -36,7 +37,7 @@ class TopologicalSpaces(TopologicalSpacesCategory): sage: Sets().Topological() Category of topological spaces sage: Sets().Topological().super_categories() - [Category of modules over Integer Ring] + [Category of sets] The category of topological spaces defines the topological structure, which shall be preserved by morphisms:: @@ -60,3 +61,50 @@ def _repr_object_names(self): """ return "topological spaces" + class SubcategoryMethods: + @cached_method + def Connected(self): + """ + Return the full subcategory of the connected objects of ``self``. + + EXAMPLES:: + + sage: Sets().Topological().Connected() + Category of connected topological spaces + + TESTS:: + + sage: TestSuite(Sets().Topological().Connected()).run() + sage: Sets().Topological().Connected.__module__ + 'sage.categories.topological_spaces' + """ + return self._with_axiom('Connected') + + @cached_method + def Compact(self): + """ + Return the subcategory of the compact objects of ``self``. + + EXAMPLES:: + + sage: Sets().Topological().Compact() + Category of compact topological spaces + + TESTS:: + + sage: TestSuite(Sets().Topological().Compact()).run() + sage: Sets().Topological().Compact.__module__ + 'sage.categories.topological_spaces' + """ + return self._with_axiom('Compact') + + class Connected(CategoryWithAxiom): + """ + The category of connected topological spaces. + """ + + class Compact(CategoryWithAxiom): + """ + The category of compact topological spaces. + """ + diff --git a/src/sage/homology/simplicial_complex.py b/src/sage/homology/simplicial_complex.py index c8c188552f6..d50f8bc7aa6 100644 --- a/src/sage/homology/simplicial_complex.py +++ b/src/sage/homology/simplicial_complex.py @@ -169,7 +169,7 @@ from sage.homology.chain_complex import ChainComplex from sage.graphs.graph import Graph from functools import reduce -lazy_import('sage.categories.category_types', 'SimplicialComplexes') +from sage.categories.simplicial_complexes import SimplicialComplexes def lattice_paths(t1, t2, length=None): """ @@ -833,7 +833,7 @@ def __init__(self, if (maximal_faces is not None and from_characteristic_function is not None): raise ValueError("maximal_faces and from_characteristic_function cannot be both defined") - CategoryObject.__init__(self, category=SimplicialComplexes()) + CategoryObject.__init__(self, category=SimplicialComplexes().Finite()) from sage.misc.misc import union C = None @@ -3284,7 +3284,9 @@ def _Hom_(self, other, category=None): sage: T = simplicial_complexes.Sphere(2) sage: H = Hom(S,T) # indirect doctest sage: H - Set of Morphisms 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)} in Category of simplicial complexes + Set of Morphisms 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)} + in Category of finite simplicial complexes sage: f = {0:0,1:1,2:3} sage: x = H(f) sage: x diff --git a/src/sage/homology/simplicial_complex_homset.py b/src/sage/homology/simplicial_complex_homset.py index 46d3aed15d4..db00d572733 100644 --- a/src/sage/homology/simplicial_complex_homset.py +++ b/src/sage/homology/simplicial_complex_homset.py @@ -67,7 +67,9 @@ def is_SimplicialComplexHomset(x): sage: T = SimplicialComplex(is_mutable=False) sage: H = Hom(S, T) sage: H - Set of Morphisms from Simplicial complex with vertex set () and facets {()} to Simplicial complex with vertex set () and facets {()} in Category of simplicial complexes + Set of Morphisms from Simplicial complex with vertex set () and facets {()} + to Simplicial complex with vertex set () and facets {()} + in Category of finite simplicial complexes sage: from sage.homology.simplicial_complex_homset import is_SimplicialComplexHomset sage: is_SimplicialComplexHomset(H) True From fcc3273fbb9e83da6c61027463e3ed4582009514 Mon Sep 17 00:00:00 2001 From: Travis Scrimshaw Date: Sat, 9 May 2015 18:17:22 -0700 Subject: [PATCH 4/4] Move dim to all manifolds, move methods from H-plane to metric spaces, some fixes. --- src/sage/categories/manifolds.py | 74 ++++++++-------- src/sage/categories/metric_spaces.py | 84 +++++++++++++++---- src/sage/categories/sets_cat.py | 4 +- src/sage/categories/simplicial_complexes.py | 21 +++++ .../hyperbolic_space/hyperbolic_interface.py | 35 +------- 5 files changed, 132 insertions(+), 86 deletions(-) diff --git a/src/sage/categories/manifolds.py b/src/sage/categories/manifolds.py index fa8ce5ff6d0..67708e7858d 100644 --- a/src/sage/categories/manifolds.py +++ b/src/sage/categories/manifolds.py @@ -22,9 +22,9 @@ class Manifolds(Category_singleton): r""" The category of manifolds over any field. - Let `k` be a field. A `k`-*manifold* `M` is a second countable - Hausdorff space such that the neighborhood of any point `x \in M` - is homeomorphic to `k^d` for some `d`. + Let `k` be a field. A `k`-*manifold* `M` of dimension `d` is a + second countable Hausdorff space such that the neighborhood of + any point `x \in M` is homeomorphic to `k^b` for some `b \leq d`. EXAMPLES:: @@ -66,6 +66,13 @@ def additional_structure(self): """ return None + class ParentMethods: + @abstract_method + def dimension(self): + """ + Return the dimension of ``self``. + """ + class SubcategoryMethods: @cached_method def Connected(self): @@ -143,44 +150,37 @@ def Complex(self): """ return self._with_axiom('Complex') + @cached_method + def FiniteDimensional(self): + """ + Return the full subcategory of the finite dimensional + objects of ``self``. + + EXAMPLES:: + + sage: from sage.categories.manifolds import Manifolds + sage: C = Manifolds().Connected().FiniteDimensional(); C + Category of finite dimensional connected manifolds + + TESTS:: + + sage: from sage.categories.manifolds import Manifolds + sage: C = Manifolds().Connected().FiniteDimensional() + sage: TestSuite(C).run() + sage: Manifolds().Connected().FiniteDimensional.__module__ + 'sage.categories.manifolds' + """ + return self._with_axiom('FiniteDimensional') + + class FiniteDimensional(CategoryWithAxiom): + """ + Category of finite dimensional manifolds. + """ + class Connected(CategoryWithAxiom): """ The category of connected manifolds. """ - class ParentMethods: - @abstract_method - def dimension(self): - """ - Return the dimension of ``self``. - """ - - class SubcategoryMethods: - @cached_method - def FiniteDimensional(self): - """ - Return the full subcategory of the finite dimensional - objects of ``self``. - - EXAMPLES:: - - sage: from sage.categories.manifolds import Manifolds - sage: C = Manifolds().Connected().FiniteDimensional(); C - Category of finite dimensional connected manifolds - - TESTS:: - - sage: from sage.categories.manifolds import Manifolds - sage: C = Manifolds().Connected().FiniteDimensional() - sage: TestSuite(C).run() - sage: Manifolds().Connected().FiniteDimensional.__module__ - 'sage.categories.manifolds' - """ - return self._with_axiom('FiniteDimensional') - - class FiniteDimensional(CategoryWithAxiom): - """ - Category of finite dimensional (connected) manifolds. - """ class Differentiable(CategoryWithAxiom): """ diff --git a/src/sage/categories/metric_spaces.py b/src/sage/categories/metric_spaces.py index d01c992fe4f..b1ca4144ea1 100644 --- a/src/sage/categories/metric_spaces.py +++ b/src/sage/categories/metric_spaces.py @@ -11,6 +11,7 @@ from sage.misc.abstract_method import abstract_method from sage.categories.category import Category from sage.categories.covariant_functorial_construction import RegressiveCovariantConstructionCategory +from sage.categories.with_realizations import WithRealizationsCategory class MetricSpacesCategory(RegressiveCovariantConstructionCategory): @@ -33,7 +34,7 @@ def default_super_categories(cls, category): A (join) category - In practice, this returns ``category.Subquotients()``, joined + In practice, this returns ``category.Metric()``, joined together with the result of the method :meth:`RegressiveCovariantConstructionCategory.default_super_categories() ` @@ -42,24 +43,20 @@ def default_super_categories(cls, category): EXAMPLES: - Consider ``category=Groups()``, which has ``cat=Monoids()`` as - super category. Then, a subgroup of a group `G` is - simultaneously a subquotient of `G`, a group by itself, and a - submonoid of `G`:: + Consider ``category=Groups()``. Then, a group `G` with a metric + is simultaneously a topological group by itself, and a + topogological space:: - sage: Groups().Subobjects().super_categories() - [Category of groups, Category of subquotients of monoids, Category of subobjects of sets] - - Mind the last item above: there is indeed currently nothing - implemented about submonoids. + sage: Groups().Metric().super_categories() + [Category of topological groups, Category of metric spaces] This resulted from the following call:: - sage: sage.categories.subobjects.SubobjectsCategory.default_super_categories(Groups()) - Join of Category of groups and Category of subquotients of monoids and Category of subobjects of sets + sage: sage.categories.metric_spaces.MetricSpacesCategory.default_super_categories(Groups()) + Join of Category of topological groups and Category of metric spaces """ return Category.join([category.Topological(), - super(MetricSpaces, cls).default_super_categories(category)]) + super(MetricSpacesCategory, cls).default_super_categories(category)]) # We currently don't have a use for this, but we probably will def _repr_object_names(self): @@ -67,7 +64,7 @@ def _repr_object_names(self): EXAMPLES:: sage: Groups().Metric() # indirect doctest - Category of metric groups + Join of Category of topological groups and Category of metric spaces """ return "metric {}".format(self.base_category()._repr_object_names()) @@ -101,6 +98,13 @@ def _test_metric(self, **options): - ``options`` -- any keyword arguments accepted by :meth:`_tester` + + EXAMPLES:: + + sage: UHP = HyperbolicPlane().UHP() + sage: UHP._test_metric() + sage: elts = [UHP.random_element() for i in range(5)] + sage: UHP._test_metric(some_elements=elts) """ tester = self._tester(**options) S = tester.some_elements() @@ -108,7 +112,7 @@ def _test_metric(self, **options): for a in S: for b in S: d = dist(a, b) - if a != b: + if a is not b: tester.assertGreater(d, 0) else: tester.assertEqual(d, 0) @@ -116,6 +120,15 @@ def _test_metric(self, **options): def metric(self): """ Return the metric of ``self``. + + EXAMPLES:: + + sage: UHP = HyperbolicPlane().UHP() + sage: m = UHP.metric() + sage: p1 = UHP.get_point(5 + 7*I) + sage: p2 = UHP.get_point(1.0 + I) + sage: m(p1, p2) + 2.23230104635820 """ return lambda a,b: self.dist(a, b) @@ -123,12 +136,51 @@ def metric(self): def dist(self, a, b): """ Return the distance between ``a`` and ``b`` in ``self``. + + EXAMPLES:: + + sage: UHP = HyperbolicPlane().UHP() + sage: p1 = UHP.get_point(5 + 7*I) + sage: p2 = UHP.get_point(1.0 + I) + sage: UHP.dist(p1, p2) + 2.23230104635820 + + sage: PD = HyperbolicPlane().PD() + sage: PD.dist(PD.get_point(0), PD.get_point(I/2)) + arccosh(5/3) """ class ElementMethods: def dist(self, b): """ - Return the distance between ``self`` and ``b``. + Return the distance between ``self`` and ``other``. + + EXAMPLES:: + + sage: UHP = HyperbolicPlane().UHP() + sage: p1 = UHP.get_point(5 + 7*I) + sage: p2 = UHP.get_point(1 + I) + sage: p1.dist(p2) + arccosh(33/7) """ return self.parent().dist(self, b) + class WithRealizations(WithRealizationsCategory): + class ParentMethods: + def dist(self, a, b): + """ + Return the distance between ``a`` and ``b`` by converting them + to a realization of ``self`` and doing the computation. + + EXAMPLES:: + + sage: H = HyperbolicPlane() + sage: PD = H.PD() + sage: p1 = PD.get_point(0) + sage: p2 = PD.get_point(I/2) + sage: H.dist(p1, p2) + arccosh(5/3) + """ + R = self.a_realization() + return R.dist(R(a), R(b)) + diff --git a/src/sage/categories/sets_cat.py b/src/sage/categories/sets_cat.py index 16cd6b9fd00..bda38036ff8 100644 --- a/src/sage/categories/sets_cat.py +++ b/src/sage/categories/sets_cat.py @@ -670,8 +670,8 @@ def Metric(self): sage: TestSuite(Sets().Metric()).run() """ - from sage.categories.metric_spaces import MetricSpaces - return MetricSpaces.category_of(self) + from sage.categories.metric_spaces import MetricSpacesCategory + return MetricSpacesCategory.category_of(self) @cached_method def Algebras(self, base_ring): diff --git a/src/sage/categories/simplicial_complexes.py b/src/sage/categories/simplicial_complexes.py index 81121e68920..d5ca22561aa 100644 --- a/src/sage/categories/simplicial_complexes.py +++ b/src/sage/categories/simplicial_complexes.py @@ -60,6 +60,12 @@ class ParentMethods: def dimension(self): """ Return the dimension of ``self``. + + EXAMPLES:: + + sage: S = SimplicialComplex([[1,3,4], [1,2],[2,5],[4,5]]) + sage: S.dimension() + 2 """ return max(c.dimension() for c in self.facets()) @@ -68,11 +74,26 @@ class ParentMethods: def facets(self): """ Return the facets of ``self``. + + EXAMPLES:: + + sage: S = SimplicialComplex([[1,3,4], [1,2],[2,5],[4,5]]) + sage: S.facets() + {(1, 2), (1, 3, 4), (2, 5), (4, 5)} """ @abstract_method def faces(self): """ Return the faces of ``self``. + + EXAMPLES:: + + sage: S = SimplicialComplex([[1,3,4], [1,2],[2,5],[4,5]]) + sage: S.faces() + {-1: {()}, + 0: {(1,), (2,), (3,), (4,), (5,)}, + 1: {(1, 2), (1, 3), (1, 4), (2, 5), (3, 4), (4, 5)}, + 2: {(1, 3, 4)}} """ diff --git a/src/sage/geometry/hyperbolic_space/hyperbolic_interface.py b/src/sage/geometry/hyperbolic_space/hyperbolic_interface.py index d8d3c411467..d2a4008207f 100644 --- a/src/sage/geometry/hyperbolic_space/hyperbolic_interface.py +++ b/src/sage/geometry/hyperbolic_space/hyperbolic_interface.py @@ -97,7 +97,7 @@ def __init__(self): sage: H = HyperbolicPlane() sage: TestSuite(H).run() """ - Parent.__init__(self, category=Sets().WithRealizations()) + Parent.__init__(self, category=Sets().Metric().WithRealizations()) self.a_realization() # We create a realization so at least one is known def _repr_(self): @@ -181,9 +181,10 @@ def super_categories(self): sage: H = HyperbolicPlane() sage: models = HyperbolicModels(H) sage: models.super_categories() - [Category of sets, Category of realizations of Hyperbolic plane] + [Category of metric spaces, + Category of realizations of Hyperbolic plane] """ - return [Sets(), Realizations(self.base())] + return [Sets().Metric(), Realizations(self.base())] class ParentMethods: def _an_element_(self): @@ -204,31 +205,3 @@ def _an_element_(self): """ return self(self.realization_of().PD().get_point(0)) - # TODO: Move to a category of metric spaces once created - @abstract_method - def dist(self, a, b): - """ - Return the distance between ``a`` and ``b``. - - EXAMPLES:: - - sage: PD = HyperbolicPlane().PD() - sage: PD.dist(PD.get_point(0), PD.get_point(I/2)) - arccosh(5/3) - """ - - class ElementMethods: - # TODO: Move to a category of metric spaces once created - def dist(self, other): - """ - Return the distance between ``self`` and ``other``. - - EXAMPLES:: - - sage: UHP = HyperbolicPlane().UHP() - sage: p1 = UHP.get_point(5 + 7*I) - sage: p2 = UHP.get_point(1 + I) - sage: p1.dist(p2) - arccosh(33/7) - """ - return self.parent().dist(self, other)