module ELynx.Sequence.Alignment
( Alignment (..),
length,
nSequences,
fromSequences,
toSequences,
summarize,
join,
concat,
concatAlignments,
filterColsConstant,
filterColsConstantSoft,
filterColsOnlyStd,
filterColsStd,
filterColsNoGaps,
FrequencyData,
distribution,
toFrequencyData,
kEffEntropy,
kEffHomoplasy,
countIUPACChars,
countGaps,
countUnknowns,
subSample,
randomSubSample,
)
where
import Control.Monad hiding (join)
import Control.Parallel.Strategies
import qualified Data.ByteString.Lazy.Char8 as BL
import Data.List hiding
( concat,
length,
)
import qualified Data.Matrix.Unboxed as M
import qualified Data.Vector.Unboxed as V
import qualified ELynx.Alphabet.Alphabet as A
import ELynx.Alphabet.Character
import qualified ELynx.Alphabet.DistributionDiversity as D
import ELynx.Sequence.Defaults
import qualified ELynx.Sequence.Sequence as S
import System.Random.Stateful
import Prelude hiding
( concat,
length,
)
data Alignment = Alignment
{ Alignment -> [Name]
names :: [S.Name],
Alignment -> [Name]
descriptions :: [S.Description],
Alignment -> Alphabet
alphabet :: A.Alphabet,
Alignment -> Matrix Character
matrix :: M.Matrix Character
}
deriving (Int -> Alignment -> ShowS
[Alignment] -> ShowS
Alignment -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Alignment] -> ShowS
$cshowList :: [Alignment] -> ShowS
show :: Alignment -> String
$cshow :: Alignment -> String
showsPrec :: Int -> Alignment -> ShowS
$cshowsPrec :: Int -> Alignment -> ShowS
Show, Alignment -> Alignment -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Alignment -> Alignment -> Bool
$c/= :: Alignment -> Alignment -> Bool
== :: Alignment -> Alignment -> Bool
$c== :: Alignment -> Alignment -> Bool
Eq)
length :: Alignment -> Int
length :: Alignment -> Int
length = forall a. Context a => Matrix a -> Int
M.cols forall b c a. (b -> c) -> (a -> b) -> a -> c
. Alignment -> Matrix Character
matrix
nSequences :: Alignment -> Int
nSequences :: Alignment -> Int
nSequences = forall a. Context a => Matrix a -> Int
M.rows forall b c a. (b -> c) -> (a -> b) -> a -> c
. Alignment -> Matrix Character
matrix
fromSequences :: [S.Sequence] -> Either String Alignment
fromSequences :: [Sequence] -> Either String Alignment
fromSequences [Sequence]
ss
| [Sequence] -> Bool
S.equalLength [Sequence]
ss Bool -> Bool -> Bool
&& forall {a}. Eq a => [a] -> Bool
allEqual (forall a b. (a -> b) -> [a] -> [b]
map Sequence -> Alphabet
S.alphabet [Sequence]
ss) =
forall a b. b -> Either a b
Right forall a b. (a -> b) -> a -> b
$
[Name] -> [Name] -> Alphabet -> Matrix Character -> Alignment
Alignment [Name]
ns [Name]
ds Alphabet
a Matrix Character
d
| [Sequence] -> Bool
S.equalLength [Sequence]
ss = forall a b. a -> Either a b
Left String
"Sequences do not have equal codes."
| Bool
otherwise = forall a b. a -> Either a b
Left String
"Sequences do not have equal lengths."
where
ns :: [Name]
ns = forall a b. (a -> b) -> [a] -> [b]
map Sequence -> Name
S.name [Sequence]
ss
ds :: [Name]
ds = forall a b. (a -> b) -> [a] -> [b]
map Sequence -> Name
S.description [Sequence]
ss
a :: Alphabet
a = Sequence -> Alphabet
S.alphabet forall a b. (a -> b) -> a -> b
$ forall a. [a] -> a
head [Sequence]
ss
bss :: [Vector Character]
bss = forall a b. (a -> b) -> [a] -> [b]
map Sequence -> Vector Character
S.characters [Sequence]
ss
d :: Matrix Character
d = forall a. Context a => [Vector a] -> Matrix a
M.fromRows [Vector Character]
bss
allEqual :: [a] -> Bool
allEqual [] = Bool
True
allEqual [a]
xs = forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all (forall a. Eq a => a -> a -> Bool
== forall a. [a] -> a
head [a]
xs) forall a b. (a -> b) -> a -> b
$ forall a. [a] -> [a]
tail [a]
xs
toSequences :: Alignment -> [S.Sequence]
toSequences :: Alignment -> [Sequence]
toSequences (Alignment [Name]
ns [Name]
ds Alphabet
a Matrix Character
da) =
forall a b c d. (a -> b -> c -> d) -> [a] -> [b] -> [c] -> [d]
zipWith3
(\Name
n Name
d Vector Character
r -> Name -> Name -> Alphabet -> Vector Character -> Sequence
S.Sequence Name
n Name
d Alphabet
a Vector Character
r)
[Name]
ns
[Name]
ds
[Vector Character]
rows
where
rows :: [Vector Character]
rows = forall a. Context a => Matrix a -> [Vector a]
M.toRows Matrix Character
da
header :: Alignment -> BL.ByteString
Alignment
a =
[Name] -> Name
BL.unlines forall a b. (a -> b) -> a -> b
$
[ String -> Name
BL.pack String
"Multi sequence alignment.",
String -> Name
BL.pack forall a b. (a -> b) -> a -> b
$ String
"Code: " forall a. [a] -> [a] -> [a]
++ Alphabet -> String
A.alphabetDescription (Alignment -> Alphabet
alphabet Alignment
a) forall a. [a] -> [a] -> [a]
++ String
".",
String -> Name
BL.pack forall a b. (a -> b) -> a -> b
$ String
"Length: " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show (Alignment -> Int
length Alignment
a) forall a. [a] -> [a] -> [a]
++ String
"."
]
forall a. [a] -> [a] -> [a]
++ [Name]
reportLengthSummary
forall a. [a] -> [a] -> [a]
++ [Name]
reportNumberSummary
where
reportLengthSummary :: [Name]
reportLengthSummary =
[ String -> Name
BL.pack forall a b. (a -> b) -> a -> b
$
String
"For each sequence, the "
forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show Int
summaryLength
forall a. [a] -> [a] -> [a]
++ String
" first bases are shown."
| Alignment -> Int
length Alignment
a forall a. Ord a => a -> a -> Bool
> Int
summaryLength
]
reportNumberSummary :: [Name]
reportNumberSummary =
[ String -> Name
BL.pack forall a b. (a -> b) -> a -> b
$
forall a. Show a => a -> String
show Int
summaryNSequences
forall a. [a] -> [a] -> [a]
++ String
" out of "
forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show (Alignment -> Int
nSequences Alignment
a)
forall a. [a] -> [a] -> [a]
++ String
" sequences are shown."
| Alignment -> Int
nSequences Alignment
a forall a. Ord a => a -> a -> Bool
> Int
summaryNSequences
]
summarize :: Alignment -> BL.ByteString
summarize :: Alignment -> Name
summarize Alignment
a = Alignment -> Name
header Alignment
a forall a. Semigroup a => a -> a -> a
<> [Sequence] -> Name
S.body (Alignment -> [Sequence]
toSequences Alignment
a)
(===) :: V.Unbox a => M.Matrix a -> M.Matrix a -> M.Matrix a
=== :: forall a. Unbox a => Matrix a -> Matrix a -> Matrix a
(===) Matrix a
l Matrix a
r = forall a. Context a => [Vector a] -> Matrix a
M.fromRows forall a b. (a -> b) -> a -> b
$ [Vector a]
lRs forall a. [a] -> [a] -> [a]
++ [Vector a]
rRs
where
lRs :: [Vector a]
lRs = forall a. Context a => Matrix a -> [Vector a]
M.toRows Matrix a
l
rRs :: [Vector a]
rRs = forall a. Context a => Matrix a -> [Vector a]
M.toRows Matrix a
r
(|||) :: V.Unbox a => M.Matrix a -> M.Matrix a -> M.Matrix a
||| :: forall a. Unbox a => Matrix a -> Matrix a -> Matrix a
(|||) Matrix a
l Matrix a
r = forall a. Context a => [Vector a] -> Matrix a
M.fromColumns forall a b. (a -> b) -> a -> b
$ [Vector a]
lCs forall a. [a] -> [a] -> [a]
++ [Vector a]
rCs
where
lCs :: [Vector a]
lCs = forall a. Context a => Matrix a -> [Vector a]
M.toColumns Matrix a
l
rCs :: [Vector a]
rCs = forall a. Context a => Matrix a -> [Vector a]
M.toColumns Matrix a
r
join :: Alignment -> Alignment -> Alignment
join :: Alignment -> Alignment -> Alignment
join Alignment
t Alignment
b
| Alignment -> Int
length Alignment
t forall a. Eq a => a -> a -> Bool
/= Alignment -> Int
length Alignment
b =
forall a. HasCallStack => String -> a
error
String
"join: Multi sequence alignments do not have equal lengths."
| Alignment -> Alphabet
alphabet Alignment
t forall a. Eq a => a -> a -> Bool
/= Alignment -> Alphabet
alphabet Alignment
b =
forall a. HasCallStack => String -> a
error
String
"join: Multi sequence alignments do not have equal alphabets."
| Bool
otherwise = [Name] -> [Name] -> Alphabet -> Matrix Character -> Alignment
Alignment [Name]
ns [Name]
ds Alphabet
al (Matrix Character
tD forall a. Unbox a => Matrix a -> Matrix a -> Matrix a
=== Matrix Character
bD)
where
ns :: [Name]
ns = Alignment -> [Name]
names Alignment
t forall a. [a] -> [a] -> [a]
++ Alignment -> [Name]
names Alignment
b
ds :: [Name]
ds = Alignment -> [Name]
descriptions Alignment
t forall a. [a] -> [a] -> [a]
++ Alignment -> [Name]
descriptions Alignment
b
tD :: Matrix Character
tD = Alignment -> Matrix Character
matrix Alignment
t
bD :: Matrix Character
bD = Alignment -> Matrix Character
matrix Alignment
b
al :: Alphabet
al = Alignment -> Alphabet
alphabet Alignment
t
concat :: Alignment -> Alignment -> Alignment
concat :: Alignment -> Alignment -> Alignment
concat Alignment
l Alignment
r
| Alignment -> Int
nSequences Alignment
l forall a. Eq a => a -> a -> Bool
/= Alignment -> Int
nSequences Alignment
r =
forall a. HasCallStack => String -> a
error
String
"concat: Multi sequence alignments do not have an equal number of sequences."
| Alignment -> Alphabet
alphabet Alignment
l forall a. Eq a => a -> a -> Bool
/= Alignment -> Alphabet
alphabet Alignment
r =
forall a. HasCallStack => String -> a
error String
"concat: Multi sequence alignments do not have an equal alphabets."
| Alignment -> [Name]
names Alignment
l forall a. Eq a => a -> a -> Bool
/= Alignment -> [Name]
names Alignment
r =
forall a. HasCallStack => String -> a
error String
"concat: Multi sequence alignments do not have an equal names."
| Alignment -> [Name]
descriptions Alignment
l forall a. Eq a => a -> a -> Bool
/= Alignment -> [Name]
descriptions Alignment
r =
forall a. HasCallStack => String -> a
error String
"concat: Multi sequence alignments do not have an equal descriptions."
| Bool
otherwise =
[Name] -> [Name] -> Alphabet -> Matrix Character -> Alignment
Alignment (Alignment -> [Name]
names Alignment
l) (Alignment -> [Name]
descriptions Alignment
l) (Alignment -> Alphabet
alphabet Alignment
l) (Matrix Character
lD forall a. Unbox a => Matrix a -> Matrix a -> Matrix a
||| Matrix Character
rD)
where
lD :: Matrix Character
lD = Alignment -> Matrix Character
matrix Alignment
l
rD :: Matrix Character
rD = Alignment -> Matrix Character
matrix Alignment
r
concatAlignments :: [Alignment] -> Alignment
concatAlignments :: [Alignment] -> Alignment
concatAlignments [] = forall a. HasCallStack => String -> a
error String
"concatAlignments: Nothing to concatenate."
concatAlignments [Alignment
a] = Alignment
a
concatAlignments [Alignment]
as = forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' Alignment -> Alignment -> Alignment
concat (forall a. [a] -> a
head [Alignment]
as) (forall a. [a] -> [a]
tail [Alignment]
as)
filterColsWith :: (V.Vector Character -> Bool) -> Alignment -> Alignment
filterColsWith :: (Vector Character -> Bool) -> Alignment -> Alignment
filterColsWith Vector Character -> Bool
p Alignment
a = Alignment
a {matrix :: Matrix Character
matrix = Matrix Character
m'}
where
m' :: Matrix Character
m' = forall a. Context a => [Vector a] -> Matrix a
M.fromColumns forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. (a -> Bool) -> [a] -> [a]
filter Vector Character -> Bool
p forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Context a => Matrix a -> [Vector a]
M.toColumns forall a b. (a -> b) -> a -> b
$ Alignment -> Matrix Character
matrix Alignment
a
filterColsConstant :: Alignment -> Alignment
filterColsConstant :: Alignment -> Alignment
filterColsConstant = (Vector Character -> Bool) -> Alignment -> Alignment
filterColsWith (\Vector Character
v -> forall a. Unbox a => (a -> Bool) -> Vector a -> Bool
V.all (forall a. Eq a => a -> a -> Bool
== forall a. Unbox a => Vector a -> a
V.head Vector Character
v) Vector Character
v)
filterColsConstantSoft :: Alignment -> Alignment
filterColsConstantSoft :: Alignment -> Alignment
filterColsConstantSoft Alignment
a = (Vector Character -> Bool) -> Alignment -> Alignment
filterColsWith Vector Character -> Bool
f Alignment
a
where
al :: Alphabet
al = Alignment -> Alphabet
alphabet Alignment
a
f :: Vector Character -> Bool
f Vector Character
v = case forall a. Unbox a => (a -> Bool) -> Vector a -> Maybe a
V.find (Alphabet -> Character -> Bool
A.isStd Alphabet
al) Vector Character
v of
Maybe Character
Nothing -> Bool
False
Just Character
c -> forall a. Unbox a => (a -> Bool) -> Vector a -> Bool
V.all (\Character
x -> Character
x forall a. Eq a => a -> a -> Bool
== Character
c Bool -> Bool -> Bool
|| Alphabet -> Character -> Bool
A.isGap Alphabet
al Character
x Bool -> Bool -> Bool
|| Alphabet -> Character -> Bool
A.isUnknown Alphabet
al Character
x) Vector Character
v
filterColsOnlyStd :: Alignment -> Alignment
filterColsOnlyStd :: Alignment -> Alignment
filterColsOnlyStd Alignment
a = (Vector Character -> Bool) -> Alignment -> Alignment
filterColsWith (forall a. Unbox a => (a -> Bool) -> Vector a -> Bool
V.all forall a b. (a -> b) -> a -> b
$ Alphabet -> Character -> Bool
A.isStd (Alignment -> Alphabet
alphabet Alignment
a)) Alignment
a
filterColsStd :: Double -> Alignment -> Alignment
filterColsStd :: Double -> Alignment -> Alignment
filterColsStd Double
prop Alignment
a =
(Vector Character -> Bool) -> Alignment -> Alignment
filterColsWith
(\Vector Character
col -> Double
prop forall a. Num a => a -> a -> a
* Double
n forall a. Ord a => a -> a -> Bool
<= forall a b. (Integral a, Num b) => a -> b
fromIntegral (forall a. Unbox a => Vector a -> Int
V.length (forall a. Unbox a => (a -> Bool) -> Vector a -> Vector a
V.filter (Alphabet -> Character -> Bool
A.isStd Alphabet
al) Vector Character
col)))
Alignment
a
where
al :: Alphabet
al = Alignment -> Alphabet
alphabet Alignment
a
n :: Double
n = forall a b. (Integral a, Num b) => a -> b
fromIntegral forall a b. (a -> b) -> a -> b
$ Alignment -> Int
nSequences Alignment
a
filterColsNoGaps :: Alignment -> Alignment
filterColsNoGaps :: Alignment -> Alignment
filterColsNoGaps Alignment
a = (Vector Character -> Bool) -> Alignment -> Alignment
filterColsWith (forall a. Unbox a => (a -> Bool) -> Vector a -> Bool
V.all forall a b. (a -> b) -> a -> b
$ Bool -> Bool
not forall b c a. (b -> c) -> (a -> b) -> a -> c
. Alphabet -> Character -> Bool
A.isGap (Alignment -> Alphabet
alphabet Alignment
a)) Alignment
a
type FrequencyData = M.Matrix Double
fMapColParChunk ::
(V.Unbox a, V.Unbox b) =>
Int ->
(V.Vector a -> V.Vector b) ->
M.Matrix a ->
M.Matrix b
fMapColParChunk :: forall a b.
(Unbox a, Unbox b) =>
Int -> (Vector a -> Vector b) -> Matrix a -> Matrix b
fMapColParChunk Int
n Vector a -> Vector b
f Matrix a
m =
forall a. Context a => [Vector a] -> Matrix a
M.fromColumns (forall a b. (a -> b) -> [a] -> [b]
map Vector a -> Vector b
f (forall a. Context a => Matrix a -> [Vector a]
M.toColumns Matrix a
m) forall a. a -> Strategy a -> a
`using` forall a. Int -> Strategy a -> Strategy [a]
parListChunk Int
n forall a. Strategy a
rseq)
toFrequencyData :: Alignment -> FrequencyData
toFrequencyData :: Alignment -> FrequencyData
toFrequencyData Alignment
a = forall a b.
(Unbox a, Unbox b) =>
Int -> (Vector a -> Vector b) -> Matrix a -> Matrix b
fMapColParChunk Int
100 (forall (v :: * -> *).
(Vector v Character, Vector v Int, Vector v Double) =>
AlphabetSpec -> v Character -> v Double
D.frequencyCharacters AlphabetSpec
spec) (Alignment -> Matrix Character
matrix Alignment
a)
where
spec :: AlphabetSpec
spec = Alphabet -> AlphabetSpec
A.alphabetSpec (Alignment -> Alphabet
alphabet Alignment
a)
distribution :: FrequencyData -> [Double]
distribution :: FrequencyData -> [Double]
distribution FrequencyData
fd =
forall a b. (a -> b) -> [a] -> [b]
map (forall a. Fractional a => a -> a -> a
/ forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
nSites) forall a b. (a -> b) -> a -> b
$
forall a. Unbox a => Vector a -> [a]
V.toList forall a b. (a -> b) -> a -> b
$
forall (t :: * -> *) a. Foldable t => (a -> a -> a) -> t a -> a
foldl1
(forall a b c.
(Unbox a, Unbox b, Unbox c) =>
(a -> b -> c) -> Vector a -> Vector b -> Vector c
V.zipWith forall a. Num a => a -> a -> a
(+))
(forall a. Context a => Matrix a -> [Vector a]
M.toColumns FrequencyData
fd)
where
nSites :: Int
nSites = forall a. Context a => Matrix a -> Int
M.cols FrequencyData
fd
parMapChunk :: Int -> (a -> b) -> [a] -> [b]
parMapChunk :: forall a b. Int -> (a -> b) -> [a] -> [b]
parMapChunk Int
n a -> b
f [a]
as = forall a b. (a -> b) -> [a] -> [b]
map a -> b
f [a]
as forall a. a -> Strategy a -> a
`using` forall a. Int -> Strategy a -> Strategy [a]
parListChunk Int
n forall a. Strategy a
rseq
chunksize :: Int
chunksize :: Int
chunksize = Int
500
kEffEntropy :: FrequencyData -> [Double]
kEffEntropy :: FrequencyData -> [Double]
kEffEntropy FrequencyData
fd = forall a b. Int -> (a -> b) -> [a] -> [b]
parMapChunk Int
chunksize forall (v :: * -> *). Vector v Double => v Double -> Double
D.kEffEntropy (forall a. Context a => Matrix a -> [Vector a]
M.toColumns FrequencyData
fd)
kEffHomoplasy :: FrequencyData -> [Double]
kEffHomoplasy :: FrequencyData -> [Double]
kEffHomoplasy FrequencyData
fd = forall a b. Int -> (a -> b) -> [a] -> [b]
parMapChunk Int
chunksize forall (v :: * -> *). Vector v Double => v Double -> Double
D.kEffHomoplasy (forall a. Context a => Matrix a -> [Vector a]
M.toColumns FrequencyData
fd)
countIUPACChars :: Alignment -> Int
countIUPACChars :: Alignment -> Int
countIUPACChars Alignment
a = forall a. Unbox a => Vector a -> Int
V.length forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Unbox a => (a -> Bool) -> Vector a -> Vector a
V.filter (Alphabet -> Character -> Bool
A.isIUPAC (Alignment -> Alphabet
alphabet Alignment
a)) forall a b. (a -> b) -> a -> b
$ Vector Character
allChars
where
allChars :: Vector Character
allChars = forall a. Context a => Matrix a -> Vector a
M.flatten forall a b. (a -> b) -> a -> b
$ Alignment -> Matrix Character
matrix Alignment
a
countGaps :: Alignment -> Int
countGaps :: Alignment -> Int
countGaps Alignment
a = forall a. Unbox a => Vector a -> Int
V.length forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Unbox a => (a -> Bool) -> Vector a -> Vector a
V.filter (Alphabet -> Character -> Bool
A.isGap (Alignment -> Alphabet
alphabet Alignment
a)) forall a b. (a -> b) -> a -> b
$ Vector Character
allChars
where
allChars :: Vector Character
allChars = forall a. Context a => Matrix a -> Vector a
M.flatten forall a b. (a -> b) -> a -> b
$ Alignment -> Matrix Character
matrix Alignment
a
countUnknowns :: Alignment -> Int
countUnknowns :: Alignment -> Int
countUnknowns Alignment
a = forall a. Unbox a => Vector a -> Int
V.length forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Unbox a => (a -> Bool) -> Vector a -> Vector a
V.filter (Alphabet -> Character -> Bool
A.isUnknown (Alignment -> Alphabet
alphabet Alignment
a)) forall a b. (a -> b) -> a -> b
$ Vector Character
allChars
where
allChars :: Vector Character
allChars = forall a. Context a => Matrix a -> Vector a
M.flatten forall a b. (a -> b) -> a -> b
$ Alignment -> Matrix Character
matrix Alignment
a
subSampleMatrix :: V.Unbox a => [Int] -> M.Matrix a -> M.Matrix a
subSampleMatrix :: forall a. Unbox a => [Int] -> Matrix a -> Matrix a
subSampleMatrix [Int]
is Matrix a
m =
forall a. Context a => [Vector a] -> Matrix a
M.fromColumns forall a b. (a -> b) -> a -> b
$ forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' (\[Vector a]
a Int
i -> forall a. Context a => Matrix a -> Int -> Vector a
M.takeColumn Matrix a
m Int
i forall a. a -> [a] -> [a]
: [Vector a]
a) [] (forall a. [a] -> [a]
reverse [Int]
is)
subSample :: [Int] -> Alignment -> Alignment
subSample :: [Int] -> Alignment -> Alignment
subSample [Int]
is Alignment
a = Alignment
a {matrix :: Matrix Character
matrix = Matrix Character
m'} where m' :: Matrix Character
m' = forall a. Unbox a => [Int] -> Matrix a -> Matrix a
subSampleMatrix [Int]
is forall a b. (a -> b) -> a -> b
$ Alignment -> Matrix Character
matrix Alignment
a
randomSubSample :: StatefulGen g m => Int -> Alignment -> g -> m Alignment
randomSubSample :: forall g (m :: * -> *).
StatefulGen g m =>
Int -> Alignment -> g -> m Alignment
randomSubSample Int
n Alignment
a g
g = do
let l :: Int
l = Alignment -> Int
length Alignment
a
[Int]
is <- forall (m :: * -> *) a. Applicative m => Int -> m a -> m [a]
replicateM Int
n forall a b. (a -> b) -> a -> b
$ forall a g (m :: * -> *).
(UniformRange a, StatefulGen g m) =>
(a, a) -> g -> m a
uniformRM (Int
0, Int
l forall a. Num a => a -> a -> a
- Int
1) g
g
forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ [Int] -> Alignment -> Alignment
subSample [Int]
is Alignment
a