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


-- | Manipulating numbers with inherent experimental/measurement uncertainty
--   
--   See <a>README.md</a>.
--   
--   Documentation maintained at <a>https://mstksg.github.io/uncertain</a>
@package uncertain
@version 0.3.1.0


module Numeric.Uncertain

-- | Represents an independent experimental value centered around a mean
--   value with "inherent" and independent uncertainty.
--   
--   Mostly useful due to its instances of numeric typeclasses like
--   <a>Num</a>, <a>Fractional</a>, etc., which allows you to add and
--   multiply and apply arbitrary numerical functions to them and have the
--   uncertainty propagate appropriately. You can also lift arbitrary
--   (sufficiently polymorphic) functions with <a>liftU</a>, <a>liftUF</a>,
--   <a>liftU2</a> and family.
--   
--   <pre>
--   ghci&gt; let x = 1.52 <a>+/-</a> 0.07
--   ghci&gt; let y = 781.4 +/- 0.3
--   ghci&gt; let z = 1.53e-1 `<tt>withPrecision'</tt> 3
--   ghci&gt; cosh x
--   2.4 +/- 0.2
--   ghci&gt; exp x / z * sin (y ** z)
--   10.9 +/- 0.9
--   ghci&gt; pi + 3 * logBase x y
--   52 +/- 5
--   </pre>
--   
--   Uncertaintly is properly propagated according to the second-degree
--   taylor series approximations of the applied functions. However, if the
--   higher-degree terms are large with respect to to the means and
--   variances of the uncertain values, these approximations may be
--   inaccurate.
--   
--   Can be created with <a>exact</a> to represent an "exact" measurement
--   with no uncertainty, <a>+/-</a> and <a>:+/-</a> to specify a standard
--   deviation as a range, <a>withPrecision</a> to specify through decimal
--   precision, and <a>withVar</a> to specify with a variance. Can also be
--   inferred from a list of samples with <a>fromSamples</a>
--   
--   <pre>
--   7.13 <a>+/-</a> 0.05
--   91800 +/- 100
--   12.5 `<tt>withVar'</tt> 0.36
--   <a>exact</a> 7.9512
--   81.42 `<tt>withPrecision'</tt> 4
--   7    :: Uncertain Double
--   9.18 :: Uncertain Double
--   <a>fromSamples</a> [12.5, 12.7, 12.6, 12.6, 12.5]
--   </pre>
--   
--   Can be deconstructed with <a>:+/-</a>, the pattern
--   synonym/pseudo-constructor which matches on the mean and a standard
--   deviation (supported on GHC 7.8+, with bidirectional constructor
--   functionality supported on GHC 7.10+). You can also access properties
--   with <a>uMean</a>, <a>uStd</a>, <a>uVar</a>, <a>uMeanStd</a>,
--   <a>uMeanVar</a>, <a>uRange</a>, etc.
--   
--   It's important to remember that each "occurrence" represents a unique
--   independent sample, so:
--   
--   <pre>
--   ghci&gt; let x = 15 <a>+/-</a> 2 in x + x
--   30 +/- 3
--   
--   ghci&gt; let x = 15 +/- 2 in x*2
--   30 +/- 4
--   </pre>
--   
--   <tt>x + x</tt> does not represent adding the same sample to itself
--   twice, it represents <i>independently</i> sampling two values within
--   the range <tt>15 +/- 2</tt> and adding them together. In general,
--   errors and deviations will cancel each-other out, leading to a smaller
--   uncertainty.
--   
--   However, <tt>x*2</tt> represents taking <i>one</i> sample and
--   multiplying it by two. This yields a greater uncertainty, because
--   errors and deviations are amplified.
--   
--   Also be aware that the <a>Show</a> instance "normalizes" the result,
--   and won't show any mean/central point to a decimal precision smaller
--   than the uncertainty, rounding off the excess.
data Uncert a

-- | Pattern match on an <a>Uncert</a> with its central value and its
--   standard deviation (see <a>uStd</a> for clarification).
--   
--   Can also be used to <i>construct</i> an <a>Uncert</a>, identically as
--   <a>+/-</a>.
--   
--   <i>Note:</i> Only supported on GHC 7.8 and above. Bidirectional
--   functionality (to allow use as a constructor) only supported on GHC
--   7.10 and above.
infixl 6 :+/-

-- | Create an <a>Uncert</a> around a central value and a given "range" of
--   uncertainty. The range is interpreted as the standard deviation of the
--   underlying random variable. Might be preferrable over <a>:+/-</a>
--   because it is more general (doesn't require a <a>Floating</a>
--   constraint) and looks a bit nicer.
--   
--   See <a>uStd</a> for more details.
(+/-) :: Num a => a -> a -> Uncert a
infixl 6 +/-

-- | Create an <a>Uncert</a> with an exact value and 0 uncertainty.
exact :: Num a => a -> Uncert a

-- | Create an <a>Uncert</a> about a given approximate central value, with
--   the given number of <i>digits of precision</i> (in decimal notation).
--   
--   <pre>
--   5.21 <a>withPrecision</a> 3 ≡ 5.21 <a>+/-</a> 0.01
--   </pre>
withPrecision :: (Floating a, RealFrac a) => a -> Int -> Uncert a

-- | Like <a>withPrecision</a>, except takes a number of "digits" of
--   precision in the desired numeric base. For example, in base 2, takes
--   the number of <i>bits</i> of precision.
--   
--   <pre>
--   <a>withPrecision</a> ≡ withPrecisionAtBase 10
--   </pre>
withPrecisionAtBase :: (Floating a, RealFrac a) => Int -> a -> Int -> Uncert a

-- | Create an <a>Uncert</a> around a central value, specifying its
--   uncertainty with a given <i>variance</i>. The variance is taken to be
--   proportional to the square of the range of uncertainty. See
--   <a>uStd</a> for more details.
--   
--   "Negative variances" are treated as positive.
withVar :: Num a => a -> a -> Uncert a

-- | Infer an <a>Uncert</a> from a given list of independent <i>samples</i>
--   of an underlying uncertain or random distribution.
fromSamples :: Fractional a => [a] -> Uncert a

-- | Get the mean (central) value of an <a>Uncert</a>.
uMean :: Uncert a -> a

-- | Get the <i>variance</i> of the uncertainty of an <a>Uncert</a>,
--   proportional to the square of "how uncertain" a value is. Is the
--   square of <a>uStd</a>.
uVar :: Uncert a -> a

-- | Get the <i>standard deviation</i> of the uncertainty of an
--   <a>Uncert</a>, proportional to "how uncertain" a value is.
--   
--   Very informally, it can be thought of as the interval above and below
--   the mean that about 68% of sampled values will fall under after
--   repeated sampling, or as the range that one is 68% sure the true value
--   is within.
--   
--   Is the square root of <a>uVar</a>.
uStd :: Floating a => Uncert a -> a

-- | Retrieve both the mean (central) value and the underlying variance of
--   an <a>Uncert</a> together.
--   
--   <pre>
--   uMeanVar ≡ <a>uMean</a> &amp;&amp;&amp; <a>uVar</a>
--   </pre>
uMeanVar :: Uncert a -> (a, a)

-- | Retreve both the mean (central) value and the underlying standard
--   deviation of an <a>Uncert</a> together. (See <a>uStd</a> for more
--   details)
--   
--   <pre>
--   uMeanStd ≡ <a>uMean</a> &amp;&amp;&amp; <a>uStd</a>
--   </pre>
uMeanStd :: Floating a => Uncert a -> (a, a)

-- | Retrieve the "range" of the underlying distribution of an
--   <a>Uncert</a>, derived from the standard deviation, where which
--   approximly 68% of sampled values are expected to occur (or within
--   which you are 68% certain the true value is).
--   
--   <pre>
--   uRange (x +/- dx) ≡ (x - dx, x + dx)
--   </pre>
uRange :: Floating a => Uncert a -> (a, a)

-- | Lifts a numeric function over an <a>Uncert</a>. Correctly propagates
--   the uncertainty according to the second-order taylor expansion
--   expansion of the function. Note that if the higher-degree taylor
--   series terms are large with respect to the mean and variance, this
--   approximation may be inaccurate.
--   
--   Should take any function sufficiently polymorphic over numeric types,
--   so you can use things like <a>sqrt</a>, <a>sin</a>, <a>negate</a>,
--   etc.
--   
--   <pre>
--   ghci&gt; liftU (\x -&gt; log x ^ 2) (12.2 +/- 0.5)
--   6.3 +/- 0.2
--   </pre>
liftU :: Fractional a => (forall s. AD s (Tower a) -> AD s (Tower a)) -> Uncert a -> Uncert a

-- | Lifts a two-argument (curried) function over two <a>Uncert</a>s.
--   Correctly propagates the uncertainty according to the second-order
--   (multivariate) taylor expansion expansion of the function. Note that
--   if the higher-degree taylor series terms are large with respect to the
--   mean and variance, this approximation may be inaccurate.
--   
--   Should take any function sufficiently polymorphic over numeric types,
--   so you can use things like <a>*</a>, <a>atan2</a>, <a>**</a>, etc.
--   
--   <pre>
--   ghci&gt; liftU2 (\x y -&gt; x**y) (13.5 +<i>- 0.1) (1.64 +</i>- 0.08)
--   70 +/- 10
--   </pre>
liftU2 :: Fractional a => (forall s. AD s (Sparse a) -> AD s (Sparse a) -> AD s (Sparse a)) -> Uncert a -> Uncert a -> Uncert a

-- | Lifts a three-argument (curried) function over three <a>Uncert</a>s.
--   See <a>liftU2</a> and <a>liftUF</a> for more details.
liftU3 :: Fractional a => (forall s. AD s (Sparse a) -> AD s (Sparse a) -> AD s (Sparse a) -> AD s (Sparse a)) -> Uncert a -> Uncert a -> Uncert a -> Uncert a

-- | Lifts a four-argument (curried) function over four <a>Uncert</a>s. See
--   <a>liftU2</a> and <a>liftUF</a> for more details.
liftU4 :: Fractional a => (forall s. AD s (Sparse a) -> AD s (Sparse a) -> AD s (Sparse a) -> AD s (Sparse a) -> AD s (Sparse a)) -> Uncert a -> Uncert a -> Uncert a -> Uncert a -> Uncert a

-- | Lifts a five-argument (curried) function over five <a>Uncert</a>s. See
--   <a>liftU2</a> and <a>liftUF</a> for more details.
liftU5 :: Fractional a => (forall s. AD s (Sparse a) -> AD s (Sparse a) -> AD s (Sparse a) -> AD s (Sparse a) -> AD s (Sparse a) -> AD s (Sparse a)) -> Uncert a -> Uncert a -> Uncert a -> Uncert a -> Uncert a -> Uncert a

-- | Lifts a multivariate numeric function on a container (given as an
--   <tt>f a -&gt; a</tt>) to work on a container of <a>Uncert</a>s.
--   Correctly propagates the uncertainty according to the second-order
--   (multivariate) taylor expansion of the function. Note that if the
--   higher-degree taylor series terms are large with respect to the means
--   and variances, this approximation may be inaccurate.
--   
--   Should take any function sufficiently polymorphic over numeric types,
--   so you can use things like <a>*</a>, <a>sqrt</a>, <a>atan2</a>, etc.
--   
--   <pre>
--   ghci&gt; liftUF (\[x,y,z] -&gt; x*y+z) [12.2 +<i>- 0.5, 56 +</i>- 2, 0.12 +/- 0.08]
--   680 +/- 40
--   </pre>
liftUF :: (Traversable f, Fractional a) => (forall s. f (AD s (Sparse a)) -> AD s (Sparse a)) -> f (Uncert a) -> Uncert a

-- | Attempts to "normalize" an <a>Uncert</a>. Rounds the uncertainty (the
--   standard deviation) to one digit of precision, and rounds the central
--   moment up to the implied precision.
--   
--   For example, it makes no real sense to have <tt>542.185433 +/-
--   83.584</tt>, because the extra digits of <tt>542.185433</tt> past the
--   tens place has no meaning because of the overpowering uncertainty.
--   Normalizing this results in <tt>540 +/- 80</tt>.
--   
--   Note that the <a>Show</a> instance for <a>Uncert</a> normalizes values
--   before showing them.
uNormalize :: (Floating a, RealFrac a) => Uncert a -> Uncert a

-- | Like <a>uNormalize</a>, but takes a numerical base to round with
--   respect to.
--   
--   <pre>
--   <a>uNormalize</a> ≡ uNormalizeAtBase 10
--   </pre>
uNormalizeAtBase :: (Floating a, RealFrac a) => Int -> Uncert a -> Uncert a

-- | Like <a>show</a> for <a>Uncert</a>, but does not normalize the value
--   (see <a>uNormalize</a>) before showing.
--   
--   <pre>
--   <a>show</a> ≡ uShow . <a>uNormalize</a>
--   </pre>
uShow :: (Show a, Floating a) => Uncert a -> String

-- | Like <a>showsPrec</a> for <a>Uncert</a>, but does not normalize the
--   value (see <a>uNormalize</a>) before showing. See documentation for
--   <a>showsPrec</a> for more information on how this is meant to be used.
uShowsPrec :: (Show a, Floating a) => Int -> Uncert a -> ShowS
instance GHC.Generics.Generic1 Numeric.Uncertain.Uncert
instance GHC.Generics.Generic (Numeric.Uncertain.Uncert a)
instance Data.Data.Data a => Data.Data.Data (Numeric.Uncertain.Uncert a)
instance (GHC.Show.Show a, GHC.Float.Floating a, GHC.Real.RealFrac a) => GHC.Show.Show (Numeric.Uncertain.Uncert a)
instance GHC.Real.Fractional a => GHC.Num.Num (Numeric.Uncertain.Uncert a)
instance GHC.Real.Fractional a => GHC.Real.Fractional (Numeric.Uncertain.Uncert a)
instance GHC.Float.Floating a => GHC.Float.Floating (Numeric.Uncertain.Uncert a)
instance GHC.Classes.Eq a => GHC.Classes.Eq (Numeric.Uncertain.Uncert a)
instance GHC.Classes.Ord a => GHC.Classes.Ord (Numeric.Uncertain.Uncert a)
instance (GHC.Real.Fractional a, GHC.Real.Real a) => GHC.Real.Real (Numeric.Uncertain.Uncert a)
instance GHC.Real.RealFrac a => GHC.Real.RealFrac (Numeric.Uncertain.Uncert a)
instance GHC.Float.RealFloat a => GHC.Float.RealFloat (Numeric.Uncertain.Uncert a)


-- | Provides the <a>Corr</a> monad, which allows one to describe complex
--   relationships between random variables and evaluate their propagated
--   uncertainties <i>respecting</i> their inter-correlations.
--   
--   See the <a>Numeric.Uncertain.Correlated.Interactive</a> module for an
--   "interactive" and exploratory interface for this module's
--   functionality.
module Numeric.Uncertain.Correlated

-- | The <a>Corr</a> monad allows us to keep track of correlated and
--   non-independent samples. It fixes a basic "failure" of the
--   <a>Uncert</a> type, which can't describe correlated samples.
--   
--   For example, consider the difference between:
--   
--   <pre>
--   ghci&gt; sum $ replicate 10 (12.5 <a>+/-</a> 0.8)
--   125 +/- 3
--   ghci&gt; 10 * (12.5 +/- 0.8)
--   125 +/- 8
--   </pre>
--   
--   The first one represents the addition of ten independent samples,
--   whose errors will in general cancel eachother out. The second one
--   represents sampling once and multiplying it by ten, which will amplify
--   any error by a full factor of 10.
--   
--   See how the <a>Corr</a> monad expresses the above computations:
--   
--   <pre>
--   ghci&gt; <tt>evalCorr</tt> $ do
--           x  &lt;- <tt>sampleUncert</tt> $ 12.5 <a>+/-</a> 0.8
--           y1 &lt;- <tt>resolveUncert</tt> $ sum (replicate 10 x)
--           y2 &lt;- resolveUncert $ 10 * x
--           return (y1, y2)
--   (125 +/- 8, 125 +/- 8)
--   
--   ghci&gt; <tt>evalCorr</tt> $ do
--           xs &lt;- replicateM 10 (<tt>sampleUncert</tt> (12.5 +/- 0.8))
--           <tt>resolveUncert</tt> $ sum xs
--   125 +/- 3
--   </pre>
--   
--   The first example samples once and describes operations on the single
--   sample; the second example samples 10 times with <tt>replicateM</tt>
--   and sums all of the results.
--   
--   Things are more interesting when you sample multiple variables:
--   
--   <pre>
--   ghci&gt; <tt>evalCorr</tt> $ do
--           x &lt;- <tt>sampleUncert</tt> $ 12.5 <a>+/-</a> 0.8
--           y &lt;- sampleUncert $ 15.9 +/- 0.5
--           z &lt;- sampleUncert $ 1.52 +/- 0.07
--           let k = y ** x
--           <tt>resolveUncert</tt> $ (x+z) * logBase z k
--   1200 +/- 200
--   </pre>
--   
--   The first parameter is a dummy phantom parameter used to prevent
--   <a>CVar</a>s from leaking out of the computation (see
--   <tt>evalCorr</tt>). The second parameter is the numeric type of all
--   samples within the description (for example, if you ever sample an
--   <tt><a>Uncert</a> <a>Double</a></tt>, the second parameter wil be
--   <a>Double</a>). The third parameter is the result type of the
--   computation -- the value the <a>Corr</a> is describing.
data Corr s a b

-- | Evaluates the value described by a <a>Corr</a> monad, taking into
--   account inter-correlations between samples.
--   
--   Takes a universally qualified <a>Corr</a>, which should not affect
--   usage. See the examples in the documentation for <a>Corr</a>. The
--   univeral qualification is mostly a type system trick to ensure that
--   you aren't allowed to ever use <a>evalCorr</a> to evaluate a
--   <a>CVar</a>.
evalCorr :: Fractional a => (forall s. Corr s a b) -> b

-- | Represents a single sample (or a value calculated from samples) within
--   the <a>Corr</a> monad. These can be created with
--   <tt>sampleUncert</tt>, <tt>sampleExact</tt>, and <a>constC</a>, or
--   made by combinining others with its numeric typeclass instances (like
--   <a>Num</a>) or its functions lifting arbitrary numeric functions (like
--   <a>liftC2</a>). These keep track of inter-correlations between
--   sources, and if you add together two <a>CVar</a>s that are correlated,
--   their results will reflect this.
--   
--   Can be "resolved" into the uncertain value they represent using
--   <tt>resolveUncert</tt>.
--   
--   Note that these are parameterized by a dummy phantom parameter
--   <tt>s</tt> so that they can't be "evaluated" out of the <a>Corr</a>
--   they live in with <tt>evalCorr</tt>.
--   
--   Note that a <tt><a>CVar</a> s a</tt> can only ever meaningfully
--   "exist" in a <tt><a>Corr</a> s a</tt>, meaning that the all samples
--   within that <a>Corr</a> are of the same type.
data CVar s a

-- | Generate a sample in <a>Corr</a> from an <a>Uncert</a> value,
--   independently from all other samples.
--   
--   Note that you can only sample <tt><a>Uncert</a> a</tt>s within a
--   <tt><a>Corr</a> s a</tt>, meaning that all other "sampled" values are
--   also <tt>a</tt>s.
sampleUncert :: Uncert a -> Corr s a (CVar s a)

-- | Generate an exact sample in <a>Corr</a> with zero uncertainty,
--   independently from all other samples.
--   
--   Not super useful, since you can do something equivalent with
--   <a>constC</a> or the numeric instances:
--   
--   <pre>
--   sampleExact x  ≡ return (<a>constC</a> x)
--   sampleExact 10 ≡ return 10
--   </pre>
--   
--   But is provided for completeness alongside <a>sampleUncert</a>.
--   
--   Note that you can exactly sample an <tt>a</tt> within a
--   <tt><a>Corr</a> s a</tt>, meaning that all other "sampled" values are
--   also <tt>a</tt>s.
sampleExact :: a -> Corr s a (CVar s a)

-- | Creates a <a>CVar</a> representing a completely independent sample
--   from all other <a>CVar</a>s containing the exact value given.
constC :: a -> CVar s a

-- | <a>Resolve</a> an <a>Uncert</a> from a <a>CVar</a> using its potential
--   multiple samples and sample sources, taking into account
--   inter-correlations between <a>CVar</a>s and samples.
--   
--   Note that if you use <a>sampleUncert</a> on the result, the new sample
--   will be treated as something completely independent. Usually this
--   should only be used as the "exit point" of a <a>Corr</a> description.
resolveUncert :: CVar s a -> Corr s a (Uncert a)

-- | Lifts a numeric function over the sample represented by a <a>CVar</a>.
--   Correctly propagates the uncertainty according to the second-order
--   taylor expansion expansion of the function. Note that if the
--   higher-degree taylor series terms are large with respect to the mean
--   and variance, this approximation may be inaccurate.
--   
--   Should take any function sufficiently polymorphic over numeric types,
--   so you can use things like <a>sqrt</a>, <a>sin</a>, <a>negate</a>,
--   etc.
--   
--   <pre>
--   ghci&gt; <tt>evalCorr</tt> $ do
--           x &lt;- <tt>sampleUncert</tt> $ 12.5 <a>+/-</a> 0.8
--           y &lt;- sampleUncert $ 15.9 +/- 0.5
--           <tt>resolveUncert</tt> $ liftC (\z -&gt; log z ^ 2) (x + y)
--   11.2 +/- 0.2
--   </pre>
liftC :: (forall t. AD t (Sparse a) -> AD t (Sparse a)) -> CVar s a -> CVar s a

-- | Lifts a two-argument (curried) function over the samples represented
--   by two <a>CVar</a>s. Correctly propagates the uncertainty according to
--   the second-order (multivariate) taylor expansion expansion of the
--   function, and properly takes into account and keeps track of all
--   inter-correlations between the <a>CVar</a> samples. Note that if the
--   higher-degree taylor series terms are large with respect to the mean
--   and variance, this approximation may be inaccurate.
--   
--   Should take any function sufficiently polymorphic over numeric types,
--   so you can use things like <a>*</a>, <a>atan2</a>, <a>**</a>, etc.
--   
--   <pre>
--   ghci&gt; <tt>evalCorr</tt> $ do
--           x &lt;- <tt>sampleUncert</tt> $ 12.5 <a>+/-</a> 0.8
--           y &lt;- sampleUncert $ 15.9 +/- 0.5
--           <tt>resolveUncert</tt> $ liftC2 (\a b -&gt; log (a + b) ^ 2) x y
--   11.2 +/- 0.2
--   </pre>
liftC2 :: (forall t. AD t (Sparse a) -> AD t (Sparse a) -> AD t (Sparse a)) -> CVar s a -> CVar s a -> CVar s a

-- | Lifts a three-argument (curried) function over the samples represented
--   by three <a>CVar</a>s. See <a>liftC2</a> and <a>liftCF</a> for more
--   details.
liftC3 :: (forall t. AD t (Sparse a) -> AD t (Sparse a) -> AD t (Sparse a) -> AD t (Sparse a)) -> CVar s a -> CVar s a -> CVar s a -> CVar s a

-- | Lifts a four-argument (curried) function over the samples represented
--   by four <a>CVar</a>s. See <a>liftC2</a> and <a>liftCF</a> for more
--   details.
liftC4 :: (forall t. AD t (Sparse a) -> AD t (Sparse a) -> AD t (Sparse a) -> AD t (Sparse a) -> AD t (Sparse a)) -> CVar s a -> CVar s a -> CVar s a -> CVar s a -> CVar s a

-- | Lifts a five-argument (curried) function over the samples represented
--   by five <a>CVar</a>s. See <a>liftC2</a> and <a>liftCF</a> for more
--   details.
liftC5 :: (forall t. AD t (Sparse a) -> AD t (Sparse a) -> AD t (Sparse a) -> AD t (Sparse a) -> AD t (Sparse a) -> AD t (Sparse a)) -> CVar s a -> CVar s a -> CVar s a -> CVar s a -> CVar s a -> CVar s a

-- | Lifts a multivariate numeric function on a container (given as an
--   <tt>f a -&gt; a</tt>) to work on a container of <a>CVar</a>s.
--   Correctly propagates the uncertainty according to the second-order
--   (multivariate) taylor expansion of the function, and properly takes
--   into account and keeps track of all inter-correlations between the
--   <a>CVar</a> samples. Note that if the higher-degree taylor series
--   terms are large with respect to the means and variances, this
--   approximation may be inaccurate.
--   
--   Should take any function sufficiently polymorphic over numeric types,
--   so you can use things like <a>*</a>, <a>sqrt</a>, <a>atan2</a>, etc.
--   
--   <pre>
--   ghci&gt; <tt>evalCorr</tt> $ do
--           x &lt;- <tt>sampleUncert</tt> $ 12.5 <a>+/-</a> 0.8
--           y &lt;- sampleUncert $ 15.9 +/- 0.5
--           z &lt;- sampleUncert $ 1.52 +/- 0.07
--           <tt>resolveUncert</tt> $ liftCF (\[a,b,c] -&gt; (a+c) * logBase c (b**a)) x y z
--   1200 +/- 200
--   </pre>
liftCF :: Functor f => (forall t. f (AD t (Sparse a)) -> AD t (Sparse a)) -> f (CVar s a) -> CVar s a


-- | Exports all of the interface of <a>Numeric.Uncertain.Correlated</a>,
--   except meant to be run in a <i>ghci</i> session "interactively" for
--   exploratory purposes, or in a plain <a>IO</a> action (instead of
--   inside a <a>Corr</a> monad).
--   
--   For example, with the <a>Numeric.Uncertain.Correlated</a> interface:
--   
--   <pre>
--   ghci&gt; <tt>evalCorr</tt> $ do
--           x &lt;- sampleUncert $ 12.5 <a>+/-</a> 0.8
--           y &lt;- sampleUncert $ 15.9 +/- 0.5
--           z &lt;- sampleUncert $ 1.52 +/- 0.07
--           let k = y**x
--           resolveUncert $ (x+z) * logBase z k
--   1200 +/- 200
--   </pre>
--   
--   And with the interface from this "interactive" module:
--   
--   <pre>
--   ghci&gt; x &lt;- <a>sampleUncert</a> $ 12.5 +/- 0.8
--   ghci&gt; y &lt;- sampleUncert $ 15.9 +/- 0.5
--   ghci&gt; z &lt;- sampleUncert $ 1.52 +/- 0.07
--   ghci&gt; let k = y**x
--   ghci&gt; <a>resolveUncert</a> $ (x+z) * logBase z k
--   1200 +/- 200
--   </pre>
--   
--   The main purpose of this module is to allow one to use <i>ghci</i> as
--   a fancy "calculator" for computing and exploring propagated
--   uncertainties of complex and potentially correlated samples with
--   uncertainty.
--   
--   Because many of the names overlap with the names from the
--   <a>Numeric.Uncertain.Correlated</a> module, it is recommended that you
--   never have both imported at the same time in <i>ghci</i> or in a file,
--   or import them qualified if you must.
--   
--   Also note that all of these methods only work with <tt><a>Uncert</a>
--   <a>Double</a></tt>s, and are not polymorphic over different numeric
--   types.
--   
--   Be aware that this module is not robustly tested in heavily concurrent
--   situations/applications.
module Numeric.Uncertain.Correlated.Interactive

-- | Represents a single sample (or a value calculated from samples) within
--   the <a>Corr</a> monad. These can be created with
--   <tt>sampleUncert</tt>, <tt>sampleExact</tt>, and <a>constC</a>, or
--   made by combinining others with its numeric typeclass instances (like
--   <a>Num</a>) or its functions lifting arbitrary numeric functions (like
--   <a>liftC2</a>). These keep track of inter-correlations between
--   sources, and if you add together two <a>CVar</a>s that are correlated,
--   their results will reflect this.
--   
--   Can be "resolved" into the uncertain value they represent using
--   <tt>resolveUncert</tt>.
--   
--   Note that these are parameterized by a dummy phantom parameter
--   <tt>s</tt> so that they can't be "evaluated" out of the <a>Corr</a>
--   they live in with <tt>evalCorr</tt>.
--   
--   Note that a <tt><a>CVar</a> s a</tt> can only ever meaningfully
--   "exist" in a <tt><a>Corr</a> s a</tt>, meaning that the all samples
--   within that <a>Corr</a> are of the same type.
data CVar s a

-- | A <a>CVar</a> specialized to work in an "interactive" context, in
--   <i>ghci</i> or <a>IO</a>.
type CVarIO = CVar RealWorld Double

-- | Generate a sample in <a>IO</a> from an <tt><a>Uncert</a>
--   <a>Double</a></tt> value, independently from all other samples.
sampleUncert :: Uncert Double -> IO CVarIO

-- | Generate an exact sample in <a>IO</a> with zero uncertainty,
--   independently from all other samples.
--   
--   Not super useful, since you can do something equivalent with
--   <a>constC</a> or the numeric instances:
--   
--   <pre>
--   sampleExact x  ≡ return (<a>constC</a> x)
--   sampleExact 10 ≡ return 10
--   </pre>
--   
--   But is provided for completeness alongside <a>sampleUncert</a>.
sampleExact :: Double -> IO CVarIO

-- | Creates a <a>CVar</a> representing a completely independent sample
--   from all other <a>CVar</a>s containing the exact value given.
constC :: a -> CVar s a

-- | <a>Resolve</a> an <a>Uncert</a> from a <a>CVarIO</a> using its
--   potential multiple samples and sample sources, taking into account
--   inter-correlations between <a>CVarIO</a>s and samples.
--   
--   Note that if you use <a>sampleUncert</a> on the result, the new sample
--   will be treated as something completely independent. Usually this
--   should only be used as the "final value" of your computation or
--   exploration.
resolveUncert :: CVarIO -> IO (Uncert Double)

-- | Lifts a numeric function over the sample represented by a <a>CVar</a>.
--   Correctly propagates the uncertainty according to the second-order
--   taylor expansion expansion of the function. Note that if the
--   higher-degree taylor series terms are large with respect to the mean
--   and variance, this approximation may be inaccurate.
--   
--   Should take any function sufficiently polymorphic over numeric types,
--   so you can use things like <a>sqrt</a>, <a>sin</a>, <a>negate</a>,
--   etc.
--   
--   <pre>
--   ghci&gt; <tt>evalCorr</tt> $ do
--           x &lt;- <tt>sampleUncert</tt> $ 12.5 <a>+/-</a> 0.8
--           y &lt;- sampleUncert $ 15.9 +/- 0.5
--           <tt>resolveUncert</tt> $ liftC (\z -&gt; log z ^ 2) (x + y)
--   11.2 +/- 0.2
--   </pre>
liftC :: (forall t. AD t (Sparse a) -> AD t (Sparse a)) -> CVar s a -> CVar s a

-- | Lifts a two-argument (curried) function over the samples represented
--   by two <a>CVar</a>s. Correctly propagates the uncertainty according to
--   the second-order (multivariate) taylor expansion expansion of the
--   function, and properly takes into account and keeps track of all
--   inter-correlations between the <a>CVar</a> samples. Note that if the
--   higher-degree taylor series terms are large with respect to the mean
--   and variance, this approximation may be inaccurate.
--   
--   Should take any function sufficiently polymorphic over numeric types,
--   so you can use things like <a>*</a>, <a>atan2</a>, <a>**</a>, etc.
--   
--   <pre>
--   ghci&gt; <tt>evalCorr</tt> $ do
--           x &lt;- <tt>sampleUncert</tt> $ 12.5 <a>+/-</a> 0.8
--           y &lt;- sampleUncert $ 15.9 +/- 0.5
--           <tt>resolveUncert</tt> $ liftC2 (\a b -&gt; log (a + b) ^ 2) x y
--   11.2 +/- 0.2
--   </pre>
liftC2 :: (forall t. AD t (Sparse a) -> AD t (Sparse a) -> AD t (Sparse a)) -> CVar s a -> CVar s a -> CVar s a

-- | Lifts a three-argument (curried) function over the samples represented
--   by three <a>CVar</a>s. See <a>liftC2</a> and <a>liftCF</a> for more
--   details.
liftC3 :: (forall t. AD t (Sparse a) -> AD t (Sparse a) -> AD t (Sparse a) -> AD t (Sparse a)) -> CVar s a -> CVar s a -> CVar s a -> CVar s a

-- | Lifts a four-argument (curried) function over the samples represented
--   by four <a>CVar</a>s. See <a>liftC2</a> and <a>liftCF</a> for more
--   details.
liftC4 :: (forall t. AD t (Sparse a) -> AD t (Sparse a) -> AD t (Sparse a) -> AD t (Sparse a) -> AD t (Sparse a)) -> CVar s a -> CVar s a -> CVar s a -> CVar s a -> CVar s a

-- | Lifts a five-argument (curried) function over the samples represented
--   by five <a>CVar</a>s. See <a>liftC2</a> and <a>liftCF</a> for more
--   details.
liftC5 :: (forall t. AD t (Sparse a) -> AD t (Sparse a) -> AD t (Sparse a) -> AD t (Sparse a) -> AD t (Sparse a) -> AD t (Sparse a)) -> CVar s a -> CVar s a -> CVar s a -> CVar s a -> CVar s a -> CVar s a

-- | Lifts a multivariate numeric function on a container (given as an
--   <tt>f a -&gt; a</tt>) to work on a container of <a>CVar</a>s.
--   Correctly propagates the uncertainty according to the second-order
--   (multivariate) taylor expansion of the function, and properly takes
--   into account and keeps track of all inter-correlations between the
--   <a>CVar</a> samples. Note that if the higher-degree taylor series
--   terms are large with respect to the means and variances, this
--   approximation may be inaccurate.
--   
--   Should take any function sufficiently polymorphic over numeric types,
--   so you can use things like <a>*</a>, <a>sqrt</a>, <a>atan2</a>, etc.
--   
--   <pre>
--   ghci&gt; <tt>evalCorr</tt> $ do
--           x &lt;- <tt>sampleUncert</tt> $ 12.5 <a>+/-</a> 0.8
--           y &lt;- sampleUncert $ 15.9 +/- 0.5
--           z &lt;- sampleUncert $ 1.52 +/- 0.07
--           <tt>resolveUncert</tt> $ liftCF (\[a,b,c] -&gt; (a+c) * logBase c (b**a)) x y z
--   1200 +/- 200
--   </pre>
liftCF :: Functor f => (forall t. f (AD t (Sparse a)) -> AD t (Sparse a)) -> f (CVar s a) -> CVar s a


-- | Provides an interface for computing and propagating uncertainty by
--   using <a>Monte Carlo simulations</a>.
--   
--   Basically simulates sampling from the distribution represented by the
--   given <a>Uncert</a>s, applying the function of interest, and
--   aggregating the mean and standard deviation of the results. <tt>x
--   <tt>+/-</tt> dx</tt> is treated as a random variable whose probability
--   density is the normal distribution with mean <tt>x</tt> and standard
--   deviation <tt>dx</tt>.
--   
--   This module attempts to duplicate the API offered by
--   <a>Numeric.Uncertain</a> and is meant to be imported qualified
--   alongside <a>Numeric.Uncertain</a>
--   
--   <pre>
--   import           Numeric.Uncertain
--   import qualified Numeric.Uncertain.MonteCarlo as MC
--   </pre>
--   
--   Actions are parameterized over all <a>PrimMonad</a> instances, so can
--   be run under both <tt>ST</tt> and <a>IO</a>, making it suitable for
--   exploratory purposes. All functions require a <a>Gen</a> from
--   <a>System.Random.MWC</a> for random value generation purposes.
--   
--   <pre>
--   ghci&gt; import qualified Numeric.Uncertain.MonteCarlo as MC
--   ghci&gt; import System.Random.MWC
--   ghci&gt; let x = 1.52 <tt>+/-</tt> 0.07
--   ghci&gt; let y = 781.4 +/- 0.3
--   ghci&gt; let z = 1.53e-1 `<tt>withPrecision'</tt> 3
--   ghci&gt; g &lt;- <a>create</a>
--   ghci&gt; cosh x
--   2.4 +/- 0.2
--   ghci&gt; MC.liftU cosh x g
--   2.4 +/- 0.2
--   ghci&gt; exp x / z * sin (y ** z)
--   10.9 +/- 0.9
--   ghci&gt; MC.liftU3 (\a b c -&gt; exp a / c * sin (b**c)) x y z g
--   10.8 +/- 1.0
--   ghci&gt; pi + 3 * logBase x y
--   52 +/- 5
--   ghci&gt; MC.liftU2 (\a b -&gt; pi + 3 * logBase a b) x y g
--   51 +/- 5
--   </pre>
module Numeric.Uncertain.MonteCarlo

-- | Sample a random <a>Double</a> from the distribution specified by an
--   <tt><a>Uncert</a> <a>Double</a></tt>. <tt>x <tt>+/-</tt> dx</tt> is
--   treated as a random variable whose probability density is the normal
--   distribution with mean <tt>x</tt> and standard deviation <tt>dx</tt>.
sampleUncert :: PrimMonad m => Uncert Double -> Gen (PrimState m) -> m Double

-- | Lifts a numeric function over an <a>Uncert</a> using a Monte Carlo
--   simulation with 1000 samples.
--   
--   <pre>
--   ghci&gt; g &lt;- <a>create</a>
--   ghci&gt; MC.liftU (\x -&gt; log x ^ 2) (12.2 +/- 0.5) g
--   6.3 +/- 0.2
--   </pre>
liftU :: PrimMonad m => (Double -> Double) -> Uncert Double -> Gen (PrimState m) -> m (Uncert Double)

-- | Lifts a two-argument (curried) function over two <a>Uncert</a>s using
--   a Monte Carlo simulation with 1000 samples.
--   
--   <pre>
--   ghci&gt; g &lt;- <a>create</a>
--   ghci&gt; MC.liftU2 (\x y -&gt; x**y) (13.5 +<i>- 0.1) (1.64 +</i>- 0.08)
--   70 +/- 20
--   </pre>
liftU2 :: PrimMonad m => (Double -> Double -> Double) -> Uncert Double -> Uncert Double -> Gen (PrimState m) -> m (Uncert Double)

-- | Lifts a three-argument (curried) function over three <a>Uncert</a>s.
--   See <a>liftU2</a> and <a>liftUF</a> for more details.
liftU3 :: PrimMonad m => (Double -> Double -> Double -> Double) -> Uncert Double -> Uncert Double -> Uncert Double -> Gen (PrimState m) -> m (Uncert Double)

-- | Lifts a four-argument (curried) function over four <a>Uncert</a>s. See
--   <a>liftU2</a> and <a>liftUF</a> for more details.
liftU4 :: PrimMonad m => (Double -> Double -> Double -> Double -> Double) -> Uncert Double -> Uncert Double -> Uncert Double -> Uncert Double -> Gen (PrimState m) -> m (Uncert Double)

-- | Lifts a five-argument (curried) function over five <a>Uncert</a>s. See
--   <a>liftU2</a> and <a>liftUF</a> for more details.
liftU5 :: PrimMonad m => (Double -> Double -> Double -> Double -> Double -> Double) -> Uncert Double -> Uncert Double -> Uncert Double -> Uncert Double -> Uncert Double -> Gen (PrimState m) -> m (Uncert Double)

-- | Lifts a multivariate numeric function on a container (given as an
--   <tt>f a -&gt; a</tt>) to work on a container of <a>Uncert</a>s using a
--   Monte Carlo simulation with 1000 samples.
--   
--   <pre>
--   ghci&gt; g &lt;- <a>create</a>
--   ghci&gt; M.liftUF (\[x,y,z] -&gt; x*y+z) [12.2 +<i>- 0.5, 56 +</i>- 2, 0.12 +/- 0.08] g
--   680 +/- 40
--   </pre>
liftUF :: (Traversable f, PrimMonad m) => (f Double -> Double) -> f (Uncert Double) -> Gen (PrimState m) -> m (Uncert Double)

-- | Like <a>liftU</a>, but allows you to specify the number of samples to
--   run the Monte Carlo simulation with.
liftU' :: PrimMonad m => Int -> (Double -> Double) -> Uncert Double -> Gen (PrimState m) -> m (Uncert Double)

-- | Like <a>liftU2</a>, but allows you to specify the number of samples to
--   run the Monte Carlo simulation with.
liftU2' :: PrimMonad m => Int -> (Double -> Double -> Double) -> Uncert Double -> Uncert Double -> Gen (PrimState m) -> m (Uncert Double)

-- | Like <a>liftU3</a>, but allows you to specify the number of samples to
--   run the Monte Carlo simulation with.
liftU3' :: PrimMonad m => Int -> (Double -> Double -> Double -> Double) -> Uncert Double -> Uncert Double -> Uncert Double -> Gen (PrimState m) -> m (Uncert Double)

-- | Like <a>liftU4</a>, but allows you to specify the number of samples to
--   run the Monte Carlo simulation with.
liftU4' :: PrimMonad m => Int -> (Double -> Double -> Double -> Double -> Double) -> Uncert Double -> Uncert Double -> Uncert Double -> Uncert Double -> Gen (PrimState m) -> m (Uncert Double)

-- | Like <a>liftU5</a>, but allows you to specify the number of samples to
--   run the Monte Carlo simulation with.
liftU5' :: PrimMonad m => Int -> (Double -> Double -> Double -> Double -> Double -> Double) -> Uncert Double -> Uncert Double -> Uncert Double -> Uncert Double -> Uncert Double -> Gen (PrimState m) -> m (Uncert Double)

-- | Like <a>liftUF</a>, but allows you to specify the number of samples to
--   run the Monte Carlo simulation with.
liftUF' :: (Traversable f, PrimMonad m) => Int -> (f Double -> Double) -> f (Uncert Double) -> Gen (PrimState m) -> m (Uncert Double)
