Class: Wallace::Distributions::GaussianDistribution
- Inherits:
-
Object
- Object
- Wallace::Distributions::GaussianDistribution
- Defined in:
- lib/distributions/gaussian_distribution.rb
Overview
Used to represent and sample values from a given Gaussian distribution.
Uses the popular Box-Muller transformation to generate two values, one of which is returned, the other which is cached (and returned upon the next request).
Since the Box-Muller transform samples two values from the distribution, rather than discarding the extra value, we cache it and return it upon the next request.
*Credit to:* stackoverflow.com/questions/5825680/code-to-generate-gaussian-normally-distributed-random-numbers-in-ruby
Instance Method Summary collapse
-
#initialize(mean, std_dev) ⇒ GaussianDistribution
constructor
Constructs a new Gaussian distribution.
-
#sample(opts = {}) ⇒ Object
Samples a value from this distribution.
Constructor Details
#initialize(mean, std_dev) ⇒ GaussianDistribution
Constructs a new Gaussian distribution.
Parameters:
-
mean, the mean of this distribution.
-
std_dev, the standard deviation of this distribution.
20 21 22 23 24 |
# File 'lib/distributions/gaussian_distribution.rb', line 20 def initialize(mean, std_dev) @mean = mean @std_dev = std_dev @cached = nil end |
Instance Method Details
#sample(opts = {}) ⇒ Object
Samples a value from this distribution.
Uses the popular Box-Muller transformation to generate two values, one of which is returned, the other which is cached (and returned upon the next request).
Parameters:
-
opts, keyword arguments for this method.
-
-> random, the random number generation to use to seed the selection process.
35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 |
# File 'lib/distributions/gaussian_distribution.rb', line 35 def sample(opts = {}) # Create a RNG if one isn't already provided. random = opts[:random] || Random.new # Return a cached value if there is one. # We could collapse these 4 lines into a much nicer: # return @values.pop if @values.empty? # However .empty? is much more expensive! unless @cached.nil? value = @cached @cached = nil return value end # Otherwise calculate two new values, caching one and # returning the other. theta = 2 * Math::PI * random.rand rho = Math.sqrt(-2 * Math.log(1 - random.rand)) scale = @std_dev * rho @cached = @mean + scale * Math.cos(theta) return @mean + scale * Math.sin(theta) end |