-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/


-- | Painless general-purpose sampling.
--   
--   flat-mcmc is a Haskell library for painless, efficient,
--   general-purpose sampling from continuous distributions.
--   
--   flat-mcmc uses an ensemble sampler that is invariant to affine
--   transformations of space. It wanders a target probability
--   distribution's parameter space as if it had been "flattened" or
--   "unstretched" in some sense, allowing many particles to explore it
--   locally and in parallel.
--   
--   In general this sampler is useful when you want decent performance
--   without dealing with any tuning parameters or local proposal
--   distributions.
--   
--   flat-mcmc exports an <a>mcmc</a> function that prints a trace to
--   stdout, as well as a <a>flat</a> transition operator that can be used
--   more generally.
--   
--   <pre>
--   import Numeric.MCMC.Flat
--   import qualified Data.Vector.Unboxed as U (unsafeIndex)
--   
--   rosenbrock :: Particle -&gt; Double
--   rosenbrock xs = negate (5  * (x1 - x0 ^ 2) ^ 2 + 0.05 * (1 - x0) ^ 2) where
--     x0 = U.unsafeIndex xs 0
--     x1 = U.unsafeIndex xs 1
--   
--   origin :: Ensemble
--   origin = ensemble [
--       particle [negate 1.0, negate 1.0]
--     , particle [negate 1.0, 1.0]
--     , particle [1.0, negate 1.0]
--     , particle [1.0, 1.0]
--     ]
--   
--   main :: IO ()
--   main = withSystemRandom . asGenIO $ mcmc 12500 origin rosenbrock
--   </pre>
@package flat-mcmc
@version 1.5.0


-- | This is the 'affine invariant ensemble' or AIEMCMC algorithm described
--   in Goodman and Weare, 2010. It is a reasonably efficient and
--   hassle-free sampler, requiring no mucking with tuning parameters or
--   local proposal distributions.
--   
--   The <a>mcmc</a> function streams a trace to stdout to be processed
--   elsewhere, while the <a>flat</a> transition can be used for more
--   flexible purposes, such as working with samples in memory.
--   
--   See <a>http://msp.org/camcos/2010/5-1/camcos-v5-n1-p04-p.pdf</a> for
--   the definitive reference of the algorithm.
module Numeric.MCMC.Flat

-- | Trace <tt>n</tt> iterations of a Markov chain and stream them to
--   stdout.
--   
--   Note that the Markov chain is defined over the space of ensembles, so
--   you'll need to provide an ensemble of particles for the start
--   location.
--   
--   <pre>
--   &gt;&gt;&gt; import Numeric.MCMC.Flat
--   
--   &gt;&gt;&gt; import Data.Vector.Unboxed (toList)
--   
--   &gt;&gt;&gt; :{
--   
--   &gt;&gt;&gt; let rosenbrock xs = negate (5  *(x1 - x0 ^ 2) ^ 2 + 0.05 * (1 - x0) ^ 2)
--               where [x0, x1] = toList xs
--   
--   &gt;&gt;&gt; :}
--   
--   &gt;&gt;&gt; :{
--   
--   &gt;&gt;&gt; let origin = ensemble [
--   
--   &gt;&gt;&gt; particle [negate 1.0, negate 1.0]
--   
--   &gt;&gt;&gt; , particle [negate 1.0, 1.0]
--   
--   &gt;&gt;&gt; , particle [1.0, negate 1.0]
--   
--   &gt;&gt;&gt; , particle [1.0, 1.0]
--   
--   &gt;&gt;&gt; ]
--   
--   &gt;&gt;&gt; :}
--   
--   &gt;&gt;&gt; withSystemRandom . asGenIO $ mcmc 2 origin rosenbrock
--   -1.0,-1.0
--   -1.0,1.0
--   1.0,-1.0
--   0.7049046915549257,0.7049046915549257
--   -0.843493377618159,-0.843493377618159
--   -1.1655594505975082,1.1655594505975082
--   0.5466534497342876,-0.9615123448709006
--   0.7049046915549257,0.7049046915549257
--   </pre>
mcmc :: (MonadIO m, PrimMonad m) => Int -> Ensemble -> (Particle -> Double) -> Gen (PrimState m) -> m ()

-- | The <a>flat</a> transition operator for driving a Markov chain over a
--   space of ensembles.
flat :: PrimMonad m => Transition m Chain

-- | A particle is an n-dimensional point in Euclidean space.
--   
--   You can create a particle by using the <tt>particle</tt> helper
--   function, or just use Data.Vector.Unboxed.fromList.
type Particle = Vector Double

-- | An ensemble is a collection of particles.
--   
--   The Markov chain we're interested in will run over the space of
--   ensembles, so you'll want to build an ensemble out of a reasonable
--   number of particles to kick off the chain.
--   
--   You can create an ensemble by using the <tt>ensemble</tt> helper
--   function, or just use Data.Vector.fromList.
type Ensemble = Vector Particle
data Chain

-- | Create a generator for variates using a fixed seed.
create :: PrimMonad m => m Gen PrimState m

-- | Seed a PRNG with data from the system's fast source of pseudo-random
--   numbers. All the caveats of <a>withSystemRandom</a> apply here as
--   well.
createSystemRandom :: IO GenIO

-- | Seed a PRNG with data from the system's fast source of pseudo-random
--   numbers ("<tt>/dev/urandom</tt>" on Unix-like systems or
--   <tt>RtlGenRandom</tt> on Windows), then run the given action.
--   
--   This is a somewhat expensive function, and is intended to be called
--   only occasionally (e.g. once per thread). You should use the
--   <a>Gen</a> it creates to generate many random numbers.
withSystemRandom :: PrimBase m => (Gen PrimState m -> m a) -> IO a

-- | Constrain the type of an action to run in the <a>IO</a> monad.
asGenIO :: () => (GenIO -> IO a) -> GenIO -> IO a

-- | A type-specialized alias for Data.Vector.fromList.
--   
--   Use this to create ensembles from lists of particles.
ensemble :: [Vector Double] -> Vector (Vector Double)

-- | A type-specialized alias for Data.Vector.Unboxed.fromList
--   
--   Use this to create particles from lists of doubles.
particle :: [Double] -> Vector Double
