simple-random 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
data/.document ADDED
@@ -0,0 +1,5 @@
1
+ README.rdoc
2
+ lib/**/*.rb
3
+ bin/*
4
+ features/**/*.feature
5
+ LICENSE
data/.gitignore ADDED
@@ -0,0 +1,21 @@
1
+ ## MAC OS
2
+ .DS_Store
3
+
4
+ ## TEXTMATE
5
+ *.tmproj
6
+ tmtags
7
+
8
+ ## EMACS
9
+ *~
10
+ \#*
11
+ .\#*
12
+
13
+ ## VIM
14
+ *.swp
15
+
16
+ ## PROJECT::GENERAL
17
+ coverage
18
+ rdoc
19
+ pkg
20
+
21
+ ## PROJECT::SPECIFIC
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&#39;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&#39; 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,10 @@
1
+ require 'rubygems'
2
+ require 'test/unit'
3
+ require 'shoulda'
4
+
5
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
6
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
7
+ require 'simple-random'
8
+
9
+ class Test::Unit::TestCase
10
+ end
@@ -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