Random numbers

From Rosetta Code
Revision as of 05:14, 28 November 2007 by rosettacode>Wegenern
Task
Random numbers
You are encouraged to solve this task according to the task description, using any language you may know.

The goal of this task is to generate a collection filled with 1000 normally distributed random numbers with a mean of 1.0 and a standard deviation of 0.5

Many libraries only generate uniformly distributed random numbers. If so, use this formula to convert them to a normal distribution.

Ada

with Ada.Numerics.Float_Random; use Ada.Numerics.Float_Random;
with Ada.Numerics.Generic_Elementary_Functions;

procedure Normal_Random is
   Seed : Generator;
   function Normal_Distribution(Seed : Generator) return Float is
      package Elementary_Flt is new 
         Ada.Numerics.Generic_Elementary_Functions(Float);
      use Elementary_Flt;
      use Ada.Numerics;
      R1 : Float;
      R2 : Float;
      Mu : constant Float := 1.0;
      Sigma : constant Float := 0.5;
   begin
      R1 := Random(Seed);
      R2 := Random(Seed);
      return Mu + (Sigma * Sqrt(-2.0 * Log(X => R1, Base => 10.0)) * 
         Cos(2.0 * Pi * R2));
   end Normal_Distribution;
      
   type Normal_Array is array(1..1000) of Float;
   Distribution : Normal_Array;
begin
   Reset(Seed);
   for I in Distribution'range loop
      Distribution(I) := Normal_Distribution(Seed);
   end loop;
end Normal_Random;

BASIC

Compiler: QuickBasic 4.5

RANDOMIZE TIMER
pi = 3.141592653589793#
DIM a(1 TO 1000) AS DOUBLE
CLS
FOR i = 1 TO 1000
   a(i) = 1 + SQR(-2 * LOG(RND)) * COS(2 * pi * RND)
NEXT i

C

#include <stdlib.h>
#include <math.h>

double drand()   /* uniform distribution, (0..1] */
{
  return (rand()+1.0)/(RAND_MAX+1.0);
}
double random_normal()  /* normal distribution, centered on 0, std dev 1 */
{
  return sqrt(-2*log(drand())) * cos(2*M_PI*drand());
}
int main()
{
  int i;
  double rands[1000];
  for (i=0; i<1000; i++)
    rands[i] = 1.0 + 0.5*random_normal();
  return 0;
}

C++

#include <cstdlib>   // for rand
#include <cmath>     // for atan, sqrt, log, cos
#include <algorithm> // for generate_n

double const pi = 4*std::atan(1.0);

// simple functor for normal distribution
class normal_distribution
{
public:
  normal_distribution(double m, double s): mu(m), sigma(s) {}
  double operator() // returns a single normally distributed number
  {
    double r1 = (std::rand() + 1.0)/(RAND_MAX + 1.0); // gives equal distribution in (0, 1]
    double r2 = (std::rand() + 1.0)/(RAND_MAX + 1.0);
    return mu + sigma * std::sqrt(-2*std::log(r1))*std::cos(2*pi*r2);
  }
private:
  double mu, sigma;
};

int main()
{
  double array[1000];
  std::generate_n(array, 1000, normal_distribution(1.0, 0.5));
}

E

accum [] for _ in 1..1000 { _.with(entropy.nextGaussian()) }

Forth

Interpreter: gforth 0.6.2

require random.fs
here to seed

-1. 1 rshift 2constant MAX-D	\ or s" MAX-D" ENVIRONMENT? drop

: frnd ( -- f )			\ uniform distribution 0..1
  rnd rnd dabs d>f MAX-D d>f f/ ;

: frnd-normal ( -- f )		\ centered on 0, std dev 1
  frnd pi f* 2e f* fcos
  frnd fln -2e f* fsqrt f* ;

: ,normals ( n -- )		\ store many, centered on 1, std dev 0.5
  0 do frnd-normal 0.5e f* 1e f+ f, loop ;

create rnd-array 1000 ,normals

Haskell

import System.Random

pairs :: [a] -> [(a,a)]
pairs (x:y:zs) = (x,y):pairs zs
pairs _        = []

gauss mu sigma (r1,r2) = 
  mu + sigma * sqrt (-2 * log r1) * cos (2 * pi * r2)

gaussians :: (RandomGen g, Random a, Floating a) => Int -> g -> [a]
gaussians n g = take n $ map (gauss 1.0 0.5) $ pairs $ randoms g
result :: IO [Double]
result = getStdGen >>= \g -> return $ gaussians 1000 g

Groovy

rnd = new Random()
result = (1..1000).inject([]) { r, i -> r << rnd.nextGaussian() }

IDL

result = 1.0 + 0.5*randomn(seed,1000)

Java

double[] list = new double[1000];
Random rng = new Random();
for(int i = 0;i<list.length;i++) {
  list[i] = 1.0 + 0.5 * rng.nextGaussian()
}

MAXScript

arr = #()
for i in 1 to 1000 do 
(
    a = random 0.0 1.0
    b = random 0.0 1.0
    c = 1.0 + 0.5 * sqrt (-2*log a) * cos (360*b) -- Maxscript cos takes degrees
    append arr c
)

Perl

use Math::Cephes qw($PI);
map {
    1.0 + 0.5 * sqrt (-2 * log rand) * cos (2 * $PI * rand)
} 1..1000

PHP

$pi 	= pi();          // Set PI
$a	= range(1,1000); // Create array
foreach(range(1,1000) as $i){

$a[$i] = 1 + sqrt(-2 * log(mt_rand())) * cos(2 * $pi * mt_rand());

}

Pop11

;;; Choose radians as arguments to trigonometic functions
true -> popradians;
;;; procedure generating standard normal distribution
define random_normal() -> result;
lvars r1 = random0(1.0), r2 = random0(1.0);
     cos(2*pi*r1)*sqrt(-2*log(r2)) -> result
enddefine;
lvars array, i;
;;; Put numbers on the stack
for i from 1 to 1000 do 1.0+0.5*random_normal() endfor;
;;; collect them into array
consvector(1000) -> array;

Python

Interpreter: Python 2.5

import random
randList = [random.gauss(1, .5) for i in range(1000)]
# or [ random.normalvariate(1, 0.5) for i in range(1000)]

Note that the random module in the Python standard library supports a number of statistical distribution methods.

Tcl

proc nrand {} {return [expr sqrt(-2*log(rand()))*cos(4*acos(0)*rand())]}
for {set i 0} {$i < 1000} {incr i} {lappend result [expr 1+.5*nrand()]}