packages feed

elynx-tools 0.3.0 → 0.3.1

raw patch · 17 files changed

+93/−470 lines, 17 filesdep +attoparsecdep −asyncdep −containersdep −matrices

Dependencies added: attoparsec

Dependencies removed: async, containers, matrices, megaparsec, parallel

Files

ChangeLog.md view
@@ -2,7 +2,14 @@ # Changelog for ELynx  -## Version 0.3.1; in development+## Version 0.3.2; in development+++## Version 0.3.1++-   Use Attoparsec.+-   Use ByteString consistently.+-   Remove elynx-tools dependency from libaries.   ## Version 0.3.0
README.md view
@@ -2,7 +2,7 @@  # The ELynx Suite -Version: 0.3.0.+Version: 0.3.1. Reproducible evolution made easy.  <p align="center"><img src="https://travis-ci.org/dschrempf/elynx.svg?branch=master"/></p>@@ -90,9 +90,9 @@      slynx --help | head -n -16 -    ELynx Suite version 0.3.0.+    ELynx Suite version 0.3.1.     Developed by Dominik Schrempf.-    Compiled on July 30, 2020, at 12:40 pm, UTC.+    Compiled on August 3, 2020, at 12:12 pm, UTC.          Usage: slynx [-v|--verbosity VALUE] [-o|--output-file-basename NAME]                   [-f|--force] COMMAND@@ -136,9 +136,9 @@      slynx concatenate --help -    ELynx Suite version 0.3.0.+    ELynx Suite version 0.3.1.     Developed by Dominik Schrempf.-    Compiled on July 30, 2020, at 12:40 pm, UTC.+    Compiled on August 3, 2020, at 12:12 pm, UTC.          Usage: slynx concatenate (-a|--alphabet NAME) INPUT-FILE       Concatenate sequences found in input files.@@ -157,9 +157,9 @@      slynx examine --help -    ELynx Suite version 0.3.0.+    ELynx Suite version 0.3.1.     Developed by Dominik Schrempf.-    Compiled on July 30, 2020, at 12:40 pm, UTC.+    Compiled on August 3, 2020, at 12:12 pm, UTC.          Usage: slynx examine (-a|--alphabet NAME) INPUT-FILE [--per-site]       Examine sequences. If data is a multi sequence alignment, additionally analyze columns.@@ -179,9 +179,9 @@      slynx filter-rows --help -    ELynx Suite version 0.3.0.+    ELynx Suite version 0.3.1.     Developed by Dominik Schrempf.-    Compiled on July 30, 2020, at 12:40 pm, UTC.+    Compiled on August 3, 2020, at 12:12 pm, UTC.          Usage: slynx filter-rows (-a|--alphabet NAME) INPUT-FILE [--longer-than LENGTH]                               [--shorter-than LENGTH] [--standard-characters]@@ -202,9 +202,9 @@      slynx filter-columns --help -    ELynx Suite version 0.3.0.+    ELynx Suite version 0.3.1.     Developed by Dominik Schrempf.-    Compiled on July 30, 2020, at 12:40 pm, UTC.+    Compiled on August 3, 2020, at 12:12 pm, UTC.          Usage: slynx filter-columns (-a|--alphabet NAME) INPUT-FILE                                  [--standard-chars DOUBLE]@@ -226,9 +226,9 @@      slynx simulate --help -    ELynx Suite version 0.3.0.+    ELynx Suite version 0.3.1.     Developed by Dominik Schrempf.-    Compiled on July 30, 2020, at 12:40 pm, UTC.+    Compiled on August 3, 2020, at 12:12 pm, UTC.          Usage: slynx simulate (-t|--tree-file Name) [-s|--substitution-model MODEL]                            [-m|--mixture-model MODEL] [-e|--edm-file NAME] @@ -305,9 +305,9 @@      slynx sub-sample --help -    ELynx Suite version 0.3.0.+    ELynx Suite version 0.3.1.     Developed by Dominik Schrempf.-    Compiled on July 30, 2020, at 12:40 pm, UTC.+    Compiled on August 3, 2020, at 12:12 pm, UTC.          Usage: slynx sub-sample (-a|--alphabet NAME) INPUT-FILE                             (-n|--number-of-sites INT)@@ -335,9 +335,9 @@      slynx translate --help -    ELynx Suite version 0.3.0.+    ELynx Suite version 0.3.1.     Developed by Dominik Schrempf.-    Compiled on July 30, 2020, at 12:40 pm, UTC.+    Compiled on August 3, 2020, at 12:12 pm, UTC.          Usage: slynx translate (-a|--alphabet NAME) INPUT-FILE (-r|--reading-frame INT)                            (-u|--universal-code CODE)@@ -360,9 +360,9 @@      tlynx --help | head -n -16 -    ELynx Suite version 0.3.0.+    ELynx Suite version 0.3.1.     Developed by Dominik Schrempf.-    Compiled on July 30, 2020, at 12:40 pm, UTC.+    Compiled on August 3, 2020, at 12:12 pm, UTC.          Usage: tlynx [-v|--verbosity VALUE] [-o|--output-file-basename NAME]                   [-f|--force] COMMAND@@ -399,9 +399,9 @@      tlynx compare --help -    ELynx Suite version 0.3.0.+    ELynx Suite version 0.3.1.     Developed by Dominik Schrempf.-    Compiled on July 30, 2020, at 12:40 pm, UTC.+    Compiled on August 3, 2020, at 12:12 pm, UTC.          Usage: tlynx compare [-n|--normalize] [-b|--bipartitions] [-t|--intersect]                           [-f|--newick-format FORMAT] NAMES@@ -428,9 +428,9 @@      tlynx examine --help -    ELynx Suite version 0.3.0.+    ELynx Suite version 0.3.1.     Developed by Dominik Schrempf.-    Compiled on July 30, 2020, at 12:40 pm, UTC.+    Compiled on August 3, 2020, at 12:12 pm, UTC.          Usage: tlynx examine INPUT-FILE [-f|--newick-format FORMAT]       Compute summary statistics of phylogenetic trees.@@ -452,9 +452,9 @@      tlynx simulate --help -    ELynx Suite version 0.3.0.+    ELynx Suite version 0.3.1.     Developed by Dominik Schrempf.-    Compiled on July 30, 2020, at 12:40 pm, UTC.+    Compiled on August 3, 2020, at 12:12 pm, UTC.          Usage: tlynx simulate [-t|--nTrees INT] [-n|--nLeaves INT] [-H|--height DOUBLE]                            [-M|--condition-on-mrca] [-l|--lambda DOUBLE] @@ -491,9 +491,9 @@      elynx --help | head -n -16 -    ELynx Suite version 0.3.0.+    ELynx Suite version 0.3.1.     Developed by Dominik Schrempf.-    Compiled on July 30, 2020, at 12:40 pm, UTC.+    Compiled on August 3, 2020, at 12:12 pm, UTC.          Usage: elynx COMMAND       Validate and redo past ELynx analyses
elynx-tools.cabal view
@@ -4,10 +4,10 @@ -- -- see: https://github.com/sol/hpack ----- hash: ce20a53fa80c7478a01a9fc6ab5b4549475e79e193a58b3e925239f9513502af+-- hash: a88ba56b54f3dbb5277c662a4a76fedadc3f78e23d8ae3f2132c17f8aee2969e  name:           elynx-tools-version:        0.3.0+version:        0.3.1 synopsis:       Tools for ELynx description:    Please see the README on GitHub at <https://github.com/dschrempf/elynx>. category:       Bioinformatics@@ -39,13 +39,10 @@       ELynx.Tools.LinearAlgebra       ELynx.Tools.List       ELynx.Tools.Logger-      ELynx.Tools.Matrix       ELynx.Tools.Misc       ELynx.Tools.Numeric-      ELynx.Tools.Parallel       ELynx.Tools.Reproduction       ELynx.Tools.Text-      ELynx.Tools.Vector       Paths_elynx_tools   autogen-modules:       Paths_elynx_tools@@ -54,23 +51,19 @@   ghc-options: -Wall -fllvm   build-depends:       aeson-    , async+    , attoparsec     , base >=4.7 && <5     , base16-bytestring     , bytestring-    , containers     , cryptohash-sha256     , deepseq     , directory     , fast-logger     , hmatrix-    , matrices-    , megaparsec     , monad-control     , monad-logger     , mwc-random     , optparse-applicative-    , parallel     , primitive     , template-haskell     , text
src/ELynx/Tools.hs view
@@ -20,13 +20,10 @@     module ELynx.Tools.LinearAlgebra,     module ELynx.Tools.List,     module ELynx.Tools.Logger,-    module ELynx.Tools.Matrix,     module ELynx.Tools.Misc,     module ELynx.Tools.Numeric,-    module ELynx.Tools.Parallel,     module ELynx.Tools.Reproduction,     module ELynx.Tools.Text,-    module ELynx.Tools.Vector,   ) where @@ -38,10 +35,7 @@ import ELynx.Tools.LinearAlgebra import ELynx.Tools.List import ELynx.Tools.Logger-import ELynx.Tools.Matrix import ELynx.Tools.Misc import ELynx.Tools.Numeric-import ELynx.Tools.Parallel import ELynx.Tools.Reproduction import ELynx.Tools.Text-import ELynx.Tools.Vector
src/ELynx/Tools/ByteString.hs view
@@ -16,51 +16,33 @@     alignRight,     alignLeftWith,     alignLeft,-    summarizeByteString,-    c2w,-    w2c,-    bShow,   ) where -import Data.ByteString.Internal-  ( c2w,-    w2c,-  )-import qualified Data.ByteString.Lazy.Char8 as L+import qualified Data.ByteString.Lazy.Char8 as BL  -- | For a given width, align string to the right; use given fill character; -- trim on the left if string is longer.-alignRightWith :: Char -> Int -> L.ByteString -> L.ByteString+alignRightWith :: Char -> Int -> BL.ByteString -> BL.ByteString alignRightWith c n s =-  L.replicate (fromIntegral n - l) c <> L.take (fromIntegral n) s+  BL.replicate (fromIntegral n - l) c <> BL.take (fromIntegral n) s   where-    l = L.length s+    l = BL.length s  -- | For a given width, align string to the right; trim on the left if string is -- longer.-alignRight :: Int -> L.ByteString -> L.ByteString+alignRight :: Int -> BL.ByteString -> BL.ByteString alignRight = alignRightWith ' '  -- | For a given width, align string to the left; use given fill character; trim -- on the right if string is longer.-alignLeftWith :: Char -> Int -> L.ByteString -> L.ByteString+alignLeftWith :: Char -> Int -> BL.ByteString -> BL.ByteString alignLeftWith c n s =-  L.take (fromIntegral n) s <> L.replicate (fromIntegral n - l) c+  BL.take (fromIntegral n) s <> BL.replicate (fromIntegral n - l) c   where-    l = L.length s+    l = BL.length s  -- | For a given width, align string to the left; trim on the right if string is -- longer.-alignLeft :: Int -> L.ByteString -> L.ByteString+alignLeft :: Int -> BL.ByteString -> BL.ByteString alignLeft = alignLeftWith ' '---- | If a string is longer than a given value, trim it and add some dots.-summarizeByteString :: Int -> L.ByteString -> L.ByteString-summarizeByteString l s-  | L.length s >= fromIntegral l = L.take (fromIntegral l) s <> L.pack "..."-  | otherwise = s---- | Conversion to 'L.ByteString'.-bShow :: Show a => a -> L.ByteString-bShow = L.pack . show
src/ELynx/Tools/Concurrent.hs view
@@ -16,13 +16,10 @@     splitGen,      -- * Concurrent calculations-    parComp,     getChunks,   ) where -import Control.Concurrent-import Control.Concurrent.Async import Control.Monad import Control.Monad.Primitive import qualified Data.Vector as V@@ -36,24 +33,6 @@   | otherwise = do     seeds :: [V.Vector Word32] <- replicateM (n -1) $ uniformVector gen 256     fmap (gen :) (mapM initialize seeds)---- -- XXX: This just doesn't work... The only thing I found:--- -- https://stackoverflow.com/a/16250010.--- parComp :: (PrimMonad m, Monoid b) => Int -> (Int -> Gen (PrimState m) -> m b)---         -> Gen (PrimState m) -> m b--- parComp num fun gen = do---   let ncap   = ceiling (fromIntegral num / fromIntegral chunksize :: Double)---       chunks = getChunks ncap num---   gs <- splitGen ncap gen---   mconcat <$> P.mapM (\(n', g') -> fun n' g') (zip chunks gs)---- | Perform random calculation in parallel. Does only work with 'IO' and the moment.-parComp :: Int -> (Int -> GenIO -> IO b) -> GenIO -> IO [b]-parComp num fun gen = do-  ncap <- getNumCapabilities-  let chunks = getChunks ncap num-  gs <- splitGen ncap gen-  mapConcurrently (uncurry fun) (zip chunks gs)  -- | For a given number of capabilities and number of calculations, get chunk -- sizes. The chunk sizes will be as evenly distributed as possible and sum up
src/ELynx/Tools/Definitions.hs view
@@ -11,42 +11,15 @@ -- Creation date: Fri Jan 25 17:17:41 2019. module ELynx.Tools.Definitions   ( -- * Definitions-    chunksize,     eps,-    eps',     precision,-    version,   ) where -import Data.Version---- TODO: Move back to automatic version handling.---- XXX: Manually handled, because automatic handling with @Paths_...@ modules--- results in errors during source tarball creation and upload.---- Careful, this version number has to be synchronized with the one specified in--- the *.cabal files. This is done with the @bump-version@ script.---- | ELynx version.-version :: Version-version = makeVersion [0, 3, 0]- -- | Required precision when comparing 'Double' values. eps :: Double eps = 1e-12 --- | Relaxed required precision when comparing 'Double' values. Often, input--- files do not provide the required double precision. In this case, it is only--- possible to check input with relaxed bounds.-eps' :: Double-eps' = 1e-5- -- | Default output precision. precision :: Int precision = 3---- | Default chunk size for parallel evaluations.-chunksize :: Int-chunksize = 500
src/ELynx/Tools/InputOutput.hs view
@@ -45,9 +45,9 @@ import Control.Monad.IO.Class import Control.Monad.Logger import Control.Monad.Trans.Reader (ask)-import qualified Data.ByteString.Lazy.Char8 as L+import Data.Attoparsec.ByteString.Lazy+import qualified Data.ByteString.Lazy.Char8 as BL import Data.List (isSuffixOf)-import Data.Maybe import qualified Data.Text as T import ELynx.Tools.Reproduction   ( Arguments (..),@@ -59,7 +59,6 @@   ) import System.Directory (doesFileExist) import System.IO-import Text.Megaparsec  -- | Get out file path with extension. getOutFilePath ::@@ -91,94 +90,60 @@  -- XXX: For now, all files are read strictly (see help of -- Control.DeepSeq.force).-readFile' :: FilePath -> IO L.ByteString-readFile' fn = withFile fn ReadMode $ (evaluate . force) <=< L.hGetContents+readFile' :: FilePath -> IO BL.ByteString+readFile' fn = withFile fn ReadMode $ (evaluate . force) <=< BL.hGetContents  -- | Read file. If file path ends with ".gz", assume gzipped file and decompress -- before read.-readGZFile :: FilePath -> IO L.ByteString+readGZFile :: FilePath -> IO BL.ByteString readGZFile f   | ".gz" `isSuffixOf` f = decompress <$> readFile' f   | otherwise = readFile' f  -- | Write file. If file path ends with ".gz", assume gzipped file and compress -- before write.-writeGZFile :: Force -> FilePath -> L.ByteString -> IO ()+writeGZFile :: Force -> FilePath -> BL.ByteString -> IO () writeGZFile frc f r-  | ".gz" `isSuffixOf` f = checkFile frc f >> L.writeFile f (compress r)-  | otherwise = checkFile frc f >> L.writeFile f r+  | ".gz" `isSuffixOf` f = checkFile frc f >> BL.writeFile f (compress r)+  | otherwise = checkFile frc f >> BL.writeFile f r  -- | Parse a possibly gzipped file.-runParserOnFile ::-  Parsec e L.ByteString a ->-  FilePath ->-  IO (Either (ParseErrorBundle L.ByteString e) a)-runParserOnFile p f = parse p f <$> readGZFile f+runParserOnFile :: Parser a -> FilePath -> IO (Either String a)+runParserOnFile p f = eitherResult . parse p <$> readGZFile f  -- | Parse a possibly gzipped file and extract the result.-parseFileWith ::-  (ShowErrorComponent e) =>-  -- | The parser.-  Parsec e L.ByteString a ->-  FilePath ->-  IO a+parseFileWith :: Parser a -> FilePath -> IO a parseFileWith p f = parseFileOrIOWith p (Just f)  -- | Parse standard input.-parseIOWith ::-  (ShowErrorComponent e) =>-  -- | The parser.-  Parsec e L.ByteString a ->-  IO a-parseIOWith p = parseByteStringWith "Standard input" p <$> L.getContents+parseIOWith :: Parser a -> IO a+parseIOWith p = parseFileOrIOWith p Nothing  -- | Parse a possibly gzipped file, or standard input, and extract the result.-parseFileOrIOWith ::-  (ShowErrorComponent e) =>-  -- | The parser.-  Parsec e L.ByteString a ->-  -- | If no file path is given, standard input is used.-  Maybe FilePath ->-  IO a+parseFileOrIOWith :: Parser a -> Maybe FilePath -> IO a parseFileOrIOWith p mf = do-  contents <- maybe L.getContents readGZFile mf-  return $ parseByteStringWith (fromMaybe "Standard input" mf) p contents+  s <- maybe BL.getContents readGZFile mf+  return $ parseByteStringWith p s  -- | Parse a 'String' and extract the result.-parseStringWith ::-  (ShowErrorComponent e) =>-  -- | Name of string.-  String ->-  -- | Parser.-  Parsec e L.ByteString a ->-  -- | Input.-  String ->-  a-parseStringWith s p l = parseByteStringWith s p (L.pack l)+parseStringWith :: Parser a -> String -> a+parseStringWith p x = parseByteStringWith p (BL.pack x) --- | Parse a 'L.ByteString' and extract the result.-parseByteStringWith ::-  (ShowErrorComponent e) =>-  -- | Name of byte string.-  String ->-  -- | Parser.-  Parsec e L.ByteString a ->-  -- | Input.-  L.ByteString ->-  a-parseByteStringWith s p l = case parse p s l of-  Left err -> error $ errorBundlePretty err+-- | Parse a 'BL.ByteString' and extract the result.+parseByteStringWith :: Parser a -> BL.ByteString -> a+parseByteStringWith p x = case eitherResult $ parse p x of+  Left err -> error err   Right val -> val  -- | Write a result with a given name to file with given extension or standard -- output. Supports compression.-out :: Reproducible a => String -> L.ByteString -> String -> ELynx a ()+out :: Reproducible a => String -> BL.ByteString -> String -> ELynx a () out name res ext = do   mfp <- getOutFilePath ext   case mfp of     Nothing -> do       $(logInfo) $ T.pack $ "Write " <> name <> " to standard output."-      liftIO $ L.putStr res+      liftIO $ BL.putStr res     Just fp -> do       $(logInfo) $ T.pack $ "Write " <> name <> " to file '" <> fp <> "'."       frc <- forceReanalysis . global <$> ask
src/ELynx/Tools/LinearAlgebra.hs view
@@ -34,6 +34,7 @@ -- | Set the diagonal entries of a matrix to zero. matrixSetDiagToZero :: Matrix R -> Matrix R matrixSetDiagToZero m = m - diag (takeDiag m)+{-# INLINE matrixSetDiagToZero #-}  -- | Display a vector with given precision. dispv :: Int -> Vector R -> String
src/ELynx/Tools/Logger.hs view
@@ -24,57 +24,15 @@  import Control.Monad.Base (liftBase) import Control.Monad.IO.Class-  ( MonadIO,-    liftIO,-  ) import Control.Monad.Logger-  ( Loc,-    LogLevel,-    LogSource,-    LoggingT,-    MonadLogger,-    filterLogger,-    logInfo,-    runLoggingT,-  ) import Control.Monad.Trans.Control (MonadBaseControl) import Control.Monad.Trans.Reader (ReaderT (runReaderT))-import qualified Data.ByteString.Char8 as B+import qualified Data.ByteString.Char8 as BS import Data.Text-  ( Text,-    pack,-  ) import ELynx.Tools.InputOutput (openFile') import ELynx.Tools.Reproduction-  ( Arguments (..),-    ELynx,-    Force,-    GlobalArguments (..),-    Reproducible (..),-    Seed (..),-    ToJSON,-    logFooter,-    logHeader,-    toLogLevel,-    writeReproduction,-  ) import System.IO-  ( BufferMode (LineBuffering),-    Handle,-    IOMode (WriteMode),-    hClose,-    hSetBuffering,-    stderr,-  )-import System.Log.FastLogger-  ( LogStr,-    fromLogStr,-  ) import System.Random.MWC-  ( createSystemRandom,-    fromSeed,-    save,-  )  -- | Unified way of creating a new section in the log. logNewSection :: MonadLogger m => Text -> m ()@@ -155,11 +113,11 @@ runELynxStderrLoggingT = (`runLoggingT` output stderr)  output :: Handle -> Loc -> LogSource -> LogLevel -> LogStr -> IO ()-output h _ _ _ msg = B.hPutStrLn h ls where ls = fromLogStr msg+output h _ _ _ msg = BS.hPutStrLn h ls where ls = fromLogStr msg  output2H :: Handle -> Handle -> Loc -> LogSource -> LogLevel -> LogStr -> IO () output2H h1 h2 _ _ _ msg = do-  B.hPutStrLn h1 ls-  B.hPutStrLn h2 ls+  BS.hPutStrLn h1 ls+  BS.hPutStrLn h2 ls   where     ls = fromLogStr msg
− src/ELynx/Tools/Matrix.hs
@@ -1,101 +0,0 @@--- |--- Module      :  ELynx.Tools.Matrix--- Copyright   :  (c) Dominik Schrempf 2020--- License     :  GPL-3.0-or-later------ Maintainer  :  dominik.schrempf@gmail.com--- Stability   :  unstable--- Portability :  portable------ Creation date: Thu Feb 14 13:33:13 2019.------ Tools for matrices from 'Numeric.LinearAlgebra'.-module ELynx.Tools.Matrix-  ( -- * Matrices-    fMapRowSeq,-    fMapRowPar,-    fMapRowParChunk,-    fMapColSeq,-    fMapColPar,-    fMapColParChunk,-    (|||),-    (===),-    subSampleMatrix,-  )-where--import Control.Parallel.Strategies-import Data.List-import qualified Data.Matrix.Generic as M-import qualified Data.Vector.Generic as V---- | Map a function on each row of a DIM2 array; sequential version.-fMapRowSeq ::-  (V.Vector v a, V.Vector v b) =>-  (v a -> v b) ->-  M.Matrix v a ->-  M.Matrix v b-fMapRowSeq f m = M.fromRows $ map f (M.toRows m)---- | Map a function on each row of a DIM2 array; parallel version.-fMapRowPar ::-  (V.Vector v a, V.Vector v b) =>-  (v a -> v b) ->-  M.Matrix v a ->-  M.Matrix v b-fMapRowPar f m = M.fromRows $ parMap rseq f (M.toRows m)---- | Map a function on each row of a DIM2 array; parallel version with given chunk size.-fMapRowParChunk ::-  (V.Vector v a, V.Vector v b) =>-  Int ->-  (v a -> v b) ->-  M.Matrix v a ->-  M.Matrix v b-fMapRowParChunk n f m =-  M.fromRows (map f (M.toRows m) `using` parListChunk n rseq)---- | Map a function on each row of a DIM2 array; sequential version.-fMapColSeq ::-  (V.Vector v a, V.Vector v b) =>-  (v a -> v b) ->-  M.Matrix v a ->-  M.Matrix v b-fMapColSeq f m = M.fromColumns $ map f (M.toColumns m)---- | Map a function on each row of a DIM2 array; parallel version.-fMapColPar ::-  (V.Vector v a, V.Vector v b) =>-  (v a -> v b) ->-  M.Matrix v a ->-  M.Matrix v b-fMapColPar f m = M.fromColumns $ parMap rseq f (M.toColumns m)---- | Map a function on each row of a DIM2 array; parallel version with given chunk size.-fMapColParChunk ::-  (V.Vector v a, V.Vector v b) =>-  Int ->-  (v a -> v b) ->-  M.Matrix v a ->-  M.Matrix v b-fMapColParChunk n f m =-  M.fromColumns (map f (M.toColumns m) `using` parListChunk n rseq)---- | Horizontal concatenation.-(|||) :: (V.Vector v a) => M.Matrix v a -> M.Matrix v a -> M.Matrix v a-(|||) l r = M.fromColumns $ lCs ++ rCs-  where-    lCs = M.toColumns l-    rCs = M.toColumns r---- | Vertical concatenation.-(===) :: (V.Vector v a) => M.Matrix v a -> M.Matrix v a -> M.Matrix v a-(===) l r = M.fromRows $ lRs ++ rRs-  where-    lRs = M.toRows l-    rRs = M.toRows r---- | Sample the given sites from a matrix.-subSampleMatrix :: (V.Vector v a) => [Int] -> M.Matrix v a -> M.Matrix v a-subSampleMatrix is m =-  M.fromColumns $ foldl' (\a i -> M.takeColumn m i : a) [] is
src/ELynx/Tools/Misc.hs view
@@ -11,10 +11,7 @@ -- -- Miscellaneous tools that do not have their own category (yet). module ELynx.Tools.Misc-  ( -- * Not yet classified stuff-    ensure,--    -- * Weird stuff+  ( -- * Weird stuff     compose,     allValues,     horizontalConcat,@@ -38,9 +35,3 @@ horizontalConcat :: [[[a]]] -> [[a]] horizontalConcat [xs] = xs horizontalConcat xss = foldl' (zipWith (++)) (head xss) (tail xss)---- | Ensure that a value satisfies a given predicate.-ensure :: (a -> Bool) -> a -> Maybe a-ensure p v-  | p v = Just v-  | otherwise = Nothing
src/ELynx/Tools/Numeric.hs view
@@ -13,24 +13,14 @@ module ELynx.Tools.Numeric   ( -- * Numeric     harmonic,-    xLogX,     roundN,   ) where -import ELynx.Tools.Equality- -- | Calculate the nth harmonic number. harmonic :: Int -> Double harmonic 1 = 1.0 harmonic n = 1.0 / fromIntegral n + harmonic (n - 1)---- | Calculate x*log(x) but set to 0.0 when x is smaller than 'eps'.-xLogX :: Double -> Double-xLogX x-  | x < 0.0 = error "Argument lower than zero."-  | x `nearlyEq` 0.0 = 0.0-  | otherwise = x * log x  -- | Round double to a given precision. roundN :: Int -> Double -> Double
− src/ELynx/Tools/Parallel.hs
@@ -1,21 +0,0 @@--- |--- Module      :  ELynx.Tools.Parallel--- Description :  Utility functions for parallel calculations--- Copyright   :  (c) Dominik Schrempf 2020--- License     :  GPL-3.0-or-later------ Maintainer  :  dominik.schrempf@gmail.com--- Stability   :  unstable--- Portability :  portable------ Creation date: Tue Apr 21 15:19:44 2020.-module ELynx.Tools.Parallel-  ( parMapChunk,-  )-where--import Control.Parallel.Strategies---- | Parallel map with given chunk size.-parMapChunk :: Int -> (a -> b) -> [a] -> [b]-parMapChunk n f as = map f as `using` parListChunk n rseq
src/ELynx/Tools/Reproduction.hs view
@@ -47,7 +47,6 @@     createCommandReproducible,     createCommand,     elynxParserInfo,-    megaReadM,      -- * Re-exports     Generic,@@ -56,44 +55,25 @@   ) where -import Control.Monad (void)+import Control.Monad import Control.Monad.Logger-  ( LogLevel (..),-    LoggingT,-  )-import Control.Monad.Trans.Reader (ReaderT)-import Crypto.Hash.SHA256 (hash)-import Data.Aeson-  ( FromJSON,-    ToJSON,-    encodeFile,-  )-import Data.ByteString.Base16 (encode)-import qualified Data.ByteString.Char8 as B+import Control.Monad.Trans.Reader hiding (local)+import Crypto.Hash.SHA256+import Data.Aeson hiding (encode)+import Data.ByteString.Base16+import qualified Data.ByteString.Char8 as BS import Data.List hiding (group) import Data.Time import Data.Vector.Unboxed (Vector) import Data.Version-  ( Version,-    showVersion,-  )-import Data.Void import Data.Word-import ELynx.Tools.Definitions (version)-import ELynx.Tools.Misc (allValues)-import GHC.Generics (Generic)+import ELynx.Tools.Misc+import GHC.Generics import Language.Haskell.TH import Options.Applicative hiding (empty) import Options.Applicative.Help.Pretty import System.Environment-  ( getArgs,-    getProgName,-  )-import Text.Megaparsec-  ( Parsec,-    errorBundlePretty,-    runParser,-  )+import Paths_elynx_tools  -- Be careful; it is necessary to synchronize the version numbers across packages. versionString :: String@@ -340,10 +320,10 @@ -- | A unique hash of the reproduction data type. getReproductionHash :: forall a. Reproducible a => Reproduction a -> String getReproductionHash r =-  B.unpack $+  BS.unpack $     encode $       hash $-        B.pack $+        BS.pack $           unlines $             -- Reproduction.             progName r :@@ -387,8 +367,8 @@ instance ToJSON a => ToJSON (Reproduction a)  -- | Helper function.-hashFile :: FilePath -> IO B.ByteString-hashFile f = encode . hash <$> B.readFile f+hashFile :: FilePath -> IO BS.ByteString+hashFile f = encode . hash <$> BS.readFile f  -- | Write an ELynx reproduction file. writeReproduction ::@@ -403,7 +383,7 @@   let outFs = map (bn ++) (outSuffixes r)   let fs = inFiles r ++ outFs   cs <- mapM hashFile fs-  let cs' = map B.unpack cs+  let cs' = map BS.unpack cs       s = Reproduction pn as version Nothing fs cs' r   void $ encodeFile (bn <> ".elynx") (setHash s) @@ -451,14 +431,6 @@     (fullDesc <> headerDoc (Just hdr') <> progDescDoc dsc <> footerDoc ftr)   where     hdr' = vsep $ map pretty hdr---- | See 'eitherReader', but for Megaparsec.-megaReadM :: Parsec Void String a -> ReadM a-megaReadM p = eitherReader $ \input ->-  let eea = runParser p "" input-   in case eea of-        Left eb -> Left $ errorBundlePretty eb-        Right a -> Right a  -- | Fill a string so that it becomes a paragraph with line breaks. Useful for -- descriptions, headers and footers.
src/ELynx/Tools/Text.hs view
@@ -17,7 +17,7 @@   ) where -import Data.ByteString.Lazy (ByteString)+import qualified Data.ByteString.Lazy.Char8 as BL import Data.Text   ( Text,     pack,@@ -30,5 +30,5 @@ tShow = pack . show  -- | Conversion to 'Text' from bytestring.-fromBs :: ByteString -> Text+fromBs :: BL.ByteString -> Text fromBs = toStrict . decodeUtf8
− src/ELynx/Tools/Vector.hs
@@ -1,60 +0,0 @@--- |--- Module      :  ELynx.Tools.Vector--- Copyright   :  (c) Dominik Schrempf 2020--- License     :  GPL-3.0-or-later------ Maintainer  :  dominik.schrempf@gmail.com--- Stability   :  unstable--- Portability :  portable------ Creation date: Thu Feb 14 13:33:13 2019.------ Tools for vectors from 'Data.Vector.Generic'.-module ELynx.Tools.Vector-  ( -- * Vectors-    sumVec,-    normalizeSumVec,-    uniformVec,-    meanVec,-    chopVec,-    randomInsertVec,-  )-where--import Control.Monad.Primitive-import qualified Data.Vector.Generic as V-import System.Random.MWC---- | Sum of elements.-sumVec :: (Num a, V.Vector v a) => v a -> a-sumVec = V.foldl' (+) 0---- | Normalize a vector such that elements sum to a given value.-normalizeSumVec :: (Fractional a, V.Vector v a) => a -> v a -> v a-normalizeSumVec c v = V.map (* c') v-  where-    s = sumVec v-    c' = c / s---- | A uniform vector of given length.-uniformVec :: (Fractional a, V.Vector v a) => Int -> v a-uniformVec n = V.replicate n (1 / fromIntegral n)---- | Mean of a vector.-meanVec :: (Fractional a, V.Vector v a) => v a -> a-meanVec v = sumVec v / fromIntegral (V.length v)---- | Chop list into chunks of given length. If the last chop is shorter than--- length, it is dropped.-chopVec :: V.Vector v a => Int -> v a -> [v a]-chopVec n xs-  | V.length xs < n = []-  | otherwise = V.take n xs : chopVec n (V.drop n xs)---- | Insert element into random position of vector.-randomInsertVec ::-  (PrimMonad m, V.Vector v a) => a -> v a -> Gen (PrimState m) -> m (v a)-randomInsertVec e v g = do-  let l = V.length v-  i <- uniformR (0, l) g-  return $ V.take i v V.++ V.singleton e V.++ V.drop i v