librarylibs/Random/src/Random.xtl
Random: randomness -- shuffles, deals, choices, uniform and normal samples, weighted picks. Import it with an alias of your choice: "r:" u_se< "Random". Put libs/Random/src on XETAL_PATH ("just path"); the reference is libs/Random/docs. Names with l: are exported; those under h: are private to this file.
Everything is built on the built-in r_oll!, so "xetal run --seed N" (or XETAL_SEED) makes a run repeatable. Every function has an effect and ends in !, as r_oll! does.
Shuffling
ʰk̲eys! : Int -> Int
k random keys, 1..big.
ʰk̲eys! ← { k → r̲oll! k r̲eshape big }
ˡs̲huffle! : a -> a
s_huffle! v: the items of v in a random order (sorting random keys).
ˡs̲huffle! ← { v → (g̲rade ʰk̲eys! t̲ally v) s̲elect v }
ˡd̲eal! : Int -> Int -> Int
k d_eal! n: k different numbers from 1..n, in random order (APL's deal).
ˡd̲eal! ← { k n → (k < 0) ∨ k > n ? @ p̲anic< "cannot deal {k} different numbers from 1 to {n}" k t̲ake ˡs̲huffle! r̲ange n }
ˡc̲hoice! : a -> a
c_hoice! v: one item of v, each as likely.
ˡc̲hoice! ← { v → 0 = t̲ally v ? @ p̲anic< "there is nothing to choose from: the list is empty" (r̲oll! t̲ally v) s̲elect v }
ˡs̲ample! : Int -> a -> a
k s_ample! v: k items of v, each drawn afresh (with replacement).
ˡs̲ample! ← { k v → (0 = t̲ally v) ∧ k > 0 ? @ p̲anic< "there is nothing to sample from: the list is empty" (r̲oll! k r̲eshape t̲ally v) s̲elect v }
Sampling distributions
ˡu̲niform! : Int -> Float
u_niform! n: n Floats, each as likely anywhere in [0, 1).
ˡu̲niform! ← { n → (f̲loat (ʰk̲eys! n) − 1) ÷ f̲loat big }