Class: SkiftetStatistical::Sampler
- Inherits:
-
Object
- Object
- SkiftetStatistical::Sampler
- Defined in:
- lib/skiftet_statistical/sampler.rb
Overview
Random sampling used by the stochastic policies (Thompson Sampling, Softmax,
Epsilon-Greedy). An injectable RNG (a Random) makes every policy fully
deterministic under test — pass rng: Random.new(seed).
Instance Attribute Summary collapse
-
#rng ⇒ Object
readonly
Returns the value of attribute rng.
Instance Method Summary collapse
-
#beta(alpha, beta) ⇒ Object
Beta(alpha, beta) drawn as G1 / (G1 + G2) with Gi ~ Gamma(., 1).
-
#gamma(shape) ⇒ Object
Gamma(shape, scale = 1) via Marsaglia–Tsang.
-
#gaussian ⇒ Object
Standard normal deviate via Box–Muller.
-
#initialize(rng = Random.new) ⇒ Sampler
constructor
A new instance of Sampler.
Constructor Details
#initialize(rng = Random.new) ⇒ Sampler
Returns a new instance of Sampler.
10 11 12 |
# File 'lib/skiftet_statistical/sampler.rb', line 10 def initialize(rng = Random.new) @rng = rng end |
Instance Attribute Details
#rng ⇒ Object (readonly)
Returns the value of attribute rng.
8 9 10 |
# File 'lib/skiftet_statistical/sampler.rb', line 8 def rng @rng end |
Instance Method Details
#beta(alpha, beta) ⇒ Object
Beta(alpha, beta) drawn as G1 / (G1 + G2) with Gi ~ Gamma(., 1).
42 43 44 45 46 47 |
# File 'lib/skiftet_statistical/sampler.rb', line 42 def beta(alpha, beta) g1 = gamma(alpha) g2 = gamma(beta) total = g1 + g2 total.zero? ? 0.5 : g1 / total end |
#gamma(shape) ⇒ Object
Gamma(shape, scale = 1) via Marsaglia–Tsang. Shapes < 1 are handled by the standard boosting identity: Gamma(k) = Gamma(k + 1) * U**(1/k).
23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
# File 'lib/skiftet_statistical/sampler.rb', line 23 def gamma(shape) raise ArgumentError, "shape must be > 0" unless shape.positive? return gamma(shape + 1.0) * (rand_open**(1.0 / shape)) if shape < 1.0 d = shape - (1.0 / 3.0) c = 1.0 / Math.sqrt(9.0 * d) loop do x = gaussian v = (1.0 + (c * x))**3 next if v <= 0.0 u = @rng.rand return d * v if u < 1.0 - (0.0331 * (x**4)) return d * v if Math.log(u) < (0.5 * x * x) + (d * (1.0 - v + Math.log(v))) end end |
#gaussian ⇒ Object
Standard normal deviate via Box–Muller.
15 16 17 18 19 |
# File 'lib/skiftet_statistical/sampler.rb', line 15 def gaussian u1 = rand_open u2 = @rng.rand Math.sqrt(-2.0 * Math.log(u1)) * Math.cos(2.0 * Math::PI * u2) end |