Skip to content

Commit

Permalink
adds a few conversion, where the embedding is not isometric.
Browse files Browse the repository at this point in the history
  • Loading branch information
kellertuer committed Sep 11, 2021
1 parent c742ea5 commit cb2f932
Show file tree
Hide file tree
Showing 5 changed files with 91 additions and 3 deletions.
4 changes: 2 additions & 2 deletions src/manifolds/CenteredMatrices.jl
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ where $c_i = \frac{1}{m}\sum_{j=1}^m p_{j,i}$ for $i = 1, \dots, n$.
"""
project(::CenteredMatrices, ::Any)

project!(M::CenteredMatrices, q, p) = copyto!(q, p .- mean(p, dims=1))
project!(::CenteredMatrices, q, p) = copyto!(q, p .- mean(p, dims=1))

@doc raw"""
project(M::CenteredMatrices, p, X)
Expand All @@ -119,7 +119,7 @@ where $c_i = \frac{1}{m}\sum_{j=1}^m x_{j,i}$ for $i = 1, \dots, n$.
"""
project(::CenteredMatrices, ::Any, ::Any)

project!(M::CenteredMatrices, Y, p, X) = (Y .= X .- mean(X, dims=1))
project!(::CenteredMatrices, Y, p::Any, X) = (Y .= X .- mean(X, dims=1))

@generated representation_size(::CenteredMatrices{m,n,𝔽}) where {m,n,𝔽} = (m, n)

Expand Down
22 changes: 22 additions & 0 deletions src/manifolds/GeneralizedGrassmann.jl
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,28 @@ function GeneralizedGrassmann(
return GeneralizedGrassmann{n,k,field,typeof(B)}(B)
end

@doc raw"""
change_metric(M::GeneralizedGrassmann, ::EuclideanMetric, p X)
Change `X` to the corresponding representer of the gradient with respect to the scaled metric
of the [`GeneralizedGrassmann`](@ref) `M`, i.e. `B\X`.
"""
function change_gradient(M::GeneralizedGrassmann, ::EuclideanMetric, p, X)
return M.B \ X
end

@doc raw"""
change_metric(M::GeneralizedGrassmann, ::EuclideanMetric, p X)
Change `X` to the corresponding vector with respect to the metric of the [`GeneralizedGrassmann`](@ref) `M`,
i.e. let ``B=LL'`` be the cholesky decomposition of the metrix `B` then the corresponding vector is ``L\X``.
"""
function change_metric(M::GeneralizedGrassmann, ::EuclideanMetric, p, X)
C2 = cholesky(M.B).L
return C2 \ X
end

@doc raw"""
check_point(M::GeneralizedGrassmann{n,k,𝔽}, p)
Expand Down
15 changes: 14 additions & 1 deletion src/manifolds/HyperbolicHyperboloid.jl
Original file line number Diff line number Diff line change
@@ -1,3 +1,16 @@
@doc raw"""
change_gradient(M::Hyperbolic, ::EuclideanMetric, p, X)
to change a Euclidena gradient from the embedding that was already projected onto the tangent space at `X`
we only have to correct for the metric, which means, that the sign of the last entry changes.
"""
function change_gradient(::Hyperbolic, ::EuclideanMetric, p, X)
Y = copy(M, p, X)
Y[end] *= -1
return Y
end

# a metric change does not seem possible here

function check_point(M::Hyperbolic, p; kwargs...)
mpv = invoke(check_point, Tuple{supertype(typeof(M)),typeof(p)}, M, p; kwargs...)
Expand Down Expand Up @@ -325,7 +338,7 @@ component such that for the
resulting `p` we have that its [`minkowski_metric`](@ref) is $⟨p,X⟩_{\mathrm{M}} = 0$,
i.e. $X_{n+1} = \frac{⟨\tilde p, Y⟩}{p_{n+1}}$, where $\tilde p = (p_1,\ldots,p_n)$.
"""
_hyperbolize(M::Hyperbolic, p, Y) = vcat(Y, dot(p[1:(end - 1)], Y) / p[end])
_hyperbolize(::Hyperbolic, p, Y) = vcat(Y, dot(p[1:(end - 1)], Y) / p[end])

@doc raw"""
inner(M::Hyperbolic{n}, p, X, Y)
Expand Down
36 changes: 36 additions & 0 deletions src/manifolds/HyperbolicPoincareBall.jl
Original file line number Diff line number Diff line change
@@ -1,3 +1,39 @@
@doc raw"""
change_gradient(M::Hyperbolic{n}, ::EuclideanMetric, p::PoincareBallPoint, X::PoincareBallTVector)
Since in the metric we always have the term `` α = \frac{2}{1-\sum_{i=1}^n p_i^2}`` per element,
the correction for the gradient reads `` Z = \frac{1}{α^2}X``.
"""
function change_gradient(
::Hyperbolic,
::EuclideanMetric,
p::PoincareBallPoint,
X::PoincareBallTVector,
)
α = 2 / (1 - norm(p.value)^2)
Y = copy(M, p, X)
Y.value ./= α^2
return Y
end

@doc raw"""
change_metric(M::Hyperbolic{n}, ::EuclideanMetric, p::PoincareBallPoint, X::PoincareBallTVector)
Since in the metric we always have the term `` α = \frac{2}{1-\sum_{i=1}^n p_i^2}`` per element,
the correction for the metric reads `` Z = \frac{1}{α}X``.
"""
function change_metric(
::Hyperbolic,
::EuclideanMetric,
p::PoincareBallPoint,
X::PoincareBallTVector,
)
α = 2 / (1 - norm(p.value)^2)
Y = copy(M, p, X)
Y.value ./= α
return Y
end

function check_point(M::Hyperbolic{N}, p::PoincareBallPoint; kwargs...) where {N}
mpv = check_point(Euclidean(N), p.value; kwargs...)
mpv === nothing || return mpv
Expand Down
17 changes: 17 additions & 0 deletions src/manifolds/PositiveNumbers.jl
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,23 @@ function check_point(M::PositiveNumbers, p; kwargs...)
return nothing
end

@doc raw"""
change_metric(M::PositiveNumbers, E::EuclideanMetric, p, X)
Given a tangent vector ``X ∈ T_p\mathcal M``representing a gradient with respect to the [`EuclideanMetric`](@ref) `g_E`,
this function changes into the positivity metric representation of
[`PositiveNumbers`](lref) `M` for the same gradient.
"""
change_gradient(::PositiveNumbers, ::EuclideanMetric, p, X) = p .* X .* p

@doc raw"""
change_metric(M::SymmetricPOsitiveDefinite, E::EuclideanMetric, p, X)
Given a tangent vector ``X ∈ T_p\mathcal M`` with respect to the [`EuclideanMetric`](@ref) `g_E`,
this function changes into the positivity metric of [`PositiveNumbers`](lref) `M` for the same gradient.
"""
change_metric(::PositiveNumbers, ::EuclideanMetric, p, X) = p .* X

"""
check_vector(M::PositiveNumbers, p, X; kwargs...)
Expand Down

0 comments on commit cb2f932

Please sign in to comment.