Skip to content

Commit

Permalink
flat!, sharp! and optimized inner of cotangent vectors for metric man…
Browse files Browse the repository at this point in the history
…ifolds
  • Loading branch information
mateuszbaran committed Aug 1, 2019
1 parent b0faa70 commit ea6ef68
Show file tree
Hide file tree
Showing 3 changed files with 81 additions and 1 deletion.
59 changes: 59 additions & 0 deletions src/Metric.jl
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,21 @@ end
return inner(M.manifold, x, v, w)
end

@traitfn function inner(B::VectorBundleFibers{<:CotangentSpaceType, MMT}, x, v, w) where {MT<:Manifold,
GT<:Metric,
MMT<:MetricManifold{MT,GT};
!HasMetric{MT,GT}}
ginv = inverse_local_metric(B.M, x)
return dot(ginv * v, ginv * w)

This comment has been minimized.

Copy link
@dkarrasch

dkarrasch Aug 1, 2019

I don't think this is correct. It should be v' * ginv * W. I'm working on a 3-arg dot in Julia.Base. JuliaLang/julia#32739 With that one, it would be dot(v, ginv, w).

This comment has been minimized.

Copy link
@mateuszbaran

mateuszbaran Aug 1, 2019

Author Member

Right, I meant to call inner instead of dot but that would perform unnecessary multiplications anyway.

This comment has been minimized.

Copy link
@sethaxen

sethaxen Aug 2, 2019

Member

dot(v, ginv * w) was the default I was thinking. Calling inner would be less efficient because one of the multiplications is just cancelling one of the ginvs. Or maybe that's what you meant.

👍 for a generalized dot product when it's available!

end

@traitfn function inner(B::VectorBundleFibers{<:CotangentSpaceType, MMT}, x, v, w) where {MT<:Manifold,
GT<:Metric,
MMT<:MetricManifold{MT,GT};
HasMetric{MT,GT}}
return inner(VectorBundleFibers(B.VS, B.M.manifold), x, v, w)
end

@traitfn function norm(M::MMT, x, v) where {MT<:Manifold,
GT<:Metric,
MMT<:MetricManifold{MT,GT};
Expand Down Expand Up @@ -457,3 +472,47 @@ end
HasMetric{MT,GT}}
return is_tangent_vector(M.manifold, x, v; kwargs...)
end

@traitfn function flat!(M::MMT,
v::FVector{CotangentSpaceType},
x,
w::FVector{TangentSpaceType}) where {MT<:Manifold,
GT<:Metric,
MMT<:MetricManifold{MT,GT};
!HasMetric{MT,GT}}
g = local_metric(M, x)
copyto!(v, g*w)
return v
end

@traitfn function flat!(M::MMT,
v::FVector{CotangentSpaceType},
x,
w::FVector{TangentSpaceType}) where {MT<:Manifold,
GT<:Metric,
MMT<:MetricManifold{MT,GT};
HasMetric{MT,GT}}
return flat!(M.manifold, v, x, w)
end

@traitfn function sharp!(M::MMT,
v::FVector{TangentSpaceType},
x,
w::FVector{CotangentSpaceType}) where {MT<:Manifold,
GT<:Metric,
MMT<:MetricManifold{MT,GT};
!HasMetric{MT,GT}}
ginv = inverse_local_metric(M, x)
copyto!(v, ginv*w)
return v
end

@traitfn function sharp!(M::MMT,
v::FVector{TangentSpaceType},
x,
w::FVector{CotangentSpaceType}) where {MT<:Manifold,
GT<:Metric,
MMT<:MetricManifold{MT,GT};
HasMetric{MT,GT}}
return flat!(M.manifold, v, x, w)

This comment has been minimized.

Copy link
@sethaxen

sethaxen Aug 2, 2019

Member

Should be sharp! I think

This comment has been minimized.

Copy link
@mateuszbaran

mateuszbaran Aug 3, 2019

Author Member

Yes, thanks for catching this.

end
5 changes: 4 additions & 1 deletion src/VectorBundle.jl
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,10 @@ function inner(B::VectorBundleFibers{<:TangentSpaceType}, x, v, w)
end

function inner(B::VectorBundleFibers{<:CotangentSpaceType}, x, v, w)
return inner(B.M, x, flat(B, x, v), flat(B, x, w))
return inner(B.M,
x,
sharp(B.M, x, FVector(CotangentSpace, v)).data,
sharp(B.M, x, FVector(CotangentSpace, w)).data)
end

norm(B::VectorBundleFibers, x, v) = sqrt(inner(B, x, v, v))
Expand Down
18 changes: 18 additions & 0 deletions test/metric_test.jl
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
include("utils.jl")

struct TestEuclidean{N} <: Manifold end
struct TestEuclideanMetric <: Metric end
Expand Down Expand Up @@ -153,6 +154,14 @@ struct BaseManifoldMetric{M} <: Metric end
Manifolds.exp!(::BaseManifold, y, x, v) = y .= x + 2 * v
Manifolds.log!(::BaseManifold, v, x, y) = v .= (y - x) / 2
Manifolds.project_tangent!(::BaseManifold, w, x, v) = w .= 2 .* v
function Manifolds.flat!(::BaseManifold, v::FVector{Manifolds.CotangentSpaceType}, x, w::FVector{Manifolds.TangentSpaceType})
v.data .= 2 .* w.data
return v
end
function Manifolds.sharp!(::BaseManifold, v::FVector{Manifolds.TangentSpaceType}, x, w::FVector{Manifolds.CotangentSpaceType})
v.data .= w.data ./ 2
return v
end

M = BaseManifold{3}()
g = BaseManifoldMetric{3}()
Expand All @@ -178,4 +187,13 @@ struct BaseManifoldMetric{M} <: Metric end
@test injectivity_radius(MM) === injectivity_radius(M)
@test is_manifold_point(MM, x) === is_manifold_point(M, x)
@test is_tangent_vector(MM, x, v) === is_tangent_vector(M, x, v)

cov = flat(M, x, FVector(TangentSpace, v))
cow = flat(M, x, FVector(TangentSpace, w))
@test cov.data flat(MM, x, FVector(TangentSpace, v)).data
cotspace = CotangentBundleFibers(M)
@test cov.data 2 * v
@test inner(M, x, v, w) inner(cotspace, x, cov.data, cow.data)
@test inner(MM, x, v, w) inner(cotspace, x, cov.data, cow.data)
@test sharp(M, x, cov).data v
end

0 comments on commit ea6ef68

Please sign in to comment.