Skip to content

Commit b7665ae

Browse files
authored
Fix info/warn print of checks (#182)
* Fix / provide more stable info/warn error prints using showerror. * News & bump version.
1 parent 8dbc729 commit b7665ae

8 files changed

+56
-30
lines changed

NEWS.md

+8-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,14 @@ All notable changes to this project will be documented in this file.
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

8-
## [0.15.6] unreleased
8+
## [0.15.7] 24/01/2024
9+
10+
### Fixed
11+
12+
* `is_point` and `is_vector` can now more stably `:info` or `:warn` when they return false,
13+
since they emply `showerror` for these displays.
14+
15+
## [0.15.6] 15/12/2023
916

1017
### Added
1118

Project.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
name = "ManifoldsBase"
22
uuid = "3362f125-f0bb-47a3-aa74-596ffd7ef2fb"
33
authors = ["Seth Axen <[email protected]>", "Mateusz Baran <[email protected]>", "Ronny Bergmann <[email protected]>", "Antoine Levitt <[email protected]>"]
4-
version = "0.15.6"
4+
version = "0.15.7"
55

66
[deps]
77
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"

docs/src/projections.md

+3-3
Original file line numberDiff line numberDiff line change
@@ -14,18 +14,18 @@ the embedding can be chosen to be the manifold ``\mathcal N = ℂ`` and due to o
1414
The first projection we can consider is for a given a point ``p∈\mathcal N`` in the embedding we can look for the closest point on the manifold ``\mathcal M``, i.e.
1515

1616
```math
17-
\operatorname*{arg\,min}_{q\in \mathcal M}\ d_{\mathcal N}(i(q),p)
17+
\operatorname*{arg\,min}_{q \mathcal M}\ d_{\mathcal N}(i(q),p)
1818
```
1919

2020
And this resulting ``q`` we call the projection of ``p`` onto the manifold ``\mathcal M``.
2121

22-
The second projection we can look at is for a given a point ``p∈\mathcal M`` and a vector in ``X\in T_{i(p)}\mathcal N`` in the embedding,
22+
The second projection we can look at is for a given a point ``p∈\mathcal M`` and a vector in ``X T_{i(p)}\mathcal N`` in the embedding,
2323
where we can similarly look for the closest tangent vector ``Y∈ T_p\mathcal M``, which we have to embed itself before itself.
2424
Embedding a tangent vector is usually the same as using the pushforward ``\mathrm{d}i_p`` of the embedding (at ``p``).
2525
We obtain
2626

2727
```math
28-
\operatorname*{arg\,min}_{Y\in T_p\mathcal M}\ \bigl\lVert \mathrm{d}i(p)[Y] - X \bigr\rVert_{i(p)}
28+
\operatorname*{arg\,min}_{Y T_p\mathcal M}\ \bigl\lVert \mathrm{d}i(p)[Y] - X \bigr\rVert_{i(p)}
2929
```
3030

3131
And we call the resulting ``Y`` the projection of ``X`` onto the tangent space ``T_p\mathcal M`` at ``p``.

docs/src/retractions.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,11 @@
33
The [exponential and logarithmic map](@ref exp-and-log) might be too expensive to evaluate or not be available in a very stable numerical way on certain manifolds ``\mathcal M``.
44
Retractions provide a possibly cheap, fast and stable alternative.
55

6-
A _retraction_ ``\operatorname{retr}_p: T_p\mathcal M → \mathcal M`` is a smooth map that fulfils (for all ``p\in\mathcal M``) that
6+
A _retraction_ ``\operatorname{retr}_p: T_p\mathcal M → \mathcal M`` is a smooth map that fulfils (for all ``p\mathcal M``) that
77

88
1. ``\operatorname{retr}_p(0) = p``
99
2. ``D\operatorname{retr}_p(0): T_p\mathcal M \to T_p\mathcal M`` is the identity map,
10-
i.e. ``D\operatorname{retr}_p(0)[X]=X`` holds for all ``X\in T_p\mathcal M``,
10+
i.e. ``D\operatorname{retr}_p(0)[X]=X`` holds for all ``X T_p\mathcal M``,
1111

1212
where ``D\operatorname{retr}_p`` denotes the differential of the retraction.
1313

src/ManifoldsBase.jl

+24-14
Original file line numberDiff line numberDiff line change
@@ -567,11 +567,10 @@ function isapprox(M::AbstractManifold, p, q; error::Symbol = :none, kwargs...)
567567
ma = check_approx(M, p, q; kwargs...)
568568
if ma !== nothing
569569
(error === :error) && throw(ma)
570-
if isnan(ma.val)
571-
s = "$(typeof(ma))\n$(ma.msg)"
572-
else
573-
s = "$(typeof(ma)) with $(ma.val)\n$(ma.msg)"
574-
end
570+
# else: collect and info showerror
571+
io = IOBuffer()
572+
showerror(io, ma)
573+
s = String(take!(io))
575574
(error === :info) && @info s
576575
(error === :warn) && @warn s
577576
return false
@@ -607,11 +606,10 @@ function isapprox(M::AbstractManifold, p, X, Y; error::Symbol = :none, kwargs...
607606
mat = check_approx(M, p, X, Y; kwargs...)
608607
if mat !== nothing
609608
(error === :error) && throw(mat)
610-
if isnan(mat.val)
611-
s = "$(typeof(mat))\n$(mat.msg)"
612-
else
613-
s = "$(typeof(mat)) with $(mat.val)\n$(mat.msg)"
614-
end
609+
# else: collect and info showerror
610+
io = IOBuffer()
611+
showerror(io, mat)
612+
s = String(take!(io))
615613
(error === :info) && @info s
616614
(error === :warn) && @warn s
617615
return false
@@ -678,7 +676,10 @@ function is_point(M::AbstractManifold, p; error::Symbol = :none, kwargs...)
678676
if mps !== nothing
679677
(error === :error) && throw(mps)
680678
if (error === :info) || (error === :warn)
681-
s = "$(typeof(mps)) with $(mps.val)\n$(mps.msg)"
679+
# else: collect and info showerror
680+
io = IOBuffer()
681+
showerror(io, mps)
682+
s = String(take!(io))
682683
(error === :info) && @info s
683684
(error === :warn) && @warn s
684685
end
@@ -688,7 +689,10 @@ function is_point(M::AbstractManifold, p; error::Symbol = :none, kwargs...)
688689
if mpe !== nothing
689690
(error === :error) && throw(mpe)
690691
if (error === :info) || (error === :warn)
691-
s = "$(typeof(mpe)) with $(mpe.val)\n$(mpe.msg)"
692+
# else: collect and info showerror
693+
io = IOBuffer()
694+
showerror(io, mpe)
695+
s = String(take!(io))
692696
(error === :info) && @info s
693697
(error === :warn) && @warn s
694698
end
@@ -756,7 +760,10 @@ function is_vector(
756760
if mXs !== nothing
757761
(error === :error) && throw(mXs)
758762
if (error === :info) || (error === :warn)
759-
s = "$(typeof(mXs)) with $(mXs.val)\n$(mXs.msg)"
763+
# else: collect and info showerror
764+
io = IOBuffer()
765+
showerror(io, mXs)
766+
s = String(take!(io))
760767
(error === :info) && @info s
761768
(error === :warn) && @warn s
762769
end
@@ -766,7 +773,10 @@ function is_vector(
766773
if mXe !== nothing
767774
(error === :error) && throw(mXe)
768775
if (error === :info) || (error === :warn)
769-
s = "$(typeof(mXe)) with $(mXe.val)\n$(mXe.msg)"
776+
# else: collect and info showerror
777+
io = IOBuffer()
778+
showerror(io, mXe)
779+
s = String(take!(io))
770780
(error === :info) && @info s
771781
(error === :warn) && @warn s
772782
end

src/PowerManifold.jl

+1-1
Original file line numberDiff line numberDiff line change
@@ -959,7 +959,7 @@ size of the power manifold and ``d_{\mathcal M}`` the dimension of the base mani
959959
``\mathcal M``, the manifold is of dimension
960960
961961
````math
962-
\dim(\mathcal N) = \dim(\mathcal M)\prod_{i=1}^d n_i = n_1n_2\cdot…\cdot n_d \dim(\mathcal M).
962+
\dim(\mathcal N) = \dim(\mathcal M)\prod_{i=1}^d n_i = n_1n_2⋅…⋅ n_d \dim(\mathcal M).
963963
````
964964
"""
965965
function manifold_dimension(M::PowerManifold)

src/decorator_trait.jl

+12-3
Original file line numberDiff line numberDiff line change
@@ -412,7 +412,10 @@ function is_point(
412412
mpe = check_point(M, p; kwargs...)
413413
if mpe !== nothing
414414
(error === :error) && throw(mpe)
415-
s = "$(typeof(mpe)) with $(mpe.val)\n$(mpe.msg)"
415+
# else: collect and info showerror
416+
io = IOBuffer()
417+
showerror(io, mpe)
418+
s = String(take!(io))
416419
(error === :info) && @info s
417420
(error === :warn) && @warn s
418421
return false
@@ -436,7 +439,10 @@ function is_vector(
436439
es = check_size(M, p, X)
437440
if es !== nothing
438441
(error === :error) && throw(es)
439-
s = "$(typeof(es)) with $(es)"
442+
# else: collect and info showerror
443+
io = IOBuffer()
444+
showerror(io, es)
445+
s = String(take!(io))
440446
(error === :info) && @info s
441447
(error === :warn) && @warn s
442448
return false
@@ -478,7 +484,10 @@ function is_vector(
478484
mXe = check_vector(M, p, X; kwargs...)
479485
mXe === nothing && return true
480486
(error === :error) && throw(mXe)
481-
s = "$(typeof(mXe)) with $(mXe.val)\n$(mXe.msg)"
487+
# else: collect and info showerror
488+
io = IOBuffer()
489+
showerror(io, mXe)
490+
s = String(take!(io))
482491
(error === :info) && @info s
483492
(error === :warn) && @warn s
484493
return false

test/domain_errors.jl

+5-5
Original file line numberDiff line numberDiff line change
@@ -37,14 +37,14 @@ end
3737
@test !is_point(M, [1, 1, 1]) # checksize fails
3838
@test_throws DomainError is_point(M, [-1, 1, 1], true) # checksize errors
3939
@test_throws DomainError is_point(M, [-1, 1, 1]; error = :error) # checksize errors
40-
cs = "DomainError with (3,)\nsize [-1, 1, 1] not (2,)"
40+
cs = "DomainError with (3,):\nsize [-1, 1, 1] not (2,)"
4141
@test_logs (:info, cs) is_point(M, [-1, 1, 1]; error = :info)
4242
@test_logs (:warn, cs) is_point(M, [-1, 1, 1]; error = :warn)
4343
@test is_point(M, [1, 1])
4444
@test is_point(M, [1, 1]; error = :error)
4545
@test_throws DomainError is_point(M, [-1, 1], true)
4646
@test_throws DomainError is_point(M, [-1, 1]; error = :error)
47-
ps = "DomainError with [-1, 1]\n<0"
47+
ps = "DomainError with [-1, 1]:\n<0"
4848
@test_logs (:info, ps) is_point(M, [-1, 1]; error = :info)
4949
@test_logs (:warn, ps) is_point(M, [-1, 1]; error = :warn)
5050

@@ -54,20 +54,20 @@ end
5454
@test !is_vector(M, [1, 1], [1, 1, 1])
5555
@test_throws DomainError is_vector(M, [1, 1], [-1, 1, 1], false, true)
5656
@test_throws DomainError is_vector(M, [1, 1], [-1, 1, 1]; error = :error)
57-
vs = "DomainError with (3,)\nsize [-1, 1, 1] not (2,)"
57+
vs = "DomainError with (3,):\nsize [-1, 1, 1] not (2,)"
5858
@test_logs (:info, vs) is_vector(M, [1, 1], [-1, 1, 1]; error = :info)
5959
@test_logs (:warn, vs) is_vector(M, [1, 1], [-1, 1, 1]; error = :warn)
6060
@test !is_vector(M, [1, 1, 1], [1, 1, 1], false)
6161
@test_throws DomainError is_vector(M, [1, 1, 1], [1, 1], true, true)
6262
@test_throws DomainError is_vector(M, [1, 1, 1], [1, 1], true; error = :error)
63-
ps2 = "DomainError with (3,)\nsize [1, 1, 1] not (2,)"
63+
ps2 = "DomainError with (3,):\nsize [1, 1, 1] not (2,)"
6464
@test_logs (:info, ps2) is_vector(M, [1, 1, 1], [1, 1], true; error = :info)
6565
@test_logs (:warn, ps2) is_vector(M, [1, 1, 1], [1, 1], true; error = :warn)
6666
@test is_vector(M, [1, 1], [1, 1])
6767
@test is_vector(M, [1, 1], [1, 1]; error = :none)
6868
@test_throws DomainError is_vector(M, [1, 1], [-1, 1]; error = :error)
6969
@test_throws DomainError is_vector(M, [1, 1], [-1, 1], true; error = :error)
70-
ps3 = "DomainError with [-1, 1]\n<0"
70+
ps3 = "DomainError with [-1, 1]:\n<0"
7171
@test_logs (:info, ps3) is_vector(M, [1, 1], [-1, 1], true; error = :info)
7272
@test_logs (:warn, ps3) is_vector(M, [1, 1], [-1, 1], true; error = :warn)
7373
end

0 commit comments

Comments
 (0)