Skip to content

Commit 76619c1

Browse files
authored
Merge pull request #168 from JuliaDiff/ox/nicerand
make rand_tangent give only nice numbers
2 parents e776799 + 231e685 commit 76619c1

File tree

2 files changed

+27
-5
lines changed

2 files changed

+27
-5
lines changed

src/rand_tangent.jl

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
"""
22
rand_tangent([rng::AbstractRNG,] x)
33
4-
Returns a randomly generated tangent vector appropriate for the primal value `x`.
4+
Returns a arbitary tangent vector _appropriate_ for the primal value `x`.
5+
Note that despite the name, no promises on the statistical randomness are made.
6+
Rather it is an arbitary value, that is generated using the `rng`.
57
"""
68
rand_tangent(x) = rand_tangent(Random.GLOBAL_RNG, x)
79

@@ -11,11 +13,21 @@ rand_tangent(rng::AbstractRNG, x::AbstractString) = NoTangent()
1113

1214
rand_tangent(rng::AbstractRNG, x::Integer) = NoTangent()
1315

14-
rand_tangent(rng::AbstractRNG, x::T) where {T<:Number} = randn(rng, T)
16+
# Try and make nice numbers with short decimal representations for good error messages
17+
# while also not biasing the sample space too much
18+
function rand_tangent(rng::AbstractRNG, x::T) where {T<:Number}
19+
# multiply by 9 to give a bigger range of values tested: no so tightly clustered around 0.
20+
return round(9 * randn(rng, T), sigdigits=5, base=2)
21+
end
22+
rand_tangent(rng::AbstractRNG, x::Float64) = rand(rng, -9:0.01:9)
23+
function rand_tangent(rng::AbstractRNG, x::ComplexF64)
24+
return ComplexF64(rand(rng, -9:0.1:9), rand(rng, -9:0.1:9))
25+
end
26+
27+
#BigFloat/MPFR is finicky about short numbers, this doesn't always work as well as it should
1528

16-
# TODO: right now Julia don't allow `randn(rng, BigFloat)`
17-
# see: https://github.com/JuliaLang/julia/issues/17629
18-
rand_tangent(rng::AbstractRNG, ::BigFloat) = big(randn(rng))
29+
# multiply by 9 to give a bigger range of values tested: no so tightly clustered around 0.
30+
rand_tangent(rng::AbstractRNG, ::BigFloat) = round(big(9 * randn(rng)), sigdigits=5, base=2)
1931

2032
rand_tangent(rng::AbstractRNG, x::StridedArray) = rand_tangent.(Ref(rng), x)
2133
rand_tangent(rng::AbstractRNG, x::Adjoint) = adjoint(rand_tangent(rng, parent(x)))

test/rand_tangent.jl

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,4 +86,14 @@ using FiniteDifferences: rand_tangent
8686
@test x + rand_tangent(x) isa typeof(x)
8787
@test x + (rand_tangent(x) + rand_tangent(x)) isa typeof(x)
8888
end
89+
90+
# Julia 1.6 changed to using Ryu printing algorithm and seems better at printing short
91+
VERSION > v"1.6" && @testset "niceness of printing" begin
92+
for i in 1:50
93+
@test length(string(rand_tangent(1.0))) <= 6
94+
@test length(string(rand_tangent(1.0 + 1.0im))) <= 12
95+
@test length(string(rand_tangent(1f0))) <= 12
96+
@test length(string(rand_tangent(big"1.0"))) <= 12
97+
end
98+
end
8999
end

0 commit comments

Comments
 (0)