Code to Generate Gaussian (Normally Distributed) Random Numbers in Ruby

Code to generate Gaussian (normally distributed) random numbers in Ruby

Python's random.gauss() and Boost's normal_distribution both use the Box-Muller transform, so that should be good enough for Ruby too.

def gaussian(mean, stddev, rand)
theta = 2 * Math::PI * rand.call
rho = Math.sqrt(-2 * Math.log(1 - rand.call))
scale = stddev * rho
x = mean + scale * Math.cos(theta)
y = mean + scale * Math.sin(theta)
return x, y
end

The method can be wrapped up in a class that returns the samples one by one.

class RandomGaussian
def initialize(mean, stddev, rand_helper = lambda { Kernel.rand })
@rand_helper = rand_helper
@mean = mean
@stddev = stddev
@valid = false
@next = 0
end

def rand
if @valid then
@valid = false
return @next
else
@valid = true
x, y = self.class.gaussian(@mean, @stddev, @rand_helper)
@next = y
return x
end
end

private
def self.gaussian(mean, stddev, rand)
theta = 2 * Math::PI * rand.call
rho = Math.sqrt(-2 * Math.log(1 - rand.call))
scale = stddev * rho
x = mean + scale * Math.cos(theta)
y = mean + scale * Math.sin(theta)
return x, y
end
end

CC0 (CC0)

To the extent possible under law, antonakos has waived all copyright and related or neighboring rights to the RandomGaussian Ruby class. This work is published from: Denmark.

Normally distributed random variables on Ruby on Rails

Thanks for the help in comments. Oli is right, I found the answer in that answer :

https://stackoverflow.com/a/8205982/2576033

Using rubystats gem - "a port of the statistics libraries from PHPMath" (pure ruby), you can generate normally distributed variables, easily and in a nice way :

gen = Rubystats::NormalDistribution.new(mean, sd)
gen.rng # a single random sample
gen.rng(100) # 100 random samples

Generate a perfectly normally distributed sample of size n in R

You can use the bayestestR package:

library(bayestestR)
x <- rnorm_perfect(n = 100, mean = 0, sd = 1)
plot(density(x))

Sample Image

Generate random value from list of numbers

Just use Array#sample:

[100, 643, 826, 804, 372, 076, 156, 152, 036, 248].sample

Available in Ruby 1.9.1+. In an earlier version of Ruby, you could

require 'backports/1.9.1/array/sample'

Simulating averages of normally-distributed random variables in R

Your correct calculation is the first one, where you are generating new realizations of the normal random variable when averaging, as opposed to using the realizations generated in the previous step.

In fact, the distribution of O2 assumes that the two normal random variables being averaged are mutually independent.

In your second calculation, this is not true, as you are averaging v1 and v2, which are not independent since both depend on o1. This is why you get larger variances in the second case.

Generate normally distributed data within a range using Fortran

There are different ways to sample from a truncated normal distribution. The "best" way depends on your mean and variance.

A simple way is just plain rejection: generate a deviate and if it's too big or small throw it away and repeat. If your parameters are such that you don't reject many this is a good method.

For the routine specified, doing this rejection is simple: sticking the whole calculation part (including the flag test) into a do...end do loop with an if (abs(normal).lt.10) exit should do it.

[This isn't elegant, and extra bookkeeping may be required, with samples being generated as pairs. But, again, if rejection happens rarely that's not too bad. Tidying is left as an exercise for the reader.]

That's how one may change the routine, but as @george comments, that probably isn't the best approach, even with the rejection. Certainly, having a function called normal which takes mean and sigma and returns a deviate which isn't from a normal distribution could be confusing.

function truncated_normal(mu, sigma, lim_a, lim_b) !Very side-effecty
... declarations ...
if ( ... test for wanting the rejection method ... ) then
do
truncated_normal = normal(mu, sigma)
if (truncated_normal.gt.lim_a.and.truncated_normal.lt.lim_b) exit
end do
else
... the other magical method when rejection is too likely ...
end if
end

Build a C++ normal distributed random number generator on Xcode 8.3

It is defined as

template< class RealType = double > class normal_distribution

where for RealType you could use only float, double or long double, otherwise it is undefined.

Code should be

std::normal_distribution<double> distribution (0.0, 1.0);

double random_value = distribution(e2);
return fabs(random_value);


Related Topics



Leave a reply



Submit