gary fredericks purely random clojure/west 2015 1 / 81apr 21, 2015 · java.util.random 1...
TRANSCRIPT
![Page 1: Gary Fredericks Purely Random Clojure/West 2015 1 / 81Apr 21, 2015 · java.util.Random 1 user>(defr(java.util.Random.42)) 2 #'user/r 3 user>(.nextIntr) 4-1170105035 5 user>(.nextIntr)](https://reader035.vdocument.in/reader035/viewer/2022071003/5fc05b36e070f27ef60c9ca6/html5/thumbnails/1.jpg)
Gary Fredericks Purely Random Clojure/West 2015 1 / 81
![Page 2: Gary Fredericks Purely Random Clojure/West 2015 1 / 81Apr 21, 2015 · java.util.Random 1 user>(defr(java.util.Random.42)) 2 #'user/r 3 user>(.nextIntr) 4-1170105035 5 user>(.nextIntr)](https://reader035.vdocument.in/reader035/viewer/2022071003/5fc05b36e070f27ef60c9ca6/html5/thumbnails/2.jpg)
java.util.Random
1 user> (def r (java.util.Random. 42))
2 #'user/r
3 user> (.nextInt r)
4 -1170105035
5 user> (.nextInt r)
6 234785527
Gary Fredericks Purely Random Clojure/West 2015 2 / 81
![Page 3: Gary Fredericks Purely Random Clojure/West 2015 1 / 81Apr 21, 2015 · java.util.Random 1 user>(defr(java.util.Random.42)) 2 #'user/r 3 user>(.nextIntr) 4-1170105035 5 user>(.nextIntr)](https://reader035.vdocument.in/reader035/viewer/2022071003/5fc05b36e070f27ef60c9ca6/html5/thumbnails/3.jpg)
java.util.Random in Clojure
1 (defn create
2 [seed]
3 {:state (bit-xor seed 0x5deece66d)})
4
5 (defn next-int
6 [{:keys [^long state]}]
7 (let [new-state (-> state
8 (unchecked-multiply 0x5deece66d)
9 (unchecked-add 0xb))
10 x (-> new-state
11 (bit-shift-right 16)
12 (unchecked-int))]
13 [x {:state new-state}]))
Gary Fredericks Purely Random Clojure/West 2015 3 / 81
![Page 4: Gary Fredericks Purely Random Clojure/West 2015 1 / 81Apr 21, 2015 · java.util.Random 1 user>(defr(java.util.Random.42)) 2 #'user/r 3 user>(.nextIntr) 4-1170105035 5 user>(.nextIntr)](https://reader035.vdocument.in/reader035/viewer/2022071003/5fc05b36e070f27ef60c9ca6/html5/thumbnails/4.jpg)
Mutable vs. Immutable
1 user> (def r (java.util.Random. 42))
2 #'user/r
3 user> (.nextInt r)
4 -1170105035
5 user> (.nextInt r)
6 234785527
78 ;; immutable version
9 user> (def r (create 42))
10 #'user/r
11 user> r
12 {:state 25214903879}
13 user> (next-int r)
14 [-1170105035 {:state 8602080079250839110}]
15 user> (next-int r)
16 [-1170105035 {:state 8602080079250839110}]
17 user> (next-int (second *1))
18 [234785527 {:state 7522434139496587225}]
Gary Fredericks Purely Random Clojure/West 2015 4 / 81
![Page 5: Gary Fredericks Purely Random Clojure/West 2015 1 / 81Apr 21, 2015 · java.util.Random 1 user>(defr(java.util.Random.42)) 2 #'user/r 3 user>(.nextIntr) 4-1170105035 5 user>(.nextIntr)](https://reader035.vdocument.in/reader035/viewer/2022071003/5fc05b36e070f27ef60c9ca6/html5/thumbnails/5.jpg)
Roadmap
Splittability and Composition
Basic Example, De�nitions
Case Study: test.checkImplementing Splittable RNGs in Clojure
Poorly
Better
Faster
Gary Fredericks Purely Random Clojure/West 2015 5 / 81
![Page 6: Gary Fredericks Purely Random Clojure/West 2015 1 / 81Apr 21, 2015 · java.util.Random 1 user>(defr(java.util.Random.42)) 2 #'user/r 3 user>(.nextIntr) 4-1170105035 5 user>(.nextIntr)](https://reader035.vdocument.in/reader035/viewer/2022071003/5fc05b36e070f27ef60c9ca6/html5/thumbnails/6.jpg)
Splittability and Composition
Gary Fredericks Purely Random Clojure/West 2015 6 / 81
![Page 7: Gary Fredericks Purely Random Clojure/West 2015 1 / 81Apr 21, 2015 · java.util.Random 1 user>(defr(java.util.Random.42)) 2 #'user/r 3 user>(.nextIntr) 4-1170105035 5 user>(.nextIntr)](https://reader035.vdocument.in/reader035/viewer/2022071003/5fc05b36e070f27ef60c9ca6/html5/thumbnails/7.jpg)
Splittability and Composition
A Tale of Two Seqs
Gary Fredericks Purely Random Clojure/West 2015 7 / 81
![Page 8: Gary Fredericks Purely Random Clojure/West 2015 1 / 81Apr 21, 2015 · java.util.Random 1 user>(defr(java.util.Random.42)) 2 #'user/r 3 user>(.nextIntr) 4-1170105035 5 user>(.nextIntr)](https://reader035.vdocument.in/reader035/viewer/2022071003/5fc05b36e070f27ef60c9ca6/html5/thumbnails/8.jpg)
Requirements
1 (defn pair-of-lazy-seqs
2 "Given a seed, returns [xs ys]
3 where xs and ys are both
4 (different) lazy infinite seqs
5 of random numbers."
6 [seed]
7 ;; ???
8 )
Gary Fredericks Purely Random Clojure/West 2015 8 / 81
![Page 9: Gary Fredericks Purely Random Clojure/West 2015 1 / 81Apr 21, 2015 · java.util.Random 1 user>(defr(java.util.Random.42)) 2 #'user/r 3 user>(.nextIntr) 4-1170105035 5 user>(.nextIntr)](https://reader035.vdocument.in/reader035/viewer/2022071003/5fc05b36e070f27ef60c9ca6/html5/thumbnails/9.jpg)
With java.util.Random
1 (defn pair-of-lazy-seqs
2 [seed]
3 (let [r (java.util.Random. seed)]
4 [(repeatedly #(.nextInt r))
5 (repeatedly #(.nextInt r))]))
Gary Fredericks Purely Random Clojure/West 2015 9 / 81
![Page 10: Gary Fredericks Purely Random Clojure/West 2015 1 / 81Apr 21, 2015 · java.util.Random 1 user>(defr(java.util.Random.42)) 2 #'user/r 3 user>(.nextIntr) 4-1170105035 5 user>(.nextIntr)](https://reader035.vdocument.in/reader035/viewer/2022071003/5fc05b36e070f27ef60c9ca6/html5/thumbnails/10.jpg)
Let's use it
1 (let [[xs ys] (pair-of-lazy-seqs 42)]
2 [(take 4 xs) (take 4 ys)])
3 =>
4 [(-1170105035 234785527 -1360544799 205897768)
5 (1325939940 -248792245 1190043011 -1255373459)]
Gary Fredericks Purely Random Clojure/West 2015 10 / 81
![Page 11: Gary Fredericks Purely Random Clojure/West 2015 1 / 81Apr 21, 2015 · java.util.Random 1 user>(defr(java.util.Random.42)) 2 #'user/r 3 user>(.nextIntr) 4-1170105035 5 user>(.nextIntr)](https://reader035.vdocument.in/reader035/viewer/2022071003/5fc05b36e070f27ef60c9ca6/html5/thumbnails/11.jpg)
Let's use it
1 (let [[xs ys] (pair-of-lazy-seqs 42)]
2 [(take 4 xs) (take 4 ys)])
3 =>
4 [(-1170105035 234785527 -1360544799 205897768)
5 (1325939940 -248792245 1190043011 -1255373459)]
6
7 (let [[xs ys] (pair-of-lazy-seqs 42)]
8 [(first xs) (first ys)])
9 => [-1170105035 234785527]
Gary Fredericks Purely Random Clojure/West 2015 11 / 81
![Page 12: Gary Fredericks Purely Random Clojure/West 2015 1 / 81Apr 21, 2015 · java.util.Random 1 user>(defr(java.util.Random.42)) 2 #'user/r 3 user>(.nextIntr) 4-1170105035 5 user>(.nextIntr)](https://reader035.vdocument.in/reader035/viewer/2022071003/5fc05b36e070f27ef60c9ca6/html5/thumbnails/12.jpg)
With java.util.Random
1 (defn pair-of-lazy-seqs
2 [seed]
3 (let [r (java.util.Random. seed)]
4 [(repeatedly #(.nextInt r))
5 (repeatedly #(.nextInt r))]))
Gary Fredericks Purely Random Clojure/West 2015 12 / 81
![Page 13: Gary Fredericks Purely Random Clojure/West 2015 1 / 81Apr 21, 2015 · java.util.Random 1 user>(defr(java.util.Random.42)) 2 #'user/r 3 user>(.nextIntr) 4-1170105035 5 user>(.nextIntr)](https://reader035.vdocument.in/reader035/viewer/2022071003/5fc05b36e070f27ef60c9ca6/html5/thumbnails/13.jpg)
With the immutable clojure RNG
1 (defn random-nums
2 [rng]
3 (lazy-seq
4 (let [[x rng2] (next-int rng)]
5 (cons x (random-nums rng2)))))
6
7 (defn pair-of-lazy-seqs
8 [seed]
9 (let [rng (create seed)]
10 [(random-nums rng)
11 (random-nums ; ????
12 )]))
Gary Fredericks Purely Random Clojure/West 2015 13 / 81
![Page 14: Gary Fredericks Purely Random Clojure/West 2015 1 / 81Apr 21, 2015 · java.util.Random 1 user>(defr(java.util.Random.42)) 2 #'user/r 3 user>(.nextIntr) 4-1170105035 5 user>(.nextIntr)](https://reader035.vdocument.in/reader035/viewer/2022071003/5fc05b36e070f27ef60c9ca6/html5/thumbnails/14.jpg)
Concept Space
Gary Fredericks Purely Random Clojure/West 2015 14 / 81
![Page 15: Gary Fredericks Purely Random Clojure/West 2015 1 / 81Apr 21, 2015 · java.util.Random 1 user>(defr(java.util.Random.42)) 2 #'user/r 3 user>(.nextIntr) 4-1170105035 5 user>(.nextIntr)](https://reader035.vdocument.in/reader035/viewer/2022071003/5fc05b36e070f27ef60c9ca6/html5/thumbnails/15.jpg)
With a splittable RNG
1 (defn random-nums2 [rng]3 (lazy-seq4 (let [[rng1 rng2] (split rng)5 x (rand-int rng1)]6 (cons x (random-nums rng2)))))7
8 (defn pair-of-lazy-seqs9 [seed]10 (let [rng (create seed)11 [rng1 rng2] (split rng)]12 [(random-nums rng1)13 (random-nums rng2)]))
Gary Fredericks Purely Random Clojure/West 2015 15 / 81
![Page 16: Gary Fredericks Purely Random Clojure/West 2015 1 / 81Apr 21, 2015 · java.util.Random 1 user>(defr(java.util.Random.42)) 2 #'user/r 3 user>(.nextIntr) 4-1170105035 5 user>(.nextIntr)](https://reader035.vdocument.in/reader035/viewer/2022071003/5fc05b36e070f27ef60c9ca6/html5/thumbnails/16.jpg)
Splittability and Composition
test.check
Gary Fredericks Purely Random Clojure/West 2015 16 / 81
![Page 17: Gary Fredericks Purely Random Clojure/West 2015 1 / 81Apr 21, 2015 · java.util.Random 1 user>(defr(java.util.Random.42)) 2 #'user/r 3 user>(.nextIntr) 4-1170105035 5 user>(.nextIntr)](https://reader035.vdocument.in/reader035/viewer/2022071003/5fc05b36e070f27ef60c9ca6/html5/thumbnails/17.jpg)
gen-xs-and-x
1 (def gen-xs-and-x
2 "Generates a pair [xs x] where xs is a list of
3 numbers and x is a number in that list."
4 (gen/bind (gen/not-empty (gen/list gen/nat))
5 (fn [xs]
6 (gen/tuple (gen/return xs)
7 (gen/elements xs)))))
8
9 (gen/sample gen-xs-and-x)
10 =>
11 ([(0) 0]
12 [(3 3 0) 0]
13 [(1 2) 2]
14 [(2 0 3 1) 1]
15 [(4 0 1 3) 1]
16 ...)
Gary Fredericks Purely Random Clojure/West 2015 17 / 81
![Page 18: Gary Fredericks Purely Random Clojure/West 2015 1 / 81Apr 21, 2015 · java.util.Random 1 user>(defr(java.util.Random.42)) 2 #'user/r 3 user>(.nextIntr) 4-1170105035 5 user>(.nextIntr)](https://reader035.vdocument.in/reader035/viewer/2022071003/5fc05b36e070f27ef60c9ca6/html5/thumbnails/18.jpg)
lists-don't-have-duplicates
1 (def lists-don't-have-duplicates
2 (prop/for-all [[xs x] gen-xs-and-x]
3 (let [x-count (->> xs
4 (filter #{x})
5 (count))]
6 (= 1 x-count))))
Gary Fredericks Purely Random Clojure/West 2015 18 / 81
![Page 19: Gary Fredericks Purely Random Clojure/West 2015 1 / 81Apr 21, 2015 · java.util.Random 1 user>(defr(java.util.Random.42)) 2 #'user/r 3 user>(.nextIntr) 4-1170105035 5 user>(.nextIntr)](https://reader035.vdocument.in/reader035/viewer/2022071003/5fc05b36e070f27ef60c9ca6/html5/thumbnails/19.jpg)
test.check shrinking
1 user> (quick-check 100 lists-don't-have-duplicates)
2 {:fail [[(4 4 5 4 2) 4]],
3 :failing-size 6,
4 :num-tests 7,
5 :result false,
6 :seed 1426989885725,
7 :shrunk {:depth 3,
8 :result false,
9 :smallest [[(4 4) 4]],
10 :total-nodes-visited 16}}
Gary Fredericks Purely Random Clojure/West 2015 19 / 81
![Page 20: Gary Fredericks Purely Random Clojure/West 2015 1 / 81Apr 21, 2015 · java.util.Random 1 user>(defr(java.util.Random.42)) 2 #'user/r 3 user>(.nextIntr) 4-1170105035 5 user>(.nextIntr)](https://reader035.vdocument.in/reader035/viewer/2022071003/5fc05b36e070f27ef60c9ca6/html5/thumbnails/20.jpg)
test.check shrink tree
Gary Fredericks Purely Random Clojure/West 2015 20 / 81
![Page 21: Gary Fredericks Purely Random Clojure/West 2015 1 / 81Apr 21, 2015 · java.util.Random 1 user>(defr(java.util.Random.42)) 2 #'user/r 3 user>(.nextIntr) 4-1170105035 5 user>(.nextIntr)](https://reader035.vdocument.in/reader035/viewer/2022071003/5fc05b36e070f27ef60c9ca6/html5/thumbnails/21.jpg)
test.check shrink tree
Gary Fredericks Purely Random Clojure/West 2015 21 / 81
![Page 22: Gary Fredericks Purely Random Clojure/West 2015 1 / 81Apr 21, 2015 · java.util.Random 1 user>(defr(java.util.Random.42)) 2 #'user/r 3 user>(.nextIntr) 4-1170105035 5 user>(.nextIntr)](https://reader035.vdocument.in/reader035/viewer/2022071003/5fc05b36e070f27ef60c9ca6/html5/thumbnails/22.jpg)
test.check shrink tree
Gary Fredericks Purely Random Clojure/West 2015 22 / 81
![Page 23: Gary Fredericks Purely Random Clojure/West 2015 1 / 81Apr 21, 2015 · java.util.Random 1 user>(defr(java.util.Random.42)) 2 #'user/r 3 user>(.nextIntr) 4-1170105035 5 user>(.nextIntr)](https://reader035.vdocument.in/reader035/viewer/2022071003/5fc05b36e070f27ef60c9ca6/html5/thumbnails/23.jpg)
test.check
The Problem
the lazy shrink-tree is nondeterministic
The Solution
Use an immutable, splittable RNG.
But where do you �nd such a thing?
Gary Fredericks Purely Random Clojure/West 2015 23 / 81
![Page 24: Gary Fredericks Purely Random Clojure/West 2015 1 / 81Apr 21, 2015 · java.util.Random 1 user>(defr(java.util.Random.42)) 2 #'user/r 3 user>(.nextIntr) 4-1170105035 5 user>(.nextIntr)](https://reader035.vdocument.in/reader035/viewer/2022071003/5fc05b36e070f27ef60c9ca6/html5/thumbnails/24.jpg)
Splittability and Composition
Summary
Gary Fredericks Purely Random Clojure/West 2015 24 / 81
![Page 25: Gary Fredericks Purely Random Clojure/West 2015 1 / 81Apr 21, 2015 · java.util.Random 1 user>(defr(java.util.Random.42)) 2 #'user/r 3 user>(.nextIntr) 4-1170105035 5 user>(.nextIntr)](https://reader035.vdocument.in/reader035/viewer/2022071003/5fc05b36e070f27ef60c9ca6/html5/thumbnails/25.jpg)
Okay So
Linear RNGs hinder composition
Programs are either nondeterministic or impossible to write
Splittable RNGs are less common, but composition-friendly
test.check impl is fragile because of its linear RNG
Gary Fredericks Purely Random Clojure/West 2015 25 / 81
![Page 26: Gary Fredericks Purely Random Clojure/West 2015 1 / 81Apr 21, 2015 · java.util.Random 1 user>(defr(java.util.Random.42)) 2 #'user/r 3 user>(.nextIntr) 4-1170105035 5 user>(.nextIntr)](https://reader035.vdocument.in/reader035/viewer/2022071003/5fc05b36e070f27ef60c9ca6/html5/thumbnails/26.jpg)
Implementations
Gary Fredericks Purely Random Clojure/West 2015 26 / 81
![Page 27: Gary Fredericks Purely Random Clojure/West 2015 1 / 81Apr 21, 2015 · java.util.Random 1 user>(defr(java.util.Random.42)) 2 #'user/r 3 user>(.nextIntr) 4-1170105035 5 user>(.nextIntr)](https://reader035.vdocument.in/reader035/viewer/2022071003/5fc05b36e070f27ef60c9ca6/html5/thumbnails/27.jpg)
Implementing Splittable RNGs in Clojure
Poorly
Better
Faster
Gary Fredericks Purely Random Clojure/West 2015 27 / 81
![Page 28: Gary Fredericks Purely Random Clojure/West 2015 1 / 81Apr 21, 2015 · java.util.Random 1 user>(defr(java.util.Random.42)) 2 #'user/r 3 user>(.nextIntr) 4-1170105035 5 user>(.nextIntr)](https://reader035.vdocument.in/reader035/viewer/2022071003/5fc05b36e070f27ef60c9ca6/html5/thumbnails/28.jpg)
Implementations
Low Quality Implementations
Gary Fredericks Purely Random Clojure/West 2015 28 / 81
![Page 29: Gary Fredericks Purely Random Clojure/West 2015 1 / 81Apr 21, 2015 · java.util.Random 1 user>(defr(java.util.Random.42)) 2 #'user/r 3 user>(.nextIntr) 4-1170105035 5 user>(.nextIntr)](https://reader035.vdocument.in/reader035/viewer/2022071003/5fc05b36e070f27ef60c9ca6/html5/thumbnails/29.jpg)
java.util.Random
Gary Fredericks Purely Random Clojure/West 2015 29 / 81
![Page 30: Gary Fredericks Purely Random Clojure/West 2015 1 / 81Apr 21, 2015 · java.util.Random 1 user>(defr(java.util.Random.42)) 2 #'user/r 3 user>(.nextIntr) 4-1170105035 5 user>(.nextIntr)](https://reader035.vdocument.in/reader035/viewer/2022071003/5fc05b36e070f27ef60c9ca6/html5/thumbnails/30.jpg)
java.util.Random
Gary Fredericks Purely Random Clojure/West 2015 30 / 81
![Page 31: Gary Fredericks Purely Random Clojure/West 2015 1 / 81Apr 21, 2015 · java.util.Random 1 user>(defr(java.util.Random.42)) 2 #'user/r 3 user>(.nextIntr) 4-1170105035 5 user>(.nextIntr)](https://reader035.vdocument.in/reader035/viewer/2022071003/5fc05b36e070f27ef60c9ca6/html5/thumbnails/31.jpg)
java.util.Random
Gary Fredericks Purely Random Clojure/West 2015 31 / 81
![Page 32: Gary Fredericks Purely Random Clojure/West 2015 1 / 81Apr 21, 2015 · java.util.Random 1 user>(defr(java.util.Random.42)) 2 #'user/r 3 user>(.nextIntr) 4-1170105035 5 user>(.nextIntr)](https://reader035.vdocument.in/reader035/viewer/2022071003/5fc05b36e070f27ef60c9ca6/html5/thumbnails/32.jpg)
java.util.Random
Gary Fredericks Purely Random Clojure/West 2015 32 / 81
![Page 33: Gary Fredericks Purely Random Clojure/West 2015 1 / 81Apr 21, 2015 · java.util.Random 1 user>(defr(java.util.Random.42)) 2 #'user/r 3 user>(.nextIntr) 4-1170105035 5 user>(.nextIntr)](https://reader035.vdocument.in/reader035/viewer/2022071003/5fc05b36e070f27ef60c9ca6/html5/thumbnails/33.jpg)
java.util.Random as a lazy seq
Gary Fredericks Purely Random Clojure/West 2015 33 / 81
![Page 34: Gary Fredericks Purely Random Clojure/West 2015 1 / 81Apr 21, 2015 · java.util.Random 1 user>(defr(java.util.Random.42)) 2 #'user/r 3 user>(.nextIntr) 4-1170105035 5 user>(.nextIntr)](https://reader035.vdocument.in/reader035/viewer/2022071003/5fc05b36e070f27ef60c9ca6/html5/thumbnails/34.jpg)
java.util.Random: splitting the seq
Gary Fredericks Purely Random Clojure/West 2015 34 / 81
![Page 35: Gary Fredericks Purely Random Clojure/West 2015 1 / 81Apr 21, 2015 · java.util.Random 1 user>(defr(java.util.Random.42)) 2 #'user/r 3 user>(.nextIntr) 4-1170105035 5 user>(.nextIntr)](https://reader035.vdocument.in/reader035/viewer/2022071003/5fc05b36e070f27ef60c9ca6/html5/thumbnails/35.jpg)
java.util.Random
Gary Fredericks Purely Random Clojure/West 2015 35 / 81
![Page 36: Gary Fredericks Purely Random Clojure/West 2015 1 / 81Apr 21, 2015 · java.util.Random 1 user>(defr(java.util.Random.42)) 2 #'user/r 3 user>(.nextIntr) 4-1170105035 5 user>(.nextIntr)](https://reader035.vdocument.in/reader035/viewer/2022071003/5fc05b36e070f27ef60c9ca6/html5/thumbnails/36.jpg)
java.util.Random as 1 32-count sequence
Gary Fredericks Purely Random Clojure/West 2015 36 / 81
![Page 37: Gary Fredericks Purely Random Clojure/West 2015 1 / 81Apr 21, 2015 · java.util.Random 1 user>(defr(java.util.Random.42)) 2 #'user/r 3 user>(.nextIntr) 4-1170105035 5 user>(.nextIntr)](https://reader035.vdocument.in/reader035/viewer/2022071003/5fc05b36e070f27ef60c9ca6/html5/thumbnails/37.jpg)
java.util.Random as 2 16-count sequences
Gary Fredericks Purely Random Clojure/West 2015 37 / 81
![Page 38: Gary Fredericks Purely Random Clojure/West 2015 1 / 81Apr 21, 2015 · java.util.Random 1 user>(defr(java.util.Random.42)) 2 #'user/r 3 user>(.nextIntr) 4-1170105035 5 user>(.nextIntr)](https://reader035.vdocument.in/reader035/viewer/2022071003/5fc05b36e070f27ef60c9ca6/html5/thumbnails/38.jpg)
java.util.Random as 4 8-count sequences
Gary Fredericks Purely Random Clojure/West 2015 38 / 81
![Page 39: Gary Fredericks Purely Random Clojure/West 2015 1 / 81Apr 21, 2015 · java.util.Random 1 user>(defr(java.util.Random.42)) 2 #'user/r 3 user>(.nextIntr) 4-1170105035 5 user>(.nextIntr)](https://reader035.vdocument.in/reader035/viewer/2022071003/5fc05b36e070f27ef60c9ca6/html5/thumbnails/39.jpg)
java.util.Random as 8 4-count sequences
Gary Fredericks Purely Random Clojure/West 2015 39 / 81
![Page 40: Gary Fredericks Purely Random Clojure/West 2015 1 / 81Apr 21, 2015 · java.util.Random 1 user>(defr(java.util.Random.42)) 2 #'user/r 3 user>(.nextIntr) 4-1170105035 5 user>(.nextIntr)](https://reader035.vdocument.in/reader035/viewer/2022071003/5fc05b36e070f27ef60c9ca6/html5/thumbnails/40.jpg)
java.util.Random as 16 2-count sequences
Gary Fredericks Purely Random Clojure/West 2015 40 / 81
![Page 41: Gary Fredericks Purely Random Clojure/West 2015 1 / 81Apr 21, 2015 · java.util.Random 1 user>(defr(java.util.Random.42)) 2 #'user/r 3 user>(.nextIntr) 4-1170105035 5 user>(.nextIntr)](https://reader035.vdocument.in/reader035/viewer/2022071003/5fc05b36e070f27ef60c9ca6/html5/thumbnails/41.jpg)
java.util.Random as 32 1-count sequences
Gary Fredericks Purely Random Clojure/West 2015 41 / 81
![Page 42: Gary Fredericks Purely Random Clojure/West 2015 1 / 81Apr 21, 2015 · java.util.Random 1 user>(defr(java.util.Random.42)) 2 #'user/r 3 user>(.nextIntr) 4-1170105035 5 user>(.nextIntr)](https://reader035.vdocument.in/reader035/viewer/2022071003/5fc05b36e070f27ef60c9ca6/html5/thumbnails/42.jpg)
Haskell's System.Random
1 stdSplit :: StdGen -> (StdGen, StdGen)
2 stdSplit std@(StdGen s1 s2)
3 = (left, right)
4 where
5 -- no statistical foundation for this!
6 left = StdGen new_s1 t2
7 right = StdGen t1 new_s2
89 new_s1 | s1 == 2147483562 = 1
10 | otherwise = s1 + 1
1112 new_s2 | s2 == 1 = 2147483398
13 | otherwise = s2 - 1
1415 StdGen t1 t2 = snd (next std)
Gary Fredericks Purely Random Clojure/West 2015 42 / 81
![Page 43: Gary Fredericks Purely Random Clojure/West 2015 1 / 81Apr 21, 2015 · java.util.Random 1 user>(defr(java.util.Random.42)) 2 #'user/r 3 user>(.nextIntr) 4-1170105035 5 user>(.nextIntr)](https://reader035.vdocument.in/reader035/viewer/2022071003/5fc05b36e070f27ef60c9ca6/html5/thumbnails/43.jpg)
The Lesson
Splittabilizing a linear algorithm can be tricky.
Gary Fredericks Purely Random Clojure/West 2015 43 / 81
![Page 44: Gary Fredericks Purely Random Clojure/West 2015 1 / 81Apr 21, 2015 · java.util.Random 1 user>(defr(java.util.Random.42)) 2 #'user/r 3 user>(.nextIntr) 4-1170105035 5 user>(.nextIntr)](https://reader035.vdocument.in/reader035/viewer/2022071003/5fc05b36e070f27ef60c9ca6/html5/thumbnails/44.jpg)
Implementations
High Quality Implementations
Gary Fredericks Purely Random Clojure/West 2015 44 / 81
![Page 45: Gary Fredericks Purely Random Clojure/West 2015 1 / 81Apr 21, 2015 · java.util.Random 1 user>(defr(java.util.Random.42)) 2 #'user/r 3 user>(.nextIntr) 4-1170105035 5 user>(.nextIntr)](https://reader035.vdocument.in/reader035/viewer/2022071003/5fc05b36e070f27ef60c9ca6/html5/thumbnails/45.jpg)
Splittable Pseudorandom Number Generatorsusing Cryptographic Hashing
Koen Claessen Michał H. PałkaChalmers University of Technology
[email protected] [email protected]
AbstractWe propose a new splittable pseudorandom number generator(PRNG) based on a cryptographic hash function. Splittable PRNGs,in contrast to linear PRNGs, allow the creation of two (seemingly)independent generators from a given random number generator.Splittable PRNGs are very useful for structuring purely functionalprograms, as they avoid the need for threading around state. Weshow that the currently known and used splittable PRNGs are eithernot efficient enough, have inherent flaws, or lack formal argumentsabout their randomness. In contrast, our proposed generator canbe implemented efficiently, and comes with a formal statementsand proofs that quantify how ‘random’ the results are that aregenerated. The provided proofs give strong randomness guaranteesunder assumptions commonly made in cryptography.
Categories and Subject Descriptors D.1.1 [Programming Tech-niques]: Applicative (Functional) Programming; D.3.3 [Program-ming Languages]: Language Constructs and Features
General Terms Algorithms, Languages
Keywords splittable pseudorandom number generators, provablesecurity, Haskell
1. IntroductionSplittable pseudorandom number generators (PRNGs) are very usefulfor structuring purely functional programs that deal with random-ness. They allow different parts of the program to independently(without interaction) generate random values, thus avoiding thethreading of a random seed through the whole program [10]. More-over, splittable PRNGs are essential when generating random infinitevalues, such as random infinite lists in a lazy language, or randomfunctions. In addition, deterministic distribution of parallel randomnumber streams, which is of interest to the High-Performance Com-puting community [22, 26], can be realised using splitting.
In Haskell, the standard module System.Random provides adefault implementation of a splittable generator StdGen, with thefollowing API:
split :: StdGen -> (StdGen, StdGen)next :: StdGen -> (Int, StdGen)
[Copyright notice will appear here once ’preprint’ option is removed.]
The function split creates two new, independent generators froma given generator. The function next can be used to create onerandom value. A user of this API is not supposed to use both nextand split on the same argument; doing so voids all warrantiesabout promised randomness.
The property-based testing framework QUICKCHECK [13]makes heavy use of splitting. Let us see it in action. Considerthe following simple (but somewhat contrived) property:
newtype Int14 = Int14 Intderiving Show
instance Arbitrary Int14 wherearbitrary = Int14 ‘fmap‘ choose (0, 13)
prop_shouldFail (_, Int14 a) (Int14 b) = a /= b
We define a new type Int14 for representing integers from 0 to 13.Next, we create a random generator for it that randomly picks anumber from 0 to 13. Finally, we define a property, which states thattwo randomly picked Int14 numbers, one of which is a componentof a randomly picked pair, are always unequal.
Testing the property yields the following result:
*Main> quickCheckWithstdArgs { maxSuccess = 10000 } prop_shouldFail
+++ OK, passed 10000 tests.
Even though the property is false (we would expect one of every 14tests to fail), all 10000 tests succeed!
The reason for this surprising behaviour is a previously unknownflaw in the standard Haskell pseudorandom number generatorused by QUICKCHECK during testing. The PRNG should pick allcombinations of numbers 0–13 for a and b, but in fact combinationswhere a and b are the same number are never picked.
It turns out that the StdGen standard generator used in currentHaskell compilers contains an ad hoc implementation of splitting.The current implementation is the source of the randomness flaw1
demonstrated above. The flaw requires a particular pattern of splitoperations to manifest and results in very strong correlation ofgenerated numbers. In fact, when 13 in the Int14 generator isreplaced by other numbers from range 1–500, the problem arises for465 of them! Unfortunately, this pattern of splits is simple and likelyto arise often in typical usage of QuickCheck. Because of this, wecannot be sure that QuickCheck properties that pass a large numberof tests are true with high probability.
Unfortunately, research devoted to pseudorandom generationhas mainly concentrated on linear generators, which do not supporton-demand splitting. Several attempts have been made at extending
1 http://hackage.haskell.org/trac/ghc/ticket/3575 and .../3620
To appear in the Proceedings of Haskell Symposium 2013 1 2013/9/15
Gary Fredericks Purely Random Clojure/West 2015 45 / 81
![Page 46: Gary Fredericks Purely Random Clojure/West 2015 1 / 81Apr 21, 2015 · java.util.Random 1 user>(defr(java.util.Random.42)) 2 #'user/r 3 user>(.nextIntr) 4-1170105035 5 user>(.nextIntr)](https://reader035.vdocument.in/reader035/viewer/2022071003/5fc05b36e070f27ef60c9ca6/html5/thumbnails/46.jpg)
Splitting Tree
1 (let [rng1 (make-rng seed)
2 [rng2 rng3] (split rng1)
3 x1 (rand-long rng2)
4 [rng4 rng5] (split rng3)
5 x2 (rang-long rng4)]
6 "hooray")
Gary Fredericks Purely Random Clojure/West 2015 46 / 81
![Page 47: Gary Fredericks Purely Random Clojure/West 2015 1 / 81Apr 21, 2015 · java.util.Random 1 user>(defr(java.util.Random.42)) 2 #'user/r 3 user>(.nextIntr) 4-1170105035 5 user>(.nextIntr)](https://reader035.vdocument.in/reader035/viewer/2022071003/5fc05b36e070f27ef60c9ca6/html5/thumbnails/47.jpg)
Linear Tree
Gary Fredericks Purely Random Clojure/West 2015 47 / 81
![Page 48: Gary Fredericks Purely Random Clojure/West 2015 1 / 81Apr 21, 2015 · java.util.Random 1 user>(defr(java.util.Random.42)) 2 #'user/r 3 user>(.nextIntr) 4-1170105035 5 user>(.nextIntr)](https://reader035.vdocument.in/reader035/viewer/2022071003/5fc05b36e070f27ef60c9ca6/html5/thumbnails/48.jpg)
Balanced Tree
Gary Fredericks Purely Random Clojure/West 2015 48 / 81
![Page 49: Gary Fredericks Purely Random Clojure/West 2015 1 / 81Apr 21, 2015 · java.util.Random 1 user>(defr(java.util.Random.42)) 2 #'user/r 3 user>(.nextIntr) 4-1170105035 5 user>(.nextIntr)](https://reader035.vdocument.in/reader035/viewer/2022071003/5fc05b36e070f27ef60c9ca6/html5/thumbnails/49.jpg)
Pseudorandom Function
Gary Fredericks Purely Random Clojure/West 2015 49 / 81
![Page 50: Gary Fredericks Purely Random Clojure/West 2015 1 / 81Apr 21, 2015 · java.util.Random 1 user>(defr(java.util.Random.42)) 2 #'user/r 3 user>(.nextIntr) 4-1170105035 5 user>(.nextIntr)](https://reader035.vdocument.in/reader035/viewer/2022071003/5fc05b36e070f27ef60c9ca6/html5/thumbnails/50.jpg)
Tree Path
Gary Fredericks Purely Random Clojure/West 2015 50 / 81
![Page 51: Gary Fredericks Purely Random Clojure/West 2015 1 / 81Apr 21, 2015 · java.util.Random 1 user>(defr(java.util.Random.42)) 2 #'user/r 3 user>(.nextIntr) 4-1170105035 5 user>(.nextIntr)](https://reader035.vdocument.in/reader035/viewer/2022071003/5fc05b36e070f27ef60c9ca6/html5/thumbnails/51.jpg)
SHA1Random
1 (deftype SHA1Random [seed path]2
3 IRandom4
5 (rand-long [_]6 (bytes->long (sha1 (str seed path))))7
8 (split [_]9 [(SHA1Random. seed (conj path 0))10 (SHA1Random. seed (conj path 1))]))11
12 (defn sha1-random13 [seed]14 (SHA1Random. seed []))
Gary Fredericks Purely Random Clojure/West 2015 51 / 81
![Page 52: Gary Fredericks Purely Random Clojure/West 2015 1 / 81Apr 21, 2015 · java.util.Random 1 user>(defr(java.util.Random.42)) 2 #'user/r 3 user>(.nextIntr) 4-1170105035 5 user>(.nextIntr)](https://reader035.vdocument.in/reader035/viewer/2022071003/5fc05b36e070f27ef60c9ca6/html5/thumbnails/52.jpg)
Implementations
Testing Quality
Gary Fredericks Purely Random Clojure/West 2015 52 / 81
![Page 53: Gary Fredericks Purely Random Clojure/West 2015 1 / 81Apr 21, 2015 · java.util.Random 1 user>(defr(java.util.Random.42)) 2 #'user/r 3 user>(.nextIntr) 4-1170105035 5 user>(.nextIntr)](https://reader035.vdocument.in/reader035/viewer/2022071003/5fc05b36e070f27ef60c9ca6/html5/thumbnails/53.jpg)
Dieharder
#=============================================================================#
# dieharder version 3.31.1 Copyright 2003 Robert G. Brown #
#=============================================================================#
Usage:
dieharder [-a] [-d dieharder test number] [-f filename] [-B]
[-D output flag [-D output flag] ... ] [-F] [-c separator]
[-g generator number or -1] [-h] [-k ks_flag] [-l]
[-L overlap] [-m multiply_p] [-n ntuple]
[-p number of p samples] [-P Xoff]
[-o filename] [-s seed strategy] [-S random number seed]
[-n ntuple] [-p number of p samples] [-o filename]
[-s seed strategy] [-S random number seed]
[-t number of test samples] [-v verbose flag]
[-W weak] [-X fail] [-Y Xtrategy]
[-x xvalue] [-y yvalue] [-z zvalue]
Gary Fredericks Purely Random Clojure/West 2015 53 / 81
![Page 54: Gary Fredericks Purely Random Clojure/West 2015 1 / 81Apr 21, 2015 · java.util.Random 1 user>(defr(java.util.Random.42)) 2 #'user/r 3 user>(.nextIntr) 4-1170105035 5 user>(.nextIntr)](https://reader035.vdocument.in/reader035/viewer/2022071003/5fc05b36e070f27ef60c9ca6/html5/thumbnails/54.jpg)
Linearization
Gary Fredericks Purely Random Clojure/West 2015 54 / 81
![Page 55: Gary Fredericks Purely Random Clojure/West 2015 1 / 81Apr 21, 2015 · java.util.Random 1 user>(defr(java.util.Random.42)) 2 #'user/r 3 user>(.nextIntr) 4-1170105035 5 user>(.nextIntr)](https://reader035.vdocument.in/reader035/viewer/2022071003/5fc05b36e070f27ef60c9ca6/html5/thumbnails/55.jpg)
Linearization - Right Linear
Gary Fredericks Purely Random Clojure/West 2015 55 / 81
![Page 56: Gary Fredericks Purely Random Clojure/West 2015 1 / 81Apr 21, 2015 · java.util.Random 1 user>(defr(java.util.Random.42)) 2 #'user/r 3 user>(.nextIntr) 4-1170105035 5 user>(.nextIntr)](https://reader035.vdocument.in/reader035/viewer/2022071003/5fc05b36e070f27ef60c9ca6/html5/thumbnails/56.jpg)
Linearization - Left Linear
Gary Fredericks Purely Random Clojure/West 2015 56 / 81
![Page 57: Gary Fredericks Purely Random Clojure/West 2015 1 / 81Apr 21, 2015 · java.util.Random 1 user>(defr(java.util.Random.42)) 2 #'user/r 3 user>(.nextIntr) 4-1170105035 5 user>(.nextIntr)](https://reader035.vdocument.in/reader035/viewer/2022071003/5fc05b36e070f27ef60c9ca6/html5/thumbnails/57.jpg)
Linearization - Alternating
Gary Fredericks Purely Random Clojure/West 2015 57 / 81
![Page 58: Gary Fredericks Purely Random Clojure/West 2015 1 / 81Apr 21, 2015 · java.util.Random 1 user>(defr(java.util.Random.42)) 2 #'user/r 3 user>(.nextIntr) 4-1170105035 5 user>(.nextIntr)](https://reader035.vdocument.in/reader035/viewer/2022071003/5fc05b36e070f27ef60c9ca6/html5/thumbnails/58.jpg)
Linearization - Balanced
Gary Fredericks Purely Random Clojure/West 2015 58 / 81
![Page 59: Gary Fredericks Purely Random Clojure/West 2015 1 / 81Apr 21, 2015 · java.util.Random 1 user>(defr(java.util.Random.42)) 2 #'user/r 3 user>(.nextIntr) 4-1170105035 5 user>(.nextIntr)](https://reader035.vdocument.in/reader035/viewer/2022071003/5fc05b36e070f27ef60c9ca6/html5/thumbnails/59.jpg)
Linearization - Right Lumpy
Gary Fredericks Purely Random Clojure/West 2015 59 / 81
![Page 60: Gary Fredericks Purely Random Clojure/West 2015 1 / 81Apr 21, 2015 · java.util.Random 1 user>(defr(java.util.Random.42)) 2 #'user/r 3 user>(.nextIntr) 4-1170105035 5 user>(.nextIntr)](https://reader035.vdocument.in/reader035/viewer/2022071003/5fc05b36e070f27ef60c9ca6/html5/thumbnails/60.jpg)
Linearization - Left Lumpy
Gary Fredericks Purely Random Clojure/West 2015 60 / 81
![Page 61: Gary Fredericks Purely Random Clojure/West 2015 1 / 81Apr 21, 2015 · java.util.Random 1 user>(defr(java.util.Random.42)) 2 #'user/r 3 user>(.nextIntr) 4-1170105035 5 user>(.nextIntr)](https://reader035.vdocument.in/reader035/viewer/2022071003/5fc05b36e070f27ef60c9ca6/html5/thumbnails/61.jpg)
Linearization - Fibonacci
Gary Fredericks Purely Random Clojure/West 2015 61 / 81
![Page 62: Gary Fredericks Purely Random Clojure/West 2015 1 / 81Apr 21, 2015 · java.util.Random 1 user>(defr(java.util.Random.42)) 2 #'user/r 3 user>(.nextIntr) 4-1170105035 5 user>(.nextIntr)](https://reader035.vdocument.in/reader035/viewer/2022071003/5fc05b36e070f27ef60c9ca6/html5/thumbnails/62.jpg)
Dieharder Results
Algorithm Linearization PASSED WEAK FAIL
j.u.Random (inherent) 95 13 6
SHA1 left-linear 111 3 0SHA1 right-linear 112 2 0SHA1 alternating 114 0 0SHA1 left-lumpy 110 4 0SHA1 right-lumpy 112 2 0SHA1 balanced 112 2 0SHA1 �bonacci 109 5 0
Gary Fredericks Purely Random Clojure/West 2015 62 / 81
![Page 63: Gary Fredericks Purely Random Clojure/West 2015 1 / 81Apr 21, 2015 · java.util.Random 1 user>(defr(java.util.Random.42)) 2 #'user/r 3 user>(.nextIntr) 4-1170105035 5 user>(.nextIntr)](https://reader035.vdocument.in/reader035/viewer/2022071003/5fc05b36e070f27ef60c9ca6/html5/thumbnails/63.jpg)
Implementations
Less Slow Implementations
Gary Fredericks Purely Random Clojure/West 2015 63 / 81
![Page 64: Gary Fredericks Purely Random Clojure/West 2015 1 / 81Apr 21, 2015 · java.util.Random 1 user>(defr(java.util.Random.42)) 2 #'user/r 3 user>(.nextIntr) 4-1170105035 5 user>(.nextIntr)](https://reader035.vdocument.in/reader035/viewer/2022071003/5fc05b36e070f27ef60c9ca6/html5/thumbnails/64.jpg)
Varying the hash function
Try a faster (noncryptographic?) pseudorandomfunction, test its quality.
Gary Fredericks Purely Random Clojure/West 2015 64 / 81
![Page 65: Gary Fredericks Purely Random Clojure/West 2015 1 / 81Apr 21, 2015 · java.util.Random 1 user>(defr(java.util.Random.42)) 2 #'user/r 3 user>(.nextIntr) 4-1170105035 5 user>(.nextIntr)](https://reader035.vdocument.in/reader035/viewer/2022071003/5fc05b36e070f27ef60c9ca6/html5/thumbnails/65.jpg)
java.util.SplittableRandom
1 public class SplittableRandom{
2
3 public SplittableRandom(long seed){...}
4
5 public long nextLong(){...};
6
7 public SplittableRandom split(){...};
8
9 }
Gary Fredericks Purely Random Clojure/West 2015 65 / 81
![Page 66: Gary Fredericks Purely Random Clojure/West 2015 1 / 81Apr 21, 2015 · java.util.Random 1 user>(defr(java.util.Random.42)) 2 #'user/r 3 user>(.nextIntr) 4-1170105035 5 user>(.nextIntr)](https://reader035.vdocument.in/reader035/viewer/2022071003/5fc05b36e070f27ef60c9ca6/html5/thumbnails/66.jpg)
The java.util.SplittableRandom Algorithm
Gary Fredericks Purely Random Clojure/West 2015 66 / 81
![Page 67: Gary Fredericks Purely Random Clojure/West 2015 1 / 81Apr 21, 2015 · java.util.Random 1 user>(defr(java.util.Random.42)) 2 #'user/r 3 user>(.nextIntr) 4-1170105035 5 user>(.nextIntr)](https://reader035.vdocument.in/reader035/viewer/2022071003/5fc05b36e070f27ef60c9ca6/html5/thumbnails/67.jpg)
(SplittableRandom. 24)
Gary Fredericks Purely Random Clojure/West 2015 67 / 81
![Page 68: Gary Fredericks Purely Random Clojure/West 2015 1 / 81Apr 21, 2015 · java.util.Random 1 user>(defr(java.util.Random.42)) 2 #'user/r 3 user>(.nextIntr) 4-1170105035 5 user>(.nextIntr)](https://reader035.vdocument.in/reader035/viewer/2022071003/5fc05b36e070f27ef60c9ca6/html5/thumbnails/68.jpg)
(-> 24 (SplittableRandom.) (.nextLong))
Gary Fredericks Purely Random Clojure/West 2015 68 / 81
![Page 69: Gary Fredericks Purely Random Clojure/West 2015 1 / 81Apr 21, 2015 · java.util.Random 1 user>(defr(java.util.Random.42)) 2 #'user/r 3 user>(.nextIntr) 4-1170105035 5 user>(.nextIntr)](https://reader035.vdocument.in/reader035/viewer/2022071003/5fc05b36e070f27ef60c9ca6/html5/thumbnails/69.jpg)
(-> 24 (SplittableRandom.) (.split))
Gary Fredericks Purely Random Clojure/West 2015 69 / 81
![Page 70: Gary Fredericks Purely Random Clojure/West 2015 1 / 81Apr 21, 2015 · java.util.Random 1 user>(defr(java.util.Random.42)) 2 #'user/r 3 user>(.nextIntr) 4-1170105035 5 user>(.nextIntr)](https://reader035.vdocument.in/reader035/viewer/2022071003/5fc05b36e070f27ef60c9ca6/html5/thumbnails/70.jpg)
(deftype IJUSR ...)
1 (deftype IJUSR [^long gamma ^long state]
2 IRandom
3 (rand-long [_]
4 (-> state (+ gamma) (mix-64)))
5 (split [this]
6 (let [state1 (+ gamma state)
7 state2 (+ gamma state1)
8 new-state (mix-64 state1)
9 new-gamma (mix-gamma state2)]
10 [(IJUSR. gamma state2)
11 (IJUSR. new-gamma new-state)])))
Gary Fredericks Purely Random Clojure/West 2015 70 / 81
![Page 71: Gary Fredericks Purely Random Clojure/West 2015 1 / 81Apr 21, 2015 · java.util.Random 1 user>(defr(java.util.Random.42)) 2 #'user/r 3 user>(.nextIntr) 4-1170105035 5 user>(.nextIntr)](https://reader035.vdocument.in/reader035/viewer/2022071003/5fc05b36e070f27ef60c9ca6/html5/thumbnails/71.jpg)
Benchmarks
linear
left-linear
right-lin
ear
alternatin
g
left-lumpy
right-lu
mpy
balan
ced
�bonacci
0
50
100
150
milliseconds
Criterium tests XORing 1,000,000 random numbers
JUR IJUSR
Gary Fredericks Purely Random Clojure/West 2015 71 / 81
![Page 72: Gary Fredericks Purely Random Clojure/West 2015 1 / 81Apr 21, 2015 · java.util.Random 1 user>(defr(java.util.Random.42)) 2 #'user/r 3 user>(.nextIntr) 4-1170105035 5 user>(.nextIntr)](https://reader035.vdocument.in/reader035/viewer/2022071003/5fc05b36e070f27ef60c9ca6/html5/thumbnails/72.jpg)
Benchmarks w/ SHA1
linear
left-linear
right-lin
ear
alternatin
g
left-lumpy
right-lu
mpy
balan
ced
�bonacci
0
500
1,000
milliseconds
Criterium tests XORing 1,000,000 random numbers
JUR IJUSR SHA1
Gary Fredericks Purely Random Clojure/West 2015 72 / 81
![Page 73: Gary Fredericks Purely Random Clojure/West 2015 1 / 81Apr 21, 2015 · java.util.Random 1 user>(defr(java.util.Random.42)) 2 #'user/r 3 user>(.nextIntr) 4-1170105035 5 user>(.nextIntr)](https://reader035.vdocument.in/reader035/viewer/2022071003/5fc05b36e070f27ef60c9ca6/html5/thumbnails/73.jpg)
Dieharder Results
Algorithm Linearization PASSED WEAK FAIL
j.u.Random (inherent) 95 13 6
SHA1 left-linear 111 3 0SHA1 right-linear 112 2 0SHA1 alternating 114 0 0SHA1 left-lumpy 110 4 0SHA1 right-lumpy 112 2 0SHA1 balanced 112 2 0SHA1 �bonacci 109 5 0
IJUSR left-linear 108 6 0IJUSR right-linear 111 3 0IJUSR alternating 109 5 0IJUSR left-lumpy 113 1 0IJUSR right-lumpy 114 0 0IJUSR balanced 114 0 0IJUSR �bonacci 111 3 0
Gary Fredericks Purely Random Clojure/West 2015 73 / 81
![Page 74: Gary Fredericks Purely Random Clojure/West 2015 1 / 81Apr 21, 2015 · java.util.Random 1 user>(defr(java.util.Random.42)) 2 #'user/r 3 user>(.nextIntr) 4-1170105035 5 user>(.nextIntr)](https://reader035.vdocument.in/reader035/viewer/2022071003/5fc05b36e070f27ef60c9ca6/html5/thumbnails/74.jpg)
Implementations
Summary
Gary Fredericks Purely Random Clojure/West 2015 74 / 81
![Page 75: Gary Fredericks Purely Random Clojure/West 2015 1 / 81Apr 21, 2015 · java.util.Random 1 user>(defr(java.util.Random.42)) 2 #'user/r 3 user>(.nextIntr) 4-1170105035 5 user>(.nextIntr)](https://reader035.vdocument.in/reader035/viewer/2022071003/5fc05b36e070f27ef60c9ca6/html5/thumbnails/75.jpg)
Okay So
Linear RNGs cannot be trivially splittabilized
Recent research provides promising options
Gary Fredericks Purely Random Clojure/West 2015 75 / 81
![Page 76: Gary Fredericks Purely Random Clojure/West 2015 1 / 81Apr 21, 2015 · java.util.Random 1 user>(defr(java.util.Random.42)) 2 #'user/r 3 user>(.nextIntr) 4-1170105035 5 user>(.nextIntr)](https://reader035.vdocument.in/reader035/viewer/2022071003/5fc05b36e070f27ef60c9ca6/html5/thumbnails/76.jpg)
Epilogue
Gary Fredericks Purely Random Clojure/West 2015 76 / 81
![Page 77: Gary Fredericks Purely Random Clojure/West 2015 1 / 81Apr 21, 2015 · java.util.Random 1 user>(defr(java.util.Random.42)) 2 #'user/r 3 user>(.nextIntr) 4-1170105035 5 user>(.nextIntr)](https://reader035.vdocument.in/reader035/viewer/2022071003/5fc05b36e070f27ef60c9ca6/html5/thumbnails/77.jpg)
Convert test.check to JavaUtilSplittableRandom
[org.clojure/test.check "0.8.0-ALPHA"]
Gary Fredericks Purely Random Clojure/West 2015 77 / 81
![Page 78: Gary Fredericks Purely Random Clojure/West 2015 1 / 81Apr 21, 2015 · java.util.Random 1 user>(defr(java.util.Random.42)) 2 #'user/r 3 user>(.nextIntr) 4-1170105035 5 user>(.nextIntr)](https://reader035.vdocument.in/reader035/viewer/2022071003/5fc05b36e070f27ef60c9ca6/html5/thumbnails/78.jpg)
Slowdown
Measuring the slowdown on test.check's own test suite.
(bench (clojure.test/run-all-tests))
Before 3.06 ± 0.045 seconds
After 3.56 ± 0.058 seconds
16.3% slower
lein benchmark-task 20 test
Before 7.62 ± 0.182 seconds
After 8.34 ± 0.210 seconds
9.3% slower
Gary Fredericks Purely Random Clojure/West 2015 78 / 81
![Page 79: Gary Fredericks Purely Random Clojure/West 2015 1 / 81Apr 21, 2015 · java.util.Random 1 user>(defr(java.util.Random.42)) 2 #'user/r 3 user>(.nextIntr) 4-1170105035 5 user>(.nextIntr)](https://reader035.vdocument.in/reader035/viewer/2022071003/5fc05b36e070f27ef60c9ca6/html5/thumbnails/79.jpg)
Empossibleized Future Features
Parallelizing tests
Resuming shrinks
Parallelized shrinks
Custom shrinking algorithms
Generating lazy seqs
Replaying a particular test with a speci�c "seed"
Gary Fredericks Purely Random Clojure/West 2015 79 / 81
![Page 80: Gary Fredericks Purely Random Clojure/West 2015 1 / 81Apr 21, 2015 · java.util.Random 1 user>(defr(java.util.Random.42)) 2 #'user/r 3 user>(.nextIntr) 4-1170105035 5 user>(.nextIntr)](https://reader035.vdocument.in/reader035/viewer/2022071003/5fc05b36e070f27ef60c9ca6/html5/thumbnails/80.jpg)
We Have Come Now To The End
Splittable RNGs are necessary for composingfunctional programs
There are existing splittable algorithms, includingjava.util.SplittableRandom
Using the SplittableRandom algorithm madetest.check more robust
Gary Fredericks Purely Random Clojure/West 2015 80 / 81
![Page 81: Gary Fredericks Purely Random Clojure/West 2015 1 / 81Apr 21, 2015 · java.util.Random 1 user>(defr(java.util.Random.42)) 2 #'user/r 3 user>(.nextIntr) 4-1170105035 5 user>(.nextIntr)](https://reader035.vdocument.in/reader035/viewer/2022071003/5fc05b36e070f27ef60c9ca6/html5/thumbnails/81.jpg)
Thank You
And also thanks to
Reid Draper
Alex Miller
BibliographyClaessen, K. ; Palka, M. (2013) "Splittable Pseudorandom Number Generators usingCryptographic Hashing". Proceedings of Haskell Symposium 2013 pp. 47-58.
Guy L. Steele, Jr., Doug Lea, and Christine H. Flood. 2014. Fast splittable pseudorandomnumber generators. In Proceedings of the 2014 ACM International Conference on ObjectOriented Programming Systems Languages & Applications (OOPSLA '14). ACM, New York,NY, USA, 453-472. DOI=10.1145/2660193.2660195http://doi.acm.org/10.1145/2660193.2660195
Gary Fredericks Purely Random Clojure/West 2015 81 / 81