Skip to content

Commit

Permalink
gh-35581: sage.{topology,homology}: Modularization fixes
Browse files Browse the repository at this point in the history
    
<!-- Please provide a concise, informative and self-explanatory title.
-->
<!-- Don't put issue numbers in the title. Put it in the Description
below. -->
<!-- For example, instead of "Fixes #12345", use "Add a new method to
multiply two integers" -->

### 📚 Description
`sage.topology` is closely linked to functionality from `sage.graphs`.
Doctests that either use methods or examples that require `sage.graphs`
are marked `# optional - sage.graphs`; likewise for `sage.groups` (for
multiplicative groups) and (less often) `sage.combinat`.
Doctests that use finite fields are marked as `# optional -
sage.rings.finite_rings` because implementation classes of GF(...)
depend on various libraries.
Doctests that compute homology are marked as `# optional - sage.modules`
because `sage.homology` needs vector spaces. This functionality is not
part of the distribution **sagemath-categories** but a higher up
distribution (as of #35095, the distribution **sagemath-polyhedra**
contains `sage.modules`, `sage.matrix`, `sage.homology`).
Doctests involving free resolutions are marked `# optional -
sage.libs.singular`.

Some examples are read from data files; the corresponding tests are now
marked `# optional - pyparsing`.

A sporadic use of a function from `numpy` has been replaced by an
equivalent `itertools` function.

The correct placement of the `# optional` tags can be (and has been)
tested using #35095.

While going through the doctests, I also reformatted some so that they
can be read in our HTML documentation style (furo) without having to
scroll horizontally.

<!-- Describe your changes here in detail. -->
<!-- Why is this change required? What problem does it solve? -->
Part of:
- #29705
<!-- If this PR resolves an open issue, please link to it here. For
example "Fixes #12345". -->
<!-- If your change requires a documentation PR, please link it
appropriately. -->

### 📝 Checklist

<!-- Put an `x` in all the boxes that apply. It should be `[x]` not `[x
]`. -->

- [x] The title is concise, informative, and self-explanatory.
- [x] The description explains in detail what this PR is about.
- [x] I have linked a relevant issue or discussion.
- [ ] I have created tests covering the changes.
- [ ] I have updated the documentation accordingly.

### ⌛ Dependencies

<!-- List all open PRs that this PR logically depends on
- #12345: short description why this is a dependency
- #34567: ...
-->

<!-- If you're unsure about any of these, don't hesitate to ask. We're
here to help! -->
    
URL: #35581
Reported by: Matthias Köppe
Reviewer(s): Kwankyu Lee, Matthias Köppe
  • Loading branch information
Release Manager committed May 27, 2023
2 parents be85e35 + c4c593a commit cb2f3c0
Show file tree
Hide file tree
Showing 26 changed files with 1,494 additions and 1,367 deletions.
55 changes: 28 additions & 27 deletions src/sage/categories/simplicial_sets.py
Original file line number Diff line number Diff line change
Expand Up @@ -347,10 +347,10 @@ def _universal_cover_dict(self):
TESTS::
sage: RP2 = simplicial_sets.RealProjectiveSpace(2)
sage: RP2._universal_cover_dict()
sage: RP2 = simplicial_sets.RealProjectiveSpace(2) # optional - sage.groups
sage: RP2._universal_cover_dict() # optional - sage.groups
(Finitely presented group < e | e^2 >, {f: e})
sage: RP2.nondegenerate_simplices()
sage: RP2.nondegenerate_simplices() # optional - sage.groups
[1, f, f * f]
"""
from sage.groups.free_group import FreeGroup
Expand Down Expand Up @@ -393,14 +393,14 @@ def universal_cover_map(self):
EXAMPLES::
sage: RP2 = simplicial_sets.RealProjectiveSpace(2)
sage: phi = RP2.universal_cover_map()
sage: phi
sage: RP2 = simplicial_sets.RealProjectiveSpace(2) # optional - sage.groups
sage: phi = RP2.universal_cover_map(); phi # optional - sage.groups
Simplicial set morphism:
From: Simplicial set with 6 non-degenerate simplices
To: RP^2
Defn: [(1, 1), (1, e), (f, 1), (f, e), (f * f, 1), (f * f, e)] --> [1, 1, f, f, f * f, f * f]
sage: phi.domain().face_data()
Defn: [(1, 1), (1, e), (f, 1), (f, e), (f * f, 1), (f * f, e)]
--> [1, 1, f, f, f * f, f * f]
sage: phi.domain().face_data() # optional - sage.groups
{(1, 1): None,
(1, e): None,
(f, 1): ((1, e), (1, 1)),
Expand Down Expand Up @@ -432,18 +432,20 @@ def covering_map(self, character):
EXAMPLES::
sage: S1 = simplicial_sets.Sphere(1)
sage: W = S1.wedge(S1)
sage: G = CyclicPermutationGroup(3)
sage: a, b = W.n_cells(1)
sage: C = W.covering_map({a : G.gen(0), b : G.one()})
sage: C
sage: W = S1.wedge(S1) # optional - sage.graphs
sage: G = CyclicPermutationGroup(3) # optional - sage.groups
sage: a, b = W.n_cells(1) # optional - sage.graphs
sage: C = W.covering_map({a : G.gen(0), b : G.one()}); C # optional - sage.graphs sage.groups
Simplicial set morphism:
From: Simplicial set with 9 non-degenerate simplices
To: Wedge: (S^1 v S^1)
Defn: [(*, ()), (*, (1,2,3)), (*, (1,3,2)), (sigma_1, ()), (sigma_1, ()), (sigma_1, (1,2,3)), (sigma_1, (1,2,3)), (sigma_1, (1,3,2)), (sigma_1, (1,3,2))] --> [*, *, *, sigma_1, sigma_1, sigma_1, sigma_1, sigma_1, sigma_1]
sage: C.domain()
Defn: [(*, ()), (*, (1,2,3)), (*, (1,3,2)), (sigma_1, ()),
(sigma_1, ()), (sigma_1, (1,2,3)), (sigma_1, (1,2,3)),
(sigma_1, (1,3,2)), (sigma_1, (1,3,2))]
--> [*, *, *, sigma_1, sigma_1, sigma_1, sigma_1, sigma_1, sigma_1]
sage: C.domain() # optional - sage.graphs sage.groups
Simplicial set with 9 non-degenerate simplices
sage: C.domain().face_data()
sage: C.domain().face_data() # optional - sage.graphs sage.groups
{(*, ()): None,
(*, (1,2,3)): None,
(*, (1,3,2)): None,
Expand Down Expand Up @@ -517,11 +519,11 @@ def cover(self, character):
EXAMPLES::
sage: S1 = simplicial_sets.Sphere(1)
sage: W = S1.wedge(S1)
sage: G = CyclicPermutationGroup(3)
sage: (a, b) = W.n_cells(1)
sage: C = W.cover({a : G.gen(0), b : G.gen(0)^2})
sage: C.face_data()
sage: W = S1.wedge(S1) # optional - sage.graphs
sage: G = CyclicPermutationGroup(3) # optional - sage.groups
sage: (a, b) = W.n_cells(1) # optional - sage.graphs
sage: C = W.cover({a : G.gen(0), b : G.gen(0)^2}) # optional - sage.graphs sage.groups
sage: C.face_data() # optional - sage.graphs sage.groups
{(*, ()): None,
(*, (1,2,3)): None,
(*, (1,3,2)): None,
Expand All @@ -531,9 +533,9 @@ def cover(self, character):
(sigma_1, (1,2,3)): ((*, ()), (*, (1,2,3))),
(sigma_1, (1,3,2)): ((*, ()), (*, (1,3,2))),
(sigma_1, (1,3,2)): ((*, (1,2,3)), (*, (1,3,2)))}
sage: C.homology(1)
sage: C.homology(1) # optional - sage.graphs sage.groups sage.modules
Z x Z x Z x Z
sage: C.fundamental_group()
sage: C.fundamental_group() # optional - sage.graphs sage.groups
Finitely presented group < e0, e1, e2, e3 | >
"""
return self.covering_map(character).domain()
Expand All @@ -546,11 +548,10 @@ def universal_cover(self):
EXAMPLES::
sage: RP3 = simplicial_sets.RealProjectiveSpace(3)
sage: C = RP3.universal_cover()
sage: C
sage: RP3 = simplicial_sets.RealProjectiveSpace(3) # optional - sage.groups
sage: C = RP3.universal_cover(); C # optional - sage.groups
Simplicial set with 8 non-degenerate simplices
sage: C.face_data()
sage: C.face_data() # optional - sage.groups
{(1, 1): None,
(1, e): None,
(f, 1): ((1, e), (1, 1)),
Expand Down
1 change: 1 addition & 0 deletions src/sage/features/standard.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ def all_features():
JoinFeature('pplpy', (PythonModule('ppl'),), spkg='pplpy'),
PythonModule('primecountpy', spkg='primecountpy'),
PythonModule('ptyprocess', spkg='ptyprocess'),
PythonModule('pyparsing', spkg='pyparsing'),
PythonModule('requests', spkg='requests'),
PythonModule('scipy', spkg='scipy'),
PythonModule('sympy', spkg='sympy')]
13 changes: 7 additions & 6 deletions src/sage/homology/algebraic_topological_model.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# -*- coding: utf-8 -*-
# sage.doctest: optional - sage.graphs
r"""
Algebraic topological model for a cell complex
Expand Down Expand Up @@ -100,8 +100,8 @@ def algebraic_topological_model(K, base_ring=None):
sage: from sage.homology.algebraic_topological_model import algebraic_topological_model
sage: RP2 = simplicial_complexes.RealProjectivePlane()
sage: phi, M = algebraic_topological_model(RP2, GF(2))
sage: M.homology()
sage: phi, M = algebraic_topological_model(RP2, GF(2)) # optional - sage.rings.finite_rings
sage: M.homology() # optional - sage.rings.finite_rings
{0: Vector space of dimension 1 over Finite Field of size 2,
1: Vector space of dimension 1 over Finite Field of size 2,
2: Vector space of dimension 1 over Finite Field of size 2}
Expand All @@ -123,7 +123,8 @@ def algebraic_topological_model(K, base_ring=None):
1
sage: phi.dual()
Chain homotopy between:
Chain complex endomorphism of Chain complex with at most 3 nonzero terms over Rational Field
Chain complex endomorphism of
Chain complex with at most 3 nonzero terms over Rational Field
and Chain complex morphism:
From: Chain complex with at most 3 nonzero terms over Rational Field
To: Chain complex with at most 3 nonzero terms over Rational Field
Expand Down Expand Up @@ -369,8 +370,8 @@ def algebraic_topological_model_delta_complex(K, base_ring=None):
sage: from sage.homology.algebraic_topological_model import algebraic_topological_model_delta_complex as AT_model
sage: RP2 = simplicial_complexes.RealProjectivePlane()
sage: phi, M = AT_model(RP2, GF(2))
sage: M.homology()
sage: phi, M = AT_model(RP2, GF(2)) # optional - sage.rings.finite_rings
sage: M.homology() # optional - sage.rings.finite_rings
{0: Vector space of dimension 1 over Finite Field of size 2,
1: Vector space of dimension 1 over Finite Field of size 2,
2: Vector space of dimension 1 over Finite Field of size 2}
Expand Down
Loading

0 comments on commit cb2f3c0

Please sign in to comment.