{-# LANGUAGE GeneralizedNewtypeDeriving #-}
module LazyPPL.Distributions.DirichletP (
Restaurant, Table, newRestaurant, newCustomer,
dp) where
import Data.List
import Data.Maybe
import LazyPPL
import LazyPPL.Distributions
import LazyPPL.Distributions.Memoization (MonadMemo)
newtype Restaurant = R [Double]
newtype Table = T Int deriving (Table -> Table -> Bool
(Table -> Table -> Bool) -> (Table -> Table -> Bool) -> Eq Table
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Table -> Table -> Bool
== :: Table -> Table -> Bool
$c/= :: Table -> Table -> Bool
/= :: Table -> Table -> Bool
Eq, Int -> Table -> ShowS
[Table] -> ShowS
Table -> String
(Int -> Table -> ShowS)
-> (Table -> String) -> ([Table] -> ShowS) -> Show Table
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Table -> ShowS
showsPrec :: Int -> Table -> ShowS
$cshow :: Table -> String
show :: Table -> String
$cshowList :: [Table] -> ShowS
showList :: [Table] -> ShowS
Show, MonadMemo Prob)
newCustomer :: Restaurant -> Prob Table
newCustomer :: Restaurant -> Prob Table
newCustomer (R [Double]
restaurant) =
do
Double
r <- Prob Double
uniform
Table -> Prob Table
forall a. a -> Prob a
forall (m :: * -> *) a. Monad m => a -> m a
return (Table -> Prob Table) -> Table -> Prob Table
forall a b. (a -> b) -> a -> b
$ Int -> Table
T (Int -> Table) -> Int -> Table
forall a b. (a -> b) -> a -> b
$ Maybe Int -> Int
forall a. HasCallStack => Maybe a -> a
fromJust (Maybe Int -> Int) -> Maybe Int -> Int
forall a b. (a -> b) -> a -> b
$ (Double -> Bool) -> [Double] -> Maybe Int
forall a. (a -> Bool) -> [a] -> Maybe Int
findIndex (Double -> Double -> Bool
forall a. Ord a => a -> a -> Bool
> Double
r) ((Double -> Double -> Double) -> [Double] -> [Double]
forall a. (a -> a -> a) -> [a] -> [a]
scanl1 Double -> Double -> Double
forall a. Num a => a -> a -> a
(+) [Double]
restaurant)
newRestaurant :: Double
-> Prob Restaurant
newRestaurant :: Double -> Prob Restaurant
newRestaurant Double
alpha = do
[Double]
sticks <- Double -> Double -> Prob [Double]
stickBreaking Double
alpha Double
0
Restaurant -> Prob Restaurant
forall a. a -> Prob a
forall (m :: * -> *) a. Monad m => a -> m a
return (Restaurant -> Prob Restaurant) -> Restaurant -> Prob Restaurant
forall a b. (a -> b) -> a -> b
$ [Double] -> Restaurant
R [Double]
sticks
stickBreaking :: Double -> Double -> Prob [Double]
stickBreaking :: Double -> Double -> Prob [Double]
stickBreaking Double
alpha Double
lower =
do
Double
r <- Double -> Double -> Prob Double
beta Double
1 Double
alpha
let v :: Double
v = Double
r Double -> Double -> Double
forall a. Num a => a -> a -> a
* (Double
1 Double -> Double -> Double
forall a. Num a => a -> a -> a
- Double
lower)
[Double]
vs <- Double -> Double -> Prob [Double]
stickBreaking Double
alpha (Double
lower Double -> Double -> Double
forall a. Num a => a -> a -> a
+ Double
v)
[Double] -> Prob [Double]
forall a. a -> Prob a
forall (m :: * -> *) a. Monad m => a -> m a
return (Double
v Double -> [Double] -> [Double]
forall a. a -> [a] -> [a]
: [Double]
vs)
dp :: Double
-> Prob a
-> Prob (Prob a)
dp :: forall a. Double -> Prob a -> Prob (Prob a)
dp Double
alpha Prob a
p = do
[a]
xs <- Prob a -> Prob [a]
forall a. Prob a -> Prob [a]
iid Prob a
p
[Double]
vs <- Double -> Double -> Prob [Double]
stickBreaking Double
alpha Double
0
Prob a -> Prob (Prob a)
forall a. a -> Prob a
forall (m :: * -> *) a. Monad m => a -> m a
return (Prob a -> Prob (Prob a)) -> Prob a -> Prob (Prob a)
forall a b. (a -> b) -> a -> b
$ do
Double
r <- Prob Double
uniform
a -> Prob a
forall a. a -> Prob a
forall (m :: * -> *) a. Monad m => a -> m a
return (a -> Prob a) -> a -> Prob a
forall a b. (a -> b) -> a -> b
$ [a]
xs [a] -> Int -> a
forall a. HasCallStack => [a] -> Int -> a
!! Maybe Int -> Int
forall a. HasCallStack => Maybe a -> a
fromJust ((Double -> Bool) -> [Double] -> Maybe Int
forall a. (a -> Bool) -> [a] -> Maybe Int
findIndex (Double -> Double -> Bool
forall a. Ord a => a -> a -> Bool
> Double
r) ((Double -> Double -> Double) -> [Double] -> [Double]
forall a. (a -> a -> a) -> [a] -> [a]
scanl1 Double -> Double -> Double
forall a. Num a => a -> a -> a
(+) [Double]
vs))