@@ -42,8 +42,80 @@ MyIndependentAlgorithm(m::Manifold; kw1 = 1, kw2 = "hello") = MyIndependentAlgor
4242
4343export Algorithm, AutoAlgorithm, ManifoldIndependentAlgorithm, SingleManifoldAlgorithm, NoAlgorithm
4444
45+ """
46+ abstract type Algorithm{M <: Manifold}
47+
48+ The abstract supertype for all GeometryOps algorithms.
49+ These define how to perform a particular [`Operation`](@ref).
50+
51+ An algorithm may be associated with one or many [`Manifold`](@ref)s.
52+ It may either have the manifold as a field, or have it as a static parameter
53+ (e.g. `struct GEOS <: Algorithm{Planar}`).
54+
55+ ## Interface
56+
57+ All `Algorithm`s must implement the following methods:
58+
59+ - `rebuild(alg, manifold::Manifold)` Rebuild algorithm `alg` with a new manifold
60+ as passed in the second argument. This may error and throw a [`WrongManifoldException`](@ref)
61+ if the manifold is not compatible with that algorithm.
62+ - `manifold(alg::Algorithm)` Return the manifold associated with the algorithm.
63+ - `best_manifold(alg::Algorithm, input)`: Return the best manifold for that algorithm, in the absence of
64+ any other context. WARNING: this may change in future and is not stable!
65+
66+ The actual implementation is left to the implementation of that particular [`Operation`](@ref).
67+
68+ ## Notable subtypes
69+
70+ - [`AutoAlgorithm`](@ref): Tells the [`Operation`](@ref) receiving
71+ it to automatically select the best algorithm for its input data.
72+ - [`ManifoldIndependentAlgorithm`](@ref): An abstract supertype for an algorithm that works on any manifold.
73+ The manifold must be stored in the algorithm for a `ManifoldIndependentAlgorithm`, and accessed via `manifold(alg)`.
74+ - [`SingleManifoldAlgorithm`](@ref): An abstract supertype for an algorithm that only works on a
75+ single manifold, specified in its type parameter. `SingleManifoldAlgorithm{Planar}` is a special case
76+ that does not have to store its manifold, since that doesn't contain any information. All other
77+ `SingleManifoldAlgorithm`s must store their manifold, since they do contain information.
78+ - [`NoAlgorithm`](@ref): A type that indicates no algorithm is to be used, essentially the equivalent
79+ of `nothing`.
80+ """
4581abstract type Algorithm{M <: Manifold } end
4682
83+ """
84+ manifold(alg::Algorithm)::Manifold
85+
86+ Return the manifold associated with the algorithm.
87+
88+ May be any subtype of [`Manifold`](@ref).
89+ """
90+ function manifold end
91+
92+ # The below definition is a special case, since [`Planar`](@ref) has no contents, being a
93+ # singleton struct.
94+ # If that changes in the future, then this method must be deleted.
95+ manifold (:: Algorithm{<: Planar} ) = Planar ()
96+
97+ """
98+ best_manifold(alg::Algorithm, input)::Manifold
99+
100+ Return the best [`Manifold`](@ref) for the algorithm `alg` based on the given `input`.
101+
102+ May be any subtype of [`Manifold`](@ref).
103+ """
104+ function best_manifold end
105+
106+ # ## Implementation of basic algorithm types
107+
108+ # ### `AutoAlgorithm`
109+
110+ """
111+ AutoAlgorithm{T, M <: Manifold}(manifold::M, x::T)
112+
113+ Indicates that the [`Operation`](@ref) should automatically select the best algorithm for
114+ its input data, based on the passed in manifold (may be an [`AutoManifold`](@ref)) and data
115+ `x`.
116+
117+ The actual implementation is left to the implementation of that particular [`Operation`](@ref).
118+ """
47119struct AutoAlgorithm{T, M <: Manifold } <: Algorithm{M}
48120 manifold:: M
49121 x:: T
52124AutoAlgorithm (m:: Manifold ; kwargs... ) = AutoAlgorithm (m, kwargs)
53125AutoAlgorithm (; kwargs... ) = AutoAlgorithm (AutoManifold (), kwargs)
54126
127+ manifold (a:: AutoAlgorithm ) = a. manifold
128+ rebuild (a:: AutoAlgorithm , m:: Manifold ) = AutoAlgorithm (m, a. x)
129+
130+
131+ # ### `ManifoldIndependentAlgorithm`
132+
133+ """
134+ abstract type ManifoldIndependentAlgorithm{M <: Manifold} <: Algorithm{M}
135+
136+ The abstract supertype for a manifold-independent algorithm, i.e., one which may work on any manifold.
55137
138+ The manifold is stored in the algorithm for a `ManifoldIndependentAlgorithm`, and accessed via `manifold(alg)`.
139+ """
56140abstract type ManifoldIndependentAlgorithm{M <: Manifold } <: Algorithm{M} end
57141
58- abstract type SingleManifoldAlgorithm{M <: Manifold } <: Algorithm{M} end
59142
60- struct NoAlgorithm{M <: Manifold } <: Algorithm{M}
61- m:: M
62- end
143+ # ### `SingleManifoldAlgorithm`
63144
64- NoAlgorithm () = NoAlgorithm (Planar ()) # TODO : add a NoManifold or AutoManifold type?
65- # Maybe AutoManifold
66- # and then we have DD.format like materialization
145+ """
146+ abstract type SingleManifoldAlgorithm{M <: Manifold} <: Algorithm{M}
147+
148+ The abstract supertype for a single-manifold algorithm, i.e., one which is known to only work
149+ on a single manifold.
150+
151+ The manifold may be accessed via `manifold(alg)`.
152+ """
153+ abstract type SingleManifoldAlgorithm{M <: Manifold } <: Algorithm{M} end
67154
68155function (Alg:: Type{<: SingleManifoldAlgorithm{M}} )(m:: M ; kwargs... ) where {M}
69156 # successful - the algorithm is designed for this manifold
@@ -76,3 +163,24 @@ function (Alg::Type{<: SingleManifoldAlgorithm{M}})(m::Manifold; kwargs...) wher
76163 # throw a WrongManifoldException and be done with it
77164 throw (WrongManifoldException {typeof(m), M, Alg} ())
78165end
166+
167+
168+ # ### `NoAlgorithm`
169+
170+ """
171+ NoAlgorithm(manifold)
172+
173+ A type that indicates no algorithm is to be used, essentially the equivalent
174+ of `nothing`.
175+
176+ Stores a manifold within itself.
177+ """
178+ struct NoAlgorithm{M <: Manifold } <: Algorithm{M}
179+ m:: M
180+ end
181+
182+ NoAlgorithm () = NoAlgorithm (Planar ()) # TODO : add a NoManifold or AutoManifold type?
183+
184+ manifold (a:: NoAlgorithm ) = a. m
185+ # Maybe AutoManifold
186+ # and then we have DD.format like materialization
0 commit comments