{-# LANGUAGE CPP #-}
{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE ViewPatterns #-}
{-# LANGUAGE NoImplicitPrelude #-}

#if __GLASGOW_HASKELL__ >= 708
{-# LANGUAGE PatternSynonyms     #-}
#endif

-- |
-- Module      : Numeric.Uncertain
-- Copyright   : (c) Justin Le 2016
-- License     : BSD3
--
-- Maintainer  : justin@jle.im
-- Stability   : experimental
-- Portability : non-portable
module Numeric.Uncertain (
  -- * 'Uncert'
  Uncert ((:+/-)),

  -- ** Creating 'Uncert' values
  (+/-),
  exact,
  withPrecision,
  withPrecisionAtBase,
  withVar,
  fromSamples,

  -- ** Inspecting properties
  uMean,
  uVar,
  uStd,
  uMeanVar,
  uMeanStd,
  uRange,

  -- * Applying arbitrary functions
  liftU,
  liftU2,
  liftU3,
  liftU4,
  liftU5,
  liftUF,

  -- * Utility functions
  uNormalize,
  uNormalizeAtBase,
  uShow,
  uShowsPrec,
)
where

import Data.Data
import Data.Foldable (toList)
import Data.Function
import Data.Hople
import Data.Ord
import GHC.Generics
import Numeric.AD.Mode.Sparse
import qualified Numeric.AD.Mode.Tower as T
import Prelude.Compat

-- | 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 `Num`,
-- `Fractional`, 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 'liftU', 'liftUF', 'liftU2' and family.
--
-- @
-- ghci> let x = 1.52 '+/-' 0.07
-- ghci> let y = 781.4 +/- 0.3
-- ghci> let z = 1.53e-1 `'withPrecision'` 3
-- ghci> cosh x
-- 2.4 +/- 0.2
-- ghci> exp x / z * sin (y ** z)
-- 10.9 +/- 0.9
-- ghci> pi + 3 * logBase x y
-- 52 +/- 5
-- @
--
-- 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 'exact' to represent an "exact" measurement with no
-- uncertainty, '+/-' and ':+/-' to specify a standard deviation as
-- a range, 'withPrecision' to specify through decimal precision, and
-- 'withVar' to specify with a variance.  Can also be inferred from a list
-- of samples with 'fromSamples'
--
-- @
-- 7.13 '+/-' 0.05
-- 91800 +/- 100
-- 12.5 `'withVar'` 0.36
-- 'exact' 7.9512
-- 81.42 `'withPrecision'` 4
-- 7    :: Uncertain Double
-- 9.18 :: Uncertain Double
-- 'fromSamples' [12.5, 12.7, 12.6, 12.6, 12.5]
-- @
--
-- Can be deconstructed with ':+/-', 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 'uMean', 'uStd', 'uVar',
-- 'uMeanStd', 'uMeanVar', 'uRange', etc.
--
-- It's important to remember that each "occurrence" represents a unique
-- independent sample, so:
--
-- @
-- ghci> let x = 15 '+/-' 2 in x + x
-- 30 +/- 3
--
-- ghci> let x = 15 +/- 2 in x*2
-- 30 +/- 4
-- @
--
-- @x + x@ does not represent adding the same sample to itself twice, it
-- represents /independently/ sampling two values within the range @15 +/- 2@
-- and adding them together.  In general, errors and deviations will cancel
-- each-other out, leading to a smaller uncertainty.
--
-- However, @x*2@ represents taking /one/ sample and multiplying it by two.
-- This yields a greater uncertainty, because errors and deviations are
-- amplified.
--
-- Also be aware that the 'Show' 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 = Un
  { forall a. Uncert a -> a
_uMean :: !a
  , forall a. Uncert a -> a
_uVar :: !a
  -- ^ maintained to be positive!
  }
  deriving (Typeable (Uncert a)
Typeable (Uncert a) =>
(forall (c :: * -> *).
 (forall d b. Data d => c (d -> b) -> d -> c b)
 -> (forall g. g -> c g) -> Uncert a -> c (Uncert a))
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c (Uncert a))
-> (Uncert a -> Constr)
-> (Uncert a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c (Uncert a)))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e))
    -> Maybe (c (Uncert a)))
-> ((forall b. Data b => b -> b) -> Uncert a -> Uncert a)
-> (forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> Uncert a -> r)
-> (forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> Uncert a -> r)
-> (forall u. (forall d. Data d => d -> u) -> Uncert a -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> Uncert a -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> Uncert a -> m (Uncert a))
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Uncert a -> m (Uncert a))
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Uncert a -> m (Uncert a))
-> Data (Uncert a)
Uncert a -> Constr
Uncert a -> DataType
(forall b. Data b => b -> b) -> Uncert a -> Uncert a
forall a. Data a => Typeable (Uncert a)
forall a. Data a => Uncert a -> Constr
forall a. Data a => Uncert a -> DataType
forall a.
Data a =>
(forall b. Data b => b -> b) -> Uncert a -> Uncert a
forall a u.
Data a =>
Int -> (forall d. Data d => d -> u) -> Uncert a -> u
forall a u.
Data a =>
(forall d. Data d => d -> u) -> Uncert a -> [u]
forall a r r'.
Data a =>
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> Uncert a -> r
forall a r r'.
Data a =>
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> Uncert a -> r
forall a (m :: * -> *).
(Data a, Monad m) =>
(forall d. Data d => d -> m d) -> Uncert a -> m (Uncert a)
forall a (m :: * -> *).
(Data a, MonadPlus m) =>
(forall d. Data d => d -> m d) -> Uncert a -> m (Uncert a)
forall a (c :: * -> *).
Data a =>
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c (Uncert a)
forall a (c :: * -> *).
Data a =>
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Uncert a -> c (Uncert a)
forall a (t :: * -> *) (c :: * -> *).
(Data a, Typeable t) =>
(forall d. Data d => c (t d)) -> Maybe (c (Uncert a))
forall a (t :: * -> * -> *) (c :: * -> *).
(Data a, Typeable t) =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c (Uncert a))
forall a.
Typeable a =>
(forall (c :: * -> *).
 (forall d b. Data d => c (d -> b) -> d -> c b)
 -> (forall g. g -> c g) -> a -> c a)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c a)
-> (a -> Constr)
-> (a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c a))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
-> ((forall b. Data b => b -> b) -> a -> a)
-> (forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall u. (forall d. Data d => d -> u) -> a -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> Data a
forall u. Int -> (forall d. Data d => d -> u) -> Uncert a -> u
forall u. (forall d. Data d => d -> u) -> Uncert a -> [u]
forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> Uncert a -> r
forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> Uncert a -> r
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> Uncert a -> m (Uncert a)
forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Uncert a -> m (Uncert a)
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c (Uncert a)
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Uncert a -> c (Uncert a)
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c (Uncert a))
forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c (Uncert a))
$cgfoldl :: forall a (c :: * -> *).
Data a =>
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Uncert a -> c (Uncert a)
gfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Uncert a -> c (Uncert a)
$cgunfold :: forall a (c :: * -> *).
Data a =>
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c (Uncert a)
gunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c (Uncert a)
$ctoConstr :: forall a. Data a => Uncert a -> Constr
toConstr :: Uncert a -> Constr
$cdataTypeOf :: forall a. Data a => Uncert a -> DataType
dataTypeOf :: Uncert a -> DataType
$cdataCast1 :: forall a (t :: * -> *) (c :: * -> *).
(Data a, Typeable t) =>
(forall d. Data d => c (t d)) -> Maybe (c (Uncert a))
dataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c (Uncert a))
$cdataCast2 :: forall a (t :: * -> * -> *) (c :: * -> *).
(Data a, Typeable t) =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c (Uncert a))
dataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c (Uncert a))
$cgmapT :: forall a.
Data a =>
(forall b. Data b => b -> b) -> Uncert a -> Uncert a
gmapT :: (forall b. Data b => b -> b) -> Uncert a -> Uncert a
$cgmapQl :: forall a r r'.
Data a =>
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> Uncert a -> r
gmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> Uncert a -> r
$cgmapQr :: forall a r r'.
Data a =>
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> Uncert a -> r
gmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> Uncert a -> r
$cgmapQ :: forall a u.
Data a =>
(forall d. Data d => d -> u) -> Uncert a -> [u]
gmapQ :: forall u. (forall d. Data d => d -> u) -> Uncert a -> [u]
$cgmapQi :: forall a u.
Data a =>
Int -> (forall d. Data d => d -> u) -> Uncert a -> u
gmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> Uncert a -> u
$cgmapM :: forall a (m :: * -> *).
(Data a, Monad m) =>
(forall d. Data d => d -> m d) -> Uncert a -> m (Uncert a)
gmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> Uncert a -> m (Uncert a)
$cgmapMp :: forall a (m :: * -> *).
(Data a, MonadPlus m) =>
(forall d. Data d => d -> m d) -> Uncert a -> m (Uncert a)
gmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Uncert a -> m (Uncert a)
$cgmapMo :: forall a (m :: * -> *).
(Data a, MonadPlus m) =>
(forall d. Data d => d -> m d) -> Uncert a -> m (Uncert a)
gmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Uncert a -> m (Uncert a)
Data, Typeable, (forall x. Uncert a -> Rep (Uncert a) x)
-> (forall x. Rep (Uncert a) x -> Uncert a) -> Generic (Uncert a)
forall x. Rep (Uncert a) x -> Uncert a
forall x. Uncert a -> Rep (Uncert a) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall a x. Rep (Uncert a) x -> Uncert a
forall a x. Uncert a -> Rep (Uncert a) x
$cfrom :: forall a x. Uncert a -> Rep (Uncert a) x
from :: forall x. Uncert a -> Rep (Uncert a) x
$cto :: forall a x. Rep (Uncert a) x -> Uncert a
to :: forall x. Rep (Uncert a) x -> Uncert a
Generic, (forall a. Uncert a -> Rep1 Uncert a)
-> (forall a. Rep1 Uncert a -> Uncert a) -> Generic1 Uncert
forall a. Rep1 Uncert a -> Uncert a
forall a. Uncert a -> Rep1 Uncert a
forall k (f :: k -> *).
(forall (a :: k). f a -> Rep1 f a)
-> (forall (a :: k). Rep1 f a -> f a) -> Generic1 f
$cfrom1 :: forall a. Uncert a -> Rep1 Uncert a
from1 :: forall a. Uncert a -> Rep1 Uncert a
$cto1 :: forall a. Rep1 Uncert a -> Uncert a
to1 :: forall a. Rep1 Uncert a -> Uncert a
Generic1)

-- | Get the mean (central) value of an 'Uncert'.
uMean :: Uncert a -> a
uMean :: forall a. Uncert a -> a
uMean = Uncert a -> a
forall a. Uncert a -> a
_uMean
{-# INLINE uMean #-}

-- | Get the /variance/ of the uncertainty of an 'Uncert', proportional to
-- the square of "how uncertain" a value is.  Is the square of 'uStd'.
uVar :: Uncert a -> a
uVar :: forall a. Uncert a -> a
uVar = Uncert a -> a
forall a. Uncert a -> a
_uVar
{-# INLINE uVar #-}

-- | Get the /standard deviation/ of the uncertainty of an 'Uncert',
-- 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 'uVar'.
uStd :: Floating a => Uncert a -> a
uStd :: forall a. Floating a => Uncert a -> a
uStd = a -> a
forall a. Floating a => a -> a
sqrt (a -> a) -> (Uncert a -> a) -> Uncert a -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Uncert a -> a
forall a. Uncert a -> a
uVar
{-# INLINE uStd #-}

-- | Create an 'Uncert' with an exact value and 0 uncertainty.
exact ::
  Num a =>
  -- | The exact value
  a ->
  Uncert a
exact :: forall a. Num a => a -> Uncert a
exact a
x = a -> a -> Uncert a
forall a. a -> a -> Uncert a
Un a
x a
0
{-# INLINE exact #-}

infixl 6 +/-
#if __GLASGOW_HASKELL__ >= 708
infixl 6 :+/-
#endif

-- | Create an 'Uncert' 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 ':+/-' because it
-- is more general (doesn't require a 'Floating' constraint) and looks
-- a bit nicer.
--
-- See 'uStd' for more details.
(+/-) ::
  Num a =>
  -- | The mean or central value
  a ->
  -- | The standard deviation of the underlying uncertainty
  a ->
  Uncert a
a
x +/- :: forall a. Num a => a -> a -> Uncert a
+/- a
dx = a -> a -> Uncert a
forall a. a -> a -> Uncert a
Un a
x (a
dx a -> a -> a
forall a. Num a => a -> a -> a
* a
dx)
{-# INLINE (+/-) #-}

-- | Create an 'Uncert' around a central value, specifying its uncertainty
-- with a given /variance/.  The variance is taken to be proportional to
-- the square of the range of uncertainty.  See 'uStd' for more details.
--
-- "Negative variances" are treated as positive.
withVar ::
  Num a =>
  -- | The mean or central value
  a ->
  -- | The variance of the underlying uncertainty
  a ->
  Uncert a
withVar :: forall a. Num a => a -> a -> Uncert a
withVar a
x a
vx = a -> a -> Uncert a
forall a. a -> a -> Uncert a
Un a
x (a -> a
forall a. Num a => a -> a
abs a
vx)
{-# INLINE withVar #-}

#if __GLASGOW_HASKELL__ >= 708
-- | Pattern match on an 'Uncert' with its central value and its standard
-- deviation (see 'uStd' for clarification).
--
-- Can also be used to /construct/ an 'Uncert', identically as '+/-'.
--
-- /Note:/ Only supported on GHC 7.8 and above.  Bidirectional
-- functionality (to allow use as a constructor) only supported on GHC
-- 7.10 and above.
--
#if __GLASGOW_HASKELL__ >= 800
pattern (:+/-) :: Floating a => a -> a -> Uncert a
#elif __GLASGOW_HASKELL__ >= 710
pattern (:+/-) :: () => Floating a => a -> a -> Uncert a
#endif
pattern x $m:+/- :: forall {r} {a}.
Floating a =>
Uncert a -> (a -> a -> r) -> ((# #) -> r) -> r
$b:+/- :: forall a. Floating a => a -> a -> Uncert a
:+/- dx <- Un x (sqrt->dx)
#if __GLASGOW_HASKELL__ >= 710
  where
    a
x :+/- a
dx = a -> a -> Uncert a
forall a. a -> a -> Uncert a
Un a
x (a
dxa -> a -> a
forall a. Num a => a -> a -> a
*a
dx)
#endif
#endif

-- | Infer an 'Uncert' from a given list of independent /samples/ of an
-- underlying uncertain or random distribution.
fromSamples :: Fractional a => [a] -> Uncert a
fromSamples :: forall a. Fractional a => [a] -> Uncert a
fromSamples = H3 a -> Uncert a
forall {a}. Fractional a => H3 a -> Uncert a
makeUn (H3 a -> Uncert a) -> ([a] -> H3 a) -> [a] -> Uncert a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [a] -> H3 a
foldStats
  where
    makeUn :: H3 a -> Uncert a
makeUn (H3 a
x0 a
x1 a
x2) = a -> a -> Uncert a
forall a. a -> a -> Uncert a
Un a
μ a
v
      where
        μ :: a
μ = a
x1 a -> a -> a
forall a. Fractional a => a -> a -> a
/ a
x0
        v :: a
v = a
x2 a -> a -> a
forall a. Fractional a => a -> a -> a
/ a
x0 a -> a -> a
forall a. Num a => a -> a -> a
- a
μ a -> a -> a
forall a. Num a => a -> a -> a
* a
μ -- maybe use pop var?
    foldStats :: [a] -> H3 a
foldStats = ((H3 a -> a -> H3 a) -> H3 a -> [a] -> H3 a)
-> H3 a -> (H3 a -> a -> H3 a) -> [a] -> H3 a
forall a b c. (a -> b -> c) -> b -> a -> c
flip (H3 a -> a -> H3 a) -> H3 a -> [a] -> H3 a
forall b a. (b -> a -> b) -> b -> [a] -> b
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' (a -> a -> a -> H3 a
forall a. a -> a -> a -> H3 a
H3 a
0 a
0 a
0) ((H3 a -> a -> H3 a) -> [a] -> H3 a)
-> (H3 a -> a -> H3 a) -> [a] -> H3 a
forall a b. (a -> b) -> a -> b
$
      \(H3 a
s0 a
s1 a
s2) a
x ->
        a -> a -> a -> H3 a
forall a. a -> a -> a -> H3 a
H3 (a
s0 a -> a -> a
forall a. Num a => a -> a -> a
+ a
1) (a
s1 a -> a -> a
forall a. Num a => a -> a -> a
+ a
x) (a
s2 a -> a -> a
forall a. Num a => a -> a -> a
+ a
x a -> a -> a
forall a. Num a => a -> a -> a
* a
x)
{-# INLINEABLE fromSamples #-}

-- | Retrieve both the mean (central) value and the underlying variance of
-- an 'Uncert' together.
--
-- @uMeanVar ≡ 'uMean' &&& 'uVar'@
uMeanVar :: Uncert a -> (a, a)
uMeanVar :: forall a. Uncert a -> (a, a)
uMeanVar (Un a
x a
vx) = (a
x, a
vx)
{-# INLINE uMeanVar #-}

-- | Retreve both the mean (central) value and the underlying standard
-- deviation of an 'Uncert' together.  (See 'uStd' for more details)
--
-- @uMeanStd ≡ 'uMean' &&& 'uStd'@
uMeanStd :: Floating a => Uncert a -> (a, a)
uMeanStd :: forall a. Floating a => Uncert a -> (a, a)
uMeanStd (Un a
x a
vx) = (a
x, a -> a
forall a. Floating a => a -> a
sqrt a
vx)
{-# INLINE uMeanStd #-}

-- | Retrieve the "range" of the underlying distribution of an 'Uncert',
-- 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).
--
-- @uRange (x +/- dx) ≡ (x - dx, x + dx)@
uRange :: Floating a => Uncert a -> (a, a)
uRange :: forall a. Floating a => Uncert a -> (a, a)
uRange (Uncert a -> (a, a)
forall a. Floating a => Uncert a -> (a, a)
uMeanStd -> (a
x, a
dx)) = (a
x a -> a -> a
forall a. Num a => a -> a -> a
- a
dx, a
x a -> a -> a
forall a. Num a => a -> a -> a
+ a
dx)
{-# INLINEABLE uRange #-}

-- | Like 'withPrecision', except takes a number of "digits" of precision in
-- the desired numeric base.  For example, in base 2, takes the number of
-- /bits/ of precision.
--
-- @'withPrecision' ≡ withPrecisionAtBase 10@
withPrecisionAtBase ::
  (Floating a, RealFrac a) =>
  -- | The base to determine precision with respect to
  Int ->
  -- | The approximate value of the 'Uncert'
  a ->
  -- | The number of "digits" of precision to take
  Int ->
  Uncert a
withPrecisionAtBase :: forall a. (Floating a, RealFrac a) => Int -> a -> Int -> Uncert a
withPrecisionAtBase Int
b a
x Int
p = a
x' a -> a -> Uncert a
forall a. Num a => a -> a -> Uncert a
+/- a
dx'
  where
    leading :: Int
    leading :: Int
leading = Int -> Int
forall a. Num a => a -> a
negate (Int -> Int) -> (a -> Int) -> a -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Int
forall b. Integral b => a -> b
forall a b. (RealFrac a, Integral b) => a -> b
floor (a -> Int) -> (a -> a) -> a -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> a -> a
forall a. Floating a => a -> a -> a
logBase (Int -> a
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
b) (a -> Int) -> a -> Int
forall a b. (a -> b) -> a -> b
$ a
x
    uncert :: Int
    uncert :: Int
uncert = Int
leading Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
p
    rounder :: a
rounder = Int -> a
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
b a -> a -> a
forall a. Floating a => a -> a -> a
** Int -> a
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
uncert
    x' :: a
x' = (a -> a -> a
forall a. Fractional a => a -> a -> a
/ a
rounder) (a -> a) -> (a -> a) -> a -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Integer -> a
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Integer -> a) -> (a -> Integer) -> a -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Integer
forall a. RealFrac a => a -> Integer
round' (a -> Integer) -> (a -> a) -> a -> Integer
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> a -> a
forall a. Num a => a -> a -> a
* a
rounder) (a -> a) -> a -> a
forall a b. (a -> b) -> a -> b
$ a
x
    dx' :: a
dx' = a
1 a -> a -> a
forall a. Fractional a => a -> a -> a
/ a
rounder
    round' :: RealFrac a => a -> Integer
    round' :: forall a. RealFrac a => a -> Integer
round' = a -> Integer
forall b. Integral b => a -> b
forall a b. (RealFrac a, Integral b) => a -> b
round
{-# INLINEABLE withPrecisionAtBase #-}

-- | Create an 'Uncert' about a given approximate central value, with the
-- given number of /digits of precision/ (in decimal notation).
--
-- @5.21 `withPrecision` 3 ≡ 5.21 '+/-' 0.01@
withPrecision ::
  (Floating a, RealFrac a) =>
  -- | The approximate value of the 'Uncert'
  a ->
  -- | The number of "digits" of precision to take
  Int ->
  Uncert a
withPrecision :: forall a. (Floating a, RealFrac a) => a -> Int -> Uncert a
withPrecision = Int -> a -> Int -> Uncert a
forall a. (Floating a, RealFrac a) => Int -> a -> Int -> Uncert a
withPrecisionAtBase Int
10
{-# INLINEABLE withPrecision #-}

-- | Like 'uNormalize', but takes a numerical base to round with respect
-- to.
--
-- @'uNormalize' ≡ uNormalizeAtBase 10@
uNormalizeAtBase ::
  (Floating a, RealFrac a) =>
  -- | The base to normalize with respect to
  Int ->
  Uncert a ->
  Uncert a
uNormalizeAtBase :: forall a. (Floating a, RealFrac a) => Int -> Uncert a -> Uncert a
uNormalizeAtBase Int
b (Uncert a -> (a, a)
forall a. Floating a => Uncert a -> (a, a)
uMeanStd -> (a
x, a
dx)) = a
x' a -> a -> Uncert a
forall a. Num a => a -> a -> Uncert a
+/- a
dx'
  where
    uncert :: Int
    uncert :: Int
uncert = Int -> Int
forall a. Num a => a -> a
negate (Int -> Int) -> (a -> Int) -> a -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Int
forall b. Integral b => a -> b
forall a b. (RealFrac a, Integral b) => a -> b
floor (a -> Int) -> (a -> a) -> a -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> a -> a
forall a. Floating a => a -> a -> a
logBase (Int -> a
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
b) (a -> Int) -> a -> Int
forall a b. (a -> b) -> a -> b
$ a
dx
    rounder :: a
rounder = Int -> a
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
b a -> a -> a
forall a. Floating a => a -> a -> a
** Int -> a
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
uncert
    roundTo :: a -> a
roundTo = (a -> a -> a
forall a. Fractional a => a -> a -> a
/ a
rounder) (a -> a) -> (a -> a) -> a -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Integer -> a
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Integer -> a) -> (a -> Integer) -> a -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Integer
forall a. RealFrac a => a -> Integer
round' (a -> Integer) -> (a -> a) -> a -> Integer
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> a -> a
forall a. Num a => a -> a -> a
* a
rounder)
    x' :: a
x' = a -> a
roundTo a
x
    dx' :: a
dx' = a -> a
roundTo a
dx
    round' :: RealFrac a => a -> Integer
    round' :: forall a. RealFrac a => a -> Integer
round' = a -> Integer
forall b. Integral b => a -> b
forall a b. (RealFrac a, Integral b) => a -> b
round
{-# INLINEABLE uNormalizeAtBase #-}

-- | Attempts to "normalize" an 'Uncert'.  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 @542.185433 +/- 83.584@,
-- because the extra digits of @542.185433@ past the tens place has no
-- meaning because of the overpowering uncertainty.   Normalizing this
-- results in @540 +/- 80@.
--
-- Note that the 'Show' instance for 'Uncert' normalizes values before
-- showing them.
uNormalize ::
  (Floating a, RealFrac a) =>
  Uncert a ->
  Uncert a
uNormalize :: forall a. (Floating a, RealFrac a) => Uncert a -> Uncert a
uNormalize = Int -> Uncert a -> Uncert a
forall a. (Floating a, RealFrac a) => Int -> Uncert a -> Uncert a
uNormalizeAtBase Int
10
{-# INLINEABLE uNormalize #-}

instance (Show a, Floating a, RealFrac a) => Show (Uncert a) where
  showsPrec :: Int -> Uncert a -> ShowS
showsPrec Int
d = Int -> Uncert a -> ShowS
forall a. (Show a, Floating a) => Int -> Uncert a -> ShowS
uShowsPrec Int
d (Uncert a -> ShowS) -> (Uncert a -> Uncert a) -> Uncert a -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Uncert a -> Uncert a
forall a. (Floating a, RealFrac a) => Uncert a -> Uncert a
uNormalize

-- | Like 'showsPrec' for 'Uncert', but does not normalize the value (see
-- 'uNormalize') before showing.  See documentation for 'showsPrec' for
-- more information on how this is meant to be used.
uShowsPrec :: (Show a, Floating a) => Int -> Uncert a -> ShowS
uShowsPrec :: forall a. (Show a, Floating a) => Int -> Uncert a -> ShowS
uShowsPrec Int
d (Uncert a -> (a, a)
forall a. Floating a => Uncert a -> (a, a)
uMeanStd -> (a
x, a
dx)) =
  Bool -> ShowS -> ShowS
showParen (Int
d Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
5) (ShowS -> ShowS) -> ShowS -> ShowS
forall a b. (a -> b) -> a -> b
$
    Int -> a -> ShowS
forall a. Show a => Int -> a -> ShowS
showsPrec Int
6 a
x
      ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> ShowS
showString String
" +/- "
      ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> a -> ShowS
forall a. Show a => Int -> a -> ShowS
showsPrec Int
6 a
dx
{-# INLINEABLE uShowsPrec #-}

-- | Like 'show' for 'Uncert', but does not normalize the value (see
-- 'uNormalize') before showing.
--
-- @'show' ≡ uShow . 'uNormalize'@
uShow :: (Show a, Floating a) => Uncert a -> String
uShow :: forall a. (Show a, Floating a) => Uncert a -> String
uShow Uncert a
u = Int -> Uncert a -> ShowS
forall a. (Show a, Floating a) => Int -> Uncert a -> ShowS
uShowsPrec Int
0 Uncert a
u String
""
{-# INLINEABLE uShow #-}

-- | Lifts a multivariate numeric function on a container (given as an @f
-- a -> a@) to work on a container of 'Uncert'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 '*', 'sqrt', 'atan2', etc.
--
-- @
-- ghci> liftUF (\\[x,y,z] -> x*y+z) [12.2 +/- 0.5, 56 +/- 2, 0.12 +/- 0.08]
-- 680 +/- 40
-- @
liftUF ::
  (Traversable f, Fractional a) =>
  -- | Function on container of values to lift
  (forall s. f (AD s (Sparse a)) -> AD s (Sparse a)) ->
  -- | Container of 'Uncert's to apply the function to
  f (Uncert a) ->
  Uncert a
liftUF :: forall (f :: * -> *) a.
(Traversable f, Fractional a) =>
(forall s. f (AD s (Sparse a)) -> AD s (Sparse a))
-> f (Uncert a) -> Uncert a
liftUF forall s. f (AD s (Sparse a)) -> AD s (Sparse a)
f f (Uncert a)
us = a -> a -> Uncert a
forall a. a -> a -> Uncert a
Un a
y a
vy
  where
    xs :: f a
xs = Uncert a -> a
forall a. Uncert a -> a
uMean (Uncert a -> a) -> f (Uncert a) -> f a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> f (Uncert a)
us
    vxs :: f a
vxs = Uncert a -> a
forall a. Uncert a -> a
uVar (Uncert a -> a) -> f (Uncert a) -> f a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> f (Uncert a)
us
    vxsL :: [a]
vxsL = f a -> [a]
forall a. f a -> [a]
forall (t :: * -> *) a. Foldable t => t a -> [a]
toList f a
vxs
    (a
fx, f (a, f a)
dfxsh) = (forall s. f (AD s (Sparse a)) -> AD s (Sparse a))
-> f a -> (a, f (a, f a))
forall (f :: * -> *) a.
(Traversable f, Num a) =>
(forall s. f (AD s (Sparse a)) -> AD s (Sparse a))
-> f a -> (a, f (a, f a))
hessian' f (AD s (Sparse a)) -> AD s (Sparse a)
forall s. f (AD s (Sparse a)) -> AD s (Sparse a)
f f a
xs
    dfxs :: f a
dfxs = (a, f a) -> a
forall a b. (a, b) -> a
fst ((a, f a) -> a) -> f (a, f a) -> f a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> f (a, f a)
dfxsh
    hess :: f (f a)
hess = (a, f a) -> f a
forall a b. (a, b) -> b
snd ((a, f a) -> f a) -> f (a, f a) -> f (f a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> f (a, f a)
dfxsh
    y :: a
y = a
fx a -> a -> a
forall a. Num a => a -> a -> a
+ a
hessQuad a -> a -> a
forall a. Fractional a => a -> a -> a
/ a
2
      where
        hessQuad :: a
hessQuad =
          [a] -> [a] -> a
forall {c} {t :: * -> *}. (Num c, Foldable t) => [c] -> t c -> c
dot [a]
vxsL
            ([a] -> a) -> (f [a] -> [a]) -> f [a] -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [[a]] -> [a]
forall {a}. [[a]] -> [a]
diag
            ([[a]] -> [a]) -> (f [a] -> [[a]]) -> f [a] -> [a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. f [a] -> [[a]]
forall a. f a -> [a]
forall (t :: * -> *) a. Foldable t => t a -> [a]
toList
            (f [a] -> a) -> f [a] -> a
forall a b. (a -> b) -> a -> b
$ (f a -> [a]) -> f (f a) -> f [a]
forall a b. (a -> b) -> f a -> f b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap f a -> [a]
forall a. f a -> [a]
forall (t :: * -> *) a. Foldable t => t a -> [a]
toList f (f a)
hess
    vy :: a
vy = [a] -> f a -> a
forall {c} {t :: * -> *}. (Num c, Foldable t) => [c] -> t c -> c
dot [a]
vxsL ((a -> Int -> a
forall a b. (Num a, Integral b) => a -> b -> a
^ (Int
2 :: Int)) (a -> a) -> f a -> f a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> f a
dfxs)
    dot :: [c] -> t c -> c
dot [c]
x = [c] -> c
forall a. Num a => [a] -> a
forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
sum ([c] -> c) -> (t c -> [c]) -> t c -> c
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (c -> c -> c) -> [c] -> [c] -> [c]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith c -> c -> c
forall a. Num a => a -> a -> a
(*) [c]
x ([c] -> [c]) -> (t c -> [c]) -> t c -> [c]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. t c -> [c]
forall a. t a -> [a]
forall (t :: * -> *) a. Foldable t => t a -> [a]
toList
    diag :: [[a]] -> [a]
diag = \case
      [] -> []
      [] : [[a]]
yss -> [[a]] -> [a]
diag ([a] -> [a]
forall {a}. [a] -> [a]
drop1 ([a] -> [a]) -> [[a]] -> [[a]]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [[a]]
yss)
      (a
x : [a]
_) : [[a]]
yss -> a
x a -> [a] -> [a]
forall a. a -> [a] -> [a]
: [[a]] -> [a]
diag ([a] -> [a]
forall {a}. [a] -> [a]
drop1 ([a] -> [a]) -> [[a]] -> [[a]]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [[a]]
yss)
      where
        drop1 :: [a] -> [a]
drop1 [] = []
        drop1 (a
_ : [a]
zs) = [a]
zs
{-# INLINEABLE liftUF #-}

-- | Lifts a numeric function over an 'Uncert'.  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 'sqrt', 'sin', 'negate', etc.
--
-- @
-- ghci> liftU (\\x -> log x ^ 2) (12.2 +/- 0.5)
-- 6.3 +/- 0.2
-- @
liftU ::
  Fractional a =>
  -- | Function on values to lift
  (forall s. AD s (T.Tower a) -> AD s (T.Tower a)) ->
  -- | 'Uncert' to apply the function to
  Uncert a ->
  Uncert a
liftU :: forall a.
Fractional a =>
(forall s. AD s (Tower a) -> AD s (Tower a))
-> Uncert a -> Uncert a
liftU forall s. AD s (Tower a) -> AD s (Tower a)
f (Un a
x a
vx) = a -> a -> Uncert a
forall a. a -> a -> Uncert a
Un a
y a
vy
  where
    (a
fx, a
dfx, a
ddfx) = case (forall s. AD s (Tower a) -> AD s (Tower a)) -> a -> [a]
forall a.
Num a =>
(forall s. AD s (Tower a) -> AD s (Tower a)) -> a -> [a]
T.diffs0 AD s (Tower a) -> AD s (Tower a)
forall s. AD s (Tower a) -> AD s (Tower a)
f a
x of
      a
a : a
b : a
c : [a]
_ -> (a
a, a
b, a
c)
      [a]
_ -> String -> (a, a, a)
forall a. HasCallStack => String -> a
error String
"diffs0 should return an infinite list"
    y :: a
y = a
fx a -> a -> a
forall a. Num a => a -> a -> a
+ a
ddfx a -> a -> a
forall a. Num a => a -> a -> a
* a
vx a -> a -> a
forall a. Fractional a => a -> a -> a
/ a
2
    vy :: a
vy = a
dfx a -> a -> a
forall a. Num a => a -> a -> a
* a
dfx a -> a -> a
forall a. Num a => a -> a -> a
* a
vx
{-# INLINEABLE liftU #-}

-- | Lifts a two-argument (curried) function over two 'Uncert'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 '*', 'atan2', '**', etc.
--
-- @
-- ghci> liftU2 (\\x y -> x**y) (13.5 +/- 0.1) (1.64 +/- 0.08)
-- 70 +/- 10
-- @
liftU2 ::
  Fractional a =>
  (forall s. AD s (Sparse a) -> AD s (Sparse a) -> AD s (Sparse a)) ->
  Uncert a ->
  Uncert a ->
  Uncert a
liftU2 :: forall a.
Fractional a =>
(forall s. AD s (Sparse a) -> AD s (Sparse a) -> AD s (Sparse a))
-> Uncert a -> Uncert a -> Uncert a
liftU2 forall s. AD s (Sparse a) -> AD s (Sparse a) -> AD s (Sparse a)
f = (H2 (Uncert a) -> Uncert a) -> Uncert a -> Uncert a -> Uncert a
forall a. (H2 a -> a) -> a -> a -> a
curryH2 ((H2 (Uncert a) -> Uncert a) -> Uncert a -> Uncert a -> Uncert a)
-> (H2 (Uncert a) -> Uncert a) -> Uncert a -> Uncert a -> Uncert a
forall a b. (a -> b) -> a -> b
$ (forall s. H2 (AD s (Sparse a)) -> AD s (Sparse a))
-> H2 (Uncert a) -> Uncert a
forall (f :: * -> *) a.
(Traversable f, Fractional a) =>
(forall s. f (AD s (Sparse a)) -> AD s (Sparse a))
-> f (Uncert a) -> Uncert a
liftUF ((AD s (Sparse a) -> AD s (Sparse a) -> AD s (Sparse a))
-> H2 (AD s (Sparse a)) -> AD s (Sparse a)
forall a. (a -> a -> a) -> H2 a -> a
uncurryH2 AD s (Sparse a) -> AD s (Sparse a) -> AD s (Sparse a)
forall s. AD s (Sparse a) -> AD s (Sparse a) -> AD s (Sparse a)
f)
{-# INLINEABLE liftU2 #-}

-- | Lifts a three-argument (curried) function over three 'Uncert's.  See
-- 'liftU2' and 'liftUF' 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
liftU3 :: forall a.
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
liftU3 forall s.
AD s (Sparse a)
-> AD s (Sparse a) -> AD s (Sparse a) -> AD s (Sparse a)
f = (H3 (Uncert a) -> Uncert a)
-> Uncert a -> Uncert a -> Uncert a -> Uncert a
forall a. (H3 a -> a) -> a -> a -> a -> a
curryH3 ((H3 (Uncert a) -> Uncert a)
 -> Uncert a -> Uncert a -> Uncert a -> Uncert a)
-> (H3 (Uncert a) -> Uncert a)
-> Uncert a
-> Uncert a
-> Uncert a
-> Uncert a
forall a b. (a -> b) -> a -> b
$ (forall s. H3 (AD s (Sparse a)) -> AD s (Sparse a))
-> H3 (Uncert a) -> Uncert a
forall (f :: * -> *) a.
(Traversable f, Fractional a) =>
(forall s. f (AD s (Sparse a)) -> AD s (Sparse a))
-> f (Uncert a) -> Uncert a
liftUF ((AD s (Sparse a)
 -> AD s (Sparse a) -> AD s (Sparse a) -> AD s (Sparse a))
-> H3 (AD s (Sparse a)) -> AD s (Sparse a)
forall a. (a -> a -> a -> a) -> H3 a -> a
uncurryH3 AD s (Sparse a)
-> AD s (Sparse a) -> AD s (Sparse a) -> AD s (Sparse a)
forall s.
AD s (Sparse a)
-> AD s (Sparse a) -> AD s (Sparse a) -> AD s (Sparse a)
f)
{-# INLINEABLE liftU3 #-}

-- | Lifts a four-argument (curried) function over four 'Uncert's.  See
-- 'liftU2' and 'liftUF' 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
liftU4 :: forall a.
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
liftU4 forall s.
AD s (Sparse a)
-> AD s (Sparse a)
-> AD s (Sparse a)
-> AD s (Sparse a)
-> AD s (Sparse a)
f = (H4 (Uncert a) -> Uncert a)
-> Uncert a -> Uncert a -> Uncert a -> Uncert a -> Uncert a
forall a. (H4 a -> a) -> a -> a -> a -> a -> a
curryH4 ((H4 (Uncert a) -> Uncert a)
 -> Uncert a -> Uncert a -> Uncert a -> Uncert a -> Uncert a)
-> (H4 (Uncert a) -> Uncert a)
-> Uncert a
-> Uncert a
-> Uncert a
-> Uncert a
-> Uncert a
forall a b. (a -> b) -> a -> b
$ (forall s. H4 (AD s (Sparse a)) -> AD s (Sparse a))
-> H4 (Uncert a) -> Uncert a
forall (f :: * -> *) a.
(Traversable f, Fractional a) =>
(forall s. f (AD s (Sparse a)) -> AD s (Sparse a))
-> f (Uncert a) -> Uncert a
liftUF ((AD s (Sparse a)
 -> AD s (Sparse a)
 -> AD s (Sparse a)
 -> AD s (Sparse a)
 -> AD s (Sparse a))
-> H4 (AD s (Sparse a)) -> AD s (Sparse a)
forall a. (a -> a -> a -> a -> a) -> H4 a -> a
uncurryH4 AD s (Sparse a)
-> AD s (Sparse a)
-> AD s (Sparse a)
-> AD s (Sparse a)
-> AD s (Sparse a)
forall s.
AD s (Sparse a)
-> AD s (Sparse a)
-> AD s (Sparse a)
-> AD s (Sparse a)
-> AD s (Sparse a)
f)
{-# INLINEABLE liftU4 #-}

-- | Lifts a five-argument (curried) function over five 'Uncert's.  See
-- 'liftU2' and 'liftUF' 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
liftU5 :: forall a.
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
liftU5 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)
f = (H5 (Uncert a) -> Uncert a)
-> Uncert a
-> Uncert a
-> Uncert a
-> Uncert a
-> Uncert a
-> Uncert a
forall a. (H5 a -> a) -> a -> a -> a -> a -> a -> a
curryH5 ((H5 (Uncert a) -> Uncert a)
 -> Uncert a
 -> Uncert a
 -> Uncert a
 -> Uncert a
 -> Uncert a
 -> Uncert a)
-> (H5 (Uncert a) -> Uncert a)
-> Uncert a
-> Uncert a
-> Uncert a
-> Uncert a
-> Uncert a
-> Uncert a
forall a b. (a -> b) -> a -> b
$ (forall s. H5 (AD s (Sparse a)) -> AD s (Sparse a))
-> H5 (Uncert a) -> Uncert a
forall (f :: * -> *) a.
(Traversable f, Fractional a) =>
(forall s. f (AD s (Sparse a)) -> AD s (Sparse a))
-> f (Uncert a) -> Uncert a
liftUF ((AD s (Sparse a)
 -> AD s (Sparse a)
 -> AD s (Sparse a)
 -> AD s (Sparse a)
 -> AD s (Sparse a)
 -> AD s (Sparse a))
-> H5 (AD s (Sparse a)) -> AD s (Sparse a)
forall a. (a -> a -> a -> a -> a -> a) -> H5 a -> a
uncurryH5 AD s (Sparse a)
-> AD s (Sparse a)
-> AD s (Sparse a)
-> AD s (Sparse a)
-> AD s (Sparse a)
-> AD s (Sparse 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)
f)
{-# INLINEABLE liftU5 #-}

instance Fractional a => Num (Uncert a) where
  + :: Uncert a -> Uncert a -> Uncert a
(+) = (forall s. AD s (Sparse a) -> AD s (Sparse a) -> AD s (Sparse a))
-> Uncert a -> Uncert a -> Uncert a
forall a.
Fractional a =>
(forall s. AD s (Sparse a) -> AD s (Sparse a) -> AD s (Sparse a))
-> Uncert a -> Uncert a -> Uncert a
liftU2 AD s (Sparse a) -> AD s (Sparse a) -> AD s (Sparse a)
forall a. Num a => a -> a -> a
forall s. AD s (Sparse a) -> AD s (Sparse a) -> AD s (Sparse a)
(+)
  {-# INLINE (+) #-}
  * :: Uncert a -> Uncert a -> Uncert a
(*) = (forall s. AD s (Sparse a) -> AD s (Sparse a) -> AD s (Sparse a))
-> Uncert a -> Uncert a -> Uncert a
forall a.
Fractional a =>
(forall s. AD s (Sparse a) -> AD s (Sparse a) -> AD s (Sparse a))
-> Uncert a -> Uncert a -> Uncert a
liftU2 AD s (Sparse a) -> AD s (Sparse a) -> AD s (Sparse a)
forall a. Num a => a -> a -> a
forall s. AD s (Sparse a) -> AD s (Sparse a) -> AD s (Sparse a)
(*)
  {-# INLINE (*) #-}
  (-) = (forall s. AD s (Sparse a) -> AD s (Sparse a) -> AD s (Sparse a))
-> Uncert a -> Uncert a -> Uncert a
forall a.
Fractional a =>
(forall s. AD s (Sparse a) -> AD s (Sparse a) -> AD s (Sparse a))
-> Uncert a -> Uncert a -> Uncert a
liftU2 (-)
  {-# INLINE (-) #-}
  negate :: Uncert a -> Uncert a
negate = (forall s. AD s (Tower a) -> AD s (Tower a))
-> Uncert a -> Uncert a
forall a.
Fractional a =>
(forall s. AD s (Tower a) -> AD s (Tower a))
-> Uncert a -> Uncert a
liftU AD s (Tower a) -> AD s (Tower a)
forall a. Num a => a -> a
forall s. AD s (Tower a) -> AD s (Tower a)
negate
  {-# INLINE negate #-}
  abs :: Uncert a -> Uncert a
abs = (forall s. AD s (Tower a) -> AD s (Tower a))
-> Uncert a -> Uncert a
forall a.
Fractional a =>
(forall s. AD s (Tower a) -> AD s (Tower a))
-> Uncert a -> Uncert a
liftU AD s (Tower a) -> AD s (Tower a)
forall a. Num a => a -> a
forall s. AD s (Tower a) -> AD s (Tower a)
abs
  {-# INLINE abs #-}
  signum :: Uncert a -> Uncert a
signum = (forall s. AD s (Tower a) -> AD s (Tower a))
-> Uncert a -> Uncert a
forall a.
Fractional a =>
(forall s. AD s (Tower a) -> AD s (Tower a))
-> Uncert a -> Uncert a
liftU AD s (Tower a) -> AD s (Tower a)
forall a. Num a => a -> a
forall s. AD s (Tower a) -> AD s (Tower a)
signum
  {-# INLINE signum #-}
  fromInteger :: Integer -> Uncert a
fromInteger = a -> Uncert a
forall a. Num a => a -> Uncert a
exact (a -> Uncert a) -> (Integer -> a) -> Integer -> Uncert a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Integer -> a
forall a. Num a => Integer -> a
fromInteger
  {-# INLINE fromInteger #-}

instance Fractional a => Fractional (Uncert a) where
  recip :: Uncert a -> Uncert a
recip = (forall s. AD s (Tower a) -> AD s (Tower a))
-> Uncert a -> Uncert a
forall a.
Fractional a =>
(forall s. AD s (Tower a) -> AD s (Tower a))
-> Uncert a -> Uncert a
liftU AD s (Tower a) -> AD s (Tower a)
forall a. Fractional a => a -> a
forall s. AD s (Tower a) -> AD s (Tower a)
recip
  {-# INLINE recip #-}
  / :: Uncert a -> Uncert a -> Uncert a
(/) = (forall s. AD s (Sparse a) -> AD s (Sparse a) -> AD s (Sparse a))
-> Uncert a -> Uncert a -> Uncert a
forall a.
Fractional a =>
(forall s. AD s (Sparse a) -> AD s (Sparse a) -> AD s (Sparse a))
-> Uncert a -> Uncert a -> Uncert a
liftU2 AD s (Sparse a) -> AD s (Sparse a) -> AD s (Sparse a)
forall a. Fractional a => a -> a -> a
forall s. AD s (Sparse a) -> AD s (Sparse a) -> AD s (Sparse a)
(/)
  {-# INLINE (/) #-}
  fromRational :: Rational -> Uncert a
fromRational = a -> Uncert a
forall a. Num a => a -> Uncert a
exact (a -> Uncert a) -> (Rational -> a) -> Rational -> Uncert a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Rational -> a
forall a. Fractional a => Rational -> a
fromRational
  {-# INLINE fromRational #-}

instance Floating a => Floating (Uncert a) where
  pi :: Uncert a
pi = a -> Uncert a
forall a. Num a => a -> Uncert a
exact a
forall a. Floating a => a
pi
  {-# INLINE pi #-}
  exp :: Uncert a -> Uncert a
exp = (forall s. AD s (Tower a) -> AD s (Tower a))
-> Uncert a -> Uncert a
forall a.
Fractional a =>
(forall s. AD s (Tower a) -> AD s (Tower a))
-> Uncert a -> Uncert a
liftU AD s (Tower a) -> AD s (Tower a)
forall a. Floating a => a -> a
forall s. AD s (Tower a) -> AD s (Tower a)
exp
  {-# INLINE exp #-}
  log :: Uncert a -> Uncert a
log = (forall s. AD s (Tower a) -> AD s (Tower a))
-> Uncert a -> Uncert a
forall a.
Fractional a =>
(forall s. AD s (Tower a) -> AD s (Tower a))
-> Uncert a -> Uncert a
liftU AD s (Tower a) -> AD s (Tower a)
forall a. Floating a => a -> a
forall s. AD s (Tower a) -> AD s (Tower a)
log
  {-# INLINE log #-}
  sqrt :: Uncert a -> Uncert a
sqrt = (forall s. AD s (Tower a) -> AD s (Tower a))
-> Uncert a -> Uncert a
forall a.
Fractional a =>
(forall s. AD s (Tower a) -> AD s (Tower a))
-> Uncert a -> Uncert a
liftU AD s (Tower a) -> AD s (Tower a)
forall a. Floating a => a -> a
forall s. AD s (Tower a) -> AD s (Tower a)
sqrt
  {-# INLINE sqrt #-}
  ** :: Uncert a -> Uncert a -> Uncert a
(**) = (forall s. AD s (Sparse a) -> AD s (Sparse a) -> AD s (Sparse a))
-> Uncert a -> Uncert a -> Uncert a
forall a.
Fractional a =>
(forall s. AD s (Sparse a) -> AD s (Sparse a) -> AD s (Sparse a))
-> Uncert a -> Uncert a -> Uncert a
liftU2 AD s (Sparse a) -> AD s (Sparse a) -> AD s (Sparse a)
forall a. Floating a => a -> a -> a
forall s. AD s (Sparse a) -> AD s (Sparse a) -> AD s (Sparse a)
(**)
  {-# INLINE (**) #-}
  logBase :: Uncert a -> Uncert a -> Uncert a
logBase = (forall s. AD s (Sparse a) -> AD s (Sparse a) -> AD s (Sparse a))
-> Uncert a -> Uncert a -> Uncert a
forall a.
Fractional a =>
(forall s. AD s (Sparse a) -> AD s (Sparse a) -> AD s (Sparse a))
-> Uncert a -> Uncert a -> Uncert a
liftU2 AD s (Sparse a) -> AD s (Sparse a) -> AD s (Sparse a)
forall a. Floating a => a -> a -> a
forall s. AD s (Sparse a) -> AD s (Sparse a) -> AD s (Sparse a)
logBase
  {-# INLINE logBase #-}
  sin :: Uncert a -> Uncert a
sin = (forall s. AD s (Tower a) -> AD s (Tower a))
-> Uncert a -> Uncert a
forall a.
Fractional a =>
(forall s. AD s (Tower a) -> AD s (Tower a))
-> Uncert a -> Uncert a
liftU AD s (Tower a) -> AD s (Tower a)
forall a. Floating a => a -> a
forall s. AD s (Tower a) -> AD s (Tower a)
sin
  {-# INLINE sin #-}
  cos :: Uncert a -> Uncert a
cos = (forall s. AD s (Tower a) -> AD s (Tower a))
-> Uncert a -> Uncert a
forall a.
Fractional a =>
(forall s. AD s (Tower a) -> AD s (Tower a))
-> Uncert a -> Uncert a
liftU AD s (Tower a) -> AD s (Tower a)
forall a. Floating a => a -> a
forall s. AD s (Tower a) -> AD s (Tower a)
cos
  {-# INLINE cos #-}
  asin :: Uncert a -> Uncert a
asin = (forall s. AD s (Tower a) -> AD s (Tower a))
-> Uncert a -> Uncert a
forall a.
Fractional a =>
(forall s. AD s (Tower a) -> AD s (Tower a))
-> Uncert a -> Uncert a
liftU AD s (Tower a) -> AD s (Tower a)
forall a. Floating a => a -> a
forall s. AD s (Tower a) -> AD s (Tower a)
asin
  {-# INLINE asin #-}
  acos :: Uncert a -> Uncert a
acos = (forall s. AD s (Tower a) -> AD s (Tower a))
-> Uncert a -> Uncert a
forall a.
Fractional a =>
(forall s. AD s (Tower a) -> AD s (Tower a))
-> Uncert a -> Uncert a
liftU AD s (Tower a) -> AD s (Tower a)
forall a. Floating a => a -> a
forall s. AD s (Tower a) -> AD s (Tower a)
acos
  {-# INLINE acos #-}
  atan :: Uncert a -> Uncert a
atan = (forall s. AD s (Tower a) -> AD s (Tower a))
-> Uncert a -> Uncert a
forall a.
Fractional a =>
(forall s. AD s (Tower a) -> AD s (Tower a))
-> Uncert a -> Uncert a
liftU AD s (Tower a) -> AD s (Tower a)
forall a. Floating a => a -> a
forall s. AD s (Tower a) -> AD s (Tower a)
atan
  {-# INLINE atan #-}
  sinh :: Uncert a -> Uncert a
sinh = (forall s. AD s (Tower a) -> AD s (Tower a))
-> Uncert a -> Uncert a
forall a.
Fractional a =>
(forall s. AD s (Tower a) -> AD s (Tower a))
-> Uncert a -> Uncert a
liftU AD s (Tower a) -> AD s (Tower a)
forall a. Floating a => a -> a
forall s. AD s (Tower a) -> AD s (Tower a)
sinh
  {-# INLINE sinh #-}
  cosh :: Uncert a -> Uncert a
cosh = (forall s. AD s (Tower a) -> AD s (Tower a))
-> Uncert a -> Uncert a
forall a.
Fractional a =>
(forall s. AD s (Tower a) -> AD s (Tower a))
-> Uncert a -> Uncert a
liftU AD s (Tower a) -> AD s (Tower a)
forall a. Floating a => a -> a
forall s. AD s (Tower a) -> AD s (Tower a)
cosh
  {-# INLINE cosh #-}
  asinh :: Uncert a -> Uncert a
asinh = (forall s. AD s (Tower a) -> AD s (Tower a))
-> Uncert a -> Uncert a
forall a.
Fractional a =>
(forall s. AD s (Tower a) -> AD s (Tower a))
-> Uncert a -> Uncert a
liftU AD s (Tower a) -> AD s (Tower a)
forall a. Floating a => a -> a
forall s. AD s (Tower a) -> AD s (Tower a)
asinh
  {-# INLINE asinh #-}
  acosh :: Uncert a -> Uncert a
acosh = (forall s. AD s (Tower a) -> AD s (Tower a))
-> Uncert a -> Uncert a
forall a.
Fractional a =>
(forall s. AD s (Tower a) -> AD s (Tower a))
-> Uncert a -> Uncert a
liftU AD s (Tower a) -> AD s (Tower a)
forall a. Floating a => a -> a
forall s. AD s (Tower a) -> AD s (Tower a)
acosh
  {-# INLINE acosh #-}
  atanh :: Uncert a -> Uncert a
atanh = (forall s. AD s (Tower a) -> AD s (Tower a))
-> Uncert a -> Uncert a
forall a.
Fractional a =>
(forall s. AD s (Tower a) -> AD s (Tower a))
-> Uncert a -> Uncert a
liftU AD s (Tower a) -> AD s (Tower a)
forall a. Floating a => a -> a
forall s. AD s (Tower a) -> AD s (Tower a)
atanh
  {-# INLINE atanh #-}

instance Eq a => Eq (Uncert a) where
  == :: Uncert a -> Uncert a -> Bool
(==) = a -> a -> Bool
forall a. Eq a => a -> a -> Bool
(==) (a -> a -> Bool) -> (Uncert a -> a) -> Uncert a -> Uncert a -> Bool
forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
`on` Uncert a -> a
forall a. Uncert a -> a
uMean
  {-# INLINE (==) #-}
  /= :: Uncert a -> Uncert a -> Bool
(/=) = a -> a -> Bool
forall a. Eq a => a -> a -> Bool
(/=) (a -> a -> Bool) -> (Uncert a -> a) -> Uncert a -> Uncert a -> Bool
forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
`on` Uncert a -> a
forall a. Uncert a -> a
uMean
  {-# INLINE (/=) #-}

instance Ord a => Ord (Uncert a) where
  compare :: Uncert a -> Uncert a -> Ordering
compare = (Uncert a -> a) -> Uncert a -> Uncert a -> Ordering
forall a b. Ord a => (b -> a) -> b -> b -> Ordering
comparing Uncert a -> a
forall a. Uncert a -> a
uMean
  {-# INLINE compare #-}

instance (Fractional a, Real a) => Real (Uncert a) where
  toRational :: Uncert a -> Rational
toRational = a -> Rational
forall a. Real a => a -> Rational
toRational (a -> Rational) -> (Uncert a -> a) -> Uncert a -> Rational
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Uncert a -> a
forall a. Uncert a -> a
uMean
  {-# INLINE toRational #-}

instance RealFrac a => RealFrac (Uncert a) where
  properFraction :: forall b. Integral b => Uncert a -> (b, Uncert a)
properFraction Uncert a
x = (b
n, Uncert a
d)
    where
      d :: Uncert a
d = (forall s. AD s (Tower a) -> AD s (Tower a))
-> Uncert a -> Uncert a
forall a.
Fractional a =>
(forall s. AD s (Tower a) -> AD s (Tower a))
-> Uncert a -> Uncert a
liftU ((Int, AD s (Tower a)) -> AD s (Tower a)
forall b. (Int, b) -> b
snd' ((Int, AD s (Tower a)) -> AD s (Tower a))
-> (AD s (Tower a) -> (Int, AD s (Tower a)))
-> AD s (Tower a)
-> AD s (Tower a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. AD s (Tower a) -> (Int, AD s (Tower a))
forall b. Integral b => AD s (Tower a) -> (b, AD s (Tower a))
forall a b. (RealFrac a, Integral b) => a -> (b, a)
properFraction) Uncert a
x
      n :: b
n = (b, a) -> b
forall a b. (a, b) -> a
fst ((b, a) -> b) -> (a -> (b, a)) -> a -> b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> (b, a)
forall b. Integral b => a -> (b, a)
forall a b. (RealFrac a, Integral b) => a -> (b, a)
properFraction (a -> b) -> a -> b
forall a b. (a -> b) -> a -> b
$ Uncert a -> a
forall a. Uncert a -> a
uMean Uncert a
x
      snd' :: (Int, b) -> b
      snd' :: forall b. (Int, b) -> b
snd' = (Int, b) -> b
forall a b. (a, b) -> b
snd
  {-# INLINEABLE properFraction #-}
  truncate :: forall b. Integral b => Uncert a -> b
truncate = a -> b
forall b. Integral b => a -> b
forall a b. (RealFrac a, Integral b) => a -> b
truncate (a -> b) -> (Uncert a -> a) -> Uncert a -> b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Uncert a -> a
forall a. Uncert a -> a
uMean
  {-# INLINE truncate #-}
  round :: forall b. Integral b => Uncert a -> b
round = a -> b
forall b. Integral b => a -> b
forall a b. (RealFrac a, Integral b) => a -> b
round (a -> b) -> (Uncert a -> a) -> Uncert a -> b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Uncert a -> a
forall a. Uncert a -> a
uMean
  {-# INLINE round #-}
  ceiling :: forall b. Integral b => Uncert a -> b
ceiling = a -> b
forall b. Integral b => a -> b
forall a b. (RealFrac a, Integral b) => a -> b
ceiling (a -> b) -> (Uncert a -> a) -> Uncert a -> b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Uncert a -> a
forall a. Uncert a -> a
uMean
  {-# INLINE ceiling #-}
  floor :: forall b. Integral b => Uncert a -> b
floor = a -> b
forall b. Integral b => a -> b
forall a b. (RealFrac a, Integral b) => a -> b
floor (a -> b) -> (Uncert a -> a) -> Uncert a -> b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Uncert a -> a
forall a. Uncert a -> a
uMean
  {-# INLINE floor #-}

instance RealFloat a => RealFloat (Uncert a) where
  floatRadix :: Uncert a -> Integer
floatRadix = a -> Integer
forall a. RealFloat a => a -> Integer
floatRadix (a -> Integer) -> (Uncert a -> a) -> Uncert a -> Integer
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Uncert a -> a
forall a. Uncert a -> a
uMean
  {-# INLINE floatRadix #-}
  floatDigits :: Uncert a -> Int
floatDigits = a -> Int
forall a. RealFloat a => a -> Int
floatDigits (a -> Int) -> (Uncert a -> a) -> Uncert a -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Uncert a -> a
forall a. Uncert a -> a
uMean
  {-# INLINE floatDigits #-}
  floatRange :: Uncert a -> (Int, Int)
floatRange = a -> (Int, Int)
forall a. RealFloat a => a -> (Int, Int)
floatRange (a -> (Int, Int)) -> (Uncert a -> a) -> Uncert a -> (Int, Int)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Uncert a -> a
forall a. Uncert a -> a
uMean
  {-# INLINE floatRange #-}
  decodeFloat :: Uncert a -> (Integer, Int)
decodeFloat = a -> (Integer, Int)
forall a. RealFloat a => a -> (Integer, Int)
decodeFloat (a -> (Integer, Int))
-> (Uncert a -> a) -> Uncert a -> (Integer, Int)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Uncert a -> a
forall a. Uncert a -> a
uMean
  {-# INLINE decodeFloat #-}
  exponent :: Uncert a -> Int
exponent = a -> Int
forall a. RealFloat a => a -> Int
exponent (a -> Int) -> (Uncert a -> a) -> Uncert a -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Uncert a -> a
forall a. Uncert a -> a
uMean
  {-# INLINE exponent #-}
  isNaN :: Uncert a -> Bool
isNaN = a -> Bool
forall a. RealFloat a => a -> Bool
isNaN (a -> Bool) -> (Uncert a -> a) -> Uncert a -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Uncert a -> a
forall a. Uncert a -> a
uMean
  {-# INLINE isNaN #-}
  isInfinite :: Uncert a -> Bool
isInfinite = a -> Bool
forall a. RealFloat a => a -> Bool
isInfinite (a -> Bool) -> (Uncert a -> a) -> Uncert a -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Uncert a -> a
forall a. Uncert a -> a
uMean
  {-# INLINE isInfinite #-}
  isDenormalized :: Uncert a -> Bool
isDenormalized = a -> Bool
forall a. RealFloat a => a -> Bool
isDenormalized (a -> Bool) -> (Uncert a -> a) -> Uncert a -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Uncert a -> a
forall a. Uncert a -> a
uMean
  {-# INLINE isDenormalized #-}
  isNegativeZero :: Uncert a -> Bool
isNegativeZero = a -> Bool
forall a. RealFloat a => a -> Bool
isNegativeZero (a -> Bool) -> (Uncert a -> a) -> Uncert a -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Uncert a -> a
forall a. Uncert a -> a
uMean
  {-# INLINE isNegativeZero #-}
  isIEEE :: Uncert a -> Bool
isIEEE = a -> Bool
forall a. RealFloat a => a -> Bool
isIEEE (a -> Bool) -> (Uncert a -> a) -> Uncert a -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Uncert a -> a
forall a. Uncert a -> a
uMean
  {-# INLINE isIEEE #-}
  encodeFloat :: Integer -> Int -> Uncert a
encodeFloat Integer
a Int
b = a -> Uncert a
forall a. Num a => a -> Uncert a
exact (Integer -> Int -> a
forall a. RealFloat a => Integer -> Int -> a
encodeFloat Integer
a Int
b)
  {-# INLINE encodeFloat #-}
  significand :: Uncert a -> Uncert a
significand = (forall s. AD s (Tower a) -> AD s (Tower a))
-> Uncert a -> Uncert a
forall a.
Fractional a =>
(forall s. AD s (Tower a) -> AD s (Tower a))
-> Uncert a -> Uncert a
liftU AD s (Tower a) -> AD s (Tower a)
forall a. RealFloat a => a -> a
forall s. AD s (Tower a) -> AD s (Tower a)
significand
  {-# INLINE significand #-}
  atan2 :: Uncert a -> Uncert a -> Uncert a
atan2 = (forall s. AD s (Sparse a) -> AD s (Sparse a) -> AD s (Sparse a))
-> Uncert a -> Uncert a -> Uncert a
forall a.
Fractional a =>
(forall s. AD s (Sparse a) -> AD s (Sparse a) -> AD s (Sparse a))
-> Uncert a -> Uncert a -> Uncert a
liftU2 AD s (Sparse a) -> AD s (Sparse a) -> AD s (Sparse a)
forall a. RealFloat a => a -> a -> a
forall s. AD s (Sparse a) -> AD s (Sparse a) -> AD s (Sparse a)
atan2
  {-# INLINE atan2 #-}