{-# OPTIONS_GHC -fplugin=GHC.TypeLits.KnownNat.Solver -fplugin=GHC.TypeLits.Normalise -fconstraint-solver-iterations=10 #-}
{-# LANGUAGE UndecidableInstances #-}

-- | Implementation of Conway-Maxwell Poisson distributions (CoMPoisson).
-- (<https://rss.onlinelibrary.wiley.com/doi/abs/10.1111/j.1467-9876.2005.00474.x>) CoMPoisson distributions generalize Poisson distributions with
-- a shape parameter that can concentrate or disperse the underlying Poisson
-- distribution.
module Goal.Probability.Distributions.CoMPoisson
    (
    -- * CoMPoisson
      CoMPoisson
    , CoMShape
    -- ** Numerics
    , comPoissonLogPartitionSum
    , comPoissonExpectations
    ) where

-- Package --

import Goal.Core
import Goal.Geometry

import Goal.Probability.Statistical
import Goal.Probability.ExponentialFamily
import Goal.Probability.Distributions

import qualified Goal.Core.Vector.Storable as S
import qualified System.Random.MWC as R


--- Analysis ---

--- CoMPoisson Distribution ---

-- | A type for storing the shape of a 'CoMPoisson' distribution.
data CoMShape

-- | The 'Manifold' of 'CoMPoisson' distributions. The 'Source' coordinates of the
-- 'CoMPoisson' are the mode $\mu$ and the "pseudo-precision" parameter $\nu$, such that $\mu / \nu$ is approximately the variance of the distribution.
type CoMPoisson = LocationShape Poisson CoMShape

-- | Approximates the log-partition function of the given CoMPoisson
-- distribution up to the specified precision.
comPoissonLogPartitionSum :: Double -> Natural # CoMPoisson -> Double
{-# INLINE comPoissonLogPartitionSum #-}
comPoissonLogPartitionSum :: Double -> (Natural # CoMPoisson) -> Double
comPoissonLogPartitionSum Double
eps Natural # CoMPoisson
np =
    let (Double
tht1,Double
tht2) = Vector 2 Double -> (Double, Double)
forall x. Storable x => Vector 2 x -> (x, x)
S.toPair (Vector 2 Double -> (Double, Double))
-> Vector 2 Double -> (Double, Double)
forall a b. (a -> b) -> a -> b
$ (Natural # CoMPoisson) -> Vector (Dimension CoMPoisson) Double
forall c x. Point c x -> Vector (Dimension x) Double
coordinates Natural # CoMPoisson
np
     in (Double, Int) -> Double
forall a b. (a, b) -> a
fst ((Double, Int) -> Double) -> (Double, Int) -> Double
forall a b. (a -> b) -> a -> b
$ Double -> Double -> Double -> (Double, Int)
comPoissonLogPartitionSum0 Double
eps Double
tht1 Double
tht2

-- | Approximates the expectations of functions given the natural parameters of
-- a CoM-Poisson distribution.
comPoissonExpectations
    :: KnownNat n
    => Double
    -> (Int -> S.Vector n Double)
    -> Natural # CoMPoisson
    -> S.Vector n Double
{-# INLINE comPoissonExpectations #-}
comPoissonExpectations :: Double
-> (Int -> Vector n Double)
-> (Natural # CoMPoisson)
-> Vector n Double
comPoissonExpectations Double
eps Int -> Vector n Double
f Natural # CoMPoisson
np =
    let (Double
tht1,Double
tht2) = Vector 2 Double -> (Double, Double)
forall x. Storable x => Vector 2 x -> (x, x)
S.toPair (Vector 2 Double -> (Double, Double))
-> Vector 2 Double -> (Double, Double)
forall a b. (a -> b) -> a -> b
$ (Natural # CoMPoisson) -> Vector (Dimension CoMPoisson) Double
forall c x. Point c x -> Vector (Dimension x) Double
coordinates Natural # CoMPoisson
np
        (Double
lgprt,Int
ln) = Double -> Double -> Double -> (Double, Int)
comPoissonLogPartitionSum0 Double
eps Double
tht1 Double
tht2
        js :: [Int]
js = [Int
0..Int
ln]
        dns :: [Double]
dns = Double -> Double
forall a. Floating a => a -> a
exp (Double -> Double) -> (Double -> Double) -> Double -> Double
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Double -> Double -> Double
forall a. Num a => a -> a -> a
subtract Double
lgprt (Double -> Double) -> [Double] -> [Double]
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> (Natural # CoMPoisson) -> Sample CoMPoisson -> [Double]
forall x.
ExponentialFamily x =>
(Natural # x) -> Sample x -> [Double]
unnormalizedLogDensities Natural # CoMPoisson
np [Int]
Sample CoMPoisson
js
     in [Vector n Double] -> Vector n Double
forall (t :: Type -> Type) a. (Foldable t, Num a) => t a -> a
sum ([Vector n Double] -> Vector n Double)
-> [Vector n Double] -> Vector n Double
forall a b. (a -> b) -> a -> b
$ (Double -> Vector n Double -> Vector n Double)
-> [Double] -> [Vector n Double] -> [Vector n Double]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith Double -> Vector n Double -> Vector n Double
forall x (n :: Nat). Numeric x => x -> Vector n x -> Vector n x
S.scale [Double]
dns (Int -> Vector n Double
f (Int -> Vector n Double) -> [Int] -> [Vector n Double]
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> [Int]
js)

-- | Approximates the mean mparameters of a CoM-Poisson distribution.
comPoissonMeans :: Double -> Natural # CoMPoisson -> Mean # CoMPoisson
{-# INLINE comPoissonMeans #-}
comPoissonMeans :: Double -> (Natural # CoMPoisson) -> Mean # CoMPoisson
comPoissonMeans Double
eps Natural # CoMPoisson
cp =
    let ss :: Int -> Mean # CoMPoisson
        ss :: Int -> Mean # CoMPoisson
ss = Int -> Mean # CoMPoisson
forall x. ExponentialFamily x => SamplePoint x -> Mean # x
sufficientStatistic
     in Vector (Dimension CoMPoisson) Double -> Mean # CoMPoisson
forall c x. Vector (Dimension x) Double -> Point c x
Point (Vector (Dimension CoMPoisson) Double -> Mean # CoMPoisson)
-> Vector (Dimension CoMPoisson) Double -> Mean # CoMPoisson
forall a b. (a -> b) -> a -> b
$ Double
-> (Int -> Vector 2 Double)
-> (Natural # CoMPoisson)
-> Vector 2 Double
forall (n :: Nat).
KnownNat n =>
Double
-> (Int -> Vector n Double)
-> (Natural # CoMPoisson)
-> Vector n Double
comPoissonExpectations Double
eps ((Mean # CoMPoisson) -> Vector 2 Double
forall c x. Point c x -> Vector (Dimension x) Double
coordinates ((Mean # CoMPoisson) -> Vector 2 Double)
-> (Int -> Mean # CoMPoisson) -> Int -> Vector 2 Double
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> Mean # CoMPoisson
ss) Natural # CoMPoisson
cp


--- Internal ---


comPoissonSequence :: Double -> Double -> [Double]
comPoissonSequence :: Double -> Double -> [Double]
comPoissonSequence Double
tht1 Double
tht2 =
    [ Double
tht1 Double -> Double -> Double
forall a. Num a => a -> a -> a
* Int -> Double
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
j Double -> Double -> Double
forall a. Num a => a -> a -> a
+ Int -> Double
forall a. Integral a => a -> Double
logFactorial Int
j Double -> Double -> Double
forall a. Num a => a -> a -> a
*Double
tht2 | (Int
j :: Int) <- [Int
0..] ]

comPoissonLogPartitionSum0 :: Double -> Double -> Double -> (Double, Int)
{-# INLINE comPoissonLogPartitionSum0 #-}
comPoissonLogPartitionSum0 :: Double -> Double -> Double -> (Double, Int)
comPoissonLogPartitionSum0 Double
eps Double
tht1 Double
tht2 =
    let md :: Int
md = Double -> Int
forall a b. (RealFrac a, Integral b) => a -> b
floor (Double -> Int) -> Double -> Int
forall a b. (a -> b) -> a -> b
$ Double -> Double -> Double
comPoissonSmoothMode Double
tht1 Double
tht2
        ([Double]
hdsqs,[Double]
tlsqs) = Int -> [Double] -> ([Double], [Double])
forall a. Int -> [a] -> ([a], [a])
splitAt Int
md ([Double] -> ([Double], [Double]))
-> [Double] -> ([Double], [Double])
forall a b. (a -> b) -> a -> b
$ Double -> Double -> [Double]
comPoissonSequence Double
tht1 Double
tht2
        mx :: Double
mx = Double
tht1 Double -> Double -> Double
forall a. Num a => a -> a -> a
* Int -> Double
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
md Double -> Double -> Double
forall a. Num a => a -> a -> a
+ Int -> Double
forall a. Integral a => a -> Double
logFactorial Int
md Double -> Double -> Double
forall a. Num a => a -> a -> a
*Double
tht2
        ehdsqs :: [Double]
ehdsqs = Double -> Double
forall a. Floating a => a -> a
exp (Double -> Double) -> (Double -> Double) -> Double -> Double
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Double -> Double -> Double
forall a. Num a => a -> a -> a
subtract Double
mx (Double -> Double) -> [Double] -> [Double]
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> [Double]
hdsqs
        etlsqs :: [Double]
etlsqs = Double -> Double
forall a. Floating a => a -> a
exp (Double -> Double) -> (Double -> Double) -> Double -> Double
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Double -> Double -> Double
forall a. Num a => a -> a -> a
subtract Double
mx (Double -> Double) -> [Double] -> [Double]
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> [Double]
tlsqs
        sqs' :: [Double]
sqs' = [Double]
ehdsqs [Double] -> [Double] -> [Double]
forall a. [a] -> [a] -> [a]
++ (Double -> Bool) -> [Double] -> [Double]
forall a. (a -> Bool) -> [a] -> [a]
takeWhile (Double -> Double -> Bool
forall a. Ord a => a -> a -> Bool
> Double
eps) [Double]
etlsqs
     in ((Double -> Double -> Double
forall a. Num a => a -> a -> a
+ Double
mx) (Double -> Double) -> (Double -> Double) -> Double -> Double
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Double -> Double
forall a. Floating a => a -> a
log1p (Double -> Double) -> (Double -> Double) -> Double -> Double
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Double -> Double -> Double
forall a. Num a => a -> a -> a
subtract Double
1 (Double -> Double) -> Double -> Double
forall a b. (a -> b) -> a -> b
$ [Double] -> Double
forall (t :: Type -> Type) a. (Foldable t, Num a) => t a -> a
sum [Double]
sqs' , [Double] -> Int
forall (t :: Type -> Type) a. Foldable t => t a -> Int
length [Double]
sqs')

comPoissonSmoothMode :: Double -> Double -> Double
comPoissonSmoothMode :: Double -> Double -> Double
comPoissonSmoothMode Double
tht1 Double
tht2 = Double -> Double
forall a. Floating a => a -> a
exp (Double
tht1Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/Double -> Double
forall a. Num a => a -> a
negate Double
tht2)

--comPoissonApproximateMean :: Double -> Double -> Double
--comPoissonApproximateMean mu nu =
--    mu + 1/(2*nu) - 0.5
--
--comPoissonApproximateVariance :: Double -> Double -> Double
--comPoissonApproximateVariance mu nu = mu / nu

overDispersedEnvelope :: Double -> Double -> Double -> Double
overDispersedEnvelope :: Double -> Double -> Double -> Double
overDispersedEnvelope Double
p Double
mu Double
nu =
    let mnm1 :: Double
mnm1 = Double
1 Double -> Double -> Double
forall a. Num a => a -> a -> a
- Double
p
        flrd :: Int
flrd = Int -> Int -> Int
forall a. Ord a => a -> a -> a
max Int
0 (Int -> Int) -> (Double -> Int) -> Double -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Double -> Int
forall a b. (RealFrac a, Integral b) => a -> b
floor (Double -> Int) -> Double -> Int
forall a b. (a -> b) -> a -> b
$ Double
mu Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/ (Double
mnm1Double -> Double -> Double
forall a. Floating a => a -> a -> a
**Double -> Double
forall a. Fractional a => a -> a
recip Double
nu)
        nmr :: Double
nmr = Double
muDouble -> Double -> Double
forall a. Floating a => a -> a -> a
**(Double
nu Double -> Double -> Double
forall a. Num a => a -> a -> a
* Int -> Double
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
flrd)
        dmr :: Double
dmr = (Double
mnm1Double -> Int -> Double
forall a b. (Num a, Integral b) => a -> b -> a
^Int
flrd) Double -> Double -> Double
forall a. Num a => a -> a -> a
* (Int -> Double
factorial Int
flrd Double -> Double -> Double
forall a. Floating a => a -> a -> a
** Double
nu)
     in Double -> Double
forall a. Fractional a => a -> a
recip Double
p Double -> Double -> Double
forall a. Num a => a -> a -> a
* Double
nmr Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/ Double
dmr

underDispersedEnvelope :: Double -> Double -> Double
underDispersedEnvelope :: Double -> Double -> Double
underDispersedEnvelope Double
mu Double
nu =
    let fmu :: Int
fmu = Double -> Int
forall a b. (RealFrac a, Integral b) => a -> b
floor Double
mu
     in (Double
mu Double -> Int -> Double
forall a b. (Num a, Integral b) => a -> b -> a
^ Int
fmu Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/ Int -> Double
factorial Int
fmu)Double -> Double -> Double
forall a. Floating a => a -> a -> a
** (Double
nu Double -> Double -> Double
forall a. Num a => a -> a -> a
- Double
1)

sampleOverDispersed :: Double -> Double -> Double -> Double -> Random Int
sampleOverDispersed :: Double -> Double -> Double -> Double -> Random Int
sampleOverDispersed Double
p Double
bnd0 Double
mu Double
nu = do
    Double
u0 <- (forall s. Gen s -> ST s Double) -> Random Double
forall a. (forall s. Gen s -> ST s a) -> Random a
Random forall s. Gen s -> ST s Double
forall a (m :: Type -> Type).
(Variate a, PrimMonad m) =>
Gen (PrimState m) -> m a
R.uniform
    let y' :: Int
y' = Int -> Int -> Int
forall a. Ord a => a -> a -> a
max Int
0 (Int -> Int) -> (Double -> Int) -> Double -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Double -> Int
forall a b. (RealFrac a, Integral b) => a -> b
floor (Double -> Int) -> Double -> Int
forall a b. (a -> b) -> a -> b
$ Double -> Double -> Double
forall a. Floating a => a -> a -> a
logBase (Double
1 Double -> Double -> Double
forall a. Num a => a -> a -> a
- Double
p) Double
u0
        nmr :: Double
nmr = (Double
muDouble -> Int -> Double
forall a b. (Num a, Integral b) => a -> b -> a
^Int
y' Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/ Int -> Double
factorial Int
y')Double -> Double -> Double
forall a. Floating a => a -> a -> a
**Double
nu
        dmr :: Double
dmr = Double
bnd0 Double -> Double -> Double
forall a. Num a => a -> a -> a
* (Double
1Double -> Double -> Double
forall a. Num a => a -> a -> a
-Double
p)Double -> Int -> Double
forall a b. (Num a, Integral b) => a -> b -> a
^Int
y' Double -> Double -> Double
forall a. Num a => a -> a -> a
* Double
p
        alph :: Double
alph = Double
nmrDouble -> Double -> Double
forall a. Fractional a => a -> a -> a
/Double
dmr
    Double
u <- (forall s. Gen s -> ST s Double) -> Random Double
forall a. (forall s. Gen s -> ST s a) -> Random a
Random forall s. Gen s -> ST s Double
forall a (m :: Type -> Type).
(Variate a, PrimMonad m) =>
Gen (PrimState m) -> m a
R.uniform
    if Double -> Bool
forall a. RealFloat a => a -> Bool
isNaN Double
alph
       then [Char] -> Random Int
forall a. HasCallStack => [Char] -> a
error [Char]
"NaN in sampling CoMPoisson: Parameters out of bounds"
       else if Double
u Double -> Double -> Bool
forall a. Ord a => a -> a -> Bool
<= Double
alph
       then Int -> Random Int
forall (m :: Type -> Type) a. Monad m => a -> m a
return Int
y'
       else Double -> Double -> Double -> Double -> Random Int
sampleOverDispersed Double
p Double
bnd0 Double
mu Double
nu

sampleUnderDispersed :: Double -> Double -> Double -> Random Int
sampleUnderDispersed :: Double -> Double -> Double -> Random Int
sampleUnderDispersed Double
bnd0 Double
mu Double
nu = do
    let psn :: Source # Poisson
        psn :: Source # Poisson
psn = Vector (Dimension Poisson) Double -> Source # Poisson
forall c x. Vector (Dimension x) Double -> Point c x
Point (Vector (Dimension Poisson) Double -> Source # Poisson)
-> Vector (Dimension Poisson) Double -> Source # Poisson
forall a b. (a -> b) -> a -> b
$ Double -> Vector 1 Double
forall a. Storable a => a -> Vector 1 a
S.singleton Double
mu
    Int
y' <- (Source # Poisson) -> Random (SamplePoint Poisson)
forall c x. Generative c x => Point c x -> Random (SamplePoint x)
samplePoint Source # Poisson
psn
    let alph0 :: Double
alph0 = Double
muDouble -> Int -> Double
forall a b. (Num a, Integral b) => a -> b -> a
^Int
y' Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/ Int -> Double
factorial Int
y'
        alph :: Double
alph = Double
alph0Double -> Double -> Double
forall a. Floating a => a -> a -> a
**Double
nu Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/ (Double
bnd0Double -> Double -> Double
forall a. Num a => a -> a -> a
*Double
alph0)
    Double
u <- (forall s. Gen s -> ST s Double) -> Random Double
forall a. (forall s. Gen s -> ST s a) -> Random a
Random forall s. Gen s -> ST s Double
forall a (m :: Type -> Type).
(Variate a, PrimMonad m) =>
Gen (PrimState m) -> m a
R.uniform
    if Double
u Double -> Double -> Bool
forall a. Ord a => a -> a -> Bool
<= Double
alph
       then Int -> Random Int
forall (m :: Type -> Type) a. Monad m => a -> m a
return Int
y'
    else Double -> Double -> Double -> Random Int
sampleUnderDispersed Double
bnd0 Double
mu Double
nu

sampleCoMPoisson :: Int -> Double -> Double -> Random [Int]
sampleCoMPoisson :: Int -> Double -> Double -> Random [Int]
sampleCoMPoisson Int
n Double
mu Double
nu
  | Double
nu Double -> Double -> Bool
forall a. Ord a => a -> a -> Bool
>= Double
1 =
      let bnd0 :: Double
bnd0 = Double -> Double -> Double
underDispersedEnvelope Double
mu Double
nu
       in Int -> Random Int -> Random [Int]
forall (m :: Type -> Type) a. Applicative m => Int -> m a -> m [a]
replicateM Int
n (Random Int -> Random [Int]) -> Random Int -> Random [Int]
forall a b. (a -> b) -> a -> b
$ Double -> Double -> Double -> Random Int
sampleUnderDispersed Double
bnd0 Double
mu Double
nu
  | Bool
otherwise =
      let p :: Double
p = Double
2Double -> Double -> Double
forall a. Num a => a -> a -> a
*Double
nu Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/ (Double
2Double -> Double -> Double
forall a. Num a => a -> a -> a
*Double
muDouble -> Double -> Double
forall a. Num a => a -> a -> a
*Double
nu Double -> Double -> Double
forall a. Num a => a -> a -> a
+ Double
1 Double -> Double -> Double
forall a. Num a => a -> a -> a
+ Double
nu)
          bnd0 :: Double
bnd0 = Double -> Double -> Double -> Double
overDispersedEnvelope Double
p Double
mu Double
nu
       in Int -> Random Int -> Random [Int]
forall (m :: Type -> Type) a. Applicative m => Int -> m a -> m [a]
replicateM Int
n (Random Int -> Random [Int]) -> Random Int -> Random [Int]
forall a b. (a -> b) -> a -> b
$ Double -> Double -> Double -> Double -> Random Int
sampleOverDispersed Double
p Double
bnd0 Double
mu Double
nu


-- Instances --


instance ExponentialFamily CoMPoisson where
    sufficientStatistic :: SamplePoint CoMPoisson -> Mean # CoMPoisson
sufficientStatistic SamplePoint CoMPoisson
k = (Double, Double) -> Mean # CoMPoisson
forall ds x c.
(IndexedListLiterals ds (Dimension x) Double,
 KnownNat (Dimension x)) =>
ds -> c # x
fromTuple (Int -> Double
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
SamplePoint CoMPoisson
k, Int -> Double
forall a. Integral a => a -> Double
logFactorial Int
SamplePoint CoMPoisson
k)
    logBaseMeasure :: Proxy CoMPoisson -> SamplePoint CoMPoisson -> Double
logBaseMeasure Proxy CoMPoisson
_ SamplePoint CoMPoisson
_ = Double
0

type instance PotentialCoordinates CoMPoisson = Natural

instance Legendre CoMPoisson where
    potential :: (PotentialCoordinates CoMPoisson # CoMPoisson) -> Double
potential =
         Double -> (Natural # CoMPoisson) -> Double
comPoissonLogPartitionSum Double
1e-16

instance AbsolutelyContinuous Natural CoMPoisson where
    logDensities :: (Natural # CoMPoisson) -> Sample CoMPoisson -> [Double]
logDensities = (Natural # CoMPoisson) -> Sample CoMPoisson -> [Double]
forall x.
(ExponentialFamily x, Legendre x,
 PotentialCoordinates x ~ Natural) =>
(Natural # x) -> Sample x -> [Double]
exponentialFamilyLogDensities

instance Transition Source Natural CoMPoisson where
    transition :: (Source # CoMPoisson) -> Natural # CoMPoisson
transition Source # CoMPoisson
p =
        let (Double
mu,Double
nu) = Vector 2 Double -> (Double, Double)
forall x. Storable x => Vector 2 x -> (x, x)
S.toPair (Vector 2 Double -> (Double, Double))
-> Vector 2 Double -> (Double, Double)
forall a b. (a -> b) -> a -> b
$ (Source # CoMPoisson) -> Vector (Dimension CoMPoisson) Double
forall c x. Point c x -> Vector (Dimension x) Double
coordinates Source # CoMPoisson
p
         in (Double, Double) -> Natural # CoMPoisson
forall ds x c.
(IndexedListLiterals ds (Dimension x) Double,
 KnownNat (Dimension x)) =>
ds -> c # x
fromTuple (Double
nu Double -> Double -> Double
forall a. Num a => a -> a -> a
* Double -> Double
forall a. Floating a => a -> a
log Double
mu, -Double
nu)

instance Transition Natural Source CoMPoisson where
    transition :: (Natural # CoMPoisson) -> Source # CoMPoisson
transition Natural # CoMPoisson
p =
        let (Double
tht1,Double
tht2) = Vector 2 Double -> (Double, Double)
forall x. Storable x => Vector 2 x -> (x, x)
S.toPair (Vector 2 Double -> (Double, Double))
-> Vector 2 Double -> (Double, Double)
forall a b. (a -> b) -> a -> b
$ (Natural # CoMPoisson) -> Vector (Dimension CoMPoisson) Double
forall c x. Point c x -> Vector (Dimension x) Double
coordinates Natural # CoMPoisson
p
         in (Double, Double) -> Source # CoMPoisson
forall ds x c.
(IndexedListLiterals ds (Dimension x) Double,
 KnownNat (Dimension x)) =>
ds -> c # x
fromTuple (Double -> Double
forall a. Floating a => a -> a
exp (-Double
tht1Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/Double
tht2), -Double
tht2)

instance (Transition c Source CoMPoisson) => Generative c CoMPoisson where
    sample :: Int -> Point c CoMPoisson -> Random (Sample CoMPoisson)
sample Int
n Point c CoMPoisson
p = do
        let (Double
mu,Double
nu) = Vector 2 Double -> (Double, Double)
forall x. Storable x => Vector 2 x -> (x, x)
S.toPair (Vector 2 Double -> (Double, Double))
-> ((Source # CoMPoisson) -> Vector 2 Double)
-> (Source # CoMPoisson)
-> (Double, Double)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Source # CoMPoisson) -> Vector 2 Double
forall c x. Point c x -> Vector (Dimension x) Double
coordinates ((Source # CoMPoisson) -> (Double, Double))
-> (Source # CoMPoisson) -> (Double, Double)
forall a b. (a -> b) -> a -> b
$ Point c CoMPoisson -> Source # CoMPoisson
forall c x. Transition c Source x => (c # x) -> Source # x
toSource Point c CoMPoisson
p
         in Int -> Double -> Double -> Random [Int]
sampleCoMPoisson Int
n Double
mu Double
nu

instance Transition Natural Mean CoMPoisson where
    transition :: (Natural # CoMPoisson) -> Mean # CoMPoisson
transition = Double -> (Natural # CoMPoisson) -> Mean # CoMPoisson
comPoissonMeans Double
1e-16

instance Transition Source Mean CoMPoisson where
    transition :: (Source # CoMPoisson) -> Mean # CoMPoisson
transition = (Natural # CoMPoisson) -> Mean # CoMPoisson
forall c x. Transition c Mean x => (c # x) -> Mean # x
toMean ((Natural # CoMPoisson) -> Mean # CoMPoisson)
-> ((Source # CoMPoisson) -> Natural # CoMPoisson)
-> (Source # CoMPoisson)
-> Mean # CoMPoisson
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Source # CoMPoisson) -> Natural # CoMPoisson
forall c x. Transition c Natural x => (c # x) -> Natural # x
toNatural

instance LogLikelihood Natural CoMPoisson Int where
    logLikelihood :: [Int] -> (Natural # CoMPoisson) -> Double
logLikelihood = [Int] -> (Natural # CoMPoisson) -> Double
forall x.
LegendreExponentialFamily x =>
Sample x -> (Natural # x) -> Double
exponentialFamilyLogLikelihood
    logLikelihoodDifferential :: [Int] -> (Natural # CoMPoisson) -> Natural #* CoMPoisson
logLikelihoodDifferential = [Int] -> (Natural # CoMPoisson) -> Natural #* CoMPoisson
forall x.
LegendreExponentialFamily x =>
Sample x -> (Natural # x) -> Mean # x
exponentialFamilyLogLikelihoodDifferential

instance Manifold CoMShape where
    type Dimension CoMShape = 1