-
Notifications
You must be signed in to change notification settings - Fork 1
/
Random-numbers-generator.py
125 lines (106 loc) · 4.25 KB
/
Random-numbers-generator.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
# -*- coding: utf-8 -*-
"""PR4.ipynb
Automatically generated by Colaboratory.
Original file is located at
https://colab.research.google.com/drive/13KU9nrRP8CjSBx6_aAWWkW4bYuYFvpkm
"""
#!/usr/bin/env python3
# coding: utf-8
# Three-sided Unfair Dice into other RV distributions
#
# IE531: Algorithms for Data Analytics
# Written by Prof. R.S. Sreenivas
#
import sys
import argparse
import random
import numpy as np
import time
import math
import matplotlib.pyplot as plt
from scipy.stats import uniform
# Some constants -- "heads" is 1 and "tails" is 0
HEADS = 1
TAILS = 0
# reading the number of trials on command line
#no_of_trials = 1000
no_of_trials = int(sys.argv[1])+0
# assign a random value for the probability of seeing a "1" (p1), "2" (p2) or "3" (p3) for
# the 3-sided unfair dice such that (p1, p2, p3) is uniformly distributed over the surface
# p1+p2+p3 = 1, where p1, p2, p3 are non-negative real numbers
def assign_probabilities_to_unfair_three_sided_dice() :
r = [np.random.uniform() for i in range(3)]
s = sum(r)
r = [ i/s for i in r ]
prob_of_one = r[0]
prob_of_two = r[1]
prob_of_three = r[2]
#assert (prob_of_one + prob_of_two + prob_of_three == 1)
return prob_of_one, prob_of_two, prob_of_three
# This function simulates a single toss of the unfair 3-sided dice
def toss_of_three_sided_unfair_dice(p1, p2, p3) :
x = np.random.uniform()
if (x < p1) :
return 1
else :
if (x < p2) :
return 2
else :
return 3
# This function simulates a fair-coin using the unfair 3-sided dice
def simulate_fair_coin_from_unfair_three_sided_dice(p1, p2, p3) :
# figure out how to convert the outcome of the unfair 3-sided dice
# into an outcome from a Fair Coin
# toss the unfair coin twice
toss1 = toss_of_three_sided_unfair_dice(p1, p2, p3)
toss2 = toss_of_three_sided_unfair_dice(p1, p2, p3)
# repeat the unfair coin toss if toss1 and toss2 are the same
while (toss1 == toss2) :
toss1 = toss_of_three_sided_unfair_dice(p1, p2, p3)
toss3 = toss_of_three_sided_unfair_dice(p1, p2, p3)
# repeat the unfair coin toss if toss3 is the same as toss1 or toss2
while((toss1 == toss3) or (toss2 == toss3)):
toss3 = toss_of_three_sided_unfair_dice(p1, p2, p3)
x = [toss1, toss2, toss3]
#print(x)
#there are 6 unique outcomes, so group them by 3
if (x == [1,2,3] or x == [1,3,2] or x == [2,1,3]) :
return HEADS
else :
return TAILS
# get a U.I.I.D RV by making the unfair three sided dice into a fair coin... and tossing the
# resulting fair-coin 32 times to get discrete RV that is uniformly distributed over the
# integers in [0, 2^{32}-1]... dividing the resulting integer by 2^{32}-1 gives us (effectively)
# a U.I.I.D. RV
def get_uiid_rvs_by_tossing_the_unfair_three_sided_dice_32_times(p1, p2, p3) :
result = 0
for i in range(0, 32) :
if (simulate_fair_coin_from_unfair_three_sided_dice(p1, p2, p3) == HEADS) :
result = result | (1 << i)
else :
result = result | (0 << i)
return float(result/(pow(2,32)-1))
# plotting the histogram of the continuous RV generated by tossing the unfair three sided dice
# sufficient number of times till we get 32 fair-coin-tosses, which are then converted into a
# number in the unit-interval
# assigning probabilities to unfair three sided dice
p1, p2, p3 = assign_probabilities_to_unfair_three_sided_dice()
z = []
for i in range(0,no_of_trials) :
z.extend([get_uiid_rvs_by_tossing_the_unfair_three_sided_dice_32_times(p1, p2, p3)])
plt.hist(z, bins=50)
plt.ylabel('Histogram for ' + str(no_of_trials) + ' trials');
plt.savefig("UIID_Histogram.pdf", bbox_inches='tight')
# converting (multiple) tosses of the unfair 3-sided Dice into a unit-normal distribution
# using the Box-Muller Method
a = []
for i in range(0,no_of_trials) :
p = get_uiid_rvs_by_tossing_the_unfair_three_sided_dice_32_times(p1, p2, p3)
q = get_uiid_rvs_by_tossing_the_unfair_three_sided_dice_32_times(p1, p2, p3)
theta = 2*math.pi*p
r = np.sqrt(-2*math.log(q))
a.extend([r*math.cos(theta)])
a.extend([r*math.sin(theta)])
plt.hist(a, bins=50)
plt.ylabel('Histogram for ' + str(2*no_of_trials) + ' trials');
plt.savefig("Unit_Normal_Histogram.pdf", bbox_inches='tight')