From 3b1de798521173dc3243cad28176efb904748f39 Mon Sep 17 00:00:00 2001 From: Lyndon White Date: Fri, 28 May 2021 19:50:27 +0100 Subject: [PATCH 1/6] make rand_tangent give only nice numbers --- src/rand_tangent.jl | 17 ++++++++++++++--- test/rand_tangent.jl | 8 ++++++++ 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/src/rand_tangent.jl b/src/rand_tangent.jl index 4ca2548..8450f50 100644 --- a/src/rand_tangent.jl +++ b/src/rand_tangent.jl @@ -1,7 +1,9 @@ """ rand_tangent([rng::AbstractRNG,] x) -Returns a randomly generated tangent vector appropriate for the primal value `x`. +Returns a arbitary tangent vector _appropriate_ for the primal value `x`. +Note that despite the name, no promises on the statistical randomness are made. +Rather it is an arbitary value, that is generated using the `rng`. """ rand_tangent(x) = rand_tangent(Random.GLOBAL_RNG, x) @@ -11,11 +13,20 @@ rand_tangent(rng::AbstractRNG, x::AbstractString) = NoTangent() rand_tangent(rng::AbstractRNG, x::Integer) = NoTangent() -rand_tangent(rng::AbstractRNG, x::T) where {T<:Number} = randn(rng, T) +# Try and make nice numbers with short decimal representations for good error messages +# while also not biasing the sample space too much +function rand_tangent(rng::AbstractRNG, x::T) where {T<:Number} + return round(8randn(rng, T), sigdigits=6, base=2) +end +rand_tangent(rng::AbstractRNG, x::Float64) = rand(rng, -9:0.01:9) +function rand_tangent(rng::AbstractRNG, x::ComplexF64) + return ComplexF64(rand(rng, -9:0.1:9), rand(rng, -9:0.1:9)) +end + # TODO: right now Julia don't allow `randn(rng, BigFloat)` # see: https://github.com/JuliaLang/julia/issues/17629 -rand_tangent(rng::AbstractRNG, ::BigFloat) = big(randn(rng)) +rand_tangent(rng::AbstractRNG, ::BigFloat) = big(rand_tangent(rng, Float64)) rand_tangent(rng::AbstractRNG, x::StridedArray) = rand_tangent.(Ref(rng), x) rand_tangent(rng::AbstractRNG, x::Adjoint) = adjoint(rand_tangent(rng, parent(x))) diff --git a/test/rand_tangent.jl b/test/rand_tangent.jl index 92a2d50..0331f24 100644 --- a/test/rand_tangent.jl +++ b/test/rand_tangent.jl @@ -86,4 +86,12 @@ using FiniteDifferences: rand_tangent @test x + rand_tangent(x) isa typeof(x) @test x + (rand_tangent(x) + rand_tangent(x)) isa typeof(x) end + + @testset "niceness of printing" begin + for i in 1:50 + @test length(string(rand_tangent(1.0))) <= 6 + @test length(string(rand_tangent(1.0 + 1.0im))) <= 12 + @test length(string(rand_tangent(1f0))) <= 12 + end + end end From 5a5d2cb4154f348999e7cbe9beeb00a8249686e3 Mon Sep 17 00:00:00 2001 From: Lyndon White Date: Fri, 28 May 2021 20:29:25 +0100 Subject: [PATCH 2/6] fix rand_tangent(::BigFloat) --- src/rand_tangent.jl | 8 +++----- test/rand_tangent.jl | 1 + 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/rand_tangent.jl b/src/rand_tangent.jl index 8450f50..e7a0760 100644 --- a/src/rand_tangent.jl +++ b/src/rand_tangent.jl @@ -16,17 +16,15 @@ rand_tangent(rng::AbstractRNG, x::Integer) = NoTangent() # Try and make nice numbers with short decimal representations for good error messages # while also not biasing the sample space too much function rand_tangent(rng::AbstractRNG, x::T) where {T<:Number} - return round(8randn(rng, T), sigdigits=6, base=2) + return round(8randn(rng, T), sigdigits=5, base=2) end rand_tangent(rng::AbstractRNG, x::Float64) = rand(rng, -9:0.01:9) function rand_tangent(rng::AbstractRNG, x::ComplexF64) return ComplexF64(rand(rng, -9:0.1:9), rand(rng, -9:0.1:9)) end - -# TODO: right now Julia don't allow `randn(rng, BigFloat)` -# see: https://github.com/JuliaLang/julia/issues/17629 -rand_tangent(rng::AbstractRNG, ::BigFloat) = big(rand_tangent(rng, Float64)) +#BigFloat/MPFR is finicky about short numbers, this doesn't always work as well as it should +rand_tangent(rng::AbstractRNG, ::BigFloat) = round(big(8randn(rng)), sigdigits=5, base=2) rand_tangent(rng::AbstractRNG, x::StridedArray) = rand_tangent.(Ref(rng), x) rand_tangent(rng::AbstractRNG, x::Adjoint) = adjoint(rand_tangent(rng, parent(x))) diff --git a/test/rand_tangent.jl b/test/rand_tangent.jl index 0331f24..6beb1c4 100644 --- a/test/rand_tangent.jl +++ b/test/rand_tangent.jl @@ -92,6 +92,7 @@ using FiniteDifferences: rand_tangent @test length(string(rand_tangent(1.0))) <= 6 @test length(string(rand_tangent(1.0 + 1.0im))) <= 12 @test length(string(rand_tangent(1f0))) <= 12 + @test length(string(rand_tangent(big"1.0"))) <= 8 end end end From 342555945c008d77b59e30b5dd695c4c260299fc Mon Sep 17 00:00:00 2001 From: Lyndon White Date: Tue, 1 Jun 2021 12:40:30 +0100 Subject: [PATCH 3/6] Explain why scaling randn --- src/rand_tangent.jl | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/rand_tangent.jl b/src/rand_tangent.jl index e7a0760..930a3c7 100644 --- a/src/rand_tangent.jl +++ b/src/rand_tangent.jl @@ -16,7 +16,8 @@ rand_tangent(rng::AbstractRNG, x::Integer) = NoTangent() # Try and make nice numbers with short decimal representations for good error messages # while also not biasing the sample space too much function rand_tangent(rng::AbstractRNG, x::T) where {T<:Number} - return round(8randn(rng, T), sigdigits=5, base=2) + # multiply by 9 to give a bigger range of values tested: no so tightly clustered around 0. + return round(9 * randn(rng, T), sigdigits=5, base=2) end rand_tangent(rng::AbstractRNG, x::Float64) = rand(rng, -9:0.01:9) function rand_tangent(rng::AbstractRNG, x::ComplexF64) @@ -24,7 +25,9 @@ function rand_tangent(rng::AbstractRNG, x::ComplexF64) end #BigFloat/MPFR is finicky about short numbers, this doesn't always work as well as it should -rand_tangent(rng::AbstractRNG, ::BigFloat) = round(big(8randn(rng)), sigdigits=5, base=2) + +# multiply by 9 to give a bigger range of values tested: no so tightly clustered around 0. +rand_tangent(rng::AbstractRNG, ::BigFloat) = round(big(9 * randn(rng)), sigdigits=5, base=2) rand_tangent(rng::AbstractRNG, x::StridedArray) = rand_tangent.(Ref(rng), x) rand_tangent(rng::AbstractRNG, x::Adjoint) = adjoint(rand_tangent(rng, parent(x))) From 74e1c37fbee6dfd530bc6bac3db05f078a4e3520 Mon Sep 17 00:00:00 2001 From: Lyndon White Date: Tue, 1 Jun 2021 12:42:25 +0100 Subject: [PATCH 4/6] bump version --- Project.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Project.toml b/Project.toml index dc435c4..51354aa 100644 --- a/Project.toml +++ b/Project.toml @@ -1,6 +1,6 @@ name = "FiniteDifferences" uuid = "26cc04aa-876d-5657-8c51-4c34ba976000" -version = "0.12.10" +version = "0.12.11" [deps] ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" From 03cdf0ec18c415c3ac4f806046c46fe8bdf910a4 Mon Sep 17 00:00:00 2001 From: Lyndon White Date: Tue, 1 Jun 2021 13:01:10 +0100 Subject: [PATCH 5/6] only test printing length on 1.6 (also relax length for bigfloats) --- test/rand_tangent.jl | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/test/rand_tangent.jl b/test/rand_tangent.jl index 6beb1c4..8863279 100644 --- a/test/rand_tangent.jl +++ b/test/rand_tangent.jl @@ -87,12 +87,13 @@ using FiniteDifferences: rand_tangent @test x + (rand_tangent(x) + rand_tangent(x)) isa typeof(x) end - @testset "niceness of printing" begin + # Julia 1.6 changed to using Ryu printing algorithm and seems better at printing short + VERSION > v"1.6" && @testset "niceness of printing" begin for i in 1:50 @test length(string(rand_tangent(1.0))) <= 6 @test length(string(rand_tangent(1.0 + 1.0im))) <= 12 @test length(string(rand_tangent(1f0))) <= 12 - @test length(string(rand_tangent(big"1.0"))) <= 8 + @test length(string(rand_tangent(big"1.0"))) <= 9 end end end From f55f885ce81d4012b132030709d45abafe5fdb82 Mon Sep 17 00:00:00 2001 From: Lyndon White Date: Tue, 1 Jun 2021 14:39:57 +0100 Subject: [PATCH 6/6] Relax big further --- test/rand_tangent.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/rand_tangent.jl b/test/rand_tangent.jl index 8863279..f5815e8 100644 --- a/test/rand_tangent.jl +++ b/test/rand_tangent.jl @@ -93,7 +93,7 @@ using FiniteDifferences: rand_tangent @test length(string(rand_tangent(1.0))) <= 6 @test length(string(rand_tangent(1.0 + 1.0im))) <= 12 @test length(string(rand_tangent(1f0))) <= 12 - @test length(string(rand_tangent(big"1.0"))) <= 9 + @test length(string(rand_tangent(big"1.0"))) <= 12 end end end