random-fu-multivariate 0.1.1.1 → 0.1.2.0
raw patch · 2 files changed
+1/−111 lines, 2 filesPVP: major bump suggested
API removals or changes: PVP suggests a major version bump
API changes (from Hackage documentation)
- Data.Random.Distribution.MultiNormal: instance GHC.TypeLits.KnownNat n => Data.Random.Distribution.Distribution Data.Random.Distribution.MultiNormal.MultiNormal (Internal.Static.R n)
- Data.Random.Distribution.MultiNormal: instance GHC.TypeLits.KnownNat n => Data.Random.Distribution.PDF Data.Random.Distribution.MultiNormal.MultiNormal (Internal.Static.R n)
- Data.Random.Distribution.MultiNormal: instance GHC.TypeLits.KnownNat n => GHC.Show.Show (Data.Random.Distribution.MultiNormal.MultiNormal (Internal.Static.R n))
- Data.Random.Distribution.MultiNormal: inv :: KnownNat n => Sq n -> Sq n
Files
random-fu-multivariate.cabal view
@@ -1,5 +1,5 @@ name: random-fu-multivariate-version: 0.1.1.1+version: 0.1.2.0 synopsis: Multivariate distributions for random-fu description: Please see README.md homepage: https://github.com/fpco/random-fu-multivariate@@ -23,7 +23,6 @@ hs-source-dirs: src exposed-modules: Data.Random.Distribution.MultivariateNormal , Data.Random.Distribution.Static.MultivariateNormal- , Data.Random.Distribution.MultiNormal ghc-options: -Wall build-depends: base >= 4.7 && < 5 , random-fu
− src/Data/Random/Distribution/MultiNormal.hs
@@ -1,109 +0,0 @@------------------------------------------------------------------- An implementation of multivariate normal distributions -------------------------------------------------------------------{--Written by: Dominic Steinitz, Jacob West-Last modified: 2016-07-27--Summary: Multivariate normal distributions are necessary for Kalman-filters and smoothers. However, strictly speaking, the functionality-provided here should exist elsewhere, perhaps in the package:-random-fu.--}--------------------------------- File header pragmas --------------------------------{-# LANGUAGE RecordWildCards #-} -- Used by multiNormalRV, multiNormalConstant- -- and multiNormalQuadraticForm-{-# LANGUAGE MultiParamTypeClasses #-} -- Necessary for Distribution instance-{-# LANGUAGE FlexibleInstances #-} -- Necessary for Show instance-{-# LANGUAGE TypeFamilies #-} -- Necessary for MultiNormal definition------------------------------ Module / Exports -----------------------------module Data.Random.Distribution.MultiNormal- (- MultiNormal(..)- , inv- )- where-------------------- Imports --------------------import Control.Monad (replicateM, when)-import Data.Maybe (fromMaybe, fromJust)-import Data.Random-import GHC.TypeLits-import Numeric.LinearAlgebra.Static--import qualified Numeric.LinearAlgebra as LA------------------------------ Helper Functions ------------------------------- Matrix inverse: for some reason, this isn't built into the--- static interface; warning: no error handling---- WARNING: Needs better error handling-inv :: KnownNat n => Sq n -> Sq n-inv = fromMaybe (error "Failed attempting to invert non-invertible matrix.") .- flip linSolve eye---------------------------------------------- Multivariate Normal Distrubtions ----------------------------------------------- This probably belongs elsewhere, maybe Data.Random, but that would--- create a dependence on Numric.LinearAlgebra which I believe is not--- there now and may be undesirable.--data family MultiNormal k :: *-data instance KnownNat n => MultiNormal (R n) =- MultiNormal { mu :: (R n), cov :: (Sym n) }----- Show Instance ----instance KnownNat n => Show (MultiNormal (R n)) where- show MultiNormal {..} = "Normal " ++ show mu ++ " " ++ show cov----- Distribution Instance ----instance KnownNat n => Distribution MultiNormal (R n) where- rvar = multiNormalRV---- WARNING: Needs better error handling-multiNormalRV :: KnownNat n => MultiNormal (R n) -> RVarT m (R n)-multiNormalRV MultiNormal {..} = do- let (vals, vecs) = eigensystem cov- when (any (<0) (LA.toList $ unwrap vals))- (error "Covariance matrix is not positive semi-definite.")-- let lSqrt = diag (fromJust . create $ LA.cmap sqrt (extract vals))- bigA = tr vecs <> lSqrt- - gnoise <- replicateM (size mu) (rvarT StdNormal)- return $ mu + bigA #> (vector gnoise)----- PDF Instance ----instance KnownNat n => PDF MultiNormal (R n) where- pdf = multiNormalPDF- logPdf = multiNormalLogPDF--multiNormalPDF :: KnownNat n => MultiNormal (R n) -> R n -> Double-multiNormalPDF mn pt =- multiNormalConstant mn * exp (multiNormalQuadraticForm mn pt)--multiNormalLogPDF :: KnownNat n => MultiNormal (R n) -> R n -> Double-multiNormalLogPDF mn pt =- multiNormalConstant mn + multiNormalQuadraticForm mn pt--multiNormalConstant :: KnownNat n => MultiNormal (R n) -> Double-multiNormalConstant MultiNormal {..} = recip . sqrt $ (2*pi)^n * detCov- where- n = size mu- detCov = LA.det . extract . unSym $ cov--multiNormalQuadraticForm :: KnownNat n => MultiNormal (R n) -> R n -> Double-multiNormalQuadraticForm MultiNormal {..} pt = (diff LA.<.> invCov LA.#> diff) / (-2)- where- diff = extract (mu - pt)- invCov = extract . inv . unSym $ cov