Skip to content

Commit c61866d

Browse files
authored
Merge pull request #2 from mauriciogtec/v1.0
Closes #1 fixes for v1.0
2 parents a314e5c + 685b7e3 commit c61866d

File tree

6 files changed

+57
-26
lines changed

6 files changed

+57
-26
lines changed

.travis.yml

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
language: julia
22
julia:
3-
- 0.6.0
4-
- 0.6.1
5-
- 0.6.2
3+
- 0.7.0
4+
- 1.0.0
5+
- 1.0.1
6+
- 1.0.2
7+
- 1.0.3
68
before_install:
79
- pip install --user codecov
810
after_success:

README.md

Lines changed: 42 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[![Build Status](https://travis-ci.org/mauriciogtec/AdaptiveRejectionSampling.jl.svg?branch=master)](https://travis-ci.org/mauriciogtec/AdaptiveRejectionSampling.jl)
2-
[![AdaptiveRejectionSampling](http://pkg.julialang.org/badges/AdaptiveRejectionSampling_0.6.svg)](http://pkg.julialang.org/detail/AdaptiveRejectionSampling)
32
[![AdaptiveRejectionSampling](http://pkg.julialang.org/badges/AdaptiveRejectionSampling_0.7.svg)](http://pkg.julialang.org/detail/AdaptiveRejectionSampling)
3+
[![AdaptiveRejectionSampling](http://pkg.julialang.org/badges/AdaptiveRejectionSampling_1.0.svg)](http://pkg.julialang.org/detail/AdaptiveRejectionSampling)
44

55
[![Coverage Status](https://coveralls.io/repos/github/mauriciogtec/AdaptiveRejectionSampling.jl/badge.svg?branch=master)](https://coveralls.io/github/mauriciogtec/AdaptiveRejectionSampling.jl?branch=master)
66
[![codecov](https://codecov.io/gh/mauriciogtec/AdaptiveRejectionSampling.jl/branch/master/graph/badge.svg)](https://codecov.io/gh/mauriciogtec/AdaptiveRejectionSampling.jl)
@@ -36,9 +36,10 @@ Let's verify the result
3636

3737

3838
```julia
39-
x = -linspace(-10.0, 10.0, 100)
40-
envelop = eval_envelop.(sampler.envelop, x)
41-
target = f.(x)
39+
# Plot the results and compare to target distribution
40+
x = range(-10.0, 10.0, length=100)
41+
envelop = [eval_envelop(sampler.envelop, xi) for xi in x]
42+
target = [f(xi) for xi in x]
4243

4344
histogram(sim, normalize = true, label = "Histogram")
4445
plot!(x, [target envelop], width = 2, label = ["Normal(μ, σ)" "Envelop"])
@@ -56,12 +57,14 @@ plot!(x, [target envelop], width = 2, label = ["Normal(μ, σ)" "Envelop"])
5657
f(x) = β^α * x^-1) * exp(-β*x) / gamma(α)
5758
support = (0.0, Inf)
5859

60+
# Build the sampler and simulate 10,000 samples
5961
sampler = RejectionSampler(f, support)
6062
@time sim = run_sampler!(sampler, 10000)
6163

62-
x = linspace(0.0, 5.0, 100)
63-
envelop = eval_envelop.(sampler.envelop, x)
64-
target = f.(x)
64+
# Plot the results and compare to target distribution
65+
x = range(0.0, 5.0, length=100)
66+
envelop = [eval_envelop(sampler.envelop, xi) for xi in x]
67+
target = [f(xi) for xi in x]
6568

6669
histogram(sim, normalize = true, label = "Histogram")
6770
plot!(x, [target envelop], width = 2, label = ["Gamma(α, β)" "Envelop"])
@@ -71,8 +74,6 @@ plot!(x, [target envelop], width = 2, label = ["Gamma(α, β)" "Envelop"])
7174

7275

7376

74-
75-
7677
![](img/example2.png)
7778

7879
## Truncated distributions and unknown normalisation constant
@@ -85,12 +86,14 @@ We don't to provide an exact density--it will sample up to proportionality--and
8586
f(x) = β^α * x^-1) * exp(-β*x) / gamma(α)
8687
support = (1.0, 3.5)
8788

89+
# Build the sampler and simulate 10,000 samples
8890
sampler = RejectionSampler(f, support)
8991
@time sim = run_sampler!(sampler, 10000)
9092

91-
x = linspace(0.01, 8.0, 100)
92-
envelop = eval_envelop.(sampler.envelop, x)
93-
target = f.(x)
93+
# Plot the results and compare to target distribution
94+
x = range(0.01, 8.0, length=100)
95+
envelop = [eval_envelop(sampler.envelop, xi) for xi in x]
96+
target = [f(xi) for xi in x]
9497

9598
histogram(sim, normalize = true, label = "histogram")
9699
plot!(x, [target envelop], width = 2, label = ["target density" "envelop"])
@@ -99,7 +102,33 @@ plot!(x, [target envelop], width = 2, label = ["target density" "envelop"])
99102
0.007766 seconds (181.82 k allocations: 3.024 MiB)
100103

101104

105+
![](img/example3.png)
106+
107+
## Elastic Net distribution
108+
109+
The following example arises from elastic net regression and smoothing problems. In these cases, the integration constants are not available analytically.
110+
111+
```julia
112+
# Define function to be sampled
113+
function f(x, μ, λ1, λ2)
114+
δ = x - μ
115+
nl = λ1 * abs(δ) + λ2 * δ^2
116+
return exp(-nl)
117+
end
118+
support = (-Inf, Inf)
119+
120+
# Build the sampler and simulate 10,000 samples
121+
μ, λ1, λ2 = 0.0, 2.0, 1.0
122+
sampler = RejectionSampler(x -> f(x, μ, λ1, λ2), support, max_segments = 5)
123+
@time sim = run_sampler!(sampler, 10000);
102124

125+
# Plot the results and compare to target distribution
126+
x = range(-2.3, 2.3, length=100)
127+
envelop = [eval_envelop(sampler.envelop, xi) for xi in x]
128+
target = [f(xi, μ, λ1, λ2) for xi in x]
103129

130+
histogram(sim, normalize = true, label = "histogram")
131+
plot!(x, [target envelop], width = 2, label = ["target density" "envelop"])
132+
```
104133

105-
![](img/example3.png)
134+
![](img/example4.png)

REQUIRE

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
julia 0.6.0
2-
ForwardDiff 0.5.0
3-
StatsBase 0.19.2
1+
julia 0.7
2+
ForwardDiff 0.10.1
3+
StatsBase 0.26.0

img/example4.png

24.8 KB
Loading

src/AdaptiveRejectionSampling.jl

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,13 @@ Finds the horizontal coordinate of the intersection between lines
2727
"""
2828
function intersection(l1::Line, l2::Line)
2929
@assert l1.slope != l2.slope "slopes should be different"
30-
- (l2.intercept - l1.intercept) / (l2.slope - l1.slope)
30+
- (l2.intercept - l1.intercept) / (l2.slope - l1.slope)
3131
end
3232

3333
"""
3434
exp_integral(l::Line, x1::Float64, x2::Float64)
3535
Computes the integral
36-
``LaTeX \int_{x_1} ^ {x_2} \exp\{ax + b\} dx. ``
36+
``LaTeX \\int_{x_1} ^ {x_2} \\exp\\{ax + b\\} dx. ``
3737
The resulting value is the weight assigned to the segment [x1, x2] in the envelop
3838
"""
3939
function exp_integral(l::Line, x1::Float64, x2::Float64)
@@ -50,8 +50,8 @@ over c_1 to c_k+1 is one, so that the envelop is interpreted as a density.
5050
"""
5151
mutable struct Envelop
5252
lines::Vector{Line}
53-
cutpoints::Vector{Float64}
54-
weights::Vector{Float64}
53+
cutpoints::AbstractVector{Float64}
54+
weights::AbstractVector{Float64}
5555
size::Int
5656

5757
Envelop(lines::Vector{Line}, support::Tuple{Float64, Float64}) = begin
@@ -161,7 +161,7 @@ interval in which f has positive value, and zero elsewhere.
161161
- `max_failed_factor::Float64 = 0.001`: level at which throw an error if one single sample has a rejection rate
162162
exceeding this value
163163
"""
164-
mutable struct RejectionSampler
164+
struct RejectionSampler
165165
objective::Objective
166166
envelop::Envelop
167167
max_segments::Int
@@ -201,7 +201,7 @@ mutable struct RejectionSampler
201201
grid_lims = max(search_range[1], support[1]), min(search_range[2], support[2])
202202
grid = grid_lims[1]:δ:grid_lims[2]
203203
i1, i2 = findfirst(grad.(grid) .> 0.), findfirst(grad.(grid) .< 0.)
204-
@assert (i1 > 0) && (i2 > 0) "couldn't find initial points, please provide them or change `search_range`"
204+
@assert (i1 != nothing) && (i2 != nothing) "couldn't find initial points, please provide them or change `search_range`"
205205
x1, x2 = grid[i1], grid[i2]
206206
RejectionSampler(f, support, (x1, x2); kwargs...)
207207
end

test/runtests.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import AdaptiveRejectionSampling
22
ars = AdaptiveRejectionSampling
33

4-
using Base.Test
4+
using Test
55

66
@testset "Line" begin
77
@test ars.Line(2.0, 3) isa ars.Line

0 commit comments

Comments
 (0)