Skip to content

Commit fc5bd5a

Browse files
committed
Add docstring and API functions to manifolds
1 parent 7c74b4d commit fc5bd5a

File tree

1 file changed

+115
-7
lines changed

1 file changed

+115
-7
lines changed

GeometryOpsCore/src/types/algorithm.jl

Lines changed: 115 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,80 @@ MyIndependentAlgorithm(m::Manifold; kw1 = 1, kw2 = "hello") = MyIndependentAlgor
4242

4343
export 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+
"""
4581
abstract 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+
"""
47119
struct AutoAlgorithm{T, M <: Manifold} <: Algorithm{M}
48120
manifold::M
49121
x::T
@@ -52,18 +124,33 @@ end
52124
AutoAlgorithm(m::Manifold; kwargs...) = AutoAlgorithm(m, kwargs)
53125
AutoAlgorithm(; 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+
"""
56140
abstract 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

68155
function (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}())
78165
end
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

Comments
 (0)