module Biobase.Types.Partition where
import qualified Data.Vector.Unboxed as VU
import qualified Data.Vector.Generic as VG
import qualified Data.Vector.Generic.Mutable as VGM
import Data.Primitive.Types
import Biobase.Types.Ring
newtype Partition = Partition {unPartition' :: Double}
deriving (Show, Read, Eq, Ord)
mkPartition :: Double -> Partition
mkPartition x
| x < 0 = error $ "mkPartition: prob <0: " ++ show x
| x > 1 = error $ "mkPartition: prob >1: " ++ show x
| otherwise = Partition $ log x
unPartition :: Partition -> Double
unPartition (Partition x) = exp x
instance Ring Partition where
(Partition a) .+. (Partition b) = Partition $ logSum a b
(Partition a) .*. (Partition b) = Partition $ a + b
(Partition a) .^. k = Partition $ a * fromIntegral k
(Partition a) .^^. k = error ".^^. not defined for Partition"
neg (Partition a) = error $ "negate partition? " ++ show a
one = Partition 1
zero = Partition 0
isZero (Partition a) = a == 0
logSum :: Double -> Double -> Double
logSum a b
| a>b = f a b
| otherwise = f b a
where
f x y = x + log1p (exp $ y x)
deriving instance VGM.MVector VU.MVector Partition
deriving instance VG.Vector VU.Vector Partition
deriving instance VU.Unbox Partition
deriving instance Prim Partition
foreign import ccall unsafe "math.h log1p"
log1p :: Double -> Double
foreign import ccall unsafe "math.h expm1"
expm1 :: Double -> Double