module MachineLearning.Random
(
sample
, sampleM
, getRandomRListM
, getRandomRVectorM
, getRandomRMatrixM
)
where
import Control.Monad (when)
import System.Random (RandomGen, Random)
import qualified Control.Monad.ST as ST
import qualified Data.Vector as V
import qualified Data.Vector.Storable as SV
import Numeric.LinearAlgebra ((><))
import qualified Data.Vector.Mutable as MV
import qualified Control.Monad.Random as RndM
import MachineLearning.Types (R, Vector, Matrix)
sample :: RandomGen g => g -> Int -> V.Vector a -> (V.Vector a, g)
sample gen n xs = RndM.runRand (sampleM n xs) gen
sampleM :: RandomGen g => Int -> V.Vector a -> RndM.Rand g (V.Vector a)
sampleM n xs = do
let rangeList = V.fromList $ zip (repeat 0) [n..(length xs)-1]
rnds <- randomsInRangesM rangeList
let (pre, post) = V.splitAt n xs
let ys = ST.runST $ do
mv <- V.thaw pre
V.zipWithM_ (\val r -> when (r < n) $ MV.write mv (mod r n) val) post rnds
V.unsafeFreeze mv
return ys
getRandomRListM :: (RandomGen g, Random a) =>
Int
-> (a, a)
-> RndM.Rand g [a]
getRandomRListM size range = mapM (\_ -> RndM.getRandomR range) [1..size]
getRandomRVectorM :: RandomGen g =>
Int
-> (R, R)
-> RndM.Rand g Vector
getRandomRVectorM size range = SV.fromList <$> getRandomRListM size range
getRandomRMatrixM :: RandomGen g =>
Int
-> Int
-> (R, R)
-> RndM.Rand g Matrix
getRandomRMatrixM r c range = (r><c) <$> getRandomRListM (r*c) range
randomsInRangesM :: (RndM.RandomGen g, RndM.Random a) => V.Vector (a, a) -> RndM.Rand g (V.Vector a)
randomsInRangesM rangeList = mapM RndM.getRandomR rangeList