module ELynx.MarkovProcess.SubstitutionModel
(
Name,
Params,
SubstitutionModel,
alphabet,
name,
params,
stationaryDistribution,
exchangeabilityMatrix,
rateMatrix,
totalRate,
Normalize (..),
substitutionModel,
scale,
normalize,
appendName,
)
where
import qualified Data.Vector.Storable as V
import ELynx.Alphabet.Alphabet
import qualified ELynx.MarkovProcess.RateMatrix as R
import qualified Numeric.LinearAlgebra as LinAlg
type Name = String
type Params = [Double]
data SubstitutionModel = SubstitutionModel
{
SubstitutionModel -> Alphabet
alphabet :: Alphabet,
SubstitutionModel -> Name
name :: Name,
SubstitutionModel -> Params
params :: Params,
SubstitutionModel -> StationaryDistribution
stationaryDistribution :: R.StationaryDistribution,
SubstitutionModel -> ExchangeabilityMatrix
exchangeabilityMatrix :: R.ExchangeabilityMatrix
}
deriving (Int -> SubstitutionModel -> ShowS
[SubstitutionModel] -> ShowS
SubstitutionModel -> Name
(Int -> SubstitutionModel -> ShowS)
-> (SubstitutionModel -> Name)
-> ([SubstitutionModel] -> ShowS)
-> Show SubstitutionModel
forall a.
(Int -> a -> ShowS) -> (a -> Name) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> SubstitutionModel -> ShowS
showsPrec :: Int -> SubstitutionModel -> ShowS
$cshow :: SubstitutionModel -> Name
show :: SubstitutionModel -> Name
$cshowList :: [SubstitutionModel] -> ShowS
showList :: [SubstitutionModel] -> ShowS
Show, ReadPrec [SubstitutionModel]
ReadPrec SubstitutionModel
Int -> ReadS SubstitutionModel
ReadS [SubstitutionModel]
(Int -> ReadS SubstitutionModel)
-> ReadS [SubstitutionModel]
-> ReadPrec SubstitutionModel
-> ReadPrec [SubstitutionModel]
-> Read SubstitutionModel
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
$creadsPrec :: Int -> ReadS SubstitutionModel
readsPrec :: Int -> ReadS SubstitutionModel
$creadList :: ReadS [SubstitutionModel]
readList :: ReadS [SubstitutionModel]
$creadPrec :: ReadPrec SubstitutionModel
readPrec :: ReadPrec SubstitutionModel
$creadListPrec :: ReadPrec [SubstitutionModel]
readListPrec :: ReadPrec [SubstitutionModel]
Read)
rateMatrix :: SubstitutionModel -> R.RateMatrix
rateMatrix :: SubstitutionModel -> ExchangeabilityMatrix
rateMatrix SubstitutionModel
sm =
ExchangeabilityMatrix
-> StationaryDistribution -> ExchangeabilityMatrix
R.fromExchangeabilityMatrix
(SubstitutionModel -> ExchangeabilityMatrix
exchangeabilityMatrix SubstitutionModel
sm)
(SubstitutionModel -> StationaryDistribution
stationaryDistribution SubstitutionModel
sm)
totalRate :: SubstitutionModel -> Double
totalRate :: SubstitutionModel -> Double
totalRate SubstitutionModel
sm = ExchangeabilityMatrix -> Double
R.totalRate (SubstitutionModel -> ExchangeabilityMatrix
rateMatrix SubstitutionModel
sm)
normalizeSumVec :: V.Vector Double -> V.Vector Double
normalizeSumVec :: StationaryDistribution -> StationaryDistribution
normalizeSumVec StationaryDistribution
v = (Double -> Double)
-> StationaryDistribution -> StationaryDistribution
forall a b.
(Storable a, Storable b) =>
(a -> b) -> Vector a -> Vector b
V.map (Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/ Double
s) StationaryDistribution
v
where
s :: Double
s = StationaryDistribution -> Double
forall a. (Storable a, Num a) => Vector a -> a
V.sum StationaryDistribution
v
{-# INLINE normalizeSumVec #-}
data Normalize = DoNormalize | DoNotNormalize
deriving (Int -> Normalize -> ShowS
[Normalize] -> ShowS
Normalize -> Name
(Int -> Normalize -> ShowS)
-> (Normalize -> Name) -> ([Normalize] -> ShowS) -> Show Normalize
forall a.
(Int -> a -> ShowS) -> (a -> Name) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Normalize -> ShowS
showsPrec :: Int -> Normalize -> ShowS
$cshow :: Normalize -> Name
show :: Normalize -> Name
$cshowList :: [Normalize] -> ShowS
showList :: [Normalize] -> ShowS
Show, ReadPrec [Normalize]
ReadPrec Normalize
Int -> ReadS Normalize
ReadS [Normalize]
(Int -> ReadS Normalize)
-> ReadS [Normalize]
-> ReadPrec Normalize
-> ReadPrec [Normalize]
-> Read Normalize
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
$creadsPrec :: Int -> ReadS Normalize
readsPrec :: Int -> ReadS Normalize
$creadList :: ReadS [Normalize]
readList :: ReadS [Normalize]
$creadPrec :: ReadPrec Normalize
readPrec :: ReadPrec Normalize
$creadListPrec :: ReadPrec [Normalize]
readListPrec :: ReadPrec [Normalize]
Read, Normalize -> Normalize -> Bool
(Normalize -> Normalize -> Bool)
-> (Normalize -> Normalize -> Bool) -> Eq Normalize
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Normalize -> Normalize -> Bool
== :: Normalize -> Normalize -> Bool
$c/= :: Normalize -> Normalize -> Bool
/= :: Normalize -> Normalize -> Bool
Eq)
substitutionModel ::
Alphabet ->
Name ->
Params ->
Normalize ->
R.StationaryDistribution ->
R.ExchangeabilityMatrix ->
SubstitutionModel
substitutionModel :: Alphabet
-> Name
-> Params
-> Normalize
-> StationaryDistribution
-> ExchangeabilityMatrix
-> SubstitutionModel
substitutionModel Alphabet
c Name
n Params
ps Normalize
nz StationaryDistribution
d ExchangeabilityMatrix
e =
if StationaryDistribution -> Bool
R.isValid StationaryDistribution
d
then
let sm :: SubstitutionModel
sm = Alphabet
-> Name
-> Params
-> StationaryDistribution
-> ExchangeabilityMatrix
-> SubstitutionModel
SubstitutionModel Alphabet
c Name
n Params
ps (StationaryDistribution -> StationaryDistribution
normalizeSumVec StationaryDistribution
d) ExchangeabilityMatrix
e
in case Normalize
nz of
Normalize
DoNormalize -> SubstitutionModel -> SubstitutionModel
normalize SubstitutionModel
sm
Normalize
DoNotNormalize -> SubstitutionModel
sm
else
Name -> SubstitutionModel
forall a. HasCallStack => Name -> a
error (Name -> SubstitutionModel) -> Name -> SubstitutionModel
forall a b. (a -> b) -> a -> b
$
Name
"substitionModel: Stationary distribution does not sum to 1.0: "
Name -> ShowS
forall a. [a] -> [a] -> [a]
++ StationaryDistribution -> Name
forall a. Show a => a -> Name
show StationaryDistribution
d
scale :: Double -> SubstitutionModel -> SubstitutionModel
scale :: Double -> SubstitutionModel -> SubstitutionModel
scale Double
r SubstitutionModel
sm = SubstitutionModel
sm {exchangeabilityMatrix = em'}
where
em' :: ExchangeabilityMatrix
em' = Double -> ExchangeabilityMatrix -> ExchangeabilityMatrix
forall t (c :: * -> *). Linear t c => t -> c t -> c t
LinAlg.scale Double
r (ExchangeabilityMatrix -> ExchangeabilityMatrix)
-> ExchangeabilityMatrix -> ExchangeabilityMatrix
forall a b. (a -> b) -> a -> b
$ SubstitutionModel -> ExchangeabilityMatrix
exchangeabilityMatrix SubstitutionModel
sm
normalize :: SubstitutionModel -> SubstitutionModel
normalize :: SubstitutionModel -> SubstitutionModel
normalize SubstitutionModel
sm = Double -> SubstitutionModel -> SubstitutionModel
scale (Double
1.0 Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/ Double
r) SubstitutionModel
sm where r :: Double
r = SubstitutionModel -> Double
totalRate SubstitutionModel
sm
appendName :: Name -> SubstitutionModel -> SubstitutionModel
appendName :: Name -> SubstitutionModel -> SubstitutionModel
appendName Name
n SubstitutionModel
sm = SubstitutionModel
sm {name = n'} where n' :: Name
n' = SubstitutionModel -> Name
name SubstitutionModel
sm Name -> ShowS
forall a. Semigroup a => a -> a -> a
<> Name
n