module DSMC.Util
( solveq
, SquareRoots
, fromUnboxed1
, iforM_
, randomSeed
, Time
, DSMCRootMonad
)
where
import Prelude hiding (Just, Nothing, Maybe, fst)
import Data.Bits
import Data.Word
import Data.Functor
import Data.List
import qualified Data.ByteString as BS
import Data.Strict.Maybe
import Data.Strict.Tuple
import qualified Data.Array.Repa as R
import qualified Data.Vector.Unboxed as VU
import System.Entropy
import System.Random.MWC
import Data.Splittable
type SquareRoots = Maybe (Pair Double Double)
solveq :: Double
-> Double
-> Double
-> SquareRoots
solveq !a !b !c
| (d > 0) = Just $ min r1 r2 :!: max r1 r2
| otherwise = Nothing
where
d = b * b 4 * a * c
q = sqrt d
t = 2 * a
r = b / t
s = q / t
r1 = r s
r2 = r + s
fromUnboxed1 :: (VU.Unbox e) => VU.Vector e -> R.Array R.U R.DIM1 e
fromUnboxed1 v = R.fromUnboxed (R.ix1 $ VU.length v) v
iforM_ :: (Monad m, VU.Unbox a) =>
VU.Vector a
-> ((Int, a) -> m b)
-> m ()
iforM_ v = VU.forM_ (VU.imap (,) v)
randomWord32Vector :: Int -> IO (VU.Vector Word32)
randomWord32Vector n =
let
accum a o = (a `shiftL` 8) .|. fromIntegral o
in do
w8stream <- getEntropy (n * 4)
let w8s = map BS.unpack $ splitIn n w8stream
return $ VU.fromList $ map (foldl' accum 0) w8s
randomSeed :: IO Seed
randomSeed = toSeed <$> randomWord32Vector 256
type Time = Double
type DSMCRootMonad = IO