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" diff --git a/src/rand_tangent.jl b/src/rand_tangent.jl index 4ca2548..930a3c7 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,21 @@ 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} + # 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) + return ComplexF64(rand(rng, -9:0.1:9), rand(rng, -9:0.1:9)) +end + +#BigFloat/MPFR is finicky about short numbers, this doesn't always work as well as it should -# 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)) +# 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))) diff --git a/test/rand_tangent.jl b/test/rand_tangent.jl index 92a2d50..f5815e8 100644 --- a/test/rand_tangent.jl +++ b/test/rand_tangent.jl @@ -86,4 +86,14 @@ using FiniteDifferences: rand_tangent @test x + rand_tangent(x) isa typeof(x) @test x + (rand_tangent(x) + rand_tangent(x)) isa typeof(x) end + + # 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"))) <= 12 + end + end end