1 """ robert.tools.statistics
2
3 Helper module implementing several statistical basic methods.
4 """
9 """ class ProbabilityDistribtions() - basic PD functionality
10
11 This class implements basic probability distribution functionality,
12 currently the generation of random distributions. One usage is the
13 random benchmark generation.
14
15 Most methods are static (class) methods. Basically, this class is used to
16 encapsulated conjoined functions.
17 """
18
19
20 IMPLEMENTED_DISTRIBUTIONS = ['uniform',
21 'gauss',
22 'exponential',
23 'half-gauss']
24
25
26
27
28 @staticmethod
30 """ get_distribution(n, method, left, right) -> distribution
31
32 n ... number of generated values
33 method ... random generation method
34 left ... left/lower limit
35 right ... right/upper limit
36 distribution ... list of generated values with given properties
37
38 Generates a list of random values by the given method in the
39 given limits. Returns floats.
40 """
41
42
43 if right < left:
44 left, right = right, left
45 inverse = True
46 else:
47 inverse = False
48 assert left >= 0
49
50 import random
51 from exceptions import ValueError
52
53 distribution = []
54
55 if left == right:
56 def single_random_value():
57 return left
58 elif method == 'uniform':
59 def single_random_value():
60 return random.uniform(left, right)
61 elif method == 'gauss':
62 mu = (left + right) / 2.0
63 sigma = (right - left) / (2.0 * 3)
64 def single_random_value():
65 value = random.gauss(mu, sigma)
66 while value < left or value > right:
67 value = random.gauss(mu, sigma)
68 return value
69 elif method == 'half-gauss':
70 if not inverse:
71 mu = left
72 else:
73 mu = right
74 sigma = right - left
75 def single_random_value():
76 value = random.gauss(mu, sigma)
77
78 if (inverse and value > mu) or (not inverse and value < mu):
79 value = 2 * mu - value
80 while (inverse and value < left) or (not inverse and value > right):
81 value = random.gauss(mu, sigma)
82 if (inverse and value > mu) or (not inverse and value < mu):
83 value = 2 * mu - value
84 return value
85 elif method == 'exponential':
86 margin = right - left
87 lambd = 2.0 / margin
88 if inverse:
89 lambd = -lambd
90 offset = right
91 else:
92 offset = left
93 def single_random_value():
94 value = random.expovariate(lambd)
95 while (inverse and value < -margin) or (not inverse and value > margin):
96 value = random.expovariate(lambd)
97 return value + offset
98 else:
99 raise ValueError('%s is not implemented.' % method)
100
101 i = 0
102 while i < n:
103 distribution.append(single_random_value())
104 i += 1
105 return distribution
106