packages feed

mcmc 0.8.1.0 → 0.8.2.0

raw patch · 2 files changed

+87/−27 lines, 2 filesPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

API changes (from Hackage documentation)

+ Mcmc.MarginalLikelihood: [mlParallelizationMode] :: MLSettings -> ParallelizationMode
- Mcmc.MarginalLikelihood: MLSettings :: AnalysisName -> MLAlgorithm -> NPoints -> BurnInSettings -> BurnInSettings -> Iterations -> ExecutionMode -> LogMode -> Verbosity -> MLSettings
+ Mcmc.MarginalLikelihood: MLSettings :: AnalysisName -> MLAlgorithm -> NPoints -> BurnInSettings -> BurnInSettings -> Iterations -> ExecutionMode -> ParallelizationMode -> LogMode -> Verbosity -> MLSettings

Files

mcmc.cabal view
@@ -1,6 +1,6 @@ cabal-version:      3.0 name:               mcmc-version:            0.8.1.0+version:            0.8.2.0 synopsis:           Sample from a posterior using Markov chain Monte Carlo description:   Please see the README on GitHub at <https://github.com/dschrempf/mcmc#readme>
src/Mcmc/MarginalLikelihood.hs view
@@ -21,6 +21,7 @@   ) where +import Control.Concurrent (getNumCapabilities) import Control.Concurrent.Async hiding (link) import Control.Monad import Control.Monad.IO.Class@@ -87,13 +88,15 @@   { mlAnalysisName :: AnalysisName,     mlAlgorithm :: MLAlgorithm,     mlNPoints :: NPoints,-    -- | Initial burn in at the starting point of the path.+    -- | Initial burn in at the starting point of the path (or each segment if+    -- running in parallel).     mlInitialBurnIn :: BurnInSettings,     -- | Repetitive burn in at each point on the path.     mlPointBurnIn :: BurnInSettings,     -- | The number of iterations performed at each point.     mlIterations :: Iterations,     mlExecutionMode :: ExecutionMode,+    mlParallelizationMode :: ParallelizationMode,     mlLogMode :: LogMode,     mlVerbosity :: Verbosity   }@@ -139,23 +142,27 @@  sampleAtPoint ::   ToJSON a =>+  Bool ->   Point ->   Settings ->   LikelihoodFunction a ->   MHG a ->   ML (MHG a)-sampleAtPoint x ss lhf a = do+sampleAtPoint isInitialBurnIn x ss lhf a = do   a'' <- liftIO $ mcmc ss' a'   let ch'' = fromMHG a''       ac = acceptances ch''       mAr = sequence $ acceptanceRates ac   logDebugB "sampleAtPoint: Summarize cycle."   logDebugB $ summarizeCycle AllProposals ac $ cycle ch''-  case mAr of-    Nothing -> logWarnB "Some acceptance rates are unavailable."-    Just ar -> do-      unless (M.null $ M.filter (<= 0.1) ar) $ logWarnB "Some acceptance rates are below 0.1."-      unless (M.null $ M.filter (>= 0.9) ar) $ logWarnB "Some acceptance rates are above 0.9."+  unless+    isInitialBurnIn+    ( case mAr of+        Nothing -> logWarnB "Some acceptance rates are unavailable."+        Just ar -> do+          unless (M.null $ M.filter (<= 0.1) ar) $ logWarnB "Some acceptance rates are below 0.1."+          unless (M.null $ M.filter (>= 0.9) ar) $ logWarnB "Some acceptance rates are above 0.9."+    )   return a''   where     -- For debugging set a proper analysis name.@@ -181,19 +188,18 @@  traversePoints ::   ToJSON a =>-  -- Current point.-  Int ->   NPoints ->-  [Point] ->+  [(Int, Point)] ->   Settings ->   LikelihoodFunction a ->   MHG a ->   -- For each point a vector of obtained likelihoods stored in the log domain.   ML [VU.Vector Likelihood]-traversePoints _ _ [] _ _ _ = return []-traversePoints i k (b : bs) ss lhf a = do-  logInfoS $ "Point " <> show i <> " of " <> show k' <> ": " <> show b <> "."-  a' <- sampleAtPoint b ss lhf a+traversePoints _ [] _ _ _ = return []+traversePoints k ((idb, b) : bs) ss lhf a = do+  let msg = printf "Point %4d of %4d: %.12f." idb k' b+  logInfoS msg+  a' <- sampleAtPoint False b ss lhf a   -- Get the links samples at this point.   ls <- liftIO $ takeT n $ trace $ fromMHG a'   -- Extract the likelihoods.@@ -205,16 +211,67 @@   -- resulting in a severe memory leak.   let !lhs = VU.convert $ VB.map (lhf . state) ls   -- Sample the other points.-  lhss <- traversePoints (i + 1) k bs ss lhf a'+  lhss <- traversePoints k bs ss lhf a'   return $ lhs : lhss   where     n = fromIterations $ sIterations ss     (NPoints k') = k +nChunks :: Int -> [a] -> [[a]]+nChunks k xs = chop (chunks k l) xs+  where+    l = length xs++chunks :: Int -> Int -> [Int]+chunks c n = filter (> 0) ns+  where+    n' = n `div` c+    r = n `mod` c+    ns = replicate r (n' + 1) ++ replicate (c - r) n'++chop :: [Int] -> [a] -> [[a]]+chop [] [] = []+chop (n : ns) xs+  | n > 0 = take n xs : chop ns (drop n xs)+  | otherwise = error "chop: n negative or zero"+chop _ _ = error "chop: not all list elements handled"++mlRunPar ::+  ToJSON a =>+  ParallelizationMode ->+  NPoints ->+  [(Int, Point)] ->+  ExecutionMode ->+  Verbosity ->+  PriorFunction a ->+  LikelihoodFunction a ->+  Cycle a ->+  Monitor a ->+  a ->+  StdGen ->+  ML [VU.Vector Likelihood]+mlRunPar pm k xs em vb prf lhf cc mn i0 g = do+  nThreads <- case pm of+    Sequential -> do+      logInfoB "Sequential execution."+      pure 1+    Parallel -> do+      n <- liftIO getNumCapabilities+      logInfoS $ "Parallel execution with " <> show n <> " cores."+      pure n+  let xsChunks = nChunks nThreads xs+  r <- ask+  xss <-+    liftIO $+      mapConcurrently+        (\thesePoints -> runReaderT (mlRun k thesePoints em vb prf lhf cc mn i0 g) r)+        xsChunks+  pure $ concat xss+ mlRun ::   ToJSON a =>   NPoints ->-  [Point] ->+  [(Int, Point)] ->   ExecutionMode ->   Verbosity ->   PriorFunction a ->@@ -241,12 +298,13 @@       ssP = Settings nm biP is trLen em Sequential NoSave LogFileOnly vb'   logDebugB "mlRun: Initialize MHG algorithm."   a0 <- liftIO $ mhg ssI prf lhf cc mn i0 g-  logDebugS $ "mlRun: Perform initial burn in at first point " <> show x0 <> "."-  a1 <- sampleAtPoint x0 ssI lhf a0+  let msg = printf "Initial burn in at point %.12f with ID %4d." x0 id0+  logInfoS msg+  a1 <- sampleAtPoint True x0 ssI lhf a0   logDebugB "mlRun: Traverse points."-  traversePoints 1 k xs ssP lhf a1+  traversePoints k xs ssP lhf a1   where-    x0 = head xs+    (id0, x0) = head xs  -- Use lists since the number of points is expected to be low. integrateSimpsonTriangle ::@@ -280,8 +338,8 @@   (lhssForward, lhssBackward) <-     lift $       concurrently-        (runReaderT (mlRun k bsForward em vb prf lhf cc mn i0 g0) r)-        (runReaderT (mlRun k bsBackward em vb prf lhf cc mn i0 g1) r)+        (runReaderT (mlRunPar pm k (zip [1 ..] bsForward) em vb prf lhf cc mn i0 g0) r)+        (runReaderT (mlRunPar pm k (zip [1 ..] bsBackward) em vb prf lhf cc mn i0 g1) r)   logInfoEndTime    logDebugB "tiWrapper: Calculate mean log likelihoods."@@ -300,6 +358,7 @@     bsForward = getPoints k     bsBackward = reverse bsForward     em = mlExecutionMode s+    pm = mlParallelizationMode s     vb = mlVerbosity s  -- Helper function to exponentiate log domain values with a double value.@@ -356,7 +415,7 @@   ML MarginalLikelihood sssWrapper s prf lhf cc mn i0 g = do   logInfoB "Stepping stone sampling."-  logLhss <- mlRun k bsForward' em vb prf lhf cc mn i0 g+  logLhss <- mlRunPar pm k (zip [1 ..] bsForward') em vb prf lhf cc mn i0 g   logInfoB "The last point does not need to be sampled with stepping stone sampling."   logDebugB "sssWrapper: Calculate marginal likelihood."   return $ sssCalculateMarginalLikelihood bsForward logLhss@@ -365,6 +424,7 @@     bsForward = getPoints k     bsForward' = init bsForward     em = mlExecutionMode s+    pm = mlParallelizationMode s     vb = mlVerbosity s  -- | Estimate the marginal likelihood.@@ -382,9 +442,9 @@   -- Initialize.   e <- initializeEnvironment s -  when (mlVerbosity s == Debug) $ do-    let n = fromAnalysisName $ mlAnalysisName s-    createDirectoryIfMissing True n+  -- Create marginal likelihood analysis directory.+  let n = fromAnalysisName $ mlAnalysisName s+  createDirectoryIfMissing True n    -- Run.   runReaderT