Last active
July 31, 2019 07:21
-
-
Save atcol/1dbcbaeafbde48be3dc48a8dabeb794d to your computer and use it in GitHub Desktop.
A simple tri-state Markov Chain generator. I think.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env stack | |
-- stack --resolver lts-13.30 script --package random | |
import Control.Monad (foldM) | |
import Data.List (elemIndex, minimumBy) | |
import Data.Maybe (fromMaybe) | |
import Debug.Trace (trace) | |
import System.IO (getLine) | |
import System.Random (randomIO, randomRIO) | |
data State = A | B | C | |
deriving (Eq, Read, Show) | |
type StateF = (State, [Double]) | |
type Table = [StateF] | |
-- | The mapping from a state to the probability of the other states | |
table :: Table | |
table = [(A, [0.3, 0.5, 0.2]) | |
,(B, [0.7, 0.3, 0.0]) | |
,(C, [0.2, 0.7, 0.1])] | |
-- | Find the next state in @Table@ according to the current @State@ and the given probability | |
step :: State -> Table -> Double -> State | |
step cs t x = do | |
let r = fst $ t !! ns | |
trace ("\nState: ns=" ++ show ns ++ ", sp=" ++ show sp ++ ", pr=" ++ show pr ++ ", x=" ++ show x) r | |
where pr = minimumBy (closestTo x) sp -- the smallest probability closest to x | |
sp = head $ map snd $ filter ((==) cs . fst) t -- the prob table for cs | |
ns = fromMaybe 0 (elemIndex pr sp) -- Our index in @t@ for the next element | |
closestTo :: (Ord a, Num a) => a -> a -> a -> Ordering | |
closestTo x = (\a b -> compare (abs $ x - a) (abs $ x - b)) | |
main :: IO () | |
main = do | |
print $ "Enter a state from " ++ show (map fst table) ++ "> " | |
cs <- getLine | |
se <- loop (read cs) 5 [] | |
print se | |
where loop _ 0 x = return x | |
loop cs c x = do | |
n <- randomIO | |
let ne = step cs table n | |
loop ne (c - 1) $ x ++ [cs] |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment