5d2375b8ba78

Update docs
[view raw] [browse files]
author Steve Losh <steve@stevelosh.com>
date Thu, 16 Mar 2017 23:28:51 +0000
parents 97926c261ee7
children 555f4470bf64
branches/tags (none)
files docs/02-usage.markdown docs/03-reference.markdown package.lisp

Changes

--- a/docs/02-usage.markdown	Thu Mar 16 22:39:40 2017 +0000
+++ b/docs/02-usage.markdown	Thu Mar 16 23:28:51 2017 +0000
@@ -1,9 +1,116 @@
 Usage
 =====
 
-cl-pcg is...
+`cl-pcg` is a [permuted congruential generator][pcg] implementation in pure
+Common Lisp.  It provides a high-level API and a low-level API.
 
 [pcg]: http://www.pcg-random.org/
 
 [TOC]
 
+The High-Level API
+------------------
+
+The high-level API is what you should start (and probably end) with.  It
+typechecks the arguments you pass in and offers a nice interface for generating
+random numbers.
+
+### Creating a Generator
+
+To create a generator you can use the `make-pcg` function:
+
+    :::lisp
+    (defparameter *gen* (make-pcg))
+
+`make-pcg` takes two keyword parameters:
+
+* `:seed` should be an `(unsigned-byte 64)`.  If omitted a random seed will be
+  generated with the underlying implementation's `cl:random` function.
+* `:stream-id` should be an `(unsigned-byte 32)`.  The default is `0`.  Streams
+  provide a way to "split" a PCG into multiple generators — check out the PCG
+  site for more information on this.
+
+Once you've got a PCG object you can use it to generate some numbers.
+
+### Generating Numbers
+
+You can use the `pcg-random` function to generate random numbers:
+
+    :::lisp
+    (defparameter *gen* (make-pcg))
+
+    (pcg-random *gen* 10)
+    ; => a random number from 0 (inclusive) to 10 (exclusive)
+
+`pcg-random` is flexible and takes a number of optional arguments to help you
+generate the kinds of numbers you need.  Its lambda list looks like this:
+
+    :::lisp
+    (pcg bound &optional max inclusive?)
+
+If only `bound` is given, the function acts much like `cl:random`.
+
+If `max` is also given, a random number in `[bound, max)` is chosen.
+
+If `inclusive?` is also given, a random number in `[bound, max]` is chosen.
+
+For example:
+
+    :::lisp
+    (defparameter *gen* (make-pcg))
+
+    (pcg-random *gen* 10)      ; => [0, 10)
+    (pcg-random *gen* 15 28)   ; => [15, 28)
+    (pcg-random *gen* 15 28 t) ; => [15, 28] <- inclusive endpoint!
+
+`pcg-random` can also generate `single-float`s if `bound` and `max` are given as
+`single-float`s.
+
+### The Global Generator
+
+If you don't want to bother creating a fresh PCG object you can pass `t` to the
+high-level API to use a globally-defined one:
+
+    :::lisp
+    (pcg-random t 10)
+
+### Advancing & Rewinding
+
+Sometimes it can be useful to advance or rewind a generator by a certain number
+of steps.  The `(pcg-advance pcg steps)` and `(pcg-rewind pcg steps)` can be
+used to do this:
+
+    :::lisp
+    (defparameter *gen* (make-pcg))
+
+    ;; Get three numbers
+    (pcg-random *gen* 1000) ; => 708
+    (pcg-random *gen* 1000) ; => 964
+    (pcg-random *gen* 1000) ; => 400
+
+    ;; Rewind three steps
+    (pcg-rewind *gen* 3)
+
+    ;; Get the same three numbers
+    (pcg-random *gen* 1000) ; => 708
+    (pcg-random *gen* 1000) ; => 964
+    (pcg-random *gen* 1000) ; => 400
+
+These functions are `O(log₂(steps))` so they'll be fast even for ludicrously
+large values of `steps`.
+
+
+The Low-Level API
+-----------------
+
+The low-level API is what you want if you need raw speed.  It consists of all
+functions in the API whose names end in `%`, like `pcg-random%`.  All of these
+functions are `declaim`ed inline for easy embedding into hot loops.
+
+As an arbitrary example, the main function in this API (`pcg-random%`) is about
+100 bytes of machine code, so it's suitable for inlining when you really need
+performance.
+
+The low-level API assumes you will pass in arguments of the correct type.  If
+you fuck this up, all bets are off.  Read the code to figure out exactly what
+you need to pass in (or just use the high-level API like a sane person).
--- a/docs/03-reference.markdown	Thu Mar 16 22:39:40 2017 +0000
+++ b/docs/03-reference.markdown	Thu Mar 16 23:28:51 2017 +0000
@@ -12,3 +12,114 @@
 
 ## Package `PCG`
 
+### `MAKE-PCG` (function)
+
+    (MAKE-PCG &KEY (SEED NIL) (STREAM-ID 0))
+
+Create and return a new PCG.
+
+  If `seed` is `nil`, a fresh random seed will be generated with the
+  implementation's `cl:random` function, as if by:
+
+    (random ... (make-random-state t))
+
+  
+
+### `MAKE-PCG%` (function)
+
+    (MAKE-PCG% SEED STREAM-ID)
+
+Create and return a new `pcg` for the given `seed` and `stream-id`.
+
+  This is a low-level function that assumes you are passing in the correct types.
+
+  
+
+### `PCG` (struct)
+
+Slots: `STATE`, `INCREMENT`
+
+### `PCG-ADVANCE` (function)
+
+    (PCG-ADVANCE PCG STEPS)
+
+Advance the state of `pcg` by `steps` steps.
+
+  This function returns `nil` and is only useful for its side effects.
+
+  
+
+### `PCG-ADVANCE%` (function)
+
+    (PCG-ADVANCE% PCG STEPS)
+
+Advance the state of `pcg` by `steps` steps.
+
+  This function returns `nil` and is only useful for its side effects.
+
+  This is a low-level function that assumes you are passing in the correct types.
+
+  
+
+### `PCG-RANDOM` (function)
+
+    (PCG-RANDOM PCG BOUND &OPTIONAL MAX INCLUSIVE?)
+
+### `PCG-RANDOM%` (function)
+
+    (PCG-RANDOM% PCG)
+
+Return a random `(unsigned-byte 32)`.
+
+  As a side effect, the state of `pcg` will be advanced.
+
+  This is a low-level function that assumes you are passing in the correct types.
+
+  
+
+### `PCG-RANDOM-BOUNDED%` (function)
+
+    (PCG-RANDOM-BOUNDED% PCG BOUND)
+
+Return a random integer between `0` (inclusive) and `bound` (exclusive).
+
+  As a side effect, the state of `pcg` will be advanced.
+
+  This is a low-level function that assumes you are passing in the correct types.
+
+  
+
+### `PCG-RANDOM-FLOAT%` (function)
+
+    (PCG-RANDOM-FLOAT% PCG)
+
+Return a random `single-float` between `0.0` and `1.0`.
+
+  As a side effect, the state of `pcg` will be advanced.
+
+  This is a low-level function that assumes you are passing in the correct types.
+
+  
+
+### `PCG-REWIND` (function)
+
+    (PCG-REWIND PCG STEPS)
+
+Rewind the state of `pcg` by `steps` steps.
+
+  This function returns `nil` and is only useful for its side effects.
+
+  
+
+### `PCG-REWIND%` (function)
+
+    (PCG-REWIND% PCG STEPS)
+
+Rewind the state of `pcg` by `steps` steps.
+
+  This function returns `nil` and is only useful for its side effects.
+
+  This is a low-level function that assumes you are passing in the correct types.
+
+  
+
--- a/package.lisp	Thu Mar 16 22:39:40 2017 +0000
+++ b/package.lisp	Thu Mar 16 23:28:51 2017 +0000
@@ -1,4 +1,19 @@
 (defpackage :pcg
   (:use :cl :pcg.quickutils)
   (:export
+    ;; High-Level API
+    :pcg
+    :make-pcg
+    :pcg-random
+    :pcg-advance
+    :pcg-rewind
+
+    ;; Low-Level API
+    :make-pcg%
+    :pcg-random%
+    :pcg-random-bounded%
+    :pcg-random-float%
+    :pcg-advance%
+    :pcg-rewind%
+
     ))