/
utilities.jl
61 lines (48 loc) · 1.51 KB
/
utilities.jl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
#####
##### utilities
#####
####
#### random reals
####
function _random_reals_scale(rng::AbstractRNG, scale::Real, cauchy::Bool)
cauchy ? scale / abs2(randn(rng)) : scale * 1.0
end
"""
$(SIGNATURES)
Random vector in ``ℝⁿ`` of length `n`.
A standard multivaritate normal or Cauchy is used, depending on `cauchy`, then scaled with
`scale`. `rng` is the random number generator used.
Not exported, but part of the API.
"""
function random_reals(n::Integer; scale::Real = 1, cauchy::Bool = false,
rng::AbstractRNG = default_rng())
randn(rng, n) .* _random_reals_scale(rng, scale, cauchy)
end
####
#### stress testing
####
"""
$(SIGNATURES)
Test `ℓ` with random values.
`N` random vectors are drawn from a standard multivariate Cauchy distribution, scaled with
`scale` (which can be a scalar or a conformable vector).
Each random vector `x` is then used as an argument in `f(ℓ, x)`. [`logdensity`](@ref),
[`logdensity_and_gradient`](@ref), and [`logdensity_gradient_and_hessian`](@ref) are
recommended for `f`.
In case the call produces an error, the value is recorded as a failure, which are returned
by the function.
Not exported, but part of the API.
"""
function stresstest(f, ℓ; N = 1000, rng::AbstractRNG = default_rng(), scale = 1)
failures = Vector{Float64}[]
d = dimension(ℓ)
for _ in 1:N
x = random_reals(d; scale = scale, cauchy = true, rng = rng)
try
f(ℓ, x)
catch e
push!(failures, x)
end
end
failures
end