source: project/wiki/eggref/4/srfi-27 @ 35482

Last change on this file since 35482 was 35482, checked in by Kon Lovett, 17 months ago

forgot mathh dep

File size: 31.5 KB
Line 
1[[tags: egg]]
2
3== SRFI 27
4
5Source of Random Bits
6
7[[toc:]]
8
9
10== Documentation
11
12A Chicken implementation of [[http://srfi.schemers.org/srfi-27/srfi-27.html|SRFI 27]].
13
14=== SRFI 27
15
16Most procedures are per the SRFI 27 specification document. Only the extensions
17are documented here.
18
19The most obvious extensions are support for multiple random number generators
20and multiple entropy sources.
21
22==== Usage
23
24<enscript language=scheme>
25(use srfi-27)
26</enscript>
27
28==== current-random-source
29
30<procedure>(current-random-source [RANDOM-SOURCE])</procedure>
31
32Parameter for the default {{random-source}}.
33
34The variable {{default-random-source}} is the initial {{(current-random-source)}}.
35
36The initial {{random-source}} is an instance of {{'mrg32k3a}}, per SRFI 27.
37
38==== random-integer/current
39
40<procedure>(random-integer/current) -> (procedure (integer) integer)</procedure>
41
42Returns an {{integer}} random generator from the {{(current-random-source)}}.
43
44Like {{random-integer}} but w/ {{(current-random-source)}}, & a {{procedure}},
45not a {{variable}}.
46
47==== random-real/current
48
49<procedure>(random-real/current) -> (procedure () real)</procedure>
50
51Returns a {{real}} random generator from the {{(current-random-source)}}.
52
53Like {{random-real}} but w/ {{(current-random-source)}}, & a {{procedure}},
54not a {{variable}}.
55
56==== registered-random-sources
57
58<procedure>(registered-random-sources) -> (list-of symbol)</procedure>
59
60Returns a {{list}} of the registered {{random-source}} names.
61
62==== registered-random-source
63
64<procedure>(registered-random-source NAME) -> (disjoint #f (procedure () random-source))</procedure>
65
66Returns the {{random-source}} creator for the specified {{NAME}} or {{#f}} if
67not registered.
68
69==== random-source?
70
71<procedure>(random-source? OBJ) -> boolean</procedure>
72
73{{random-source}} predicate.
74
75<procedure>(check-random-source LOC OBJ [NAM])</procedure>
76
77Raise error when {{OBJ}} not a {{random-source}}. {{NAM}} is the optional
78parameter name.
79
80<procedure>(error-random-source LOC OBJ [NAM])</procedure>
81
82Raise error for {{OBJ}} not a {{random-source}}. {{NAM}} is the optional
83parameter name.
84
85==== make-random-source
86
87<procedure>(make-random-source [SOURCE (current-random-source)]) -> random-source</procedure>
88
89{{SOURCE}} is either a {{random-source}} or the {{symbol}} of a registered
90{{random-source}}, the name.
91
92==== new-random-source
93
94<procedure>(new-random-source [RANDOM-SOURCE (current-random-source)]) -> random-source</procedure>
95
96Same as {{(make-random-source RANDOM-SOURCE)}}.
97
98==== random-source-name
99
100<procedure>(random-source-name RANDOM-SOURCE) -> symbol</procedure>
101
102The symbolic name of the {{RANDOM-SOURCE}}.
103
104==== random-source-documentation
105
106<procedure>(random-source-documentation RANDOM-SOURCE) -> string</procedure>
107
108Some more information for the {{RANDOM-SOURCE}}.
109
110==== random-source-log2-period
111
112<procedure>(random-source-log2-period RANDOM-SOURCE) -> integer</procedure>
113
114The period of the {{RANDOM-SOURCE}} as a power of 2. A {{fixnum}}.
115
116==== random-source-maximum-range
117
118<procedure>(random-source-maximum-range RANDOM-SOURCE) -> inexact-integer</procedure>
119
120The largest integer the {{RANDOM-SOURCE}} can produce without resort to a
121{{bignum}} representation. Currently an inexact-integer {{flonum}}, even for
12264-bit CPUs.
123
124==== random-source-entropy-source
125
126<procedure>(random-source-entropy-source RANDOM-SOURCE) -> entropy-source</procedure>
127
128The current {{entropy-source}} for the {{RANDOM-SOURCE}}.
129
130==== random-source-entropy-source-set!
131
132<procedure>(random-source-entropy-source-set! RANDOM-SOURCE ENTROPY-SOURCE)</procedure>
133
134Changes the current {{entropy-source}} for the {{RANDOM-SOURCE}}.
135
136==== random-source-state-ref
137
138<procedure>(random-source-state-ref RANDOM-SOURCE) -> random-state</procedure>
139
140Per the SRFI 27 specification the {{random-state}} is a valid external
141representation of {{RANDOM-SOURCE}} state.
142
143==== random-source-state-set!
144
145<procedure>(random-source-state-set! RANDOM-SOURCE RANDOM-STATE)</procedure>
146
147Only a {{RANDOM-STATE}} produced by a {{random-source-state-ref}} of the same
148{{random-source}} is acceptable.
149
150==== random-source-randomize!
151
152<procedure>(random-source-randomize! RANDOM-SOURCE [ENTROPY-SOURCE])</procedure>
153
154==== random-source-pseudo-randomize!
155
156<procedure>(random-source-pseudo-randomize! RANDOM-SOURCE I J)</procedure>
157
158==== random-source-make-integers
159
160<procedure>(random-source-make-integers RANDOM-SOURCE) -> (procedure (integer) integer)</procedure>
161
162The result is a {{procedure}}: {{(random-source-make-integers RANDOM-SOURCE)}}
163
164==== random-source-make-reals
165
166<procedure>(random-source-make-reals RANDOM-SOURCE [PRECISION]) -> (procedure () real)</procedure>
167
168The result is a {{procedure}}: {{(random-source-make-reals RANDOM-SOURCE PRECISION)}}
169
170{{PRECISION}} maybe {{#f}}, in which case the value is {{flonum-epsilon}}.
171
172==== random-source-make-u8vectors
173
174<procedure>(random-source-make-u8vectors RANDOM-SOURCE) -> (procedure (integer) u8vector)</procedure>
175
176Returns a {{procedure}} of one argument, the length of the generated vector,
177the returns a vector of random 8-bit unsigned values, a SRFI 4 {{u8vector}}.
178
179The variable {{random-u8vector}} is a {{procedure}}:
180{{(random-source-make-u8vectors default-random-source)}}
181
182==== random-source-make-f64vectors
183
184<procedure>(random-source-make-f64vectors RANDOM-SOURCE [PRECISION]) -> (procedure (integer) f64vector)</procedure>
185
186Returns a {{procedure}} of one argument, the length of the generated vector,
187the returns a vector of random 64-bit floating-point values, a SRFI 4 {{f64vector}}.
188
189The variable {{random-f64vector}} is a {{procedure}}:
190{{(random-source-make-f64vectors default-random-source)}}
191
192==== current-entropy-source
193
194<procedure>(current-entropy-source [ENTROPY-SOURCE])</procedure>
195
196Parameter for the default {{entropy-source}}.
197
198{{default-entropy-source}} is the initial {{(current-entropy-source)}}.
199
200The initial {{entropy-source}} is an instance of {{'system-clock}}.
201
202==== registered-entropy-sources
203
204<procedure>(registered-entropy-sources) -> (list-of symbol)</procedure>
205
206Returns a {{list}} of the registered {{entropy-source}} names.
207
208==== registered-entropy-source
209
210<procedure>(registered-entropy-source NAME) -> (or boolean procedure)</procedure>
211
212Returns the {{entropy-source}} creator for the specified {{NAME}} or {{#f}} if not
213registered.
214
215==== entropy-source?
216
217<procedure>(entropy-source? OBJ) -> boolean</procedure>
218
219{{entropy-source}} predicate.
220
221<procedure>(check-entropy-source LOC OBJ [NAM])</procedure>
222
223Raise error when {{OBJ}} not an {{entropy-source}}. {{NAM}} is the optional
224parameter name.
225
226<procedure>(error-entropy-source LOC OBJ [NAM])</procedure>
227
228Raise error for {{OBJ}} not an {{entropy-source}}. {{NAM}} is the optional
229parameter name.
230
231==== make-entropy-source
232
233<procedure>(make-entropy-source [SOURCE (current-entropy-source)]) -> entropy-source</procedure>
234
235{{SOURCE}} is either a {{entropy-source}} or the {{symbol}} of a registered
236{{entropy-source}}, the name.
237
238==== new-entropy-source
239
240<procedure>(new-entropy-source ENTROPY-SOURCE) -> entropy-source</procedure>
241
242Same as {{(make-random-entropy ENTROPY-SOURCE)}}.
243
244==== entropy-source-name
245
246<procedure>(entropy-source-name ENTROPY-SOURCE) -> symbol</procedure>
247
248The symbolic name of the {{ENTROPY-SOURCE}}.
249
250==== entropy-source-documentation
251
252<procedure>(entropy-source-documentation ENTROPY-SOURCE) -> string</procedure>
253
254Some more information for the {{ENTROPY-SOURCE}}.
255
256==== entropy-source-u8
257
258<procedure>(entropy-source-u8 ENTROPY-SOURCE) -> fixnum</procedure>
259
260Returns a non-negative {{fixnum}} from the {{ENTROPY-SOURCE}}.
261
262==== entropy-source-f64
263
264<procedure>(entropy-source-f64 ENTROPY-SOURCE) -> flonum</procedure>
265
266Returns a {{flonum}} from the {{ENTROPY-SOURCE}}.
267
268==== entropy-source-u8vector
269
270<procedure>(entropy-source-u8vector ENTROPY-SOURCE LENGTH [U8VECTOR]) -> u8vector</procedure>
271
272Returns a {{u8vector}} with the 0 thru {{LENGTH-1}} elements filled with non-negative
273{{fixnum}}s from the {{ENTROPY-SOURCE}}. If {{U8VECTOR}} is supplied then this
274is used otherwise a new vector is returned.
275
276==== entropy-source-f64vector
277
278<procedure>(entropy-source-f64vector ENTROPY-SOURCE LENGTH [F64VECTOR]) -> f64vector</procedure>
279
280Returns a {{f64vector}} with the 0 thru {{LENGTH-1}} elements filled with
281{{flonum}}s from the {{ENTROPY-SOURCE}}. If {{F64VECTOR}} is supplied then this
282is used otherwise a new vector is returned.
283
284==== entropy-source-integer
285
286<procedure>(entropy-source-integer ENTROPY-SOURCE) -> integer</procedure>
287
288Returns an {{integer}} from the {{ENTROPY-SOURCE}}.
289
290
291=== Random Sources
292
293A random source module must be loaded before it can be used. This maybe obvious
294but a call of {{(make-random-source 'moa)}} will fail unless the extension
295"moa" is loaded.
296
297See {{make-random-source}} for use of the {{NAME}}.
298
299==== Pierre L'Ecuyer's Multiple Recursive Generator 32k3a random number generator
300
301===== Usage
302
303<enscript language=scheme>
304(use mrg32k3a)
305</enscript>
306
307===== make-random-source-mrg32k3a
308
309<procedure>(make-random-source-mrg32k3a) -> random-source</procedure>
310
311Registered {{NAME}} is {{'mrg32k3a}}
312
313==== George Marsaglia's Multiply With Carry random number generator
314
315===== Usage
316
317<enscript language=scheme>
318(use mwc)
319</enscript>
320
321===== make-random-source-mwc
322
323<procedure>(make-random-source-mwc) -> random-source</procedure>
324
325Registered {{NAME}} is {{'mwc}}
326
327==== George Marsaglia's Mother Of All random number generator
328
329===== Usage
330
331<enscript language=scheme>
332(use moa)
333</enscript>
334
335===== make-random-source-moa
336
337<procedure>(make-random-source-moa) -> random-source</procedure>
338
339Registered {{NAME}} is {{'moa}}
340
341
342=== Entropy Sources
343
344An entropy source module must be loaded before it can be used.
345
346==== System Clock
347
348===== Usage
349
350<enscript language=scheme>
351(use entropy-clock)
352</enscript>
353
354===== make-entropy-source-system-clock
355
356<procedure>(make-entropy-source-system-clock) -> entropy-source</procedure>
357
358Registered {{NAME}} is {{'system-clock}}
359
360==== Windows Crypt Device
361
362===== Usage
363
364<enscript language=scheme>
365(use entropy-windows)
366</enscript>
367
368===== make-entropy-source-crypt
369
370<procedure>(make-entropy-source-crypt [BUFFER-LENGTH]) -> entropy-source</procedure>
371
372Registered {{NAME}} is {{'crypt}}
373
374==== Unix Random Device
375
376===== Usage
377
378<enscript language=scheme>
379(use entropy-unix)
380</enscript>
381
382===== make-entropy-source-urandom-device
383
384<procedure>(make-entropy-source-urandom-device) -> entropy-source</procedure>
385
386Registered {{NAME}} is {{'random-device}}
387
388===== make-entropy-source-random-device
389
390<procedure>(make-entropy-source-random-device) -> entropy-source</procedure>
391
392Registered {{NAME}} is {{'urandom-device}}
393
394
395=== Procedure Entropy Source
396
397{{U8PROC}} is a procedure of no arguments returning a {{fixnum}} in the range
398{{0 .. 255}}.
399
400{{F64PROC}} is a procedure of no arguments returning a finite {{flonum}}.
401
402==== Usage
403
404<enscript language=scheme>
405(use entropy-procedure)
406</enscript>
407
408==== make-entropy-source/procedures
409
410<procedure>(make-entropy-source/procedures U8PROC F64PROC [name: (NAME (gensym 'procedures-))] [docu: (DOCU "Entropy from procedures")]) -> entropy-source</procedure>
411
412Returns an unregistered {{entropy-source}} built from the supplied {{U8PROC}}
413and {{F64PROC}} procedures.
414
415==== make-entropy-source/f64procedure
416
417<procedure>(make-entropy-source/f64procedure F64PROC [name: (NAME (gensym 'procedures-))] [docu: (DOCU "Entropy from procedures")]) -> entropy-source</procedure>
418
419Returns an unregistered {{entropy-source}} built from the supplied {{F64PROC}}
420procedure.
421
422
423=== Port Entropy Source
424
425==== Usage
426
427<enscript language=scheme>
428(use entropy-port)
429</enscript>
430
431==== entropy-port-lifetime
432
433<parameter>(entropy-port-lifetime [SECONDS])</parameter>
434
435The number of {{SECONDS}} an entropy port is kept open without any activity.
436
437{{SECONDS}} is a {{positive real}} or a {{boolean}}: {{#t}}, to reset the default
438seconds, or {{#f}}, to determine the lifetime by GC finalization.
439
440==== make-entropy-source/port
441
442<procedure>(make-entropy-source/port PORT [name: (NAME (gensym 'port-))] [docu: (DOCU "Entropy from an open port")]) -> entropy-source</procedure>
443
444Returns an unregistered {{entropy-source}} built from the supplied {{PORT}},
445which is treated as a binary stream.
446
447The {{PORT}} is kept open and must be closed by the caller, if at all.
448
449==== make-entropy-source/port-open
450
451<procedure>(make-entropy-source/port-open OPENER [name: (NAME (gensym 'port-))] [docu: (DOCU "Entropy from port")]) -> entropy-source</procedure>
452
453Returns an unregistered {{entropy-source}} built from the supplied {{OPENER}}.
454
455{{OPENER}} is a {{(procedure () port)}}, returning an opened {{port}}.
456
457The returned {{port}} has an {{(entropy-port-lifetime)}} so the {{port}} may be
458closed and {{OPENER}} called more than once.
459
460==== make-entropy-source/port-open-timed
461
462<procedure>(make-entropy-source/port-open-timed OPENER SECONDS [name: (NAME (gensym 'timed-port-))] [docu: (DOCU "Entropy from timed open port")]) -> entropy-source</procedure>
463
464Returns an unregistered {{entropy-source}} built from the supplied {{OPENER}} &
465{{SECONDS}}.
466
467{{SECONDS}} is interpreted as with {{entropy-port-lifetime}}.
468
469{{OPENER}} is interpreted as with {{make-entropy-source/port-open}}.
470
471==== make-entropy-source/file
472
473<procedure>(make-entropy-source/file NAMSTR [name: (NAME (gensym 'file-))] [docu: (DOCU (string-append "Entropy from file \"" namstr "\""))]) -> entropy-source</procedure>
474
475Returns an unregistered {{entropy-source}} using the file named by the pathname
476{{NAMSTR}}.
477
478The opened {{port}} for the file {{NAMSTR}} is interpreted as with
479{{make-entropy-source/port-open}}.
480
481
482=== Simple Distributions
483
484Provides exact and inexact generators. All return 2 values: the generator
485itself and a procedure returning the argument values used to parameterize the
486generator. The second return value can be ignored.
487
488==== Usage
489
490<enscript language=scheme>
491(use srfi-27-uniform-random)
492</enscript>
493
494==== make-uniform-random-integers
495
496<procedure>(make-uniform-random-integers [high: (HIGH #f)] [low: (LOW 0)] [precision: (PRECISION 1)] [source: (SOURCE (current-random-source))]) -> (procedure () integer)</procedure>
497
498{{LOW}}, {{HIGH}} and {{PRECISION}} are {{integer}}s.
499
500{{SOURCE}} is a {{random-source}}.
501
502{{HIGH}}, if not supplied, is the {{(- (random-source-maximum-range source) 1)}}.
503
504The generator returns integers in the range {{LOW .. HIGH}} with an index of
505{{PRECISION}}. Unlike a {{(random-integer)}} result negative integers are
506possible.
507
508{{(random-integer/current)}} <> {{(make-uniform-random-integers)}}.
509{{(random-integer/current)}} returns {{((integer) -> integer)}}.
510{{(make-uniform-random-integers)}} returns {{(() -> integer)}}.
511
512==== make-uniform-random-reals
513
514<procedure>(make-uniform-random-reals [precision: PRECISION] [source: (SOURCE (current-random-source))]) -> (procedure () real)</procedure>
515
516The generator is as {{(random-source-make-reals SOURCE PRECISION)}}.
517
518{{PRECISION}} maybe {{#f}}, in which case the value is {{flonum-epsilon}}.
519
520{{SOURCE}} is a {{random-source}}.
521
522{{(random-real/current)}} = {{(make-uniform-random-reals)}}. Both return
523procedures of {{(() -> real)}}.
524
525=== Vector Distributions
526
527The procedures named as per {{make-random-...}} return a {{procedure}} of one
528argument {{N}}, the length of the vector to be created.
529
530The nomenclature {{vector%}} is used to indicate a disjoint type union of
531{{vector, f32vector, f64vector}}. If the user is really keen to access the API
532for this type it is available in the, undocumented, "srfi-27-vector-support"
533module.
534
535==== Usage
536
537<enscript language=scheme>
538(use srfi-27-vector)
539</enscript>
540
541==== make-random-permutations
542==== random-permutation!
543
544<procedure>(make-random-permutations [randoms: (RANDOMS random-integer/current)]) -> (procedure (integer) vector)</procedure>
545<procedure>(random-permutation! VECTOR [randoms: (RANDOMS random-integer/current)]) -> vector</procedure>
546
547Performs the "Knuth shuffle" (or "Fisher-Yates shuffle").
548
549Fills {{VECTOR}} with a random permutation of the finite set {0 ... {{N}}-1}, where
550{{N}} = {{(vector-length VECTOR)}}.
551
552{{RANDOMS}} is a {{procedure}}: {{(exact-real) -> exact-real}}
553
554(From Gambit)
555
556==== make-random-vector
557==== random-vector!
558
559<procedure>(make-random-vector [randoms: (RANDOMS random-real/current)]) -> (procedure (integer) vector)</procedure>
560<procedure>(random-vector! VECTOR% [randoms: (RANDOMS random-real/current)]) -> vector%</procedure>
561
562Fills {{VECTOR}} with inexact real random numbers from the random distribution
563generator {{randoms}}.
564
565{{RANDOMS}} is a {{procedure}}: {{() -> inexact-real}}
566
567==== make-random-hollow-sphere
568==== random-hollow-sphere!
569
570<procedure>(make-random-hollow-sphere [mu: (MU 0.0)] [sigma: (SIGMA 1.0)] [randoms: (RANDOMS (random-real/current))]) -> (procedure (integer) vector)</procedure>
571<procedure>(random-hollow-sphere! VECTOR% [mu: (MU 0.0)] [sigma: (SIGMA 1.0)] [randoms: (RANDOMS (random-real/current))]) -> vector%</procedure>
572
573Fills {{VECTOR%}} with inexact real random numbers the sum of whose squares
574are equal to {{1.0}}.
575
576Thinking of {{VECTOR%}} as coordinates in space of dimension {{N}} =
577{{(vector%-length VECTOR%)}}, the coordinates are uniformly distributed over
578the surface of the unit n-sphere.
579
580(From Gambit)
581
582==== make-random-solid-sphere
583==== random-solid-sphere!
584
585<procedure>(make-random-solid-sphere [mu: (MU 0.0)] [sigma: (SIGMA 1.0)] [randoms: (RANDOMS (random-real/current))]) -> (procedure (integer) vector)</procedure>
586<procedure>(random-solid-sphere! VECTOR% [mu: (MU 0.0)] [sigma: (SIGMA 1.0)] [randoms: (RANDOMS (random-real/current))]) -> vector%</procedure>
587
588Fills {{VECTOR%}} with inexact real random numbers the sum of whose squares
589are less than {{1.0}}.
590
591Thinking of {{VECTOR%}} as coordinates in space of dimension {{N}} =
592{{(vector%-length VECTOR%)}}, the coordinates are uniformly distributed within
593the unit n-sphere.
594
595(From Gambit)
596
597
598=== Other Distributions
599
600Provides generators for some common distributions ranging over some subset of
601the inexact-reals. The domain of the generators depends, of course, on the
602specific distribution.
603
604All return 2 values: the generator itself and a procedure returning the
605argument values used to parameterize the generator. The second return value can
606be ignored.
607
608The identifiers matching {{*make-random-<distribution>}} are reserved.
609
610==== Usage
611
612<enscript language=scheme>
613(use srfi-27-distributions)
614</enscript>
615
616All distributions are available from the omnibus module
617{{srfi-27-distributions}}, and individually as the {{srfi-27-<distribution>}}
618module.
619
620==== make-random-normals
621
622<procedure>(make-random-normals [mu: (MU 0.0)] [sigma: (SIGMA 1.0)] [randoms: (RANDOMS (random-real/current))]) -> (procedure () real)</procedure>
623
624{{MU}} is {{real}}.
625
626{{SIGMA}} is {{nonzero-real}}.
627
628{{RANDOMS}} is a {{(procedure () real)}}
629
630<enscript language=scheme>
631(use srfi-27-normals)
632</enscript>
633
634==== make-random-exponentials
635
636<procedure>(make-random-exponentials [mu: (MU 1.0)] [randoms: (RANDOMS (random-real/current))]) -> (procedure () real)</procedure>
637
638{{MU}} is {{real}} in [{{0}} {{1}}].
639
640{{RANDOMS}} is a {{(procedure () real)}}
641
642<enscript language=scheme>
643(use srfi-27-exponentials)
644</enscript>
645
646==== make-random-triangles
647
648<procedure>(make-random-triangles [s: (S 0.0)] [m: (M 0.5)] [l: (L 1.0)] [randoms: (RANDOMS (random-real/current))]) -> (procedure () real)</procedure>
649
650{{S}} is {{real}}.
651
652{{M}} is {{real}} in [{{S}} {{L}}].
653
654{{L}} is {{real}} in ]{{S}} {{+inf.0}}[.
655
656{{RANDOMS}} is a {{(procedure () real)}}
657
658<enscript language=scheme>
659(use srfi-27-triangles)
660</enscript>
661
662==== make-random-poissons
663
664<procedure>(make-random-poissons [mu: (MU 1.0)] [randoms: (RANDOMS (random-real/current))]) -> (procedure () integer)</procedure>
665
666{{MU}} is {{nonnegative-real}}.
667
668{{RANDOMS}} is a {{(procedure () real)}}
669
670<enscript language=scheme>
671(use srfi-27-poissons)
672</enscript>
673
674==== make-random-bernoullis
675
676<procedure>(make-random-bernoullis [p: (P 0.5)] [randoms: (RANDOMS (random-real/current))]) -> (procedure () boolean)</procedure>
677
678{{P}} is {{real}} in [{{0}} {{1}}].
679
680{{RANDOMS}} is a {{(procedure () real)}}
681
682<enscript language=scheme>
683(use srfi-27-bernoullis)
684</enscript>
685
686==== make-random-binomials
687
688<procedure>(make-random-binomials [t: (T 1)] [p: (P 0.5)] [randoms: (RANDOMS (random-real/current))]) -> (procedure () integer)</procedure>
689
690{{T}} is {{cardinal-integer}}.
691
692{{P}} is {{real}} in [{{0}} {{1}}].
693
694{{RANDOMS}} is a {{(procedure () real)}}
695
696<enscript language=scheme>
697(use srfi-27-binomials)
698</enscript>
699
700==== make-random-geometrics
701
702<procedure>(make-random-geometrics [p: (P 0.5)] [randoms: (RANDOMS (random-real/current))])) -> (procedure () integer)</procedure>
703
704{{P}} is {{real}} in [{{0}} {{1}}].
705
706{{RANDOMS}} is a {{(procedure () real)}}
707
708<enscript language=scheme>
709(use srfi-27-geometrics)
710</enscript>
711
712==== make-random-lognormals
713
714<procedure>(make-random-lognormals [mu: (MU 1.0)] [sigma: (SIGMA 1.0)] [randoms: (RANDOMS (random-real/current))]) -> (procedure () real)</procedure>
715
716{{MU}} is {{nonzero-real}}.
717
718{{SIGMA}} is {{nonnegative-real}}.
719
720{{RANDOMS}} is a {{(procedure () real)}}
721
722<enscript language=scheme>
723(use srfi-27-lognormals)
724</enscript>
725
726==== make-random-cauchys
727
728<procedure>(make-random-cauchys [median: (MEDIAN 0.0)] [sigma: (SIGMA 1.0)] [randoms: (RANDOMS (random-real/current))]) -> (procedure () real)</procedure>
729
730{{MEDIAN}} is {{real}}.
731
732{{SIGMA}} is {{positive-real}}.
733
734{{RANDOMS}} is a {{(procedure () real)}}
735
736<enscript language=scheme>
737(use srfi-27-cauchys)
738</enscript>
739
740==== make-random-gammas
741
742<procedure>(make-random-gammas [alpha: (ALPHA 1.0)] [theta: (THETA 1.0)] [randoms: (RANDOMS (random-real/current))]) -> (procedure () real)</procedure>
743
744{{ALPHA}} is {{positive-real}}.
745
746{{THETA}} is {{positive-real}}.
747
748{{RANDOMS}} is a {{(procedure () real)}}
749
750<enscript language=scheme>
751(use srfi-27-gammas)
752</enscript>
753
754==== make-random-erlangs
755
756<procedure>(make-random-erlangs [alpha: (ALPHA 1)] [theta: (THETA 1.0)] [randoms: (RANDOMS (random-real/current))]) -> (procedure () real)</procedure>
757
758{{ALPHA}} is {{positive-real}}.
759
760{{THETA}} is {{positive-real}}.
761
762{{RANDOMS}} is a {{(procedure () real)}}
763
764<enscript language=scheme>
765(use srfi-27-erlangs)
766</enscript>
767
768==== make-random-paretos
769
770<procedure>(make-random-paretos [alpha: (ALPHA 1.0)] [xmin: (XMIN 1.0)] [randoms: (RANDOMS (random-real/current))]) -> (procedure () real)</procedure>
771
772{{ALPHA}} is {{positive-real}}.
773
774{{XMIN}} is {{positive-real}}.
775
776{{RANDOMS}} is a {{(procedure () real)}}
777
778<enscript language=scheme>
779(use srfi-27-paretos)
780</enscript>
781
782==== make-random-levys
783
784<procedure>(make-random-levys [gamma: (GAMMA 1.0)] [delta: (DELTA 0.0)] [randoms: (RANDOMS (random-real/current))]) -> (procedure () real)</procedure>
785
786{{GAMMA}} is {{nonnegative-real}}.
787
788{{DELTA}} is {{positive-real}}.
789
790{{RANDOMS}} is a {{(procedure () real)}}
791
792<enscript language=scheme>
793(use srfi-27-levys)
794</enscript>
795
796==== make-random-weibulls
797
798<procedure>(make-random-weibulls [shape: (SHAPE 1.0)] [scale: (SCALE 1.0)] [randoms: (RANDOMS (random-real/current))]) -> (procedure () real)</procedure>
799
800{{SHAPE}} is {{positive-real}}.
801
802{{SCALE}} is {{positive-real}}.
803
804{{RANDOMS}} is a {{(procedure () real)}}
805
806<enscript language=scheme>
807(use srfi-27-weibulls)
808</enscript>
809
810
811== Examples
812
813* A procedure for creating K-vector (whatever that is) generators. The use of
814George Marsaglia's Multiply With Carry {{random-source}} and the "/dev/random"
815{{entropy-source}} are for exposition only.
816
817<enscript language=scheme>
818(use srfi-27 srfi-27-uniform-random srfi-27-vector mwc entropy-unix entropy-port)
819
820(define (make-random-k-vector #!optional (k 1024) (rs (make-random-source 'mwc)) es)
821  (let (
822    (new-es
823      (or
824        es
825        ;don't keep open port around too much
826        (parameterize ((entropy-port-lifetime 30))
827          (make-entropy-source-random-device))))
828    (old-es
829      (random-source-entropy-source rs)) )
830    (dynamic-wind
831      (lambda ()
832        (random-source-entropy-source-set! rs new-es) )
833      (lambda ()
834        (let* (
835          (rnd (make-uniform-random-integers low: (- k) high: (+ k) precision: 2 source: rs))
836          (vecgen (make-random-vector randoms: rnd)) )
837          (lambda (#!optional (k k)) (vecgen k)) ) )
838      (lambda ()
839        (random-source-entropy-source-set! rs old-es) ) ) ) )
840</enscript>
841
842* Providing a fixed entropy-source, a constant seed.
843
844<enscript language=scheme>
845(use data-structures entropy-procedure)
846
847(define (make-entropy-constant n)
848  (make-entropy-source/f64procedure
849    (constantly (exact->inexact n))
850    name: (string->uninterned-symbol (conc "entropy-constant-" n))
851    docu: (conc "Entropy constant " n)) )
852</enscript>
853
854* A silly OO version of a random distribution generator
855
856<enscript language=scheme>
857(use srfi-1 srfi-13)
858(use coops)
859(use srfi-27-normals srfi-27-exponentials)
860
861;; Named (has a name) "concept"
862(define-generic (name obj))
863(define-class <named> () (
864  (namsym reader: name) ) )
865
866;; Parameterized extension "concept"
867(define-class <parameterized> () (ctor params src))
868
869;; Moves forward thru a set of values "concept"
870(define-generic (next-value obj))
871(define-class <stepper> () (nxtval))
872(define-method (next-value (obj <stepper>))
873  ((slot-value obj 'nxtval)))
874(define-generic (reset obj))
875(define-method (reset (obj <stepper>))
876  (let-values (
877    ((gen _)
878      (apply
879        (slot-value obj 'ctor)
880        `(,@(slot-value obj 'params) ,(slot-value obj 'src)))) )
881    (set! (slot-value obj 'nxtval) gen) ) )
882
883;; Parameterized generative set of random values "concept"
884(define-class <random-distribution> (<named> <parameterized> <stepper>) (
885  ;holds any value, temporarily
886  tmpval ) )
887
888;; Create an instance of <random-distribution> where the arguments are
889;; the same as the documented procedural distribution API.
890;;
891;; SRFI 27 API: ({some distribution constructor} arg...)
892;;      OO API: (make-random-distribution {some distribution constructor} arg...)
893(define-syntax make-random-distribution
894  (syntax-rules ()
895    ((_ ?ctor ?arg0 ...)
896      ;use tmpval to hold the ctor call form
897      (make <random-distribution> 'tmpval (list ?ctor ?arg0 ...)) ) ) )
898
899(define-method (initialize-instance (obj <random-distribution>))
900  ; The 'ctor' must be a globally defined procedure compiled with
901  ; procedure-information. So if following nomenclature then the last
902  ; procedure name element will be the kind of distribution:
903  ; make-random-<distribution>. And the <random-source> will be the
904  ; last argument.
905  ;
906  ; (I do not endorse this kind of "auto-magic". For example only.)
907  (let* (
908      (tmpval
909        (or
910          (slot-value obj 'tmpval)
911          `(,make-random-normals)))
912      (ctor
913        (car tmpval) )
914      (procinfo
915        (procedure-information ctor))
916      (procname
917        (and procinfo (pair? procinfo) (symbol->string (car procinfo))))
918      (procname
919        (and
920          procname
921          (and-let* ((kndpos (string-index-right procname #\-)))
922            (substring/shared procname (add1 kndpos)))))
923      (dstr-vals
924        (receive (apply ctor (cdr tmpval))))
925      (params
926        (and
927          (<= 2 (length dstr-vals))
928          (receive ((second dstr-vals))))) )
929    ;"free" the temp slot
930    (set! (slot-value obj 'tmpval) #f)
931    ;initialize state
932    (set! (slot-value obj 'namsym) (string->symbol procname))
933    (set! (slot-value obj 'nxtval) (first dstr-vals))
934    (set! (slot-value obj 'ctor) ctor)
935    (set! (slot-value obj 'params) (and params (drop-right params 1)))
936    (set! (slot-value obj 'src) (and params (last params))) ) )
937
938;; Use it
939(use coops-extras)
940
941(define expn-rd (make-random-distribution make-random-exponentials mu: 0.5))
942(describe-object expn-rd)
943;coops instance of class `<random-distribution>':
944;tmpval: #f
945;namsym: exponentials
946;  ctor: #<procedure (srfi-27-exponentials#make-random-exponentials . tmp302303)>
947;params: (0.5)
948;   src: #<procedure>
949;nxtval: #<procedure (f_1191)>
950
951(next-value expn-rd) ;=> ...
952</enscript>
953
954
955== Notes
956
957* Due to the SRFI 27 requirement to generate numbers of any precision the
958"numbers" extension is always loaded. Be careful of creating a generator in a
959calling context where extended range is possible and consuming the results of
960the generator in a context without such range.
961
962* Portions by Sebastian Egner and Brad Lucier. (See the "book" SRFI 27
963implementation.)
964
965
966== Bugs and Limitations
967
968* Support for 64-bit platforms is poor. Need to provide core random integer
969generators which are defined over the 64-bit integer range. Currently 64-bit
970fixnum bounds are processed as if using a 32-bit platform. However, due to the
971bignum implementation, results in the 64-bit fixnum range are coerced to fixnum.
972
973* The random distribution API is poorly documented.
974
975* The implementation API is not documented. See the source distribution.
976
977* Use of an entropy-source as a random-source is impossible without the
978undocumented implementation API.
979
980
981== Requirements
982
983[[miscmacros]]
984[[numbers]]
985[[check-errors]]
986[[vector-lib]]
987[[timed-resource]]
988[[mathh]]
989
990[[setup-helper]]
991
992[[test]]
993
994
995== Author
996
997[[/users/kon-lovett|Kon Lovett]]
998
999
1000== Version history
1001
1002; 3.3.2 : Make {{entropy-source-random}} & {{entropy-source-urandom}} timed-resources.
1003; 3.3.1 : Remove unfinished entropy-linux module per #1434.
1004; 3.3.0 : Added 14 distribution modules.
1005; 3.2.11 : Include {{composite-random-source}} & {{composite-entropy-source}}, since tested.
1006; 3.2.10 : Uses test egg now.
1007; 3.2.9 : Fix {{make-random-bernoullis}}, add distributions test.
1008; 3.2.8 : .
1009; 3.2.7 : Fix {{entropy-source-system-clock}} {{entropy-source-u8}}.
1010; 3.2.6 : Add {{random-integer/current}}, {{random-real/current}}. Doesn't use synch, thread-utils eggs. Fix {{make-uniform-random-integers}}.
1011; 3.2.5 : Revert to own clock entropy implementation. Fix vector map/fill. Use EXTERNAL-ID for name.
1012; 3.2.4 : Error when unregistered source.
1013; 3.2.3 : Rename registration -> source-registration. Fix {{random-source-entropy-source-set!}}, must accept {{#f}} {{entropy-source}}. Fix broken srfi-27-vector.
1014; 3.2.2 : more tests.
1015; 3.2.1 : fp-extn module.
1016; 3.2.0 : Include registration.scm.
1017; 3.1.9 : registration module.
1018; 3.1.8 : Fix for ticket #630.
1019; 3.1.7 : Fix for unsigned integer from entropic f64.
1020; 3.1.6 : Fix for {{composite-random-source}} missing argument.
1021; 3.1.5 : Fix for {{mrg32k3a}} bad state values.
1022; 3.1.4 : Fix for {{mrg32k3a-pack-state}} bad index.
1023; 3.1.3 : Fix for 64-bit fixnums and random integers.
1024; 3.1.2 : Fix for "entropy-windows" {{make-entropy-source-crypt}}.
1025; 3.1.1 : Moved thread stuff to own extensions.
1026; 3.1.0 : Changed all {{random-source-name}} to lowercase symbols. Changed {{random-state}} tags to same as {{random-source-name}}. Added {{new-(random|entropy)-source}}, {{@(random|entropy)-source-constructor}} & {{(random|entropy)-source-name}}. Exported {{registered-(random|entropy)-sources}} & {{registered-(random|entropy)-source}}.
1027; 3.0.1 : Bug fix for bad external state symbol. Use of 64-bit arithmetic instead of double in C code.
1028; 3.0.0 : Initial release for Chicken 4
1029
1030
1031== License
1032
1033Copyright (C) 2010-2017 Kon Lovett. All rights reserved.
1034
1035Permission is hereby granted, free of charge, to any person obtaining a
1036copy of this software and associated documentation files (the Software),
1037to deal in the Software without restriction, including without limitation
1038the rights to use, copy, modify, merge, publish, distribute, sublicense,
1039and/or sell copies of the Software, and to permit persons to whom the
1040Software is furnished to do so, subject to the following conditions:
1041
1042The above copyright notice and this permission notice shall be included
1043in all copies or substantial portions of the Software.
1044
1045THE SOFTWARE IS PROVIDED ASIS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1046IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1047FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
1048THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
1049OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
1050ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
1051OTHER DEALINGS IN THE SOFTWARE.
1052
1053Does not supercede any restrictions found in the source code.
Note: See TracBrowser for help on using the repository browser.