module Sound.SC3.Lang.Random.Gen where
import qualified Data.DList as DL
import Data.Maybe
import System.Random
import System.Random.Shuffle
import qualified Sound.SC3.Lang.Collection as C
import Sound.SC3.Lang.Core
import qualified Sound.SC3.Lang.Math as M
rand :: (RandomGen g,Random n,Num n) => n -> g -> (n,g)
rand n = randomR (0,n)
r_iterate :: (t -> (a, t)) -> t -> [a]
r_iterate f g = let (r,g') = f g in r : r_iterate f g'
mk_kvariant :: r -> (t -> r -> r) -> (r -> r') -> Int -> (g -> (t,g)) -> g -> (r',g)
mk_kvariant k_nil k_join un_k k f =
let go x i g = case i of
0 -> (un_k x,g)
_ -> let (y,g') = f g
in go (k_join y x) (i 1) g'
in go k_nil k
kvariant :: Int -> (g->(a,g)) -> g->([a],g)
kvariant = mk_kvariant [] (:) id
kvariant' :: Int -> (g->(a,g)) -> g->([a],g)
kvariant' = mk_kvariant DL.empty (flip DL.snoc) DL.toList
nrand :: (RandomGen g,Random n,Num n) => Int -> n -> g -> ([n],g)
nrand k = kvariant k . rand
s_rand :: (RandomGen g,Random n,Num n) => n -> g -> [n]
s_rand = r_iterate . rand
rand2 :: (RandomGen g,Random n,Num n) => n -> g -> (n,g)
rand2 n = randomR (n,n)
s_rand2 :: (RandomGen g,Random n,Num n) => n -> g -> [n]
s_rand2 = r_iterate . rand2
nrand2 :: (RandomGen g,Random a,Num a) => Int -> a -> g -> ([a],g)
nrand2 k = kvariant k . rand2
rrand :: (Random n, RandomGen g) => n -> n -> g -> (n,g)
rrand = curry randomR
nrrand :: (RandomGen g,Random a,Num a) => Int -> a -> a -> g -> ([a],g)
nrrand k = kvariant k .: rrand
choose :: RandomGen g => [a] -> g -> (a,g)
choose l g =
let (i,g') = randomR (0,length l 1) g
in (l !! i,g')
nchoose :: RandomGen g => Int -> [a] -> g -> ([a],g)
nchoose k = kvariant k . choose
exprand :: (Floating n,Random n,RandomGen g) => n -> n -> g -> (n,g)
exprand l r g =
let (n,g') = rrand 0.0 1.0 g
in (M.exprange l r n,g')
nexprand :: (Floating n,Random n,RandomGen g) =>
Int -> n -> n -> g -> ([n],g)
nexprand k = kvariant k .: exprand
coin :: (RandomGen g, Random a, Ord a, Fractional a) => a -> g -> (Bool,g)
coin n g =
let (i,g') = randomR (0.0,1.0) g
in (i < n,g')
ncoin :: (RandomGen g, Random a, Ord a, Fractional a) => Int -> a -> g -> ([Bool],g)
ncoin k = kvariant k . coin
scramble :: RandomGen g => [t] -> g -> ([t],g)
scramble k g =
let (_,g') = next g
in (shuffle' k (length k) g,g')
wchoose :: (RandomGen g,Random a,Ord a,Fractional a) => [b] -> [a] -> g -> (b,g)
wchoose l w g =
let (i,g') = randomR (0.0,1.0) g
n = fromMaybe (error "wchoose: windex") (C.windex w i)
in (l !! n,g')
wchoose_N :: (Fractional a,Ord a,RandomGen g,Random a) => [b] -> [a] -> g -> (b, g)
wchoose_N l w = wchoose l (C.normalizeSum w)
nwchoose_N :: (Fractional a,Ord a,RandomGen g,Random a) => Int -> [b] -> [a] -> g -> ([b], g)
nwchoose_N n = kvariant n .: wchoose_N