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

Last change on this file since 34551 was 34551, checked in by Kon Lovett, 4 years ago

rel .11

File size: 30.2 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 instace 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 floatingpoint 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 instace 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) => (disjoint #f (procedure () entropy-source))</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 finalizstion.
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
608==== Usage
609
610<enscript language=scheme>
611(use srfi-27-distributions)
612</enscript>
613
614==== make-random-normals
615
616<procedure>(make-random-normals [#:mu (MU 0.0)] [#:sigma (SIGMA 1.0)] [#:randoms (RANDOMS (random-real/current))]) => (procedure () real)</procedure>
617
618{{MU}} is {{real}}.
619
620{{SIGMA}} is {{nonzero-real}}.
621
622{{RANDOMS}} is a {{(procedure () real)}}
623
624==== make-random-exponentials
625
626<procedure>(make-random-exponentials [#:mu (MU 1.0)] [#:randoms (RANDOMS (random-real/current))]) => (procedure () real)</procedure>
627
628{{MU}} is {{real}} in [{{0}} {{1}}].
629
630{{RANDOMS}} is a {{(procedure () real)}}
631
632==== make-random-triangles
633
634<procedure>(make-random-triangles [#:s (S 0.0)] [#:m (M 0.5)] [#:l (L 1.0)] [#:randoms (RANDOMS (random-real/current))]) => (procedure () real)</procedure>
635
636{{S}} is {{real}}.
637
638{{M}} is {{real}} in [{{S}} {{L}}].
639
640{{L}} is {{real}} in ]{{S}} {{+inf.0}}[.
641
642{{RANDOMS}} is a {{(procedure () real)}}
643
644==== make-random-poissons
645
646<procedure>(make-random-poissons [#:mu (MU 1.0)] [#:randoms (RANDOMS (random-real/current))]) => (procedure () integer)</procedure>
647
648{{MU}} is {{nonnegative-real}}.
649
650{{RANDOMS}} is a {{(procedure () real)}}
651
652==== make-random-bernoullis
653
654<procedure>(make-random-bernoullis [#:p (P 0.5)] [#:randoms (RANDOMS (random-real/current))]) => (procedure () boolean)</procedure>
655
656{{P}} is {{real}} in [{{0}} {{1}}].
657
658{{RANDOMS}} is a {{(procedure () real)}}
659
660==== make-random-binomials
661
662<procedure>(make-random-binomials [#:t (T 1)] [#:p (P 0.5)] [#:randoms (RANDOMS (random-real/current))]) => (procedure () integer)</procedure>
663
664{{T}} is {{cardinal-integer}}.
665
666{{P}} is {{real}} in [{{0}} {{1}}].
667
668{{RANDOMS}} is a {{(procedure () real)}}
669
670==== make-random-geometrics
671
672<procedure>(make-random-geometrics [#:p (P 0.5)] [#:randoms (RANDOMS (random-real/current))])) => (procedure () integer)</procedure>
673
674{{P}} is {{real}} in [{{0}} {{1}}].
675
676{{RANDOMS}} is a {{(procedure () real)}}
677
678==== make-random-lognormals
679
680<procedure>(make-random-lognormals [#:mu (MU 1.0)] [#:sigma (SIGMA 1.0)] [#:randoms (RANDOMS (random-real/current))]) => (procedure () real)</procedure>
681
682{{MU}} is {{nonzero-real}}.
683
684{{SIGMA}} is {{nonnegative-real}}.
685
686{{RANDOMS}} is a {{(procedure () real)}}
687
688==== make-random-cauchys
689
690<procedure>(make-random-cauchys [#:median (MEDIAN 0.0)] [#:sigma (SIGMA 1.0)] [#:randoms (RANDOMS (random-real/current))]) => (procedure () real)</procedure>
691
692{{MEDIAN}} is {{real}}.
693
694{{SIGMA}} is {{positive-real}}.
695
696{{RANDOMS}} is a {{(procedure () real)}}
697
698==== make-random-gammas
699
700<procedure>(make-random-gammas [#:alpha (ALPHA 1.0)] [#:theta (THETA 1.0)] [#:randoms (RANDOMS (random-real/current))]) => (procedure () real)</procedure>
701
702{{ALPHA}} is {{positive-real}}.
703
704{{THETA}} is {{positive-real}}.
705
706{{RANDOMS}} is a {{(procedure () real)}}
707
708==== make-random-erlangs
709
710<procedure>(make-random-erlangs [#:alpha (ALPHA 1)] [#:theta (THETA 1.0)] [#:randoms (RANDOMS (random-real/current))]) => (procedure () real)</procedure>
711
712{{ALPHA}} is {{positive-real}}.
713
714{{THETA}} is {{positive-real}}.
715
716{{RANDOMS}} is a {{(procedure () real)}}
717
718==== make-random-paretos
719
720<procedure>(make-random-paretos [#:alpha (ALPHA 1.0)] [#:xmin (XMIN 1.0)] [#:randoms (RANDOMS (random-real/current))]) => (procedure () real)</procedure>
721
722{{ALPHA}} is {{positive-real}}.
723
724{{XMIN}} is {{positive-real}}.
725
726{{RANDOMS}} is a {{(procedure () real)}}
727
728==== make-random-levys
729
730<procedure>(make-random-levys [#:gamma (GAMMA 1.0)] [#:delta (DELTA 0.0)] [#:randoms (RANDOMS (random-real/current))]) => (procedure () real)</procedure>
731
732{{GAMMA}} is {{nonnegative-real}}.
733
734{{DELTA}} is {{positive-real}}.
735
736{{RANDOMS}} is a {{(procedure () real)}}
737
738==== make-random-weibulls
739
740<procedure>(make-random-weibulls [#:shape (SHAPE 1.0)] [#:scale (SCALE 1.0)] [#:randoms (RANDOMS (random-real/current))]) => (procedure () real)</procedure>
741
742{{SHAPE}} is {{positive-real}}.
743
744{{SCALE}} is {{positive-real}}.
745
746{{RANDOMS}} is a {{(procedure () real)}}
747
748
749== Examples
750
751* A procedure for creating K-vector (whatever that is) generators. The use of
752George Marsaglia's Multiply With Carry {{random-source}} and the "/dev/random"
753{{entropy-source}} are for exposition only.
754
755<enscript language=scheme>
756(use srfi-27 srfi-27-uniform-random srfi-27-vector mwc entropy-unix entropy-port)
757
758(define (make-random-k-vector #!optional (k 1024) (rs (make-random-source 'mwc)) es)
759  (let ((new-es
760          (or
761            es
762            ;don't keep open port around too much
763            (parameterize ((entropy-port-lifetime 30))
764              (make-entropy-source-random-device))) )
765        (old-es (random-source-entropy-source rs) ) )
766    (dynamic-wind
767      (lambda ()
768        (random-source-entropy-source-set! rs new-es) )
769      (lambda ()
770        (let* ((rnd (make-uniform-random-integers #:low (- k) #:high (+ k) #:precision 2 #:source rs) )
771               (vecgen (make-random-vector #:randoms rnd) ) )
772          (lambda (#!optional (k k)) (vecgen k)) ) )
773      (lambda ()
774        (random-source-entropy-source-set! rs old-es) ) ) ) )
775</enscript>
776
777* Providing a fixed entropy-source, a constant seed.
778
779<enscript language=scheme>
780(use data-structures entropy-procedure)
781
782(define (make-entropy-constant n)
783  (make-entropy-source/f64procedure
784    (constantly (exact->inexact n))
785    #:name (string->uninterned-symbol (conc "entropy-constant-" n))
786    #:docu (conc "Entropy constant " n)) )
787</enscript>
788
789* A silly OO version of random distribution generator
790
791<enscript language=scheme>
792(use srfi-1 srfi-13 coops srfi-27-distributions)
793
794;; Named (has a name) "concept"
795(define-generic (name obj))
796(define-class <named> () (
797  (namsym #:reader name) ) )
798
799;; Parameterized extension "concept"
800(define-class <parameterized> () (ctor params src))
801
802;; Moves forward thru a set of values "concept"
803(define-generic (next-value obj))
804(define-class <stepper> () (nxtval))
805(define-method (next-value (obj <stepper>))
806  ((slot-value obj 'nxtval)))
807(define-generic (reset obj))
808(define-method (reset (obj <stepper>))
809  (let-values (
810      ((gen _)
811        (apply
812          (slot-value obj 'ctor)
813          `(,@(slot-value obj 'params) ,(slot-value obj 'src))) ) )
814    (set! (slot-value obj 'nxtval) gen) ) )
815
816;; Parameterized generative set of random values "concept"
817(define-class <random-distribution> (<named> <parameterized> <stepper>) (
818  ;holds any value, temporarily
819  tmpval ) )
820
821;; Create an instance of <random-distribution> where the arguments are
822;; the same as the documented procedural distribution API.
823;;
824;; SRFI 27 API: ({some distribution constructor} arg...)
825;;      OO API: (make-random-distribution {some distribution constructor} arg...)
826(define-syntax make-random-distribution
827  (syntax-rules ()
828    ((_ ?ctor ?arg0 ...)
829      ;use tmpval to hold the ctor call form
830      (make <random-distribution> 'tmpval (list ?ctor ?arg0 ...)) ) ) )
831
832(define-method (initialize-instance (obj <random-distribution>))
833  ; The 'ctor' must be a globally defined procedure compiled with
834  ; procedure-information. So if following nomenclature then the last
835  ; procedure name element will be the kind of distribution:
836  ; make-random-<distribution>. And the <random-source> will be the
837  ; last argument.
838  ;
839  ; (I do not endorse this kind of "auto-magic". For example only.)
840  (let* (
841      (tmpval
842        (or
843          (slot-value obj 'tmpval)
844          `(,make-random-normals)) )
845      (ctor
846        (car tmpval) )
847      (procinfo
848        (procedure-information ctor) )
849      (procname
850        (and procinfo (pair? procinfo) (symbol->string (car procinfo))))
851      (procname
852        (and
853          procname
854          (and-let* ((kndpos (string-index-right procname #\-)))
855            (substring/shared procname (add1 kndpos)) ) ) )
856      (dstr-vals
857        (receive (apply ctor (cdr tmpval))) )
858      (params
859        (and
860          (<= 2 (length dstr-vals))
861          (receive ((second dstr-vals)))) ) )
862    ;"free" the temp slot
863    (set! (slot-value obj 'tmpval) #f)
864    ;initialize state
865    (set! (slot-value obj 'namsym) (string->symbol procname))
866    (set! (slot-value obj 'nxtval) (first dstr-vals))
867    (set! (slot-value obj 'ctor) ctor)
868    (set! (slot-value obj 'params) (and params (drop-right params 1)))
869    (set! (slot-value obj 'src) (and params (last params))) ) )
870
871;; Use it
872(use coops-extras)
873
874(define expn-rd (make-random-distribution make-random-exponentials #:mu 0.5))
875(describe-object expn-rd)
876;coops instance of class `<random-distribution>':
877;tmpval : #f
878;namsym : exponentials
879;params : (0.5)
880;   src : #<procedure (f_1415)>
881;nxtval : #<procedure (f_1037)>
882
883(next-value expn-rd) ;=> ...
884</enscript>
885
886
887== Notes
888
889* Due to the SRFI 27 requirement to generate numbers of any precision the
890"numbers" extension is always loaded. Be careful of creating a generator in a
891calling context where extended range is possible and consuming the results of
892the generator in a context without such range.
893
894* Portions by Sebastian Egner and Brad Lucier. (See the "book" SRFI 27
895implementation.)
896
897
898== Bugs and Limitations
899
900* The random distribution API is poorly documented.
901
902* The implementation API is not documented. See the source distribution.
903
904* Support for 64-bit platforms is poor. Need to provide core random integer
905generators which are defined over the 64-bit integer range. Currently 64-bit
906fixnum bounds are processed as if using a 32-bit platform. However, due to the
907bignum implementation, results in the 64-bit fixnum range are coerced to fixnum.
908
909* Use of an entropy-source as a random-source is impossible without the
910undocumented implementation API.
911
912
913== Requirements
914
915[[miscmacros]]
916[[numbers]]
917[[check-errors]]
918[[vector-lib]]
919[[timed-resource]]
920[[setup-helper]]
921[[test]]
922
923
924== Author
925
926[[/users/kon-lovett|Kon Lovett]]
927
928
929== Version history
930
931; 3.2.11 : Include {{composite-random-source}} & {{composite-entropy-source}}, since tested.
932; 3.2.10 : Uses test egg now.
933; 3.2.9 : Fix {{make-random-bernoullis}}, add distributions test.
934; 3.2.8 : .
935; 3.2.7 : Fix {{entropy-source-system-clock}} {{entropy-source-u8}}.
936; 3.2.6 : Add {{random-integer/current}}, {{random-real/current}}. Doesn't use synch, thread-utils eggs. Fix {{make-uniform-random-integers}}.
937; 3.2.5 : Revert to own clock entropy implementation. Fix vector map/fill. Use EXTERNAL-ID for name.
938; 3.2.4 : Error when unregistered source.
939; 3.2.3 : Rename registration -> source-registration. Fix {{random-source-entropy-source-set!}}, must accept {{#f}} {{entropy-source}}. Fix broken srfi-27-vector.
940; 3.2.2 : more tests.
941; 3.2.1 : fp-extn module.
942; 3.2.0 : Include registration.scm.
943; 3.1.9 : registration module.
944; 3.1.8 : Fix for ticket #630.
945; 3.1.7 : Fix for unsigned integer from entropic f64.
946; 3.1.6 : Fix for {{composite-random-source}} missing argument.
947; 3.1.5 : Fix for {{mrg32k3a}} bad state values.
948; 3.1.4 : Fix for {{mrg32k3a-pack-state}} bad index.
949; 3.1.3 : Fix for 64-bit fixnums and random integers.
950; 3.1.2 : Fix for "entropy-windows" {{make-entropy-source-crypt}}.
951; 3.1.1 : Moved thread stuff to own extensions.
952; 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}}.
953; 3.0.1 : Bug fix for bad external state symbol. Use of 64-bit arithmetic instead of double in C code.
954; 3.0.0 : Initial release for Chicken 4
955
956
957== License
958
959Copyright (C) 2010-2017 Kon Lovett. All rights reserved.
960
961Permission is hereby granted, free of charge, to any person obtaining a
962copy of this software and associated documentation files (the Software),
963to deal in the Software without restriction, including without limitation
964the rights to use, copy, modify, merge, publish, distribute, sublicense,
965and/or sell copies of the Software, and to permit persons to whom the
966Software is furnished to do so, subject to the following conditions:
967
968The above copyright notice and this permission notice shall be included
969in all copies or substantial portions of the Software.
970
971THE SOFTWARE IS PROVIDED ASIS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
972IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
973FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
974THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
975OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
976ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
977OTHER DEALINGS IN THE SOFTWARE.
978
979Does not supercede any restrictions found in the source code.
Note: See TracBrowser for help on using the repository browser.