Skip to content

Commit

Permalink
Update docstrings, format code, and a few additions (#16)
Browse files Browse the repository at this point in the history
* Standardize/fix docstrings

* Use variable name method

* Rename variable to y

* Make local injectivity radius fall back to global

* Fix docstrings

* Run JuliaFormatter

* Replace broadcast with explicit copy

* Add AbstractEstimationMethod

* Fix variable name

* Remove space

* Increment version number

* Rewrap docstrings

* Avoid hanging equals

* Simplify check with equiv logic

* Change variable name

* Rephrase

* Use active language and wrap

* Add/remove whitespace

* Rephrase

* Remove unused variable names

* Remove whitespace

* Standardize error messages

* Make injectivity_radius error by default

* Increment version number

* Add more decorator manifold tests

* Add global testset

* Rewrap at length 92 per BlueStyle

* Ommit space between long and short form functions

* Merge docstrings for similar signatures
  • Loading branch information
sethaxen authored Dec 21, 2019
1 parent 965fdf7 commit 8d9e3d1
Show file tree
Hide file tree
Showing 9 changed files with 519 additions and 412 deletions.
4 changes: 2 additions & 2 deletions Project.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name = "ManifoldsBase"
uuid = "3362f125-f0bb-47a3-aa74-596ffd7ef2fb"
authors = ["Seth Axen <[email protected]>", "Mateusz Baran <[email protected]>", "Ronny Bergmann <[email protected]>", "Antoine Levitt <[email protected]>"]
version = "0.2.0"
authors = ["Seth Axen <[email protected]>", "Mateusz Baran <[email protected]>", "Ronny Bergmann <[email protected]>", "Antoine Levitt <[email protected]>"]
version = "0.3.0"

[deps]
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
Expand Down
150 changes: 96 additions & 54 deletions src/ArrayManifold.jl
Original file line number Diff line number Diff line change
@@ -1,37 +1,42 @@
"""
ArrayManifold{M <: Manifold} <: Manifold
ArrayManifold{M<:Manifold} <: Manifold
A manifold to encapsulate manifolds working on array representations of
`MPoints` and `TVectors` in a transparent way, such that for these manifolds its
not necessary to introduce explicit types for the points and tangent vectors,
but they are encapsulated/stripped automatically when needed.
A manifold to encapsulate manifolds working on array representations of `MPoints` and
`TVectors` in a transparent way, such that for these manifolds it's not necessary to
introduce explicit types for the points and tangent vectors, but they are
encapsulated/stripped automatically when needed.
This manifold is a decorator for a manifold, i.e. it decorates a manifold `M`
with types points, vectors, and covectors.
This manifold is a decorator for a manifold, i.e. it decorates a manifold `M` with types
points, vectors, and covectors.
"""
struct ArrayManifold{M <: Manifold} <: Manifold
struct ArrayManifold{M<:Manifold} <: Manifold
manifold::M
end
convert(::Type{M},m::ArrayManifold{M}) where M <: Manifold = m.manifold
convert(::Type{ArrayManifold{M}},m::M) where M <: Manifold = ArrayManifold(m)

convert(::Type{M}, m::ArrayManifold{M}) where {M<:Manifold} = m.manifold
convert(::Type{ArrayManifold{M}}, m::M) where {M<:Manifold} = ArrayManifold(m)

is_decorator_manifold(::ArrayManifold) = Val(true)

"""
ArrayMPoint <: MPoint
represent a point on an [`ArrayManifold`](@ref), i.e. on a manifold where data
can be represented by arrays. The array is stored internally and semantically
this distinguished the value from [`ArrayTVector`](@ref)s and [`ArrayCoTVector`](@ref)s
Represent a point on an [`ArrayManifold`](@ref), i.e. on a manifold where data can be
represented by arrays. The array is stored internally and semantically. This distinguished
the value from [`ArrayTVector`](@ref)s and [`ArrayCoTVector`](@ref)s.
"""
struct ArrayMPoint{V <: AbstractArray{<:Number}} <: MPoint
struct ArrayMPoint{V<:AbstractArray{<:Number}} <: MPoint
value::V
end
convert(::Type{V},x::ArrayMPoint{V}) where V <: AbstractArray{<:Number} = x.value
convert(::Type{ArrayMPoint{V}},x::V) where V <: AbstractArray{<:Number} = ArrayMPoint{V}(x)
eltype(::Type{ArrayMPoint{V}}) where V = eltype(V)

convert(::Type{V}, x::ArrayMPoint{V}) where {V<:AbstractArray{<:Number}} = x.value
convert(::Type{ArrayMPoint{V}}, x::V) where {V<:AbstractArray{<:Number}} = ArrayMPoint{V}(x)

eltype(::Type{ArrayMPoint{V}}) where {V} = eltype(V)

similar(x::ArrayMPoint) = ArrayMPoint(similar(x.value))
similar(x::ArrayMPoint, ::Type{T}) where T = ArrayMPoint(similar(x.value, T))
similar(x::ArrayMPoint, ::Type{T}) where {T} = ArrayMPoint(similar(x.value, T))

function copyto!(x::ArrayMPoint, y::ArrayMPoint)
copyto!(x.value, y.value)
return x
Expand All @@ -40,18 +45,24 @@ end
"""
ArrayTVector <: TVector
represent a tangent vector an [`ArrayManifold`](@ref), i.e. on a manifold where data
can be represented by arrays. The array is stored internally and semantically
this distinguished the value from [`ArrayMPoint`](@ref)s and [`ArrayCoTVector`](@ref)s
Represent a tangent vector to a point on an [`ArrayManifold`](@ref), i.e. on a manifold
where data can be represented by arrays. The array is stored internally and semantically.
This distinguished the value from [`ArrayMPoint`](@ref)s and [`ArrayCoTVector`](@ref)s.
"""
struct ArrayTVector{V <: AbstractArray{<:Number}} <: TVector
struct ArrayTVector{V<:AbstractArray{<:Number}} <: TVector
value::V
end
convert(::Type{V},v::ArrayTVector{V}) where V <: AbstractArray{<:Number} = v.value
convert(::Type{ArrayTVector{V}},v::V) where V <: AbstractArray{<:Number} = ArrayTVector{V}(v)
eltype(::Type{ArrayTVector{V}}) where V = eltype(V)

convert(::Type{V}, v::ArrayTVector{V}) where {V<:AbstractArray{<:Number}} = v.value
function convert(::Type{ArrayTVector{V}}, v::V) where {V<:AbstractArray{<:Number}}
return ArrayTVector{V}(v)
end

eltype(::Type{ArrayTVector{V}}) where {V} = eltype(V)

similar(x::ArrayTVector) = ArrayTVector(similar(x.value))
similar(x::ArrayTVector, ::Type{T}) where T = ArrayTVector(similar(x.value, T))
similar(x::ArrayTVector, ::Type{T}) where {T} = ArrayTVector(similar(x.value, T))

function copyto!(x::ArrayTVector, y::ArrayTVector)
copyto!(x.value, y.value)
return x
Expand All @@ -60,23 +71,29 @@ end
(+)(v1::ArrayTVector, v2::ArrayTVector) = ArrayTVector(v1.value + v2.value)
(-)(v1::ArrayTVector, v2::ArrayTVector) = ArrayTVector(v1.value - v2.value)
(-)(v::ArrayTVector) = ArrayTVector(-v.value)
(*)(a::Number, v::ArrayTVector) = ArrayTVector(a*v.value)
(*)(a::Number, v::ArrayTVector) = ArrayTVector(a * v.value)

"""
ArrayCoTVector <: CoTVector
represent a cotangent vector an [`ArrayManifold`](@ref), i.e. on a manifold where data
can be represented by arrays. The array is stored internally and semantically
this distinguished the value from [`ArrayMPoint`](@ref)s and [`ArrayTVector`](@ref)s
Represent a cotangent vector to a point on an [`ArrayManifold`](@ref), i.e. on a manifold
where data can be represented by arrays. The array is stored internally and semantically.
This distinguished the value from [`ArrayMPoint`](@ref)s and [`ArrayTVector`](@ref)s.
"""
struct ArrayCoTVector{V <: AbstractArray{<:Number}} <: TVector
struct ArrayCoTVector{V<:AbstractArray{<:Number}} <: TVector
value::V
end
convert(::Type{V},v::ArrayCoTVector{V}) where V <: AbstractArray{<:Number} = v.value
convert(::Type{ArrayCoTVector{V}},v::V) where V <: AbstractArray{<:Number} = ArrayCoTVector{V}(v)
eltype(::Type{ArrayCoTVector{V}}) where V = eltype(V)

convert(::Type{V}, v::ArrayCoTVector{V}) where {V<:AbstractArray{<:Number}} = v.value
function convert(::Type{ArrayCoTVector{V}}, v::V) where {V<:AbstractArray{<:Number}}
return ArrayCoTVector{V}(v)
end

eltype(::Type{ArrayCoTVector{V}}) where {V} = eltype(V)

similar(x::ArrayCoTVector) = ArrayCoTVector(similar(x.value))
similar(x::ArrayCoTVector, ::Type{T}) where T = ArrayCoTVector(similar(x.value, T))
similar(x::ArrayCoTVector, ::Type{T}) where {T} = ArrayCoTVector(similar(x.value, T))

function copyto!(x::ArrayCoTVector, y::ArrayCoTVector)
copyto!(x.value, y.value)
return x
Expand All @@ -85,21 +102,20 @@ end
(+)(v1::ArrayCoTVector, v2::ArrayCoTVector) = ArrayCoTVector(v1.value + v2.value)
(-)(v1::ArrayCoTVector, v2::ArrayCoTVector) = ArrayCoTVector(v1.value - v2.value)
(-)(v::ArrayCoTVector) = ArrayCoTVector(-v.value)
(*)(a::Number, v::ArrayCoTVector) = ArrayCoTVector(a*v.value)
(*)(a::Number, v::ArrayCoTVector) = ArrayCoTVector(a * v.value)

"""
array_value(x)
returns the internal array value of a [`ArrayMPoint`](@ref), [`ArrayTVector`](@ref)
or [`ArrayCoTVector`](@ref) if the value `x` is encapsulated as such, otherwise
if `x` is already an array, it just returns `x`
Return the internal array value of a [`ArrayMPoint`](@ref), [`ArrayTVector`](@ref), or
[`ArrayCoTVector`](@ref) if the value `x` is encapsulated as such. Return `x` if it is
already an array.
"""
array_value(x::AbstractArray) = x
array_value(x::ArrayMPoint) = x.value
array_value(v::ArrayTVector) = v.value
array_value(v::ArrayCoTVector) = v.value


function isapprox(M::ArrayManifold, x, y; kwargs...)
is_manifold_point(M, x, true; kwargs...)
is_manifold_point(M, y, true; kwargs...)
Expand Down Expand Up @@ -179,31 +195,57 @@ function zero_tangent_vector(M::ArrayManifold, x; kwargs...)
return w
end

function vector_transport_to!(M::ArrayManifold, vto, x, v, y, m::AbstractVectorTransportMethod; kwargs...)
function vector_transport_to!(
M::ArrayManifold,
vto,
x,
v,
y,
m::AbstractVectorTransportMethod;
kwargs...,
)
is_manifold_point(M, y, true; kwargs...)
is_tangent_vector(M, x, v, true; kwargs...)
vector_transport_to!(M.manifold,
array_value(vto),
array_value(x),
array_value(v),
array_value(y),
m)
vector_transport_to!(
M.manifold,
array_value(vto),
array_value(x),
array_value(v),
array_value(y),
m,
)
is_tangent_vector(M, y, vto, true; kwargs...)
return vto
end

function vector_transport_along!(M::ArrayManifold, vto, x, v, c, m::AbstractVectorTransportMethod; kwargs...)
function vector_transport_along!(
M::ArrayManifold,
vto,
x,
v,
c,
m::AbstractVectorTransportMethod;
kwargs...,
)
is_tangent_vector(M, x, v, true; kwargs...)
vector_transport_along!(M.manifold,
array_value(vto),
array_value(x),
array_value(v),
c,
m)
vector_transport_along!(
M.manifold,
array_value(vto),
array_value(x),
array_value(v),
c,
m,
)
is_tangent_vector(M, c(1), vto, true; kwargs...)
return vto
end

injectivity_radius(M::ArrayManifold) = injectivity_radius(M.manifold)
function injectivity_radius(M::ArrayManifold, x, args...; kwargs...)
is_manifold_point(M, x, true; kwargs...)
return injectivity_radius(M.manifold, array_value(x), args...)
end

function check_manifold_point(M::ArrayManifold, x::MPoint; kwargs...)
return check_manifold_point(M.manifold, array_value(x); kwargs...)
end
Expand Down
32 changes: 17 additions & 15 deletions src/DefaultManifold.jl
Original file line number Diff line number Diff line change
@@ -1,26 +1,28 @@
"""
DefaultManifold <: Manifold
This default manifold illustrates the main features of the interface and provides
a good starting point for an own manifold. It is a simplified/shortened variant
of `Euclidean` from `Manifolds.jl`.
This default manifold illustrates the main features of the interface and provides a skeleton
to build one's own manifold. It is a simplified/shortened variant of `Euclidean` from
`Manifolds.jl`.
this manifold further illustrates, how to type your manifold points
and tangent vectors. Note that the interface does not require this, but it
might be handy in debugging and educative situations to verify correctness of
involved variabes.
This manifold further illustrates how to type your manifold points and tangent vectors. Note
that the interface does not require this, but it might be handy in debugging and educative
situations to verify correctness of involved variabes.
"""
struct DefaultManifold{T<:Tuple} <: Manifold where {T} end
DefaultManifold(n::Vararg{Int,N}) where N = DefaultManifold{Tuple{n...}}()
DefaultManifold(n::Vararg{Int,N}) where {N} = DefaultManifold{Tuple{n...}}()

@generated representation_size(::DefaultManifold{T}) where {T} = Tuple(T.parameters...)
@generated manifold_dimension(::DefaultManifold{T}) where {T} = *(T.parameters...)
@inline inner(::DefaultManifold, x, v, w) = dot(v, w)
distance(::DefaultManifold, x, y) = norm(x-y)
distance(::DefaultManifold, x, y) = norm(x - y)
norm(::DefaultManifold, x, v) = norm(v)
exp!(M::DefaultManifold, y, x, v) = (y .= x .+ v)
log!(M::DefaultManifold, v, x, y) = (v .= y .- x)
zero_tangent_vector!(M::DefaultManifold, v, x) = fill!(v, 0)
project_point!(M::DefaultManifold, y, x) = (y .= x)
project_tangent!(M::DefaultManifold, w, x, v) = (w .= v)
vector_transport_to!(M::DefaultManifold, vto, x, v, y, ::ParallelTransport) = (vto .= v)
exp!(::DefaultManifold, y, x, v) = (y .= x .+ v)
log!(::DefaultManifold, v, x, y) = (v .= y .- x)
zero_tangent_vector!(::DefaultManifold, v, x) = fill!(v, 0)
project_point!(::DefaultManifold, y, x) = copyto!(y, x)
project_tangent!(::DefaultManifold, w, x, v) = copyto!(w, v)
function vector_transport_to!(::DefaultManifold, vto, x, v, y, ::ParallelTransport)
return copyto!(vto, v)
end
injectivity_radius(::DefaultManifold) = Inf
Loading

2 comments on commit 8d9e3d1

@sethaxen
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@JuliaRegistrator
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Registration pull request created: JuliaRegistries/General/7005

After the above pull request is merged, it is recommended that a tag is created on this repository for the registered package version.

This will be done automatically if Julia TagBot is installed, or can be done manually through the github interface, or via:

git tag -a v0.3.0 -m "<description of version>" 8d9e3d11ba6d640d3793aaff872ebb722e6d6ea6
git push origin v0.3.0

Please sign in to comment.