{-# LANGUAGE BangPatterns #-}
module Data.Array.Repa.Algorithms.Randomish
( randomishIntArray
, randomishIntVector
, randomishDoubleArray
, randomishDoubleVector)
where
import Data.Word
import Data.Vector.Unboxed (Vector)
import Data.Array.Repa as R
import qualified Data.Vector.Unboxed.Mutable as MV
import qualified Data.Vector.Unboxed as V
import qualified Data.Vector.Generic as G
randomishIntArray
:: Shape sh
=> sh
-> Int
-> Int
-> Int
-> Array U sh Int
randomishIntArray !sh !valMin !valMax !seed
= fromUnboxed sh $ randomishIntVector (R.size sh) valMin valMax seed
randomishIntVector
:: Int
-> Int
-> Int
-> Int
-> Vector Int
randomishIntVector !len !valMin' !valMax' !seed'
= let
multiplier :: Word64
multiplier = 16807
modulus :: Word64
modulus = 2^(31 :: Integer) - 1
seed
| seed' == 0 = 1
| otherwise = seed'
!valMin = fromIntegral valMin'
!valMax = fromIntegral valMax' + 1
!range = valMax - valMin
{-# INLINE f #-}
f x = multiplier * x `mod` modulus
in G.create
$ do
vec <- MV.new len
let go !ix !x
| ix == len = return ()
| otherwise
= do let x' = f x
MV.write vec ix $ fromIntegral $ (x `mod` range) + valMin
go (ix + 1) x'
go 0 (f $ f $ f $ fromIntegral seed)
return vec
randomishDoubleArray
:: Shape sh
=> sh
-> Double
-> Double
-> Int
-> Array U sh Double
randomishDoubleArray !sh !valMin !valMax !seed
= fromUnboxed sh $ randomishDoubleVector (R.size sh) valMin valMax seed
randomishDoubleVector
:: Int
-> Double
-> Double
-> Int
-> Vector Double
randomishDoubleVector !len !valMin !valMax !seed
= let range = valMax - valMin
mx = 2^(30 :: Integer) - 1
mxf = fromIntegral (mx :: Integer)
ints = randomishIntVector len 0 mx seed
in V.map (\n -> valMin + (fromIntegral n / mxf) * range) ints