morphism

Morphisms between Surfaces

Note

Typically, morphisms are actual maps between surfaces that preserve the structure of the surface. In this case, such morphisms live in the appropriate category. However, sometimes, morphisms are not meaningful on the points of a surface but just on homology say.

We aim to encode this in the category of the morphism to some extent. For example, a morphism in the category of translation surfaces, is preserving the structure of a translation surface. A morphism in the category of objects, on the other hand, is not preserving any structure of a topological space but just meaningful in some other context.

Note

Our morphism infrastructure contains quite a few workarounds to make the SageMath machinery work. The fundamental problem that we are facing is that our parents (surfaces) are not unique representations. However, surfaces do implement equality if they are indistinguishable (and this is a good idea to make pickling work). SageMath has the assumption that if S == T (which in SageMath normally implies S is T) that then Hom(S) is Hom(T). We could implement this, but then Hom(T).domain() is not T but S. Instead, we opted for tricking the coercion machinery into allowing our non-unique homsets. Namely, when comparing morphisms, we do not coerce them into a common parent first but compare them directly.

EXAMPLES:

We can use morphisms to follow a surface through a retriangulation process:

sage: from flatsurf import translation_surfaces
sage: S = translation_surfaces.regular_octagon()
sage: morphism = S.subdivide_edges(3)
sage: morphism = morphism.codomain().triangulate() * morphism
sage: T = morphism.codomain()

sage: morphism
Composite morphism:
  From: Translation Surface in H_2(2) built from a regular octagon
  To:   Triangulation of Translation Surface in H_2(2, 0^8) built from a regular octagon with 16 marked vertices
  Defn: Edge-Subdivision morphism:
          From: Translation Surface in H_2(2) built from a regular octagon
          To:   Translation Surface in H_2(2, 0^8) built from a regular octagon with 16 marked vertices
        then Triangulation morphism:
          From: Translation Surface in H_2(2, 0^8) built from a regular octagon with 16 marked vertices
          To:   Triangulation of Translation Surface in H_2(2, 0^8) built from a regular octagon with 16 marked vertices

We can then map points through the morphism:

sage: p = S(0, (0, 0))
sage: p
Vertex 0 of polygon 0

sage: q = morphism(p)
sage: q
Vertex 0 of polygon (0, 10)

A non-singular point:

sage: p = S(0, (1, 1))
sage: p
Point (1, 1) of polygon 0

sage: q = morphism(p)
sage: q
Point (1, 1) of polygon (0, 7)
class flatsurf.geometry.morphism.CompositionMorphism(parent, lhs, rhs)[source]

The formal composition of two morphisms between surfaces.

EXAMPLES:

sage: from flatsurf import translation_surfaces
sage: S = translation_surfaces.regular_octagon()
sage: f = S.triangulate()
sage: T = f.codomain()
sage: g = T.delaunay_triangulate()

sage: composition = g * f
sage: composition
Composite morphism:
  From: Translation Surface in H_2(2) built from a regular octagon
  To:   Delaunay triangulation of Triangulation of Translation Surface in H_2(2) built from a regular octagon
  Defn: Triangulation morphism:
          From: Translation Surface in H_2(2) built from a regular octagon
          To:   Triangulation of Translation Surface in H_2(2) built from a regular octagon
        then Delaunay triangulation morphism:
          From: Triangulation of Translation Surface in H_2(2) built from a regular octagon
          To:   Delaunay triangulation of Triangulation of Translation Surface in H_2(2) built from a regular octagon
__eq__(other)[source]

Return whether this morphism is indistinguishable from other.

EXAMPLES:

sage: from flatsurf import translation_surfaces
sage: S = translation_surfaces.regular_octagon()
sage: f = S.triangulate()
sage: T = f.codomain()
sage: g = T.delaunay_triangulate()

sage: g * f == g * f
True
__hash__()[source]

Return a hash value for this morphism that is compatible with __eq__().

EXAMPLES:

sage: from flatsurf import translation_surfaces
sage: S = translation_surfaces.regular_octagon()
sage: f = S.triangulate()
sage: T = f.codomain()
sage: g = T.delaunay_triangulate()

sage: hash(g * f) == hash(g * f)
True
__init__(parent, lhs, rhs)[source]
__module__ = 'flatsurf.geometry.morphism'
section()[source]

Return a section of this morphism.

EXAMPLES:

sage: from flatsurf import translation_surfaces
sage: S = translation_surfaces.regular_octagon()
sage: f = S.triangulate()
sage: T = f.codomain()
sage: g = T.delaunay_triangulate()
sage: h = g * f

sage: h.section()
Composite morphism:
  From: Delaunay triangulation of Triangulation of Translation Surface in H_2(2) built from a regular octagon
  To:   Translation Surface in H_2(2) built from a regular octagon
  Defn: Section morphism:
          From: Delaunay triangulation of Triangulation of Translation Surface in H_2(2) built from a regular octagon
          To:   Triangulation of Translation Surface in H_2(2) built from a regular octagon
          Defn: Section of Delaunay triangulation morphism:
                  From: Triangulation of Translation Surface in H_2(2) built from a regular octagon
                  To:   Delaunay triangulation of Triangulation of Translation Surface in H_2(2) built from a regular octagon
        then Section morphism:
          From: Triangulation of Translation Surface in H_2(2) built from a regular octagon
          To:   Translation Surface in H_2(2) built from a regular octagon
          Defn: Section of Triangulation morphism:
                  From: Translation Surface in H_2(2) built from a regular octagon
                  To:   Triangulation of Translation Surface in H_2(2) built from a regular octagon
class flatsurf.geometry.morphism.DelaunayDecompositionIsomorphism[source]

An isomorphism between Delaunay decompositions.

Note

This method relies on pyflatsurf to figure out the isomorphism when _factorization() is called. This is not a NamedFactorizationMorphism since the factorization is not pickleable currently. This is not a very pretty solution since the exact chosen isomorphism is now an implementation detail that could change between different versions of libflatsurf.

EXAMPLES:

sage: from flatsurf import translation_surfaces
sage: S = translation_surfaces.square_torus()
sage: T = S.relabel({0: 1})
sage: isomorphism = S.delaunay_decompose(codomain=T)._factorization()  # optional: pyflatsurf  # random output due to cppyy deprecation warnings
sage: isomorphism  # optional: pyflatsurf
Delaunay decomposition morphism:
  From: Translation Surface in H_1(0) built from a square
  To:   Translation Surface in H_1(0) built from a square
__annotations__ = {}
__eq__(other)[source]

Return whether this isomorphism is indistinguishable from other.

EXAMPLES:

sage: from flatsurf import translation_surfaces
sage: S = translation_surfaces.square_torus()
sage: T = S.relabel({0: 1})
sage: S.delaunay_decompose(codomain=T)._factorization() == S.delaunay_decompose(codomain=T)._factorization()  # optional: pyflatsurf
True
__hash__()[source]

Return a hash value for this isomorphism that is compatible with __eq__().

EXAMPLES:

sage: from flatsurf import translation_surfaces
sage: S = translation_surfaces.square_torus()
sage: T = S.relabel({0: 1})
sage: hash(S.delaunay_decompose(codomain=T)._factorization()) == hash(S.delaunay_decompose(codomain=T)._factorization())  # optional: pyflatsurf
True
__module__ = 'flatsurf.geometry.morphism'
__reduce__()[source]

Return a picklable version of this morphism.

EXAMPLES:

sage: from flatsurf import translation_surfaces
sage: S = translation_surfaces.square_torus()
sage: T = S.relabel({0: 1})
sage: isomorphism = S.delaunay_decompose(codomain=T)._factorization()  # optional: pyflatsurf
sage: loads(dumps(isomorphism)) == isomorphism  # optional: pyflatsurf
True
_factorization()[source]

Return the sequence of morphism that implement this isomorphism.

EXAMPLES:

sage: from flatsurf import translation_surfaces
sage: S = translation_surfaces.square_torus()
sage: T = S.relabel({0: 1})
sage: isomorphism = S.delaunay_decompose(codomain=T)._factorization()  # optional: pyflatsurf
sage: isomorphism._factorization()  # optional: pyflatsurf
Composite morphism:
  From: Translation Surface in H_1(0) built from a square
  To:   Translation Surface in H_1(0) built from a square
  Defn: Triangulation morphism:
          From: Translation Surface in H_1(0) built from a square
          To:   Triangulation of Translation Surface in H_1(0) built from a square
        then pyflatsurf conversion morphism:
          From: Triangulation of Translation Surface in H_1(0) built from a square
          To:   Surface backed by FlatTriangulationCombinatorial...
        then pyflatsurf deformation morphism:
          From: Surface backed by FlatTriangulationCombinatorial...
          To:   Surface backed by FlatTriangulationCombinatorial...
          Defn: ...
        then pyflatsurf reconversion morphism:
          From: Surface backed by FlatTriangulationCombinatorial...
          To:   Triangulation of Translation Surface in H_1(0) built from a square
        then Section morphism:
          From: Triangulation of Translation Surface in H_1(0) built from a square
          To:   Translation Surface in H_1(0) built from a square
          Defn: Section of Triangulation morphism:
                  From: Translation Surface in H_1(0) built from a square
                  To:   Triangulation of Translation Surface in H_1(0) built from a square
class flatsurf.geometry.morphism.DelaunayDecompositionMorphism(parent, morphism)[source]

A morphism describing the Delaunay decomposition of a Delaunay triangulation.

EXAMPLES:

sage: from flatsurf import translation_surfaces
sage: S = translation_surfaces.square_torus()
sage: f = S.delaunay_decompose()._factorization()._morphisms[1]
sage: f
Delaunay decomposition morphism:
  From: Delaunay triangulation of Translation Surface in H_1(0) built from a square
  To:   Delaunay cell decomposition of Translation Surface in H_1(0) built from a square
  Defn: Section of Triangulation morphism:
          From: Delaunay cell decomposition of Translation Surface in H_1(0) built from a square
          To:   Delaunay triangulation of Translation Surface in H_1(0) built from a square

This morphism is implemented as the formal section of a triangulation morphism:

sage: f.section()
Triangulation morphism:
  From: Delaunay cell decomposition of Translation Surface in H_1(0) built from a square
  To:   Delaunay triangulation of Translation Surface in H_1(0) built from a square
__annotations__ = {}
__eq__(other)[source]

Return whether this morphism is indistinguishable from other.

EXAMPLES:

sage: from flatsurf import translation_surfaces
sage: S = translation_surfaces.square_torus()
sage: f = S.delaunay_decompose()._factorization()._morphisms[1]
sage: g = S.delaunay_decompose()._factorization()._morphisms[1]

sage: f == g
True
__hash__()[source]

Return a hash value for this morphism that is compatible with __eq__().

EXAMPLES:

sage: from flatsurf import translation_surfaces
sage: S = translation_surfaces.square_torus()
sage: f = S.delaunay_decompose()._factorization()._morphisms[1]
sage: g = S.delaunay_decompose()._factorization()._morphisms[1]

sage: hash(f) == hash(g)
True
__module__ = 'flatsurf.geometry.morphism'
class flatsurf.geometry.morphism.DelaunayTriangulationMorphism[source]

A morphism from a triangulated surface to its Delaunay triangulation.

EXAMPLES:

sage: from flatsurf import translation_surfaces
sage: S = translation_surfaces.square_torus()
sage: f = S.delaunay_triangulate()._factorization()._morphisms[1]
sage: f
Delaunay retriangulation morphism:
  From: Triangulation of Translation Surface in H_1(0) built from a square
  To:   Delaunay triangulation of Translation Surface in H_1(0) built from a square
__annotations__ = {}
__eq__(other)[source]

Return whether this morphism is indistinguishable from other.

EXAMPLES:

sage: from flatsurf import translation_surfaces
sage: S = translation_surfaces.square_torus()
sage: f = S.delaunay_triangulate()._factorization()._morphisms[1]
sage: g = S.delaunay_triangulate()._factorization()._morphisms[1]
sage: f == g
True
__hash__()[source]

Return a hash value for this morphism that is compatible with __eq__().

EXAMPLES:

sage: from flatsurf import translation_surfaces
sage: S = translation_surfaces.square_torus()
sage: f = S.delaunay_triangulate()._factorization()._morphisms[1]
sage: g = S.delaunay_triangulate()._factorization()._morphisms[1]
sage: hash(f) == hash(g)
True
__module__ = 'flatsurf.geometry.morphism'
class flatsurf.geometry.morphism.DelaunayTriangulationMorphism_delaunay_decomposition[source]

A triangulation that maps a a Delaunay decomposition into the Delaunay triangulation from which it was created.

This morphism is used internally in delaunay_decompose(), the actual delaunay decomposition, is the inverse of this morphism.

EXAMPLES:

sage: from flatsurf import translation_surfaces
sage: S = translation_surfaces.square_torus()
sage: f = S.delaunay_decompose()._factorization()._morphisms[1].section()
sage: f
Triangulation morphism:
  From: Delaunay cell decomposition of Translation Surface in H_1(0) built from a square
  To:   Delaunay triangulation of Translation Surface in H_1(0) built from a square
__annotations__ = {}
__eq__(other)[source]

Return whether this morphism is indistinguishable from other.

EXAMPLES:

sage: from flatsurf import translation_surfaces
sage: S = translation_surfaces.square_torus()
sage: f = S.delaunay_decompose()._factorization()._morphisms[1].section()
sage: g = S.delaunay_decompose()._factorization()._morphisms[1].section()
sage: f == g
True
__hash__()[source]

Return a hash value for this morphism that is compatible with __eq__().

EXAMPLES:

sage: from flatsurf import translation_surfaces
sage: S = translation_surfaces.square_torus()
sage: f = S.delaunay_decompose()._factorization()._morphisms[1].section()
sage: g = S.delaunay_decompose()._factorization()._morphisms[1].section()
sage: hash(f) == hash(g)
True
__module__ = 'flatsurf.geometry.morphism'
class flatsurf.geometry.morphism.GL2RMorphism(parent, m)[source]

A morphism that describes the application of a matrix in \(GL_2(\mathbb{R})\) on each polygon of a surface.

EXAMPLES:

sage: from flatsurf import translation_surfaces
sage: S = translation_surfaces.square_torus()
sage: f = S.apply_matrix(matrix([[1, 2], [0, 1]]), in_place=False)
sage: f
Linear morphism:
  From: Translation Surface in H_1(0) built from a square
  To:   Translation Surface in H_1(0) built from a quadrilateral
  Defn: [1 2]
        [0 1]
__annotations__ = {}
__eq__(other)[source]

Return whether this morphis is indistinguishable from other

EXAMPLES:

sage: from flatsurf import translation_surfaces
sage: S = translation_surfaces.square_torus()
sage: f = S.apply_matrix(matrix([[1, 2], [0, 1]]), in_place=False)
sage: g = S.apply_matrix(matrix([[1, 2], [0, 1]]), in_place=False)
sage: f == g
True
__hash__()[source]

Return a hash value for this morphism that is compatible with __eq__().

EXAMPLES:

sage: from flatsurf import translation_surfaces
sage: S = translation_surfaces.square_torus()
sage: f = S.apply_matrix(matrix([[1, 2], [0, 1]]), in_place=False)
sage: g = S.apply_matrix(matrix([[1, 2], [0, 1]]), in_place=False)
sage: hash(f) == hash(g)
True
__init__(parent, m)[source]
__module__ = 'flatsurf.geometry.morphism'
section()[source]

Return an inverse of this morphism.

EXAMPLES:

sage: from flatsurf import translation_surfaces
sage: S = translation_surfaces.square_torus()
sage: f = S.apply_matrix(matrix([[1, 2], [0, 1]]), in_place=False)
sage: f.section()
Linear morphism:
  From: Translation Surface in H_1(0) built from a quadrilateral
  To:   Translation Surface in H_1(0) built from a square
  Defn: [ 1 -2]
        [ 0  1]
class flatsurf.geometry.morphism.IdentityMorphism(parent)[source]

The identity morphism from a surface to itself.

EXAMPLES:

sage: from flatsurf import translation_surfaces
sage: S = translation_surfaces.mcmullen_L(1, 1, 1, 1)
sage: identity = End(S).identity()
sage: identity
Identity endomorphism of Translation Surface in H_2(2) built from 3 squares
__annotations__ = {}
__eq__(other)[source]

Return whether this morphism is indistinguishable from other.

EXAMPLES:

sage: from flatsurf import translation_surfaces
sage: S = translation_surfaces.mcmullen_L(1, 1, 1, 1)
sage: identity = End(S).identity()
sage: identitz = End(S).identity()
sage: identity == identitz
True

A morphism that is the identity but still distinguishable from the plain identity:

sage: identitz = S.apply_matrix(matrix([[1, 0], [0, 1]]), in_place=False)
sage: identity == identitz
False
__hash__()[source]

Return a hash value for this morphism that is compatible with __eq__().

EXAMPLES:

sage: from flatsurf import translation_surfaces
sage: S = translation_surfaces.mcmullen_L(1, 1, 1, 1)
sage: hash(End(S).identity()) == hash(End(S).identity())
True
__init__(parent)[source]
__module__ = 'flatsurf.geometry.morphism'
__reduce__()[source]

Return a serializable version of this morphism.

EXAMPLES:

sage: from flatsurf import translation_surfaces
sage: S = translation_surfaces.mcmullen_L(1, 1, 1, 1)
sage: f = End(S).identity()

sage: loads(dumps(f)) == f
True
section()[source]

Return an inverse of this morphism, i.e., this morphism itself.

EXAMPLES:

sage: from flatsurf import translation_surfaces
sage: S = translation_surfaces.mcmullen_L(1, 1, 1, 1)
sage: identity = End(S).identity()
sage: identity.section() == identity
True
class flatsurf.geometry.morphism.MorphismSpace(X, Y, category=None, base=None, check=True)[source]

A set of morphisms between structures attached to surfaces.

This is a base class for surface morphisms but also for other structures such as morphisms in homology.

Note

Since surfaces are not unique parents, we need to override some functionality of the SageMath Homset here to make pickling work correctly.

EXAMPLES:

sage: from flatsurf import translation_surfaces, MutableOrientedSimilaritySurface
sage: S = translation_surfaces.mcmullen_L(1, 1, 1, 1)
sage: triangulation = S.triangulate()

sage: homset = triangulation.parent()
sage: homset
Surface Morphisms from Translation Surface in H_2(2) built from 3 squares to Triangulation of Translation Surface in H_2(2) built from 3 squares
__annotations__ = {}
__module__ = 'flatsurf.geometry.morphism'
__reduce__()[source]

Return a serializable version of this morphism.

EXAMPLES:

sage: from flatsurf import translation_surfaces, MutableOrientedSimilaritySurface
sage: S = translation_surfaces.mcmullen_L(1, 1, 1, 1)
sage: loads(dumps(End(S))) == End(S)
True
base_ring()[source]

Return the base ring of this morphism space.

EXAMPLES:

sage: from flatsurf import translation_surfaces, MutableOrientedSimilaritySurface
sage: S = translation_surfaces.mcmullen_L(1, 1, 1, 1)
sage: S.triangulate().base_ring()
Rational Field
identity()[source]

Return the identical morphism from the domain to the codomain of this space.

EXAMPLES:

sage: from flatsurf import translation_surfaces, MutableOrientedSimilaritySurface
sage: S = translation_surfaces.mcmullen_L(1, 1, 1, 1)
sage: End(S).identity()
Identity endomorphism of Translation Surface in H_2(2) built from 3 squares
class flatsurf.geometry.morphism.NamedFactorizationMorphism(parent, name, factorization)[source]

A morphism that is implement by another morphism but has a more appealing name when printing.

This is commonly used when implementing new morphisms that rely on a sequence of existing morphisms while providing a nice interface to the user of sage-flatsurf.

EXAMPLES:

sage: from flatsurf import translation_surfaces
sage: S = translation_surfaces.square_torus()
sage: f = S.triangulate()
sage: g = f.codomain().apply_matrix(matrix([[1, 2], [0, 1]]), in_place=False)

sage: from flatsurf.geometry.morphism import NamedFactorizationMorphism
sage: h = NamedFactorizationMorphism._create_morphism(S, g.codomain(), "Foo", g * f)
sage: h
Foo morphism:
  From: Translation Surface in H_1(0) built from a square
  To:   Translation Surface in H_1(0) built from 2 triangles
__annotations__ = {}
__eq__(other)[source]

Return whether this morphism is indistinguishable from other.

EXAMPLES:

sage: from flatsurf import translation_surfaces
sage: S = translation_surfaces.square_torus()
sage: f = S.triangulate()
sage: g = f.codomain().apply_matrix(matrix([[1, 2], [0, 1]]), in_place=False)

sage: from flatsurf.geometry.morphism import NamedFactorizationMorphism
sage: h0 = NamedFactorizationMorphism._create_morphism(S, g.codomain(), "Foo", g * f)
sage: h1 = NamedFactorizationMorphism._create_morphism(S, g.codomain(), "Foo", g * f)

sage: h0 == h1
True
__hash__()[source]

Return a hash value for this morphism that is compatible with __eq__().

EXAMPLES:

sage: from flatsurf import translation_surfaces
sage: S = translation_surfaces.square_torus()
sage: f = S.triangulate()
sage: g = f.codomain().apply_matrix(matrix([[1, 2], [0, 1]]), in_place=False)

sage: from flatsurf.geometry.morphism import NamedFactorizationMorphism
sage: h0 = NamedFactorizationMorphism._create_morphism(S, g.codomain(), "Foo", g * f)
sage: h1 = NamedFactorizationMorphism._create_morphism(S, g.codomain(), "Foo", g * f)

sage: hash(h0) == hash(h1)
True
__init__(parent, name, factorization)[source]
__module__ = 'flatsurf.geometry.morphism'
_factorization()[source]

Return the morphism underlying this morphism.

EXAMPLES:

sage: from flatsurf import translation_surfaces
sage: S = translation_surfaces.square_torus()
sage: f = S.triangulate()
sage: g = f.codomain().apply_matrix(matrix([[1, 2], [0, 1]]), in_place=False)

sage: from flatsurf.geometry.morphism import NamedFactorizationMorphism
sage: h = NamedFactorizationMorphism._create_morphism(S, g.codomain(), "Foo", g * f)

sage: h._factorization()
Composite morphism:
  From: Translation Surface in H_1(0) built from a square
  To:   Translation Surface in H_1(0) built from 2 triangles
  Defn: Triangulation morphism:
          From: Translation Surface in H_1(0) built from a square
          To:   Triangulation of Translation Surface in H_1(0) built from a square
        then Linear morphism:
          From: Triangulation of Translation Surface in H_1(0) built from a square
          To:   Translation Surface in H_1(0) built from 2 triangles
          Defn: [1 2]
                [0 1]
class flatsurf.geometry.morphism.NamedUnknownMorphism(parent, name)[source]

A morphism that is not functional, typically a placeholder for functionality that has not been implemented yet.

EXAMPLES:

sage: from flatsurf import translation_surfaces, MutableOrientedSimilaritySurface
sage: S = MutableOrientedSimilaritySurface.from_surface(translation_surfaces.square_torus())
sage: f = S.triangulate()
sage: f
Triangulation morphism:
  From: Unknown Surface
  To:   Triangulation of Translation Surface in H_1(0) built from a square
__annotations__ = {}
__eq__(other)[source]

Return whether this morphism is indistinguishable from other.

EXAMPLES:

sage: from flatsurf import translation_surfaces, MutableOrientedSimilaritySurface
sage: S = MutableOrientedSimilaritySurface.from_surface(translation_surfaces.square_torus())
sage: S.triangulate() == S.triangulate()
True
__hash__()[source]

Return a hash value for this morphism that is compatible with __eq__().

EXAMPLES:

sage: from flatsurf import translation_surfaces, MutableOrientedSimilaritySurface
sage: S = MutableOrientedSimilaritySurface.from_surface(translation_surfaces.square_torus())
sage: hash(S.triangulate()) == hash(S.triangulate())
True
__init__(parent, name)[source]
__module__ = 'flatsurf.geometry.morphism'
__reduce__()[source]

Return a serializable version of this morphism.

EXAMPLES:

sage: from flatsurf import translation_surfaces, MutableOrientedSimilaritySurface
sage: S = MutableOrientedSimilaritySurface.from_surface(translation_surfaces.square_torus())
sage: loads(dumps(S.triangulate())) == S.triangulate()
True
class flatsurf.geometry.morphism.SectionMorphism(parent, morphism)[source]

The formal section of a morphism.

EXAMPLES:

sage: from flatsurf import translation_surfaces
sage: S = translation_surfaces.regular_octagon()
sage: morphism = S.subdivide_edges(2)
sage: section = morphism.section()
sage: section
Section morphism:
  From: Translation Surface in H_2(2, 0^4) built from a regular octagon with 8 marked vertices
  To:   Translation Surface in H_2(2) built from a regular octagon
  Defn: Section of Edge-Subdivision morphism:
          From: Translation Surface in H_2(2) built from a regular octagon
          To:   Translation Surface in H_2(2, 0^4) built from a regular octagon with 8 marked vertices
__annotations__ = {}
__eq__(other)[source]

Return whether this section is indistinguishable from other.

EXAMPLES:

sage: from flatsurf import translation_surfaces
sage: S = translation_surfaces.square_torus()
sage: f = S.triangulate()
sage: f.section() == f.section()
True
__hash__()[source]

Return a hash value for this morphism that is compatible with __eq__().

EXAMPLES:

sage: from flatsurf import translation_surfaces
sage: S = translation_surfaces.square_torus()
sage: f = S.triangulate()
sage: hash(f.section()) == hash(f.section())
True
__init__(parent, morphism)[source]
__module__ = 'flatsurf.geometry.morphism'
section()[source]

Return a section of this section.

EXAMPLES:

sage: from flatsurf import translation_surfaces
sage: S = translation_surfaces.regular_octagon()
sage: morphism = S.subdivide_edges(2)
sage: section = morphism.section()
sage: section.section() == morphism
True
class flatsurf.geometry.morphism.SubdivideEdgesMorphism(parent, parts)[source]

A morphism that inserts marked points on edges.

EXAMPLES:

sage: from flatsurf import translation_surfaces
sage: S = translation_surfaces.square_torus()
sage: f = S.subdivide_edges()
sage: f
Edge-Subdivision morphism:
  From: Translation Surface in H_1(0) built from a square
  To:   Translation Surface in H_1(0^3) built from a square
__annotations__ = {}
__eq__(other)[source]

Return whether this morphism is indistinguishable from other.

EXAMPLES:

sage: from flatsurf import translation_surfaces
sage: S = translation_surfaces.regular_octagon()
sage: S.subdivide_edges(2) == S.subdivide_edges(2)
True
__hash__()[source]

Return a hash value for this morphism that is compatible with __eq__()

EXAMPLES:

sage: from flatsurf import translation_surfaces
sage: S = translation_surfaces.regular_octagon()
sage: hash(S.subdivide_edges(2)) == hash(S.subdivide_edges(2))
True
__init__(parent, parts)[source]
__module__ = 'flatsurf.geometry.morphism'
class flatsurf.geometry.morphism.SurfaceMorphism[source]

Abstract base class for all morphisms that map from a domain surface to a codomain surface.

INPUT:

  • domain – a surface or None; if None (or if the domain is mutable), the domain is replaced with the UnknownSurface which means that almost all queries related to the domain are going to fail.

  • codomain – a surface or None; if None (or if the codomain is mutable), the codomain is replaced with the UnknownSurface which means that almost all queries related to the codomain are going to fail.

EXAMPLES:

sage: from flatsurf import translation_surfaces
sage: S = translation_surfaces.square_torus()
sage: morphism = S.apply_matrix(matrix([[2, 0], [0, 1]]), in_place=False)
sage: morphism.domain()
Translation Surface in H_1(0) built from a square

sage: morphism.codomain()
Translation Surface in H_1(0) built from a rectangle
__annotations__ = {}
__call__(x)[source]

Return the image of x under this morphism.

INPUT:

  • x – a point of the domain of this morphism or an object defined on the domain such as a homology class, a saddle connection or a cohomology class. (Mapping of most of these inputs might not be implemented, either because it makes no real mathematical sense or because it has simply not been implemented yet.)

EXAMPLES:

sage: from flatsurf import translation_surfaces
sage: S = translation_surfaces.square_torus()
sage: morphism = S.apply_matrix(matrix([[2, 0], [0, 1]]), in_place=False)

The image of a point:

sage: morphism(S(0, (1/2, 0)))
Point (1, 0) of polygon 0

sage: morphism(_)
Traceback (most recent call last):
...
ValueError: point must be in the domain of this morphism
__dict__ = mappingproxy({'__module__': 'flatsurf.geometry.morphism', '__doc__': '\n    Abstract base class for all morphisms that map from a ``domain`` surface to\n    a ``codomain`` surface.\n\n    INPUT:\n\n    - ``domain`` -- a surface or ``None``; if ``None`` (or if the domain is\n      mutable), the domain is replaced with the :class:`UnknownSurface` which\n      means that almost all queries related to the domain are going to fail.\n\n    - ``codomain`` -- a surface or ``None``; if ``None`` (or if the codomain is\n      mutable), the codomain is replaced with the :class:`UnknownSurface` which\n      means that almost all queries related to the codomain are going to fail.\n\n    EXAMPLES::\n\n        sage: from flatsurf import translation_surfaces\n        sage: S = translation_surfaces.square_torus()\n        sage: morphism = S.apply_matrix(matrix([[2, 0], [0, 1]]), in_place=False)\n        sage: morphism.domain()\n        Translation Surface in H_1(0) built from a square\n\n        sage: morphism.codomain()\n        Translation Surface in H_1(0) built from a rectangle\n\n    TESTS::\n\n        sage: from flatsurf.geometry.morphism import SurfaceMorphism\n        sage: isinstance(morphism, SurfaceMorphism)\n        True\n\n    ', '_parent': <classmethod(<function SurfaceMorphism._parent>)>, '_category': <classmethod(<function SurfaceMorphism._category>)>, '_create_morphism': <classmethod(<function SurfaceMorphism._create_morphism>)>, '__getattr__': <function SurfaceMorphism.__getattr__>, 'section': <function SurfaceMorphism.section>, '_repr_type': <function SurfaceMorphism._repr_type>, '__call__': <function SurfaceMorphism.__call__>, '_image_point': <function SurfaceMorphism._image_point>, '_section_point': <function SurfaceMorphism._section_point>, '_test_section_point': <function SurfaceMorphism._test_section_point>, '_image_homology': <function SurfaceMorphism._image_homology>, '_section_homology': <function SurfaceMorphism._section_homology>, '_test_section_homology': <function SurfaceMorphism._test_section_homology>, '_image_homology_matrix': <sage.misc.cachefunc.CachedMethod object>, '_section_homology_matrix': <function SurfaceMorphism._section_homology_matrix>, '_image_homology_gen': <function SurfaceMorphism._image_homology_gen>, '_section_homology_gen': <function SurfaceMorphism._section_homology_gen>, '_image_homology_edge': <function SurfaceMorphism._image_homology_edge>, '_section_homology_edge': <function SurfaceMorphism._section_homology_edge>, '_composition': <function SurfaceMorphism._composition>, '__eq__': <function SurfaceMorphism.__eq__>, '__hash__': <function SurfaceMorphism.__hash__>, '__dict__': <attribute '__dict__' of 'SurfaceMorphism' objects>, '__annotations__': {}})
__eq__(other)[source]

Return whether this morphism is indistinguishable from other.

EXAMPLES:

sage: from flatsurf import translation_surfaces
sage: S = translation_surfaces.square_torus()
sage: H = End(S)

sage: H.identity() == H.identity()
True
__getattr__(name)[source]

Redirect attribute lookup to the codomain.

EXAMPLES:

A lot of methods that used to return a surface now return a morphism. To make transition of existing code easier, we look up attributes that cannot be found on the morphism up on the codomain and issue a deprecation warning:

sage: from flatsurf import translation_surfaces
sage: S = translation_surfaces.square_torus()
sage: morphism = S.apply_matrix(matrix([[2, 0], [0, 1]]), in_place=False)

sage: morphism.is_triangulated()
doctest:warning
...
UserWarning: This methods returns a morphism instead of a surface. Use .codomain().is_triangulated to access the surface instead of the morphism.
False

sage: morphism.codomain().is_triangulated()
False

sage: morphism.is_foo()
Traceback (most recent call last):
...
AttributeError: ... has no attribute 'is_foo'
__hash__()[source]

Return a hash value for this morphism that is compatible with __eq__().

EXAMPLES:

sage: from flatsurf import translation_surfaces
sage: S = translation_surfaces.square_torus()
sage: H = End(S)

sage: hash(H.identity()) == hash(H.identity())
True
__module__ = 'flatsurf.geometry.morphism'
section()[source]

Return a section of this morphism from its codomain to its domain.

EXAMPLES:

sage: from flatsurf import translation_surfaces
sage: S = translation_surfaces.square_torus()
sage: morphism = S.apply_matrix(matrix([[2, 0], [0, 1]]), in_place=False)
sage: morphism.section()
Linear morphism:
  From: Translation Surface in H_1(0) built from a rectangle
  To:   Translation Surface in H_1(0) built from a square
  Defn: [1/2   0]
        [  0   1]
class flatsurf.geometry.morphism.SurfaceMorphismSpace(X, Y, category=None, base=None, check=True)[source]

The set of morphisms from surface domain to surface codomain.

Note

Since surfaces are not unique parents, we need to override some functionality of the SageMath Homset here to make pickling work correctly.

EXAMPLES:

sage: from flatsurf import translation_surfaces, MutableOrientedSimilaritySurface
sage: S = translation_surfaces.mcmullen_L(1, 1, 1, 1)
sage: identity = End(S).identity()

sage: endset = identity.parent()
sage: endset
Surface Endomorphisms of Translation Surface in H_2(2) built from 3 squares
__annotations__ = {}
__eq__(other)[source]

Return whether this space is indistinguishable from other.

EXAMPLES:

sage: from flatsurf import translation_surfaces, MutableOrientedSimilaritySurface
sage: S = translation_surfaces.mcmullen_L(1, 1, 1, 1)

sage: End(S) == End(S)
True
__hash__()[source]

Return a hash value for this space that is compatible with __eq__().

EXAMPLES:

sage: from flatsurf import translation_surfaces, MutableOrientedSimilaritySurface
sage: S = translation_surfaces.mcmullen_L(1, 1, 1, 1)

sage: hash(End(S)) == hash(End(S))
True
__module__ = 'flatsurf.geometry.morphism'
__reduce__()[source]

Return a serializable version of this morphism.

EXAMPLES:

sage: from flatsurf import translation_surfaces, MutableOrientedSimilaritySurface
sage: S = translation_surfaces.mcmullen_L(1, 1, 1, 1)
sage: loads(dumps(End(S))) == End(S)
True
__repr__()[source]

Return a printable representation of this space.

EXAMPLES:

sage: from flatsurf import translation_surfaces, MutableOrientedSimilaritySurface
sage: S = translation_surfaces.mcmullen_L(1, 1, 1, 1)
sage: End(S)
Surface Endomorphisms of Translation Surface in H_2(2) built from 3 squares
identity()[source]

Return the identical morphism from the domain to the codomain of this space.

EXAMPLES:

sage: from flatsurf import translation_surfaces, MutableOrientedSimilaritySurface
sage: S = translation_surfaces.mcmullen_L(1, 1, 1, 1)
sage: End(S).identity()
Identity endomorphism of Translation Surface in H_2(2) built from 3 squares
class flatsurf.geometry.morphism.SurfaceMorphism_factorization[source]

A morphism between surfaces that is backed by another morphism, usually a CompositionMorphism.

EXAMPLES:

sage: from flatsurf import translation_surfaces
sage: S = translation_surfaces.square_torus()
sage: f = S.delaunay_triangulate()
sage: f
Delaunay triangulation morphism:
  From: Translation Surface in H_1(0) built from a square
  To:   Delaunay triangulation of Translation Surface in H_1(0) built from a square

sage: f._factorization()
Composite morphism:
  From: Translation Surface in H_1(0) built from a square
  To:   Delaunay triangulation of Translation Surface in H_1(0) built from a square
  Defn: Triangulation morphism:
          From: Translation Surface in H_1(0) built from a square
          To:   Triangulation of Translation Surface in H_1(0) built from a square
        then Delaunay retriangulation morphism:
          From: Triangulation of Translation Surface in H_1(0) built from a square
          To:   Delaunay triangulation of Translation Surface in H_1(0) built from a square
__annotations__ = {}
__module__ = 'flatsurf.geometry.morphism'
_factorization()[source]

Return the morphism underlying this morphism.

EXAMPLES:

sage: from flatsurf import translation_surfaces
sage: S = translation_surfaces.square_torus()
sage: f = S.delaunay_triangulate()

sage: f._factorization()
Composite morphism:
  From: Translation Surface in H_1(0) built from a square
  To:   Delaunay triangulation of Translation Surface in H_1(0) built from a square
  Defn: Triangulation morphism:
          From: Translation Surface in H_1(0) built from a square
          To:   Triangulation of Translation Surface in H_1(0) built from a square
        then Delaunay retriangulation morphism:
          From: Triangulation of Translation Surface in H_1(0) built from a square
          To:   Delaunay triangulation of Translation Surface in H_1(0) built from a square
class flatsurf.geometry.morphism.TriangulationMorphism_LazyTriangulatedSurface[source]

A triangulation that maps a surface into a class LazyTriangulatedSurface.

EXAMPLES:

sage: from flatsurf import translation_surfaces
sage: S = translation_surfaces.square_torus()
sage: f = S.triangulate()
sage: f
Triangulation morphism:
  From: Translation Surface in H_1(0) built from a square
  To:   Triangulation of Translation Surface in H_1(0) built from a square
__annotations__ = {}
__eq__(other)[source]

Return whether this triangulation is indistinguishable from other.

EXAMPLES:

sage: from flatsurf import translation_surfaces
sage: S = translation_surfaces.square_torus()
sage: S.triangulate() == S.triangulate()
True
__hash__()[source]

Return a hash value for this triangulation that is compatible with __eq__().

EXAMPLES:

sage: from flatsurf import translation_surfaces
sage: S = translation_surfaces.square_torus()
sage: hash(S.triangulate()) == hash(S.triangulate())
True
__module__ = 'flatsurf.geometry.morphism'
class flatsurf.geometry.morphism.TriangulationMorphism_base[source]

Abstract base class for morphisms from a surface to its triangulation.

EXAMPLES:

sage: from flatsurf import translation_surfaces
sage: G = SymmetricGroup(4)
sage: S = translation_surfaces.origami(G('(1,2,3,4)'), G('(1,4,2,3)'))
sage: f = S.triangulate()
sage: f
Triangulation morphism:
  From: Origami defined by r=(1,2,3,4) and u=(1,4,2,3)
  To:   Triangulation of Origami defined by r=(1,2,3,4) and u=(1,4,2,3)
__annotations__ = {}
__module__ = 'flatsurf.geometry.morphism'
class flatsurf.geometry.morphism.UnknownRing[source]

A placeholder for a SageMath ring that has been lost in the process of creating a morphism.

Ideally, every morphism has a domain and a codomain. However, when migrating code that did not produce a morphism originally, it can be complicated to get a hold of the actual domain/codomain of a morphism.

Instead, it is often convenient to set the domain/codomain to None, i.e., stating that the domain/codomain is unknown. When this happens, also the ring over which the domain/codomain is defined is technically unknown. We use this placeholder ring in these situations since a surface requires a ring it is defined over.

This ring provides no functionality other than being in the category of rings.

EXAMPLES:

sage: from flatsurf import translation_surfaces, MutableOrientedSimilaritySurface
sage: S = translation_surfaces.square_torus()
sage: S = MutableOrientedSimilaritySurface.from_surface(S)

sage: triangulation = S.triangulate(in_place=True)
doctest:warning
...
UserWarning: in-place triangulation has been deprecated and the in_place keyword argument will be removed from triangulate() in a future version of sage-flatsurf
sage: triangulation.domain()
Unknown Surface
sage: triangulation.domain().base_ring()
The Unknown Ring
__annotations__ = {}
__dict__ = mappingproxy({'__module__': 'flatsurf.geometry.morphism', '__doc__': '\n    A placeholder for a SageMath ring that has been lost in the process of\n    creating a morphism.\n\n    Ideally, every morphism has a domain and a codomain. However, when\n    migrating code that did not produce a morphism originally, it can be\n    complicated to get a hold of the actual domain/codomain of a morphism.\n\n    Instead, it is often convenient to set the domain/codomain to ``None``,\n    i.e., stating that the domain/codomain is unknown. When this happens, also\n    the ring over which the domain/codomain is defined is technically unknown.\n    We use this placeholder ring in these situations since a surface requires a\n    ring it is defined over.\n\n    This ring provides no functionality other than being in the category of\n    rings.\n\n    EXAMPLES::\n\n        sage: from flatsurf import translation_surfaces, MutableOrientedSimilaritySurface\n        sage: S = translation_surfaces.square_torus()\n        sage: S = MutableOrientedSimilaritySurface.from_surface(S)\n\n        sage: triangulation = S.triangulate(in_place=True)\n        doctest:warning\n        ...\n        UserWarning: in-place triangulation has been deprecated and the in_place keyword argument will be removed from triangulate() in a future version of sage-flatsurf\n        sage: triangulation.domain()\n        Unknown Surface\n        sage: triangulation.domain().base_ring()\n        The Unknown Ring\n\n    TESTS::\n\n        sage: from flatsurf.geometry.morphism import UnknownRing\n        sage: isinstance(triangulation.domain().base_ring(), UnknownRing)\n        True\n        sage: isinstance(triangulation.codomain().base_ring(), UnknownRing)\n        False\n\n        sage: TestSuite(triangulation.codomain().base_ring()).run()\n\n    ', '__init__': <function UnknownRing.__init__>, '_repr_': <function UnknownRing._repr_>, '__dict__': <attribute '__dict__' of 'UnknownRing' objects>, '__annotations__': {}})
__init__()[source]
__module__ = 'flatsurf.geometry.morphism'
class flatsurf.geometry.morphism.UnknownSurface(base, category=None)[source]

A placeholder surface for a morphism’s domain or codomain when that codomain is unknown or mutable.

In SageMath a morphism must have an explicit domain and codomain. However, the domain of a morphism might not actually be known, for example when deforming a mutable surface, or exposing it might break things when it is mutable.

In such cases, we replace the domain with this unknown surface which has no functionality other than being a surface.

EXAMPLES:

sage: from flatsurf import translation_surfaces, MutableOrientedSimilaritySurface
sage: S = translation_surfaces.square_torus()
sage: S = MutableOrientedSimilaritySurface.from_surface(S)
sage: S
Translation Surface built from a square

sage: triangulation = S.triangulate()

sage: triangulation.domain()
Unknown Surface
sage: triangulation.codomain()
Triangulation of Translation Surface in H_1(0) built from a square
__annotations__ = {}
__module__ = 'flatsurf.geometry.morphism'
is_compact()[source]

Return whether this surface is compact as a topological space.

EXAMPLES:

sage: from flatsurf import translation_surfaces, MutableOrientedSimilaritySurface
sage: S = translation_surfaces.square_torus()
sage: S = MutableOrientedSimilaritySurface.from_surface(S)
sage: S = S.triangulate(in_place=False).domain()
sage: S.is_compact()
True
is_finite_type()[source]

Return whether this surface is built from a finite number of polygons.

EXAMPLES:

sage: from flatsurf import translation_surfaces, MutableOrientedSimilaritySurface
sage: S = translation_surfaces.square_torus()
sage: S = MutableOrientedSimilaritySurface.from_surface(S)
sage: S = S.triangulate(in_place=False).domain()
sage: S.is_finite_type()
True
is_mutable()[source]

Return whether this surface can be mutated.

Since nothing about this surface can be changed, we return that it is immutable.

EXAMPLES:

sage: from flatsurf import translation_surfaces, MutableOrientedSimilaritySurface
sage: S = translation_surfaces.square_torus()
sage: S = MutableOrientedSimilaritySurface.from_surface(S)
sage: S = S.triangulate(in_place=False).domain()
sage: S.is_mutable()
False
is_with_boundary()[source]

Return whether this surface has a boundary of unglued edges.

Since we do not record whether this unknown surface stands in for a surface that has a boundary, we throw an error.

EXAMPLES:

sage: from flatsurf import translation_surfaces, MutableOrientedSimilaritySurface
sage: S = translation_surfaces.square_torus()
sage: S = MutableOrientedSimilaritySurface.from_surface(S)
sage: S = S.triangulate(in_place=False).domain()
sage: S.is_with_boundary()
Traceback (most recent call last):
...
NotImplementedError: cannot determine whether an unknown surface has boundary
opposite_edge(label, edge)[source]

Return the edge that is glued to the edge of the polygon with label.

Since we do not know anything about the gluings of this surface, we throw an error.

EXAMPLES:

sage: from flatsurf import translation_surfaces, MutableOrientedSimilaritySurface
sage: S = translation_surfaces.square_torus()
sage: S = MutableOrientedSimilaritySurface.from_surface(S)
sage: S = S.triangulate(in_place=False).domain()
sage: S.opposite_edge(0, 0)
Traceback (most recent call last):
...
NotImplementedError: cannot determine how the unknown surface is glued
polygon(label)[source]

Return the polygon with label.

Since we do not know the polygons that make up this surface, we throw an error.

EXAMPLES:

sage: from flatsurf import translation_surfaces, MutableOrientedSimilaritySurface
sage: S = translation_surfaces.square_torus()
sage: S = MutableOrientedSimilaritySurface.from_surface(S)
sage: S = S.triangulate(in_place=False).domain()
sage: S.polygon(0)
Traceback (most recent call last):
...
NotImplementedError: cannot determine polygons of the unknown surface
roots()[source]

Return the root labels of the connected components of this surface.

Since this surface doesn’t really have any labels, we throw an error.

EXAMPLES:

sage: from flatsurf import translation_surfaces, MutableOrientedSimilaritySurface
sage: S = translation_surfaces.square_torus()
sage: S = MutableOrientedSimilaritySurface.from_surface(S)
sage: S = S.triangulate(in_place=False).domain()
sage: S.roots()
Traceback (most recent call last):
...
NotImplementedError: cannot determine root labels in an unknown surface
flatsurf.geometry.morphism.unpickle_NamedUnknownMorphism(*args)[source]

Unpickle a NamedUnknownMorphism.

This works around a bug in SageMath 9.8 which fails to unpickle through NamedUnknownMorphism._create_morphism directly with: AttributeError: type object 'sage.misc.inherit_comparison.InheritComparisonMeta' has no attribute '_create_morphism'

EXAMPLES:

sage: from flatsurf import translation_surfaces, MutableOrientedSimilaritySurface
sage: S = MutableOrientedSimilaritySurface.from_surface(translation_surfaces.square_torus())
sage: loads(dumps(S.triangulate())) == S.triangulate()
True