-- | -- Module : Simulation.Aivika.Lattice.Internal.Lattice -- Copyright : Copyright (c) 2016-2017, David Sorokin -- License : BSD3 -- Maintainer : David Sorokin -- Stability : experimental -- Tested with: GHC 7.10.3 -- -- This module defines the lattice. -- module Simulation.Aivika.Lattice.Internal.Lattice (LIOLattice(..), lattice, newRandomLattice, newRandomLatticeWithProb) where import Control.Monad import Control.Monad.Trans import Data.Array import qualified System.Random.MWC as MWC -- | Specifies the lattice. data LIOLattice = LIOLattice { lioParentMemberIndex :: Int -> Int -> Int, -- ^ Get the parent member index by the specified -- time and member indices. lioSize :: Int -- ^ Tha lattice size. } -- | Create a new random lattice by the specified probability and size, -- where the probabilty defines whether the interior child node derives -- from the right parent. newRandomLatticeWithProb :: Double -> Int -> IO LIOLattice newRandomLatticeWithProb p m = do g <- MWC.withSystemRandom (return :: MWC.GenIO -> IO MWC.GenIO) xss0 <- forM [0 .. m] $ \i -> do xs0 <- forM [0 .. i] $ \k -> if k == 0 then return k else if k == i then return (k - 1) else do x <- MWC.uniform g :: IO Double if x > p then return (k - 1) else return k return $ listArray (0, i) xs0 let xss = listArray (0, m) xss0 return LIOLattice { lioParentMemberIndex = \i k -> (xss ! i) ! k, lioSize = m } -- | Create a new random lattice by the specified size with equal probabilities, -- whether the interior child node derives from the left or right parents. newRandomLattice :: Int -> IO LIOLattice newRandomLattice = newRandomLatticeWithProb 0.5 -- | Return a lattice by the specifed size and the parent member function. lattice :: Int -- ^ the lattice size -> (Int -> Int -> Int) -- ^ get the parent member index by the specified -- time and member indices -> LIOLattice lattice m f = LIOLattice f m