A Test suite
The submodule Manifolds.Test provides functions to test mathematical properties of functions defined for a manifold according to the API from ManifoldsBase.jl.
Manifolds.Test โ Module
Manifolds.TestThe module Manifolds.Test contains functions to test functions from Manifolds.jl. Most functionality is provided only when Test.jl is loaded as well, i.e. populated with methods by the extension.
The test functions provided are meant to verify that the defined functions on a specific manifold behave as expected, for example that an allocating and in-place version of a function give the same result, or that for example the exponential map computes a point on the manifold, and calling the logarithmic map on the result yields the original tangent vector again, for tangent vectors within the injectivity radius.
In general for every function defined in the API for manifolds, this module shall provide a test function with
- the same name prefixed by
test_ - the same function arguments as the original function
- keyword arguments to control which tests to perform
The main function is
Manifolds.Test.test_manifold โ Function
test_manifold(G::AbstractManifold, properties::Dict, expectations::Dict)Test the AbstractManifold $\mathcal M$ based on a Dict of properties and a Dict of expectations.
Three functions are expected to be defined (without explicitly being passed in the properties): is_point(M, p), is_vector(M, p, X), and isapprox(M, p, q) / isapprox(M, p, X, Y), since these are essential for verifying results.
From the following properties, the two often expected to be defined are :Points and :Vectors, which should contain at least two points and two tangent vectors, respectively.
Possible properties are
:Aliasedis a boolean (same as:Mutatingby default) whether to test the mutating variants with aliased input:Atlasesis a vector of atlases, which can be used to test chart related functions likeget_parametersandget_pointat each of the:Points, each in the chart selected byget_chart_index. Transition maps are tested from the chart of the first to the chart of the last point. Since atlases usually differ in which functions they implement, calltest_manifoldseparately for atlases with different sets of:Functions.:Basesis a vector of bases, which can be used to test basis related functions, one basis for each entry in:Coordinates:Covectorsis a vector of covectors, which should be in the cotangent space of the correspondinig point entry in:Points:Coordinatesis a vector of coordinates, which can be used to test coordinate related functions, one coordinate vector for each entry in:Bases:EmbeddedPointsis a vector of points in the embedding space ofM, to testproject:EmbeddedVectorsis a vector of tangent vectors in the embedding space ofM, to testproject:Functionsis a vector of all defined functions forMnote a test is activated by the function (likeexp), adding the mutating function (likeexp!) overwrites the global default (see:Mutating) to true.:GeodesicMaxTimeis a real number indicating the time parameter to use when testinggeodesic:GeodesicSamplesis an integer indicating the number of samples to use when testinggeodesicandshortest_geodesic(defaults to 100):InvalidPointsis a vector of points that are not onM, e.g. to testis_point:InvalidVectorsis a vector of tangent vectors that are not in the tangent space of the first point from:Points:InverseRetractionMethodsis a vector of inverse retraction methods to test onMthese should have the same order as:RetractionMethods(usemissingfor skipping one):Mutatingis a boolean (trueby default) whether to test the mutating variants of functions or not. when setting this to false, you can still activate single functions mutation checks by adding the mutating function to:Functions:Nameis a name of the test. If not provided, defaults to"$M":NormalVectorsis a vector of normal vectors, where each should be in the normal space of the corresponding point entries in:Points:OtherMetricsis a vector of metrics that are not the default metric ofM, to testis_default_metric:Pointsis a vector of at least 2 points onM, which should not be the same point:RetractionMethodsis a vector of retraction methods to test onMthese should have the same order as:InverseRetractionMethods(usemissingfor skipping one):Rngis a random number generator to use for generating random points/vectors if needed:Seedis a seed to use for generating random points/vectors if needed:ShortestGeodesicTimeis a real number indicating the time parameter to use when testingshortest_geodesic(defaults to 0.5):Vectorsis a vector of at least 2 tangent vectors, which should be in the tangent space of the correspondinig point entries in:Points:SecondVectoris a single second vector in the tangent space of the first entry of:Points, for example to testinner:VectorTransportMethodsis a vector of vector transport methods to test onM:TestVectorArithmeticis a boolean (trueby default) whether to test basic arithmetic and broadcasting of the first two:Vectors(or the first one and:SecondVector), if at least one tangent vector is provided:TestRandReproducibilityis a boolean (by default the value of:Mutating, ortrueifrand!is among the:Functions) whether to test thatrandandrand!draw the same points and tangent vectors from copies of a random number generator:TestRandScalingis a boolean (falseby default) whether to test that random tangent vectors scale linearly with the keywordฯofrand:TestMidpointSymmetryis a boolean (trueby default) whether to test the symmetry property of the midpoint function:TestChartIndexParametersis a boolean (falseby default) whether to test the variantget_chart_index(M, A, i, a)for the:Atlases:InducedBasisBackendis a differentiation backend (missingby default, which deactivates the test), for exampleAutoFiniteDifferences(central_fdm(5, 1)), to test theinduced_basisof the:Atlasesagainst the derivative ofget_point, seetest_induced_basis:TestInfois a boolean (trueby default) whether to test that whethererror=:infoin verification functions issues info messages.:TestWarnis a boolean (trueby default) whether to test that whethererror=:warnin verification functions issues warning.
Possible entries of the expectations dictionary are
- any function tested to provide their expected resulting value, e.g.
exp => pfor the result ofexp(M, p, X) - for retractions, inverse retractions, and vector transports, the key is a tuple of the function and the method, e.g.
(retract, method) => q - for
embed, andproject, the key is a tuple of the function and:Pointor:Vector, e.g. `(embed, :Point) of expected (embedded) points or vectors, omitting that symbol is interpreted as the expected point. - for
injectivity_radius- you can provide the global test for just the function,
- you can provide the radius for a specific point with
(injectivity_radius, p) - you can provide a global or local one for retractions as well usinr
(injectivity_radius, rm)andinjectivity_radius, p, rm, respectively
- for
get_basis, the key is a tuple of the function and the basis, e.g.(get_basis, B) => ...to the expected basis - for
get_coordinatesthe key is a tuple of the function and the basis, e.g.(get_coordinates, B) => c - for
get_vectorthe key is a tuple of the function, the coordinate vector, and the basis, e.g.(get_vector, c, B) => X - for atlas related functions, the key is a tuple of the function and the atlas
Afor the result at the first point in the chart selected byget_chart_index, e.g.(get_parameters, A) => a,(get_chart_index, A) => i,(check_chart_switch, A) => false,(local_metric, A) => g,(Manifolds.inverse_chart_injectivity_radius, A) => r, and(transition_map_diff, A) => cfor the coordinates of the first vector, while(transition_map, A_from, A_to) => bis keyed by both atlases - for
get_embeddingthe key(get_embedding, T)with the typeTof the first point is the expected embedding for points of that type, which defaults to the expectation forget_embedding - for
get_vectorsthe key is a tuple of the function and the basis, e.g.(get_vectors, B) => :Symbolwhere:Orthogonaltests for orthogonality:Orthonormaltests additionally to the previous for unit length
get_basison any provided basis, if that function is available. - for
is_default_metric, the value is the default metric - for
rand,(number_eltype, rand) => Tspecifies the expected number typeTof random points and tangent vectors :atol => 0.0a global absolute tolerance:atols -> Dict()a dictionaryfunction -> atolfor tolerances of specific function tested.:Types-> Dict() a dictionaryfunction -> Typefor specifying expected types of results of specific functions, for examplemanifold_dimension => Int.:IsPointErrorsis a vector of expected error types for each invalid point provided in:InvalidPoints, usemissingto skip testing for errors for a specific point.:IsVectorErrorsis a vector of expected error types for each invalid vector provided in:InvalidVectors, usemissingto skip testing for errors for a specific vector.:IsVectorBasepointErroris an expected error type when the base point is invalid e.g. foris_vector
A manifold is described by two dictionaries, one of properties and one of expected results.
using Manifolds, TestM = Sphere(2)p = [1.0, 0.0, 0.0]q = [0.0, 1.0, 0.0]X = [0.0, ฯ / 4, 0.0]Manifolds.Test.test_manifold( M, Dict( :Functions => [distance, exp, log, manifold_dimension, norm, repr], :Points => [p, q], :Vectors => [X], ), Dict(:atol => 1.0e-14, manifold_dimension => 2, repr => "Sphere(2)"),);Test.DefaultTestSet("Manifolds.Test suite for Sphere(2)", Any[Test.DefaultTestSet("distance(M, p, q)", Any[], 4, false, false, true, 1.794239726245767e9, 1.79423972626599e9, false, "/home/runner/work/Manifolds.jl/Manifolds.jl/ext/ManifoldsTestExt/ManifoldsTestExt.jl", Random.Xoshiro(0x20b2a02cbbc40d9a, 0xe4f1426f6d5c07ea, 0x632b2529bc576cc3, 0xa5be6db14db38560, 0x47932124d175eac7)), Test.DefaultTestSet("exp(M, p, X)", Any[], 7, false, false, true, 1.794239726680788e9, 1.79423972691469e9, false, "/home/runner/work/Manifolds.jl/Manifolds.jl/ext/ManifoldsTestExt/ManifoldsTestExt.jl", Random.Xoshiro(0x20b2a02cbbc40d9a, 0xe4f1426f6d5c07ea, 0x632b2529bc576cc3, 0xa5be6db14db38560, 0x47932124d175eac7)), Test.DefaultTestSet("log(M, p, q)", Any[], 5, false, false, true, 1.794239727263444e9, 1.794239727263516e9, false, "/home/runner/work/Manifolds.jl/Manifolds.jl/ext/ManifoldsTestExt/ManifoldsTestExt.jl", Random.Xoshiro(0x20b2a02cbbc40d9a, 0xe4f1426f6d5c07ea, 0x632b2529bc576cc3, 0xa5be6db14db38560, 0x47932124d175eac7)), Test.DefaultTestSet("manifold_dimension(M)", Any[], 3, false, false, true, 1.794239727368984e9, 1.794239727368999e9, false, "/home/runner/work/Manifolds.jl/Manifolds.jl/ext/ManifoldsTestExt/ManifoldsTestExt.jl", Random.Xoshiro(0x20b2a02cbbc40d9a, 0xe4f1426f6d5c07ea, 0x632b2529bc576cc3, 0xa5be6db14db38560, 0x47932124d175eac7)), Test.DefaultTestSet("norm(M, p, X)", Any[], 2, false, false, true, 1.794239727475046e9, 1.79423972747506e9, false, "/home/runner/work/Manifolds.jl/Manifolds.jl/ext/ManifoldsTestExt/ManifoldsTestExt.jl", Random.Xoshiro(0x20b2a02cbbc40d9a, 0xe4f1426f6d5c07ea, 0x632b2529bc576cc3, 0xa5be6db14db38560, 0x47932124d175eac7)), Test.DefaultTestSet("repr(M)", Any[], 1, false, false, true, 1.794239727562109e9, 1.794239727562131e9, false, "/home/runner/work/Manifolds.jl/Manifolds.jl/ext/ManifoldsTestExt/ManifoldsTestExt.jl", Random.Xoshiro(0x20b2a02cbbc40d9a, 0xe4f1426f6d5c07ea, 0x632b2529bc576cc3, 0xa5be6db14db38560, 0x47932124d175eac7)), Test.DefaultTestSet("Tangent vector arithmetic", Any[], 18, false, false, true, 1.794239728348024e9, 1.794239728348125e9, false, "/home/runner/work/Manifolds.jl/Manifolds.jl/ext/ManifoldsTestExt/ManifoldsTestExt.jl", Random.Xoshiro(0x20b2a02cbbc40d9a, 0xe4f1426f6d5c07ea, 0x632b2529bc576cc3, 0xa5be6db14db38560, 0x47932124d175eac7))], 0, false, false, true, 1.794239725733882e9, 1.794239728348135e9, false, "/home/runner/work/Manifolds.jl/Manifolds.jl/ext/ManifoldsTestExt/ManifoldsTestExt.jl", Random.Xoshiro(0x20b2a02cbbc40d9a, 0xe4f1426f6d5c07ea, 0x632b2529bc576cc3, 0xa5be6db14db38560, 0x47932124d175eac7))Functions for individual tests
Manifolds.Test.test_affine_connection โ Function
Manifolds.Test.test_affine_connection(
M, A, i, a, Xc, Yc;
available_functions = [],
expected_value = NoExpectation(),
name = "affine_connection on $M in $A",
test_mutating = true,
test_symmetry = true,
kwargs...
)Test the affine_connection on manifold M at the point with parameters a in chart i of atlas A for vectors with coordinates Xc and Yc in the induced basis.
- that the result is a coordinate vector of the same length as
a - that the result matches
expected_value, if given - that the result is linear in
Xcand inYc - that the result is symmetric in
XcandYc, i.e. the connection is torsion-free (if activated) - that the mutating version
affine_connection!matches the non-mutating version, (if activated) - that the result matches
levi_civita_affine_connection(if activated)
Manifolds.Test.test_check_chart_switch โ Function
Manifolds.Test.test_check_chart_switch(
M, A, i, a;
expected_value = NoExpectation(),
name = "check_chart_switch on $M in $A",
)Test the check_chart_switch on manifold M for parameters a in chart i of atlas A.
- that the result is a boolean
- that the result matches
expected_value, if given
Manifolds.Test.test_copy โ Function
Manifolds.Test.test_copy(M, p, X;
name = "copying on $M for $(typeof(p)) points",
kwargs...
)Test copy(M, p) and copy(M, p, X) on a manifold M.
- that the copied point/vector is a valid point/vector on the manifold / tangent space
- that the copied point/vector matches the original point/vector but is new memory
Manifolds.Test.test_copyto โ Function
Manifolds.Test.test_copyto(M, p, X;
name = "copying on $M for $(typeof(p)) points",
kwargs...
)Test copyto!(M, q, p) and copyto!(M, Y, p, X) on a manifold M.
- that the copied point/vector is a valid point/vector on the manifold / tangent space
- that the copied point/vector matches the original point/vector and is the same memory
Note that since this function does not modify its input, is is called test_copyto.
Manifolds.Test.test_default_retraction โ Function
Manifolds.Test.test_default_retraction(
M, T=missing;
expected_value = NoExpectation(),
expected_type = isexpected(expected_value) ? Expect(typeof(expect(expected_value))) : NoExpectation(),
name = "default_retraction_method on $M $(ismissing(T) ? "" : "for type $T")",
)Test the default_retraction_method on manifold M.
- that it returns an
AbstractRetractionMethod - that the result matches
expected_value, if given - that the result is of type
expected_type, if given, defaults to the type of the value
Manifolds.Test.test_default_inverse_retraction โ Function
Manifolds.Test.test_default_inverse_retraction(
M, T=missing;
expected_value = NoExpectation(),
expected_type = !isexpected(expected_value) ? NoExpectation() : typeof(expected_value),
name = "default_inverse_retraction_method on $M $(ismissing(T) ? "" : "for type $T")",
)Test the default_inverse_retraction_method on manifold M.
- that it returns an
AbstractInverseRetractionMethod - that the result matches
expected_value, if given - that the result is of type
expected_type, if given, defaults to the type of the value
Manifolds.Test.test_default_vector_transport_method โ Function
Manifolds.Test.test_default_vector_transport_method(
M, T=missing;
expected_value = NoExpectation(),
expected_type = isexpected(expected_value) ? Expect(typeof(expect(expected_value))) : NoExpectation(),
name = "default_vector_transport_method on $M $(ismissing(T) ? "" : "for type $T")",
)Test the default_vector_transport_method on manifold M.
- that it returns an
AbstractVectorTransportMethod - that the result matches
expected_value, if given - that the result is of type
expected_type, if given, defaults to the type of the value
Manifolds.Test.test_distance โ Function
Manifolds.Test.test_distance(
M, p, q;
available_functions=[], expected_value=NoExpectation(),
name = "Distance on $M between $(typeof(p)) points",
kwargs...
)Test the distance function on manifold M between points p and q.
- that the result is a nonnegative number
- that the distance from
ptopis zero - that the distance is symmetric
- that the result matches
expected_value, if given - that the distance is equal to the norm of the logarithmic map (if
logandnormare available) (only performed if eitherinjectivity_radiusis not available or the points are within)
Manifolds.Test.test_exp โ Function
Manifolds.Test.test_exp(
M, p, X, t=1.0;
available_functions=[], expected_value=NoExpectation(), test_mutating=true,
test_log = (log in available_functions),
test_aliased = true,
test_fused = true,
test_injectivity_radius = (injectivity_radius in available_functions),
name = "Exponential map on $M for $(typeof(p)) points",
kwargs...
)Test the exponential map on manifold M at point p with tangent vector X.
- that the result is a valid point on the manifold
- that the result matches
expected_value, if given - that the mutating version
exp!matches the non-mutating version, (if activated) - that
exp!works on aliased in put (p=q) (if activated for mutating) - that the logarithmic map inverts the exponential map (if activated)
(only performed if either injectivity_radius is not available or X is within)
- that the fused version
exp_fused(M, p, t, X)matches the non-fused version (if activated)
Manifolds.Test.test_embed โ Function
Manifolds.Test.test_embed(
M, p, X=missing;
available_functions=[],
expected_point=NoExpectation(),
expected_vector=NoExpectation(),
test_aliased=true,
test_mutating=true,
name = "Embedding on $M for $(typeof(p)) points",
kwargs...
)Test the embed(M, p) and embed(M, p, X) to embed points and tangent vectors (if not missing).
Besides a simple call of embed (for both variants) the following ones are prefoemd if get_embedding is available:
- that the embedded point is a valid point on the embedding manifold
- that the embedded vector is a valid tangent vector on the embedding manifold (if
get_embeddingis available andXis notmissing) - that the result matches
expected_pointandexpected_vector, respectively, if given - that the projection inverts the embedding (if
projectis available) - that the mutating version
embed!produces the same result(s) (if activated andget_embeddingis available) - that
embed!works on aliased input (p=qorX=Y) (if activated and p/q or X/Y are of same type)
Manifolds.Test.test_embed_project โ Function
Manifolds.Test.test_embed_project(
M, ap, aX = missing;
available_functions=[],
expected_point=NoExpectation(),
expected_vector=NoExpectation(),
test_aliased=true,
test_mutating=true,
name = "Projection on $M for $(typeof(q)) points",
kwargs...
)Test the p=embed_project(M, ap) and embed_project(M, p, aX) to project points and tangent vectors (if not aX is not missing) after embedding them. Besides a simple call of embed_project (for both variants) the following tests are performed
- that the projected point is a valid point on the manifold
- that the projected vector is a valid tangent vector on the manifold
- that the result matches
expected_pointandexpected_vector, respectively, if given - that the mutating version
embed_project!produces the same result(s) (if activated) - that
embed_project!works on aliased input (p=qorX=Y) (if activated and p/q or X/Y are of same type)
Manifolds.Test.test_flat โ Function
Manifolds.Test.test_flat(M, p, X;
available_functions = [],
expected_value= NoExpectation(),
test_mutating = true,
name = "Flat on $M for $(typeof(p)) points",
kwargs...
)Test the flat operation on manifold M at point p with tangent vector X.
- (we can not yet test valid cotangent vectors)
- that the result matches
expected_value, if given - that
sharpis the inverse - that mutating version
flat!matches non-mutating version (if activated)
Manifolds.Test.test_induced_basis โ Function
Manifolds.Test.test_induced_basis(
M, A, i, p, X;
available_functions = [],
differential_atol = 1.0e-8,
differential_backend = missing,
expected_value = NoExpectation(),
name = "induced_basis on $M in $A",
kwargs...
)Test the induced_basis on manifold M of chart i in atlas A using a point p in the domain of the chart and a tangent vector X at p.
- that the result is a basis
- that the result matches
expected_value, if given - that
get_coordinatesin the basis yieldsmanifold_dimensioncoordinates (if available) andget_vectorinverts it (if available) - that each basis vector matches, up to
differential_atol, theprojection of the derivative of the embedded (seeembed)get_pointalong the corresponding parameter curve, computed with the DifferentiationInterface.jl backenddifferential_backend, for exampleAutoFiniteDifferences(central_fdm(5, 1))from FiniteDifferences.jl (if notmissing)
Manifolds.Test.test_injectivity_radius โ Function
Manifolds.Test.test_injectivity_radius(M, p = missing;
expected_value = NoExpectation(),
expected_global_value = NoExpectation(),
retraction_method = missing,
name = "Injectivity radius on $M at point $(ismissing(p) ? "" : "$typeof(p)")) and $(retraction_method)",
kwargs...
)Test the injectivity radius on manifold M at point p.
- that the result is a nonnegative real number
- that the result matches
expected_value, if given - if a point
pis given, that the result is larger or equal to the global injectivity radius
Manifolds.Test.test_inner โ Function
Manifolds.Test.test_inner(M, p, X, Y;
available_functions=[], expected_value = NoExpectation(),
name = "Inner product on $M at point $(typeof(p))",
test_norm = (norm in available_functions),
kwargs...
)Test the inner product on the manifold M at point p for tangent vectors X and Y.
- that the result is a number, which may be complex, e.g. on complex manifolds
- that the result matches
expected_value, if given - that the inner product is conjugate symmetric
- that the inner product of
Xwith itself is real and, if the metric is positive definite, seeis_positive_definite_metric, nonnegative - that the inner product of
Xwith itself is the same as its norm squared (if activated)
Manifolds.Test.test_inner(M, A::AbstractAtlas, i, a, Xc, Yc;
available_functions=[], expected_value = NoExpectation(),
name = "Inner product on $M in $A",
test_norm = (norm in available_functions),
kwargs...
)Test the inner product on the manifold M at the point with parameters a in chart i of atlas A for tangent vectors with coordinates Xc and Yc in the induced basis.
- that the result is a number
- that the result matches
expected_value, if given - that the inner product is conjugate symmetric
- that the inner product of
Xcwith itself is the same as its norm squared (if activated) - that the result matches the inner product of the corresponding tangent vectors (if
get_vectoris available)
Manifolds.Test.test_inverse_chart_injectivity_radius โ Function
Manifolds.Test.test_inverse_chart_injectivity_radius(
M, A, i;
expected_value = NoExpectation(),
name = "inverse_chart_injectivity_radius on $M in $A",
kwargs...
)Test the inverse_chart_injectivity_radius on manifold M for chart i of atlas A.
- that the result is a positive real number
- that the result matches
expected_value, if given
Manifolds.Test.test_inverse_retract โ Function
Manifolds.Test.test_inverse_retract(
M, p, q, m::AbstractInverseRetractionMethod;
available_functions=[],
expected_value = NoExpectation(),
name = "Inverse retraction $m on $M at point $(typeof(p))",
retraction_method = missing,
test_mutating = true,
test_retraction = (retract in available_functions) && !ismissing(retraction_method),
kwargs...
)Test the inverse retraction method m on manifold M at point p towards point q.
- that the result is a valid tangent vector at
pon the manifold - that the result matches
expected_value, if given - that the mutating version
inverse_retract!matches the non-mutating version, (if activated) - that the retraction inverts the inverse retraction (if activated)
Manifolds.Test.test_is_default_metric โ Function
Manifolds.Test.test_is_default_metric(M, metric::AbstractMetric, other_metrics = [];
name = "is_default_metric on $M",
)Test the is_default_metric on manifold M.
- that it returns true for the given
metric - that it returns false for all other provided metrics
Manifolds.Test.test_is_flat โ Function
Manifolds.Test.test_is_flat(
M;
expected_value = NoExpectation(),
name = "is_flat on $M",
)Test the function is_flat on manifold M. Since it returns a boolean, there is also only the check that it agrees with the expected_value, if given.
Manifolds.Test.test_is_positive_definite_metric โ Function
Manifolds.Test.test_is_positive_definite_metric(
M;
expected_value = NoExpectation(),
name = "is_positive_definite_metric on $M",
)Test the function is_positive_definite_metric on manifold M.
- that it agrees with the numbers of negative and zero eigenvalues in the
metric_signaturebeing zero - that it agrees with the
expected_value, if given
Manifolds.Test.test_is_point โ Function
Manifolds.Test.test_is_point(
M, p, qs...;
errors = [],
name = "is_point on $M for $(typeof(p)) points",
test_warn = true,
test_info = true,
kwargs...
)Test the function is_point for a point p on manifold M.
- that for
pit returnstrue. - that for each
qinqsit- returns
false - issues a warning (if activated)
- issues an info message (if activated)
- throws the corresponding error from
error_types(if notmissing)
- returns
Manifolds.Test.test_is_vector โ Function
Manifolds.Test.test_is_vector(
M, p, X, Ys...;
basepoint_error = NoExpectation(),
check_basepoint = true,
errors = [],
name = "is_vector on $M for $(typeof(p)) points",
test_warn = true,
test_info = true,
q = missing,
kwargs...
)Test the function is_vector on manifold M at point p for tangent vector X.
- that for
Xit returnstrue. - that for each
YinYsit- returns
false - issues a warning (if activated)
- issues an info message (if activated)
- throws the corresponding error from
error_types(if notmissing)
- returns
- if
check_basepointistrue, then it checks that- for
pthis still returnstrue - for the base point
qit- returns
false - issues a warning (if activated)
- issues an info message (if activated)
- throws the corresponding error from
basepoint_error(if given)
- returns
- for
Manifolds.Test.test_geodesic โ Function
Manifolds.Test.test_geodesic(M, p, X, t=1.0;
available_functions=[],
expected_value = NoExpectation(),
N = 10,
name = "Geodesic on $M for $(typeof(p)) points",
kwargs...
)Test the geodesic on manifold M at point p with tangent vector X at time t.
- that at time
0the geodesic returnsp - that the function
ฮณ = geodesic(M, p, X)is consistent with evaluation at0andt` - that the result is a valid point on the manifold
- that the result matches
expected_value, if given - that the geodesic has constant speed (if activated): between
Nsamples on[0, t]the speed is the same and equal tonorm(M, p, X)
Manifolds.Test.test_get_basis โ Function
Manifolds.Test.test_get_basis(
M, p, b::AbstractBasis;
available_functions = [],
expected_value = NoExpectation(),
expected_type = isexpected(expected_value) ? Expect(typeof(expect(expected_value))) : Expect(CachedBasis),
name = "get_basis on $M at point $(typeof(p)) for basis $(typeof(b))",
)Test the get_basis on manifold M at point p for basis b.
- that it returns a basis of type
expected_type, which defaults toCachedBasis. - that the result matches
expected_value, if given
Manifolds.Test.test_get_chart_index โ Function
Manifolds.Test.test_get_chart_index(
M, A, p;
available_functions = [],
expected_value = NoExpectation(),
name = "get_chart_index on $M in $A for point $(typeof(p))",
test_parameters = false,
kwargs...
)Test the get_chart_index on manifold M in atlas A for point p.
- that the chart selection is deterministic
- that the result matches
expected_value, if given - that
plies in the domain of the selected chart, i.e.get_pointinvertsget_parametersthere (if both are available) - that the variant
get_chart_index(M, A, i, a)selecting a chart based on parametersain chartiis deterministic and selects a chart, whose domain containsp(if activated)
Manifolds.Test.test_get_coordinates โ Function
Manifolds.Test.test_get_coordinates(
M, p, X, B;
available_functions = [],
expected_value = NoExpectation(),
name = "get_coordinates on $M at point $(typeof(p))",
test_mutating = true,
)Test the get_coordinates on manifold M at point p for a tangent vector X and a basis B.
- that the result is a valid coordinate vector, that is of correct length
- that the result matches
expected_value, if given - that the mutating version
get_coordinates!matches the non-mutating version, (if activated) - that
get_vectorinvertsget_coordinates(if activated)
Manifolds.Test.test_get_default_atlas โ Function
Manifolds.Test.test_get_default_atlas(M;
expected_value = NoExpectation(),
expected_type = isexpected(expected_value) ? Expect(typeof(expect(expected_value))) : Expect(AbstractAtlas{โ}),
name = "get_default_atlas on $M",
)Test the get_default_atlas on manifold M.
- that it returns an atlas of type
expected_type, which defaults to a real-valuedAbstractAtlas - that the result matches
expected_value, if given
Manifolds.Test.test_get_embedding โ Function
Manifolds.Test.test_get_embedding(M, P=missing;
expected_value = NoExpectation(),
expected_type = isexpected(expected_value) ? Expect(typeof(expect(expected_value))) : NoExpectation(),
name = "get_embedding on $M $(ismissing(P) ? "" : "for type $P")",
)Test the get_embedding on manifold M.
- that it returns an
AbstractManifold. - that its type matches
expected_type, if given, defaults to the type of the expected value - that the result matches
expected_value, if given
Manifolds.Test.test_get_parameters โ Function
Manifolds.Test.test_get_parameters(
M, A, i, p;
available_functions = [],
expected_value = NoExpectation(),
name = "get_parameters on $M in $A for point $(typeof(p))",
test_mutating = true,
kwargs...
)Test the get_parameters on manifold M for point p in chart i of atlas A.
- that the result is a vector of length
manifold_dimension - that the result matches
expected_value, if given - that the mutating version
get_parameters!matches the non-mutating version, (if activated) - that
get_pointinvertsget_parameters(if activated)
Manifolds.Test.test_get_point โ Function
Manifolds.Test.test_get_point(
M, A, i, a;
available_functions = [],
expected_value = NoExpectation(),
name = "get_point on $M in $A for parameters $(typeof(a))",
test_mutating = true,
kwargs...
)Test the get_point on manifold M for parameters a in chart i of atlas A.
- that the result is a valid point on the manifold
- that the result matches
expected_value, if given - that the mutating version
get_point!matches the non-mutating version, (if activated) - that
get_parametersinvertsget_point(if activated)
Manifolds.Test.test_get_vector โ Function
Manifolds.Test.test_get_vector(
M, p, c, B;
available_functions=[],
expected_value = NoExpectation(),
name = "get_vector on $M at point $(typeof(p))",
test_mutating = true,
kwargs...
)Test the get_vector on manifold M at point p for a vector of coordinates c in basis B.
- that the result is a valid tangent vector at
pon the manifold - that the result matches
expected_value, if given - that the mutating version
get_vector!matches the non-mutating version, (if activated) - that
get_coordinatesinvertsget_vector(if activated)
Manifolds.Test.test_get_vectors โ Function
Manifolds.Test.test_get_vectors(
M, p, b;
available_functions=[],
name = "get_vectors on $M at point $(typeof(p))",
test_orthogonality = false,
test_normality = false,
kwargs...
)Test the get_vectors on manifold M at point p for basis b, where the basis is assumed to come from a call to get_basis.
- that there are as many vectors as the manifold dimension (if available)
- that each vector is a valid tangent vector at
pon the manifold - that the vectors are orthogonal (if activated)
- that the vectors are normal (if activated)
Manifolds.Test.test_local_metric โ Function
Manifolds.Test.test_local_metric(
M, A, i, a;
available_functions = [],
expected_value = NoExpectation(),
name = "local_metric on $M in $A",
test_positive_definite = true,
kwargs...
)Test the local_metric on manifold M at the point with parameters a in chart i of atlas A.
- that the result is a symmetric matrix of size
nรn, wherenis the length ofa - that the result is positive definite (if activated)
- that the result matches
expected_value, if given - that the result is the Gram matrix of the
induced_basisvectors with respect toinner(ifget_vectoris available) - that
inverse_local_metricis its inverse (if available) - that
det_local_metricis its determinant (if available) - that
log_local_metric_densityis the logarithm of the square root of the absolute value of its determinant (if available)
Manifolds.Test.test_log โ Function
Manifolds.Test.test_log(
M, p, q;
available_functions=[], expected_value=NoExpectation(), test_mutating=true,
test_exp = (exp in available_functions),
test_injectivity_radius = (injectivity_radius in available_functions),
name = "Logarithmic map on $M for $(typeof(p)) points",
kwargs...
)Test the logarithmic map on manifold M at point p towards q.
- that the result is a valid tangent vector at
pon the manifold - that the result matches
expected_value, if given - that the mutating version
log!matches the non-mutating version, (if activated) - that the exponential map inverts the logarithmic map (if activated) (only performed if either
injectivity_radiusis not available orXis within)
Manifolds.Test.test_manifold_dimension โ Function
test_manifold_dimension(
M;
expected_value = NoExpectation(),
expected_type = Int,
name = "Manifold dimension for $M",
)Test that the dimension of the manifold M is consistent.
- that the dimension is nonnegative
- that it is an integer (of type
expected_type,Intby default) - that it matches the expected value (if provided)
Manifolds.Test.test_manifold_volume โ Function
Manifolds.Test.test_manifold_volume(
M;
expected_value = NoExpectation(),
name = "Manifold volume for $M",
)Test the volume of the manifold M.
- that the volume is nonnegative
- that it matches the expected value (if provided)
Manifolds.Test.test_metric_signature โ Function
Manifolds.Test.test_metric_signature(
M;
expected_value = NoExpectation(),
name = "Metric signature of $M",
)Test the function metric_signature on manifold M.
- that the result is a tuple of three nonnegative integers
- that they sum to the
manifold_dimensionofM - that it agrees with the
expected_value, if given
Manifolds.Test.test_mid_point โ Function
Manifolds.Test.test_mid_point(M, p, q;
available_functions=[],
expected_value = NoExpectation(),
test_aliased = true,
test_mutating = true,
test_symmetry = true,
name = "Mid-point on $M between $(typeof(p)) points",
kwargs...
)Test the mid-point function on manifold M between points p and q.
- that the result is a valid point on the manifold
- that the result matches
expected_value, if given - that the mid-point is symmetric (if activated)
- that the distance from
pandqto the mid-point is half the distance fromptoq(if distance is present) - that the mutating version
mid_point!matches the non-mutating version (if activated) - that
mid_point!works on aliased in put (r=porr=q) (if activated for mutating)
Manifolds.Test.test_norm โ Function
Manifolds.Test.test_norm(M, p, X;
available_functions = [], expected_value = NoExpectation(),
name = "Norm on $M at point $(typeof(p))",
test_inner = (inner in available_functions),
kwargs...
)Test the norm on the manifold M at point p for tangent vector X.
- that the result is a real number
- that the result matches
expected_value, if given - that the norm of
Xwith itself is non negative - that the inner product of
Xwith itself is the same as its norm squared (if activated)
Manifolds.Test.test_norm(M, A::AbstractAtlas, i, a, Xc;
available_functions = [], expected_value = NoExpectation(),
name = "Norm on $M in $A",
test_inner = (inner in available_functions),
kwargs...
)Test the norm on the manifold M at the point with parameters a in chart i of atlas A for the tangent vector with coordinates Xc in the induced basis.
- that the result is a real number
- that the result matches
expected_value, if given - that the norm is non negative
- that the inner product of
Xcwith itself in the chart is the same as its norm squared (if activated) - that the result matches the norm of the corresponding tangent vector (if
get_vectoris available)
Manifolds.Test.test_parallel_transport โ Function
Manifolds.Test.test_parallel_transport(
M, p, X, q;
available_functions=[],
direction = (log in available_functions) ? log(M, p, q) : missing,
expected_value=NoExpectation(),
expected_value_direction=NoExpectation(),
name = "Parallel transport on $M at point $(typeof(p))",
test_aliased = true,
test_mutating = true,
kwargs...
)Test the parallel transport on manifold M at point p with tangent vector X to a point q.
this defaults to testing parallel_transport_to, but can also be used to test parallel_transport_direction, by passing that function to the available_functions, using the direction argument. The direction has to be the one that transports X also to q. If it is missing, it is computed with the default inverse retraction when vector_transport_direction is tested, and nothing deactivates the test of vector_transport_direction.
- that the result is a valid tangent vector at
qon the manifold - that the result matches
expected_value, if given - that the mutating version
parallel_transport!matches the non-mutating version - that
parallel_transport_toworks on aliased in put (Y=X) (if activated) - that the direction of the transport is consistent with
expected_direction, if given - that the mutating version
parallel_transport_direction!matches the non-mutating version (if activated) - that
parallel_transport_directionworks on aliased in put (Y=XorY=d) (if activated for mutating) - that both functions are consistent
Manifolds.Test.test_project โ Function
Manifolds.Test.test_project(
M, q, Y = missing;
available_functions = [],
expected_point = NoExpectation(),
expected_vector = NoExpectation(),
test_aliased = true,
test_mutating = true,
name = "Projection on $M for $(typeof(q)) points",
kwargs...
)Test the project(M, q) and project(M, q, Y) to project points and tangent vectors (if not missing).
Besides a simple call of project (for both variants) the following tests are performed
- that the projected point is a valid point on the manifold
- that the projected vector is a valid tangent vector on the manifold
- that the result matches
expected_pointandexpected_vector, respectively, if given - that the mutating version
project!produces the same result(s) (if activated) - that
project!works on aliased input (p=qorX=Y) (if activated and p/q or X/Y are of same type)
Manifolds.Test.test_rand โ Function
Manifolds.Test.test_rand(M;
vector_at = missing,
expected_eltype = NoExpectation(),
seed = missing,
test_mutating = true,
test_reproducibility = test_mutating,
test_scaling = false,
rng = missing,
name = "Random sampling on $M",
kwargs...
)Test the random sampling functions rand(M) and rand(M; vector_at=p) on manifold M, where p is the point drawn by rand(M) unless the keyword vector_at provides one.
- that the result of
rand(M)is a valid point on the manifold - that the result of
rand(M; vector_at=p)is a valid tangent vector atpon the manifold - that the mutating versions
rand!match the non-mutating versions (if activated) - that the four mentioned functions also work with a seed upfront.
- that both the point and the tangent vector have the number type
expected_eltype(if provided) - that
randandrand!draw the same point and the same tangent vector from copies of the random number generatorrng, or of the default one (iftest_reproducibilityis activated) - that
rand(M; vector_at=p, ฯ=2)is twice the tangent vector drawn with the defaultฯfrom the same random number generator state (iftest_scalingis activated)
Manifolds.Test.test_repr โ Function
Manifolds.Test.test_repr(
M;
expected_value = NoExpectation(),
name = "(String) repr_esentation of $M",
)Test that the default show method works as expected by calling repr(M).
Manifolds.Test.test_representation_size โ Function
Manifolds.Test.test_representation_size(
M;
expected_value = NoExpectation(),
name = "Representation size of $M",
)Test the representation size of the manifold M.
- that the result is tuple of nonnegative integers or nothing (if there is no reasonable representation)
- that it matches the expected value (if provided)
Manifolds.Test.test_retract โ Function
Manifolds.Test.test_retract(
M, p, X, m::AbstractRetractionMethod;
available_functions=[],
expected_value = NoExpectation(),
inverse_retraction_method = missing,
name = "Retraction $m on $M at point $(typeof(p))",
t = 1.0,
test_aliased = true,
test_fused = true,
test_mutating = true,
test_inverse_retraction = (inverse_retract in available_functions) && !ismissing(inverse_retraction_method),
kwargs...
)Test the retraction method m on manifold M at point p with tangent vector X.
- that the result is a valid point on the manifold
- that the result matches
expected_value, if given - that the mutating version
retract!matches the non-mutating version, (if activated) - that
retract!works on aliased in put (p=q) (if activated for mutating) - that the inverse retraction inverts the retraction (if activated)
- that the fused version
retract_fused(M, p, X, t, m)matches the non-fused version (if activated)
Manifolds.Test.test_sectional_curvature โ Function
Manifolds.Test.test_sectional_curvature(
M, p, X, Y;
available_functions = [],
expected_value = NoExpectation(),
expected_min = NoExpectation(),
expected_max = NoExpectation(),
name = "Sectional curvature on $M at point $(typeof(p))",
kwargs...
)Test the sectional curvature on manifold M at point p for tangent vectors X and Y.
- that the result is a real number
- that the result matches
expected_value, if given - that the minimum sectional curvature at
pis less than or equal to the sectional curvature - that the maximum sectional curvature at
pis greater than or equal to the sectional curvature - that the minimum and maximum sectional curvatures match
expected_minandexpected_max, if given
Manifolds.Test.test_sharp โ Function
Manifolds.Test.test_sharp(M, p, ฮพ;
available_functions=[],
expected_value = NoExpectation(),
test_mutating = true,
name = "Sharp on $M for $(typeof(p)) points",
kwargs...
)Test the sharp operation on manifold M at point p with cotangent vector ฮพ.
- test that the result is a valid tangent vector at
pon the manifold - that the result matches
expected_value, if given - that
flatis the inverse - that mutating version
sharp!matches non-mutating version (if activated)
Manifolds.Test.test_shortest_geodesic โ Function
Manifolds.Test.test_shortest_geodesic(M, p, q, t=0.5;
available_functions=[],
expected_value = NoExpectation(),
N = 10,
name = "Shortest geodesic on $M for $(typeof(p)) points",
kwargs...
)Test the shortest geodesic on manifold M from p to q at time t.
- that at time
0the geodesic returnsp, at time1it returnsq - that the function
ฮณ = shortest_geodesic(M, p, q)is consistent with evaluation at0,1andt - that the result at
tis a valid point on the manifold - that the geodesic has constant speed (if activated) using
Nsamples and the approximated derivative via finite differences - that the geodesic is length minimizing, i.e. the sum of the segments is approximately equal to the distance from
ptoq(if activated)
Manifolds.Test.test_transition_map โ Function
Manifolds.Test.test_transition_map(
M, A_from, i_from, A_to, i_to, a;
available_functions = [],
expected_value = NoExpectation(),
name = "transition_map on $M from $A_from to $A_to",
test_mutating = true,
kwargs...
)Test the transition_map on manifold M of parameters a from chart i_from of atlas A_from to chart i_to of atlas A_to.
- that the result is a vector of the same length as
a - that the result matches
expected_value, if given - that the short form
transition_map(M, A, i_from, i_to, a)agrees, ifA_from == A_to - that both parameters represent the same point, i.e.
get_pointagrees on them (if available) - that the transition map back to
(A_from, i_from)inverts it - that the mutating version
transition_map!matches the non-mutating version, (if activated)
Manifolds.Test.test_transition_map_diff โ Function
Manifolds.Test.test_transition_map_diff(
M, A, i_from, a, c, i_to;
available_functions = [],
expected_value = NoExpectation(),
name = "transition_map_diff on $M in $A",
test_mutating = true,
kwargs...
)Test the transition_map_diff on manifold M from chart i_from to chart i_to of atlas A at the point with parameters a for the tangent vector with coordinates c in the induced basis.
- that the result is a vector of the same length as
c - that the result matches
expected_value, if given - that both coordinates represent the same tangent vector in the respective
induced_basis(ifget_vectoris available) - that the differential of the transition map back to
i_frominverts it - that the mutating version
transition_map_diff!matches the non-mutating version, (if activated)
Manifolds.Test.test_vector_arithmetic โ Function
Manifolds.Test.test_vector_arithmetic(
M, p, X, Y;
name = "Tangent vector arithmetic on $M at point $(typeof(p))",
test_inplace = !(X isa Number),
kwargs...
)Test that tangent vectors X and Y at p on M support the basic arithmetic of a vector space.
- that
X + Y,X - Y,2 * X,X * 2,X / 2,2 \ X,+Xand-Xare tangent vectors and consistent with each other - that broadcasting, e.g.
2 .* X .+ Y, agrees with the non-broadcasting operations and returns the same type asX(unlessXis a zero-dimensional array) - that in-place broadcasting, e.g.
Z .= 2 .* X .+ Y, works (if activated)
Manifolds.Test.test_vector_transport โ Function
Manifolds.Test.test_vector_transport(
M, p, X, q, m = default_vector_transport_method(M);
available_functions=[],
direction = missing,
expected_value = NoExpectation(),
expected_value_direction = NoExpectation(),
test_aliased = true,
test_mutating = true,
name = "Vector transport method $(m) on $M at point $(typeof(p))",
kwargs...
)Test the vector transport on manifold M at point p with tangent vector X to a point q.
this defaults to testing vector_transport_to, but can also be used to test vector_transport_direction, by passing that function to the available_functions, using the direction argument. The direction has to be the one that transports X also to q.
- that the result is a valid tangent vector at
qon the manifold - that the result matches
expected_value, if given - that the mutating version
vector_transport!matches the non-mutating version - that
vector_transport_toworks on aliased in put (Y=X) (if activated) - that the direction of the transport is consistent with
expected_direction, if given - that the mutating version
vector_transport_direction!matches the non-mutating version (if activated) - that
vector_transport_directionworks on aliased in put (Y=XorY=d) (if activated for mutating) - that both functions are consistent
Manifolds.Test.test_volume_density โ Function
Manifolds.Test.test_volume_density(
M, p, X;
expected_value = NoExpectation(),
name = "Manifold volume density for $M",
kwargs...
)Test the volume_density of the manifold M.
- that it matches the expected value (if provided)
Manifolds.Test.test_Weingarten โ Function
Manifolds.Test.test_Weingarten(
M, p, X, V;
available_functions = [],
expected_value = NoExpectation(),
test_aliased = true,
test_mutating = true,
name = "Weingarten map on $M at point $(typeof(p))",
kwargs...
)Test the Weingarten map on manifold M at point p for tangent vector X and normal vector V.
- that the result is a valid tangent vector at
pon the manifold - that the result matches
expected_value, if given - that the result is consistent with the mutating version
weingarten!(if activated) - that
Weingarten!works on aliased in put (Y=X) (if activated for mutating)
Manifolds.Test.test_zero_vector โ Function
Manifolds.Test.test_zero_vector(M, p;
available_functions=[],
test_mutating = true,
test_norm = (norm in available_functions),
name = "Zero vector test on $M at point $(typeof(p))",
)Test the zero vector on the manifold M at point p.
- verify that it is a valid tangent vector
- verify that its norm is zero (if provided)
- verify that the mutating version
zero_vector!matches the non-mutating version (if activated)
Internals to handle expectations
Manifolds.Test.AbstractExpectation โ Type
AbstractExpectationAn abstract type for expectations in tests.
Manifolds.Test.Expect โ Type
Expect{T} <: AbstractExpectationA struct to hold expected values for tests of type T.
Fields
value::Tthe expected value
Constructor
Expect(value::T)Manifolds.Test.NoExpectation โ Type
NoExpectation <: AbstractExpectationA struct to indicate that no expectation is provided for a test.
Manifolds.Test.expect โ Function
expect(e::Union{Expect, NoExpectation})Get the expected value if provided, error otherwise.
Manifolds.Test.isexpected โ Function
isexpected(e::Union{Expect, NoExpectation})Check if an expectation is provided.