simple-random 0.9.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.document +5 -0
- data/.gitignore +21 -0
- data/LICENSE +251 -0
- data/README.rdoc +17 -0
- data/Rakefile +53 -0
- data/VERSION +1 -0
- data/lib/simple-random.rb +187 -0
- data/simple-random.gemspec +54 -0
- data/test/helper.rb +10 -0
- data/test/test_simple_random.rb +93 -0
- metadata +92 -0
data/.document
ADDED
data/.gitignore
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,251 @@
|
|
1
|
+
<html>
|
2
|
+
<head>
|
3
|
+
<title>The Code Project Open License (COPL)</title>
|
4
|
+
<Style>
|
5
|
+
BODY, P, TD { font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 10pt }
|
6
|
+
H1,H2,H3,H4,H5 { color: #ff9900; font-weight: bold; }
|
7
|
+
H1 { font-size: 14pt;color:black }
|
8
|
+
H2 { font-size: 13pt; }
|
9
|
+
H3 { font-size: 12pt; }
|
10
|
+
H4 { font-size: 10pt; color: black; }
|
11
|
+
PRE { BACKGROUND-COLOR: #FBEDBB; FONT-FAMILY: "Courier New", Courier, mono; WHITE-SPACE: pre; }
|
12
|
+
CODE { COLOR: #990000; FONT-FAMILY: "Courier New", Courier, mono; }
|
13
|
+
.SpacedList li { padding: 5px 0px 5px 0px;}
|
14
|
+
</style>
|
15
|
+
</head>
|
16
|
+
<body bgcolor="#FFFFFF" color=#000000>
|
17
|
+
|
18
|
+
<h1>The Code Project Open License (CPOL) 1.02</h1>
|
19
|
+
<br />
|
20
|
+
|
21
|
+
<center>
|
22
|
+
<div style="text-align: left; border: 2px solid #000000; width: 660; background-color: #FFFFD9; padding: 20px;">
|
23
|
+
|
24
|
+
<h2>Preamble</h2>
|
25
|
+
<p>
|
26
|
+
This License governs Your use of the Work. This License is intended to allow developers
|
27
|
+
to use the Source Code and Executable Files provided as part of the Work in any
|
28
|
+
application in any form.
|
29
|
+
</p>
|
30
|
+
<p>
|
31
|
+
The main points subject to the terms of the License are:</p>
|
32
|
+
<ul>
|
33
|
+
<li>Source Code and Executable Files can be used in commercial applications;</li>
|
34
|
+
<li>Source Code and Executable Files can be redistributed; and</li>
|
35
|
+
<li>Source Code can be modified to create derivative works.</li>
|
36
|
+
<li>No claim of suitability, guarantee, or any warranty whatsoever is provided. The software is
|
37
|
+
provided "as-is".</li>
|
38
|
+
<li>The Article accompanying the Work may not be distributed or republished without the
|
39
|
+
Author's consent</li>
|
40
|
+
</ul>
|
41
|
+
|
42
|
+
<p>
|
43
|
+
This License is entered between You, the individual or other entity reading or otherwise
|
44
|
+
making use of the Work licensed pursuant to this License and the individual or other
|
45
|
+
entity which offers the Work under the terms of this License ("Author").</p>
|
46
|
+
|
47
|
+
<h2>License</h2>
|
48
|
+
<p>
|
49
|
+
THE WORK (AS DEFINED BELOW) IS PROVIDED UNDER THE TERMS OF THIS CODE PROJECT OPEN
|
50
|
+
LICENSE ("LICENSE"). THE WORK IS PROTECTED BY COPYRIGHT AND/OR OTHER APPLICABLE
|
51
|
+
LAW. ANY USE OF THE WORK OTHER THAN AS AUTHORIZED UNDER THIS LICENSE OR COPYRIGHT
|
52
|
+
LAW IS PROHIBITED.</p>
|
53
|
+
<p>
|
54
|
+
BY EXERCISING ANY RIGHTS TO THE WORK PROVIDED HEREIN, YOU ACCEPT AND AGREE TO BE
|
55
|
+
BOUND BY THE TERMS OF THIS LICENSE. THE AUTHOR GRANTS YOU THE RIGHTS CONTAINED HEREIN
|
56
|
+
IN CONSIDERATION OF YOUR ACCEPTANCE OF SUCH TERMS AND CONDITIONS. IF YOU DO NOT
|
57
|
+
AGREE TO ACCEPT AND BE BOUND BY THE TERMS OF THIS LICENSE, YOU CANNOT MAKE ANY
|
58
|
+
USE OF THE WORK.</p>
|
59
|
+
|
60
|
+
<ol class="SpacedList">
|
61
|
+
<li><strong>Definitions.</strong>
|
62
|
+
|
63
|
+
<ol class="SpacedList" style="list-style-type: lower-alpha;">
|
64
|
+
<li><strong>"Articles"</strong> means, collectively, all articles written by Author
|
65
|
+
which describes how the Source Code and Executable Files for the Work may be used
|
66
|
+
by a user.</li>
|
67
|
+
<li><b>"Author"</b> means the individual or entity that offers the Work under the terms
|
68
|
+
of this License.<strong></strong></li>
|
69
|
+
<li><strong>"Derivative Work"</strong> means a work based upon the Work or upon the
|
70
|
+
Work and other pre-existing works.</li>
|
71
|
+
<li><b>"Executable Files"</b> refer to the executables, binary files, configuration
|
72
|
+
and any required data files included in the Work.</li>
|
73
|
+
<li>"<b>Publisher</b>" means the provider of the website, magazine, CD-ROM, DVD or other
|
74
|
+
medium from or by which the Work is obtained by You.</li>
|
75
|
+
<li><b>"Source Code"</b> refers to the collection of source code and configuration files
|
76
|
+
used to create the Executable Files.</li>
|
77
|
+
<li><b>"Standard Version"</b> refers to such a Work if it has not been modified, or
|
78
|
+
has been modified in accordance with the consent of the Author, such consent being
|
79
|
+
in the full discretion of the Author. </li>
|
80
|
+
<li><b>"Work"</b> refers to the collection of files distributed by the Publisher, including
|
81
|
+
the Source Code, Executable Files, binaries, data files, documentation, whitepapers
|
82
|
+
and the Articles. </li>
|
83
|
+
<li><b>"You"</b> is you, an individual or entity wishing to use the Work and exercise
|
84
|
+
your rights under this License.
|
85
|
+
</li>
|
86
|
+
</ol>
|
87
|
+
</li>
|
88
|
+
|
89
|
+
<li><strong>Fair Use/Fair Use Rights.</strong> Nothing in this License is intended to
|
90
|
+
reduce, limit, or restrict any rights arising from fair use, fair dealing, first
|
91
|
+
sale or other limitations on the exclusive rights of the copyright owner under copyright
|
92
|
+
law or other applicable laws.
|
93
|
+
</li>
|
94
|
+
|
95
|
+
<li><strong>License Grant.</strong> Subject to the terms and conditions of this License,
|
96
|
+
the Author hereby grants You a worldwide, royalty-free, non-exclusive, perpetual
|
97
|
+
(for the duration of the applicable copyright) license to exercise the rights in
|
98
|
+
the Work as stated below:
|
99
|
+
|
100
|
+
<ol class="SpacedList" style="list-style-type: lower-alpha;">
|
101
|
+
<li>You may use the standard version of the Source Code or Executable Files in Your
|
102
|
+
own applications. </li>
|
103
|
+
<li>You may apply bug fixes, portability fixes and other modifications obtained from
|
104
|
+
the Public Domain or from the Author. A Work modified in such a way shall still
|
105
|
+
be considered the standard version and will be subject to this License.</li>
|
106
|
+
<li>You may otherwise modify Your copy of this Work (excluding the Articles) in any
|
107
|
+
way to create a Derivative Work, provided that You insert a prominent notice in
|
108
|
+
each changed file stating how, when and where You changed that file.</li>
|
109
|
+
<li>You may distribute the standard version of the Executable Files and Source Code
|
110
|
+
or Derivative Work in aggregate with other (possibly commercial) programs as part
|
111
|
+
of a larger (possibly commercial) software distribution. </li>
|
112
|
+
<li>The Articles discussing the Work published in any form by the author may not be
|
113
|
+
distributed or republished without the Author's consent. The author retains
|
114
|
+
copyright to any such Articles. You may use the Executable Files and Source Code
|
115
|
+
pursuant to this License but you may not repost or republish or otherwise distribute
|
116
|
+
or make available the Articles, without the prior written consent of the Author.</li>
|
117
|
+
</ol>
|
118
|
+
|
119
|
+
Any subroutines or modules supplied by You and linked into the Source Code or Executable
|
120
|
+
Files this Work shall not be considered part of this Work and will not be subject
|
121
|
+
to the terms of this License.
|
122
|
+
</li>
|
123
|
+
|
124
|
+
<li><strong>Patent License.</strong> Subject to the terms and conditions of this License,
|
125
|
+
each Author hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free,
|
126
|
+
irrevocable (except as stated in this section) patent license to make, have made, use, import,
|
127
|
+
and otherwise transfer the Work.</li>
|
128
|
+
|
129
|
+
<li><strong>Restrictions.</strong> The license granted in Section 3 above is expressly
|
130
|
+
made subject to and limited by the following restrictions:
|
131
|
+
|
132
|
+
<ol class="SpacedList" style="list-style-type: lower-alpha;">
|
133
|
+
<li>You agree not to remove any of the original copyright, patent, trademark, and
|
134
|
+
attribution notices and associated disclaimers that may appear in the Source Code
|
135
|
+
or Executable Files. </li>
|
136
|
+
<li>You agree not to advertise or in any way imply that this Work is a product of Your
|
137
|
+
own. </li>
|
138
|
+
<li>The name of the Author may not be used to endorse or promote products derived from
|
139
|
+
the Work without the prior written consent of the Author.</li>
|
140
|
+
<li>You agree not to sell, lease, or rent any part of the Work. This does not restrict
|
141
|
+
you from including the Work or any part of the Work inside a larger software
|
142
|
+
distribution that itself is being sold. The Work by itself, though, cannot be sold,
|
143
|
+
leased or rented.</li>
|
144
|
+
<li>You may distribute the Executable Files and Source Code only under the terms of
|
145
|
+
this License, and You must include a copy of, or the Uniform Resource Identifier
|
146
|
+
for, this License with every copy of the Executable Files or Source Code You distribute
|
147
|
+
and ensure that anyone receiving such Executable Files and Source Code agrees that
|
148
|
+
the terms of this License apply to such Executable Files and/or Source Code. You
|
149
|
+
may not offer or impose any terms on the Work that alter or restrict the terms of
|
150
|
+
this License or the recipients' exercise of the rights granted hereunder. You
|
151
|
+
may not sublicense the Work. You must keep intact all notices that refer to this
|
152
|
+
License and to the disclaimer of warranties. You may not distribute the Executable
|
153
|
+
Files or Source Code with any technological measures that control access or use
|
154
|
+
of the Work in a manner inconsistent with the terms of this License. </li>
|
155
|
+
<li>You agree not to use the Work for illegal, immoral or improper purposes, or on pages
|
156
|
+
containing illegal, immoral or improper material. The Work is subject to applicable
|
157
|
+
export laws. You agree to comply with all such laws and regulations that may apply
|
158
|
+
to the Work after Your receipt of the Work.
|
159
|
+
</li>
|
160
|
+
</ol>
|
161
|
+
</li>
|
162
|
+
|
163
|
+
<li><strong>Representations, Warranties and Disclaimer.</strong> THIS WORK IS PROVIDED
|
164
|
+
"AS IS", "WHERE IS" AND "AS AVAILABLE", WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES
|
165
|
+
OR CONDITIONS OR GUARANTEES. YOU, THE USER, ASSUME ALL RISK IN ITS USE, INCLUDING
|
166
|
+
COPYRIGHT INFRINGEMENT, PATENT INFRINGEMENT, SUITABILITY, ETC. AUTHOR EXPRESSLY
|
167
|
+
DISCLAIMS ALL EXPRESS, IMPLIED OR STATUTORY WARRANTIES OR CONDITIONS, INCLUDING
|
168
|
+
WITHOUT LIMITATION, WARRANTIES OR CONDITIONS OF MERCHANTABILITY, MERCHANTABLE QUALITY
|
169
|
+
OR FITNESS FOR A PARTICULAR PURPOSE, OR ANY WARRANTY OF TITLE OR NON-INFRINGEMENT,
|
170
|
+
OR THAT THE WORK (OR ANY PORTION THEREOF) IS CORRECT, USEFUL, BUG-FREE OR FREE OF
|
171
|
+
VIRUSES. YOU MUST PASS THIS DISCLAIMER ON WHENEVER YOU DISTRIBUTE THE WORK OR DERIVATIVE
|
172
|
+
WORKS.
|
173
|
+
</li>
|
174
|
+
|
175
|
+
<li><b>Indemnity. </b>You agree to defend, indemnify and hold harmless the Author and
|
176
|
+
the Publisher from and against any claims, suits, losses, damages, liabilities,
|
177
|
+
costs, and expenses (including reasonable legal or attorneys� fees) resulting from
|
178
|
+
or relating to any use of the Work by You.
|
179
|
+
</li>
|
180
|
+
|
181
|
+
<li><strong>Limitation on Liability.</strong> EXCEPT TO THE EXTENT REQUIRED BY APPLICABLE
|
182
|
+
LAW, IN NO EVENT WILL THE AUTHOR OR THE PUBLISHER BE LIABLE TO YOU ON ANY LEGAL
|
183
|
+
THEORY FOR ANY SPECIAL, INCIDENTAL, CONSEQUENTIAL, PUNITIVE OR EXEMPLARY DAMAGES
|
184
|
+
ARISING OUT OF THIS LICENSE OR THE USE OF THE WORK OR OTHERWISE, EVEN IF THE AUTHOR
|
185
|
+
OR THE PUBLISHER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
|
186
|
+
</li>
|
187
|
+
|
188
|
+
<li><strong>Termination.</strong>
|
189
|
+
|
190
|
+
<ol style="list-style-type: lower-alpha;">
|
191
|
+
<li>This License and the rights granted hereunder will terminate automatically upon
|
192
|
+
any breach by You of any term of this License. Individuals or entities who have
|
193
|
+
received Derivative Works from You under this License, however, will not have their
|
194
|
+
licenses terminated provided such individuals or entities remain in full compliance
|
195
|
+
with those licenses. Sections 1, 2, 6, 7, 8, 9, 10 and 11 will survive any termination
|
196
|
+
of this License. </li>
|
197
|
+
|
198
|
+
<li>If You bring a copyright, trademark, patent or any other infringement claim against
|
199
|
+
any contributor over infringements You claim are made by the Work, your License
|
200
|
+
from such contributor to the Work ends automatically.</li>
|
201
|
+
|
202
|
+
<li>Subject to the above terms and conditions, this License is perpetual (for the duration
|
203
|
+
of the applicable copyright in the Work). Notwithstanding the above, the Author
|
204
|
+
reserves the right to release the Work under different license terms or to stop
|
205
|
+
distributing the Work at any time; provided, however that any such election will
|
206
|
+
not serve to withdraw this License (or any other license that has been, or is required
|
207
|
+
to be, granted under the terms of this License), and this License will continue
|
208
|
+
in full force and effect unless terminated as stated above.
|
209
|
+
</li>
|
210
|
+
</ol>
|
211
|
+
</li>
|
212
|
+
|
213
|
+
<li><strong>Publisher</strong>. The parties hereby confirm that the Publisher shall
|
214
|
+
not, under any circumstances, be responsible for and shall not have any liability
|
215
|
+
in respect of the subject matter of this License. The Publisher makes no warranty
|
216
|
+
whatsoever in connection with the Work and shall not be liable to You or any party
|
217
|
+
on any legal theory for any damages whatsoever, including without limitation any
|
218
|
+
general, special, incidental or consequential damages arising in connection to this
|
219
|
+
license. The Publisher reserves the right to cease making the Work available to
|
220
|
+
You at any time without notice</li>
|
221
|
+
|
222
|
+
<li><strong>Miscellaneous</strong>
|
223
|
+
|
224
|
+
<ol class="SpacedList" style="list-style-type: lower-alpha;">
|
225
|
+
<li>This License shall be governed by the laws of the location of the head office of
|
226
|
+
the Author or if the Author is an individual, the laws of location of the principal
|
227
|
+
place of residence of the Author.</li>
|
228
|
+
<li>If any provision of this License is invalid or unenforceable under applicable law,
|
229
|
+
it shall not affect the validity or enforceability of the remainder of the terms
|
230
|
+
of this License, and without further action by the parties to this License, such
|
231
|
+
provision shall be reformed to the minimum extent necessary to make such provision
|
232
|
+
valid and enforceable. </li>
|
233
|
+
<li>No term or provision of this License shall be deemed waived and no breach consented
|
234
|
+
to unless such waiver or consent shall be in writing and signed by the party to
|
235
|
+
be charged with such waiver or consent. </li>
|
236
|
+
<li>This License constitutes the entire agreement between the parties with respect to
|
237
|
+
the Work licensed herein. There are no understandings, agreements or representations
|
238
|
+
with respect to the Work not specified herein. The Author shall not be bound by
|
239
|
+
any additional provisions that may appear in any communication from You. This License
|
240
|
+
may not be modified without the mutual written agreement of the Author and You.
|
241
|
+
</li>
|
242
|
+
</ol>
|
243
|
+
|
244
|
+
</li>
|
245
|
+
</ol>
|
246
|
+
|
247
|
+
</div>
|
248
|
+
</center>
|
249
|
+
|
250
|
+
</body>
|
251
|
+
</html>
|
data/README.rdoc
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
= simple-random
|
2
|
+
|
3
|
+
Description goes here.
|
4
|
+
|
5
|
+
== Note on Patches/Pull Requests
|
6
|
+
|
7
|
+
* Fork the project.
|
8
|
+
* Make your feature addition or bug fix.
|
9
|
+
* Add tests for it. This is important so I don't break it in a
|
10
|
+
future version unintentionally.
|
11
|
+
* Commit, do not mess with rakefile, version, or history.
|
12
|
+
(if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
|
13
|
+
* Send me a pull request. Bonus points for topic branches.
|
14
|
+
|
15
|
+
== Copyright
|
16
|
+
|
17
|
+
Copyright (c) 2010 Jason Adams. See LICENSE for details.
|
data/Rakefile
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'jeweler'
|
6
|
+
Jeweler::Tasks.new do |gem|
|
7
|
+
gem.name = "simple-random"
|
8
|
+
gem.summary = %Q{Simple Random Number Generator}
|
9
|
+
gem.description = %Q{Simple Random Number Generator including Beta, Cauchy, Chi square, Exponential, Gamma, Inverse Gamma, Laplace (double exponential), Normal, Student t, Uniform, and Weibull. Ported from John D. Cook's C# Code.}
|
10
|
+
gem.email = "jasonmadams@gmail.com"
|
11
|
+
gem.homepage = "http://github.com/ealdent/simple-random"
|
12
|
+
gem.authors = ["John D. Cook", "Jason Adams"]
|
13
|
+
gem.add_development_dependency "shoulda", ">= 0"
|
14
|
+
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
15
|
+
end
|
16
|
+
Jeweler::GemcutterTasks.new
|
17
|
+
rescue LoadError
|
18
|
+
puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
|
19
|
+
end
|
20
|
+
|
21
|
+
require 'rake/testtask'
|
22
|
+
Rake::TestTask.new(:test) do |test|
|
23
|
+
test.libs << 'lib' << 'test'
|
24
|
+
test.pattern = 'test/**/test_*.rb'
|
25
|
+
test.verbose = true
|
26
|
+
end
|
27
|
+
|
28
|
+
begin
|
29
|
+
require 'rcov/rcovtask'
|
30
|
+
Rcov::RcovTask.new do |test|
|
31
|
+
test.libs << 'test'
|
32
|
+
test.pattern = 'test/**/test_*.rb'
|
33
|
+
test.verbose = true
|
34
|
+
end
|
35
|
+
rescue LoadError
|
36
|
+
task :rcov do
|
37
|
+
abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
task :test => :check_dependencies
|
42
|
+
|
43
|
+
task :default => :test
|
44
|
+
|
45
|
+
require 'rake/rdoctask'
|
46
|
+
Rake::RDocTask.new do |rdoc|
|
47
|
+
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
48
|
+
|
49
|
+
rdoc.rdoc_dir = 'rdoc'
|
50
|
+
rdoc.title = "simple-random #{version}"
|
51
|
+
rdoc.rdoc_files.include('README*')
|
52
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
53
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.9.0
|
@@ -0,0 +1,187 @@
|
|
1
|
+
class SimpleRandom
|
2
|
+
def initialize
|
3
|
+
@m_w = 521288629
|
4
|
+
@m_z = 362436069
|
5
|
+
end
|
6
|
+
|
7
|
+
def set_seed(*args)
|
8
|
+
if args.size > 1
|
9
|
+
@m_w = args.first.to_i if args.first.to_i != 0
|
10
|
+
@m_z = args.last.to_i if args.last.to_i != 0
|
11
|
+
elsif args.first.is_a?(Numeric)
|
12
|
+
@m_w = args.first.to_i if args.first.to_i != 0
|
13
|
+
elsif args.first.is_a?(Time)
|
14
|
+
x = args.first.to_i
|
15
|
+
@m_w = x >> 16
|
16
|
+
@m_z = x % 4294967296 # 2 ** 32
|
17
|
+
else
|
18
|
+
x = Time.now.to_i
|
19
|
+
@m_w = x >> 16
|
20
|
+
@m_z = x % 4294967296 # 2 ** 32
|
21
|
+
end
|
22
|
+
|
23
|
+
@m_w %= 4294967296
|
24
|
+
@m_z %= 4294967296
|
25
|
+
end
|
26
|
+
|
27
|
+
# Produce a uniform random sample from the open interval (lower, upper).
|
28
|
+
# The method will not return either end point.
|
29
|
+
def uniform(lower = 0, upper = 1)
|
30
|
+
raise 'Invalid range' if upper <= lower
|
31
|
+
((get_unsigned_int + 1) * (upper - lower) / 4294967296.0) + lower
|
32
|
+
end
|
33
|
+
|
34
|
+
# Sample normal distribution with given mean and standard deviation
|
35
|
+
def normal(mean = 0.0, standard_deviation = 1.0)
|
36
|
+
raise 'Invalid standard deviation' if standard_deviation <= 0
|
37
|
+
mean + standard_deviation * ((-2.0 * Math.log(uniform)) ** 0.5) * Math.sin(2.0 * Math::PI * uniform)
|
38
|
+
end
|
39
|
+
|
40
|
+
# Get exponential random sample with specified mean
|
41
|
+
def exponential(mean = 1)
|
42
|
+
raise 'Mean must be positive' if mean <= 0
|
43
|
+
-1.0 * mean * Math.log(uniform)
|
44
|
+
end
|
45
|
+
|
46
|
+
# Implementation based on "A Simple Method for Generating Gamma Variables"
|
47
|
+
# by George Marsaglia and Wai Wan Tsang. ACM Transactions on Mathematical Software
|
48
|
+
# Vol 26, No 3, September 2000, pages 363-372.
|
49
|
+
def gamma(shape, scale)
|
50
|
+
if shape >= 1.0
|
51
|
+
d = shape - 1.0 / 3.0
|
52
|
+
c = 1 / ((9 * d) ** 0.5)
|
53
|
+
while true
|
54
|
+
v = 0.0
|
55
|
+
while v <= 0.0
|
56
|
+
x = normal
|
57
|
+
v = 1.0 + c * x
|
58
|
+
end
|
59
|
+
v = v ** 3
|
60
|
+
u = uniform
|
61
|
+
if u < (1.0 - 0.0331 * (x ** 4)) || Math.log(u) < (0.5 * (x ** 2) + d * (1.0 - v + Math.log(v)))
|
62
|
+
return scale * d * v
|
63
|
+
end
|
64
|
+
end
|
65
|
+
elsif shape <= 0.0
|
66
|
+
raise 'Shape must be positive'
|
67
|
+
else
|
68
|
+
g = gamma(shape + 1.0, 1.0)
|
69
|
+
w = uniform
|
70
|
+
return scale * g * (w ** (1.0 / shape))
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def chi_square(degrees_of_freedom)
|
75
|
+
gamma(0.5 * degrees_of_freedom, 2.0)
|
76
|
+
end
|
77
|
+
|
78
|
+
def inverse_gamma(shape, scale)
|
79
|
+
1.0 / gamma(shape, 1.0 / scale)
|
80
|
+
end
|
81
|
+
|
82
|
+
def beta(a, b)
|
83
|
+
u = gamma(a, 1)
|
84
|
+
v = gamma(b, 1)
|
85
|
+
u / (u + v)
|
86
|
+
end
|
87
|
+
|
88
|
+
def weibull(shape, scale)
|
89
|
+
raise 'Shape and scale must be positive' if shape <= 0.0 || scale <= 0.0
|
90
|
+
|
91
|
+
scale * ((-Math.log(uniform)) ** (1.0 / shape))
|
92
|
+
end
|
93
|
+
|
94
|
+
def cauchy(median, scale)
|
95
|
+
raise 'Scale must be positive' if scale <= 0
|
96
|
+
|
97
|
+
median + scale * Math.tan(Math::PI * (uniform - 0.5))
|
98
|
+
end
|
99
|
+
|
100
|
+
def student_t(degrees_of_freedom)
|
101
|
+
raise 'Degrees of freedom must be positive' if degrees_of_freedom <= 0
|
102
|
+
|
103
|
+
normal / ((chi_square(degrees_of_freedom) / degrees_of_freedom) ** 0.5)
|
104
|
+
end
|
105
|
+
|
106
|
+
def laplace(mean, scale)
|
107
|
+
u = uniform
|
108
|
+
mean + Math.log(2) + ((u < 0.5 ? 1 : -1) * scale * Math.log(u < 0.5 ? u : 1 - u))
|
109
|
+
end
|
110
|
+
|
111
|
+
def log_normal(mu, sigma)
|
112
|
+
Math.exp(normal(mu, sigma))
|
113
|
+
end
|
114
|
+
|
115
|
+
private
|
116
|
+
|
117
|
+
# This is the heart of the generator.
|
118
|
+
# It uses George Marsaglia's MWC algorithm to produce an unsigned integer.
|
119
|
+
# See http://www.bobwheeler.com/statistics/Password/MarsagliaPost.txt
|
120
|
+
def get_unsigned_int
|
121
|
+
@m_z = 36969 * (@m_z & 65535) + (@m_z >> 16);
|
122
|
+
@m_w = 18000 * (@m_w & 65535) + (@m_w >> 16);
|
123
|
+
((@m_z << 16) + (@m_w & 65535)) % 4294967296
|
124
|
+
end
|
125
|
+
|
126
|
+
def gamma_function(x)
|
127
|
+
g = [
|
128
|
+
1.0,
|
129
|
+
0.5772156649015329,
|
130
|
+
-0.6558780715202538,
|
131
|
+
-0.420026350340952e-1,
|
132
|
+
0.1665386113822915,
|
133
|
+
-0.421977345555443e-1,
|
134
|
+
-0.9621971527877e-2,
|
135
|
+
0.7218943246663e-2,
|
136
|
+
-0.11651675918591e-2,
|
137
|
+
-0.2152416741149e-3,
|
138
|
+
0.1280502823882e-3,
|
139
|
+
-0.201348547807e-4,
|
140
|
+
-0.12504934821e-5,
|
141
|
+
0.1133027232e-5,
|
142
|
+
-0.2056338417e-6,
|
143
|
+
0.6116095e-8,
|
144
|
+
0.50020075e-8,
|
145
|
+
-0.11812746e-8,
|
146
|
+
0.1043427e-9,
|
147
|
+
0.77823e-11,
|
148
|
+
-0.36968e-11,
|
149
|
+
0.51e-12,
|
150
|
+
-0.206e-13,
|
151
|
+
-0.54e-14,
|
152
|
+
0.14e-14
|
153
|
+
]
|
154
|
+
|
155
|
+
r = 1.0
|
156
|
+
|
157
|
+
return 1e308 if x > 171.0
|
158
|
+
if x.is_a?(Fixnum) || x == x.to_i
|
159
|
+
if x > 0
|
160
|
+
ga = (2...x).inject(1.0) { |prod, i| prod * i }
|
161
|
+
else
|
162
|
+
1e308
|
163
|
+
end
|
164
|
+
else
|
165
|
+
if x.abs > 1.0
|
166
|
+
r = (1..(x.abs.to_i)).inject(1.0) { |prod, i| prod * (x.abs - i) }
|
167
|
+
z = x.abs - x.abs.to_i
|
168
|
+
else
|
169
|
+
z = x
|
170
|
+
end
|
171
|
+
|
172
|
+
gr = g[24]
|
173
|
+
23.downto(0).each do |i|
|
174
|
+
gr = gr * z + g[i]
|
175
|
+
end
|
176
|
+
ga = 1.0 / (gr * z)
|
177
|
+
if x.abs > 1
|
178
|
+
ga *= r
|
179
|
+
if x < 0
|
180
|
+
ga = -Math::PI / (x * ga * Math.sin(Math::PI * x))
|
181
|
+
end
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
185
|
+
ga
|
186
|
+
end
|
187
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = %q{simple-random}
|
8
|
+
s.version = "0.9.0"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["John D. Cook", "Jason Adams"]
|
12
|
+
s.date = %q{2010-07-24}
|
13
|
+
s.description = %q{Simple Random Number Generator including Beta, Cauchy, Chi square, Exponential, Gamma, Inverse Gamma, Laplace (double exponential), Normal, Student t, Uniform, and Weibull. Ported from John D. Cook's C# Code.}
|
14
|
+
s.email = %q{jasonmadams@gmail.com}
|
15
|
+
s.extra_rdoc_files = [
|
16
|
+
"LICENSE",
|
17
|
+
"README.rdoc"
|
18
|
+
]
|
19
|
+
s.files = [
|
20
|
+
".document",
|
21
|
+
".gitignore",
|
22
|
+
"LICENSE",
|
23
|
+
"README.rdoc",
|
24
|
+
"Rakefile",
|
25
|
+
"VERSION",
|
26
|
+
"lib/simple-random.rb",
|
27
|
+
"simple-random.gemspec",
|
28
|
+
"test/helper.rb",
|
29
|
+
"test/test_simple_random.rb"
|
30
|
+
]
|
31
|
+
s.homepage = %q{http://github.com/ealdent/simple-random}
|
32
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
33
|
+
s.require_paths = ["lib"]
|
34
|
+
s.rubygems_version = %q{1.3.7}
|
35
|
+
s.summary = %q{Simple Random Number Generator}
|
36
|
+
s.test_files = [
|
37
|
+
"test/helper.rb",
|
38
|
+
"test/test_simple_random.rb"
|
39
|
+
]
|
40
|
+
|
41
|
+
if s.respond_to? :specification_version then
|
42
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
43
|
+
s.specification_version = 3
|
44
|
+
|
45
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
46
|
+
s.add_development_dependency(%q<shoulda>, [">= 0"])
|
47
|
+
else
|
48
|
+
s.add_dependency(%q<shoulda>, [">= 0"])
|
49
|
+
end
|
50
|
+
else
|
51
|
+
s.add_dependency(%q<shoulda>, [">= 0"])
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
data/test/helper.rb
ADDED
@@ -0,0 +1,93 @@
|
|
1
|
+
# TODO: use Kolmogorov-Smirnov test instead: http://en.wikipedia.org/wiki/Kolmogorov_Smirnov
|
2
|
+
|
3
|
+
require 'helper'
|
4
|
+
|
5
|
+
SAMPLE_SIZE = 10000
|
6
|
+
MAXIMUM_EPSILON = 0.01
|
7
|
+
|
8
|
+
def generate_numbers(generator, distribution, *args)
|
9
|
+
(1..SAMPLE_SIZE).map { generator.send(distribution.to_sym, *args) }
|
10
|
+
end
|
11
|
+
|
12
|
+
class Array
|
13
|
+
def mean
|
14
|
+
if size > 0
|
15
|
+
inject(0.0) { |sum, i| sum + i } / size.to_f
|
16
|
+
else
|
17
|
+
0.0
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def standard_deviation
|
22
|
+
if size > 1
|
23
|
+
m = mean
|
24
|
+
(inject(0.0) { |sum, i| sum + ((i - m) ** 2) } / (size - 1).to_f) ** 0.5
|
25
|
+
else
|
26
|
+
1.0
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
class TestSimpleRandom < Test::Unit::TestCase
|
32
|
+
context "A simple random number generator" do
|
33
|
+
setup do
|
34
|
+
@r = SimpleRandom.new
|
35
|
+
end
|
36
|
+
|
37
|
+
should "generate random numbers from a uniform distribution in the interval (0, 1)" do
|
38
|
+
SAMPLE_SIZE.times do
|
39
|
+
u = @r.uniform
|
40
|
+
assert u < 1
|
41
|
+
assert u > 0
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
should "generate uniformly random numbers with mean approximately 0.5" do
|
46
|
+
numbers = generate_numbers(@r, :uniform)
|
47
|
+
epsilon = (0.5 - numbers.mean).abs
|
48
|
+
|
49
|
+
assert epsilon < MAXIMUM_EPSILON
|
50
|
+
end
|
51
|
+
|
52
|
+
should "generate random numbers from a normal distribution with mean approximately 0" do
|
53
|
+
numbers = generate_numbers(@r, :normal)
|
54
|
+
epsilon = (0.0 - numbers.mean).abs
|
55
|
+
|
56
|
+
assert epsilon < MAXIMUM_EPSILON
|
57
|
+
end
|
58
|
+
|
59
|
+
should "generate random numbers from a normal distribution with sample standard deviation approximately 1" do
|
60
|
+
numbers = generate_numbers(@r, :normal)
|
61
|
+
epsilon = (1.0 - numbers.standard_deviation).abs
|
62
|
+
|
63
|
+
assert epsilon < MAXIMUM_EPSILON
|
64
|
+
end
|
65
|
+
|
66
|
+
should "generate random numbers from an exponential distribution with mean approximately 1" do
|
67
|
+
numbers = generate_numbers(@r, :exponential)
|
68
|
+
epsilon = (1.0 - numbers.mean).abs
|
69
|
+
|
70
|
+
assert epsilon < MAXIMUM_EPSILON
|
71
|
+
end
|
72
|
+
|
73
|
+
should "generate a random number sampled from a gamma distribution" do
|
74
|
+
assert @r.gamma(5, 2.3)
|
75
|
+
end
|
76
|
+
|
77
|
+
should "generate a random number sampled from an inverse gamma distribution" do
|
78
|
+
assert @r.inverse_gamma(5, 2.3)
|
79
|
+
end
|
80
|
+
|
81
|
+
should "generate a random number sampled from a beta distribution" do
|
82
|
+
assert @r.beta(5, 2.3)
|
83
|
+
end
|
84
|
+
|
85
|
+
should "generate a random number sampled from a chi-square distribution" do
|
86
|
+
assert @r.chi_square(10)
|
87
|
+
end
|
88
|
+
|
89
|
+
should "generate a random number using weibull" do
|
90
|
+
assert @r.weibull(5, 2.3)
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
metadata
ADDED
@@ -0,0 +1,92 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: simple-random
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 59
|
5
|
+
prerelease: false
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 9
|
9
|
+
- 0
|
10
|
+
version: 0.9.0
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- John D. Cook
|
14
|
+
- Jason Adams
|
15
|
+
autorequire:
|
16
|
+
bindir: bin
|
17
|
+
cert_chain: []
|
18
|
+
|
19
|
+
date: 2010-07-24 00:00:00 -04:00
|
20
|
+
default_executable:
|
21
|
+
dependencies:
|
22
|
+
- !ruby/object:Gem::Dependency
|
23
|
+
name: shoulda
|
24
|
+
prerelease: false
|
25
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
26
|
+
none: false
|
27
|
+
requirements:
|
28
|
+
- - ">="
|
29
|
+
- !ruby/object:Gem::Version
|
30
|
+
hash: 3
|
31
|
+
segments:
|
32
|
+
- 0
|
33
|
+
version: "0"
|
34
|
+
type: :development
|
35
|
+
version_requirements: *id001
|
36
|
+
description: Simple Random Number Generator including Beta, Cauchy, Chi square, Exponential, Gamma, Inverse Gamma, Laplace (double exponential), Normal, Student t, Uniform, and Weibull. Ported from John D. Cook's C# Code.
|
37
|
+
email: jasonmadams@gmail.com
|
38
|
+
executables: []
|
39
|
+
|
40
|
+
extensions: []
|
41
|
+
|
42
|
+
extra_rdoc_files:
|
43
|
+
- LICENSE
|
44
|
+
- README.rdoc
|
45
|
+
files:
|
46
|
+
- .document
|
47
|
+
- .gitignore
|
48
|
+
- LICENSE
|
49
|
+
- README.rdoc
|
50
|
+
- Rakefile
|
51
|
+
- VERSION
|
52
|
+
- lib/simple-random.rb
|
53
|
+
- simple-random.gemspec
|
54
|
+
- test/helper.rb
|
55
|
+
- test/test_simple_random.rb
|
56
|
+
has_rdoc: true
|
57
|
+
homepage: http://github.com/ealdent/simple-random
|
58
|
+
licenses: []
|
59
|
+
|
60
|
+
post_install_message:
|
61
|
+
rdoc_options:
|
62
|
+
- --charset=UTF-8
|
63
|
+
require_paths:
|
64
|
+
- lib
|
65
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
66
|
+
none: false
|
67
|
+
requirements:
|
68
|
+
- - ">="
|
69
|
+
- !ruby/object:Gem::Version
|
70
|
+
hash: 3
|
71
|
+
segments:
|
72
|
+
- 0
|
73
|
+
version: "0"
|
74
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
75
|
+
none: false
|
76
|
+
requirements:
|
77
|
+
- - ">="
|
78
|
+
- !ruby/object:Gem::Version
|
79
|
+
hash: 3
|
80
|
+
segments:
|
81
|
+
- 0
|
82
|
+
version: "0"
|
83
|
+
requirements: []
|
84
|
+
|
85
|
+
rubyforge_project:
|
86
|
+
rubygems_version: 1.3.7
|
87
|
+
signing_key:
|
88
|
+
specification_version: 3
|
89
|
+
summary: Simple Random Number Generator
|
90
|
+
test_files:
|
91
|
+
- test/helper.rb
|
92
|
+
- test/test_simple_random.rb
|