packages feed

ad 0.12 → 0.13

raw patch · 11 files changed

+174/−117 lines, 11 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

+ Numeric.AD.Internal: instance Iso (f a) (AD f a)
+ Numeric.AD.Internal: instance Iso a (Id a)
+ Numeric.AD.Internal: instance Iso a a
+ Numeric.AD.Internal: probed :: f a -> f (AD Id a)
+ Numeric.AD.Internal: unprobed :: f (AD Id a) -> f a

Files

Numeric/AD.hs view
@@ -6,15 +6,15 @@ -- License     :  BSD3 -- Maintainer  :  ekmett@gmail.com -- Stability   :  experimental--- Portability :  GHC only +-- Portability :  GHC only -- -- Mixed-Mode Automatic Differentiation.--- +-- -- Each combinator exported from this module chooses an appropriate AD mode. ----------------------------------------------------------------------------- -module Numeric.AD -    ( +module Numeric.AD+    (     -- * Gradients       grad, grad2 @@ -58,9 +58,9 @@ import Data.Foldable (Foldable, foldr') import Control.Applicative import Numeric.AD.Classes  (Mode(..))-import Numeric.AD.Internal (AD(..), probe, unprobe)+import Numeric.AD.Internal (AD(..), probed, unprobe) import Numeric.AD.Forward  (diff, diffUU, diff2, diff2UU, diffUF, diff2UF)-import Numeric.AD.Tower    (diffsUU, diffs0UU , diffsUF, diffs0UF , diffs, diffs0, taylor, taylor0) +import Numeric.AD.Tower    (diffsUU, diffs0UU , diffsUF, diffs0UF , diffs, diffs0, taylor, taylor0) import Numeric.AD.Reverse  (diffFU, diff2FU, grad, grad2)  import qualified Numeric.AD.Forward as Forward@@ -77,9 +77,9 @@                | n > m     = Reverse.jacobian2 f bs                | otherwise = Forward.jacobian2 f bs     where-        as = f (probe <$> bs)+        as = f (probed bs)         n = size bs         m = size as         size :: Foldable f => f a -> Int-        size = foldr' (\_ b -> 1 + b) 0 +        size = foldr' (\_ b -> 1 + b) 0 {-# INLINE jacobian2 #-}
Numeric/AD/Classes.hs view
@@ -6,14 +6,14 @@ -- License     :  BSD3 -- Maintainer  :  ekmett@gmail.com -- Stability   :  experimental--- Portability :  GHC only +-- Portability :  GHC only -- -----------------------------------------------------------------------------  module Numeric.AD.Classes-    ( +    (     -- * AD modes-      Mode(..) +      Mode(..)     , one     -- * Automatically Deriving AD     , Jacobian(..)@@ -30,7 +30,7 @@  infixl 8 **! infixl 7 *!, /!, ^*, *^, ^/-infixl 6 +!, -!, <+> +infixl 6 +!, -!, <+> infix 4 ==!  -- | Higher-order versions of the stock numerical methods.@@ -56,20 +56,20 @@ -- class (Show1 t, Eq t) => Num1 t where     fromInteger1 :: Num a => Integer -> t a     (+!),(-!),(*!) :: Num a => t a -> t a -> t a-    negate1, abs1, signum1 :: Num a => t a -> t a +    negate1, abs1, signum1 :: Num a => t a -> t a  -- class Num1 t => Fractional1 t where     (/!) :: Fractional a => t a -> t a -> t a     recip1 :: Fractional a => t a -> t a-    fromRational1 :: Fractional a => Rational -> t a +    fromRational1 :: Fractional a => Rational -> t a --- class (Num1 t, Ord1 t) => Real1 t +-- class (Num1 t, Ord1 t) => Real1 t     toRational1 :: Real a => t a -> Rational -- unsafe --- class Fractional1 t => Floating1 t -    pi1 :: Floating a => t a +-- class Fractional1 t => Floating1 t+    pi1 :: Floating a => t a     exp1, log1, sqrt1 :: Floating a => t a -> t a-    (**!), logBase1 :: Floating a => t a -> t a -> t a +    (**!), logBase1 :: Floating a => t a -> t a -> t a     sin1, cos1, tan1, asin1, acos1, atan1 :: Floating a => t a -> t a     sinh1, cosh1, tanh1, asinh1, acosh1, atanh1 :: Floating a => t a -> t a @@ -86,7 +86,7 @@     encodeFloat1  :: RealFloat a => Integer -> Int -> t a     exponent1     :: RealFloat a => t a -> Int     significand1  :: RealFloat a => t a -> t a-    scaleFloat1   :: RealFloat a => Int -> t a -> t a +    scaleFloat1   :: RealFloat a => Int -> t a -> t a     isNaN1, isInfinite1, isDenormalized1, isNegativeZero1, isIEEE1 :: RealFloat a => t a -> Bool     atan21 :: RealFloat a => t a -> t a -> t a @@ -100,13 +100,13 @@     enumFromThenTo1 :: (Num a, Enum a) => t a -> t a -> t a -> [t a]  -- class Bounded1 t where-    minBound1 :: (Num a, Bounded a) => t a +    minBound1 :: (Num a, Bounded a) => t a     maxBound1 :: (Num a, Bounded a) => t a  class Lifted t => Mode t where      -- | Embed a constant-    lift  :: Num a => a -> t a +    lift  :: Num a => a -> t a      -- | Vector sum     (<+>) :: Num a => t a -> t a -> t a@@ -118,7 +118,7 @@     (^*) :: Num a => t a -> a -> t a      -- | Scalar division-    (^/) :: Fractional a => t a -> a -> t a +    (^/) :: Fractional a => t a -> a -> t a      -- | > 'zero' = 'lift' 0     zero :: Num a => t a@@ -139,9 +139,9 @@ negOne = lift (-1) {-# INLINE negOne #-} --- | 'Primal' is used by 'deriveMode' but is not exposed +-- | 'Primal' is used by 'deriveMode' but is not exposed -- via the 'Mode' class to prevent its abuse by end users--- via the AD data type. +-- via the AD data type. -- -- It provides direct access to the result, stripped of its derivative information, -- but this is unsafe in general as (lift . primal) would discard derivative@@ -153,7 +153,7 @@  -- | 'Jacobian' is used by 'deriveMode' but is not exposed -- via 'Mode' to prevent its abuse by end users--- via the 'AD' data type. +-- via the 'AD' data type. class (Mode t, Mode (D t)) => Jacobian t where     type D t :: * -> * @@ -168,7 +168,7 @@ withPrimal :: (Jacobian t, Num a) => t a -> a -> t a withPrimal t a = unary (const a) one t -fromBy :: (Jacobian t, Num a) => t a -> t a -> Int -> a -> t a +fromBy :: (Jacobian t, Num a) => t a -> t a -> Int -> a -> t a fromBy a delta n x = binary (\_ _ -> x) one (fromIntegral1 n) a delta  fromIntegral1 :: (Integral n, Lifted t, Num a) => n -> t a@@ -176,7 +176,7 @@ {-# INLINE fromIntegral1 #-}  square1 :: (Lifted t, Num a) => t a -> t a-square1 x = x *! x +square1 x = x *! x {-# INLINE square1 #-}  on :: (a -> a -> c) -> (b -> a) -> b -> b -> c@@ -193,16 +193,16 @@  -- | @'deriveLifted' t@ provides ----- > instance Lifted $t +-- > instance Lifted $t -- -- given supplied instances for ----- > instance Lifted $t => Primal $t where ... +-- > instance Lifted $t => Primal $t where ... -- > instance Lifted $t => Jacobian $t where ...--- +-- -- The seemingly redundant @'Lifted' $t@ constraints are caused by Template Haskell staging restrictions. deriveLifted :: Q Type -> Q [Dec]-deriveLifted _t = [d| +deriveLifted _t = [d|     instance Lifted $_t where         (==!)         = (==) `on` primal         compare1      = compare `on` primal@@ -219,16 +219,16 @@         fromRational1 = lift . fromRational         (/!)          = lift2 (/) $ \x y -> (recip1 y, x)         recip1        = lift1 recip (negate1 . square1)-    +         pi1       = lift pi         exp1      = lift1_ exp const         log1      = lift1 log recip1         logBase1 x y = log1 y /! log1 x         sqrt1     = lift1_ sqrt (\z _ -> recip1 (lift 2 *! z))-        (**!)     = lift2_ (**) (\z x y -> (y *! z /! x, z *! log1 x)) -- error at 0 ** n +        (**!)     = lift2_ (**) (\z x y -> (y *! z /! x, z *! log1 x)) -- error at 0 ** n         sin1      = lift1 sin cos1         cos1      = lift1 cos $ \x -> negate1 (sin1 x)-        tan1 x    = sin1 x /! cos1 x +        tan1 x    = sin1 x /! cos1 x         asin1     = lift1 asin $ \x -> recip1 (sqrt1 (one -! square1 x))         acos1     = lift1 acos $ \x -> negate1 (recip1 (sqrt1 (one -! square1 x)))         atan1     = lift1 atan $ \x -> recip1 (one +! square1 x)@@ -238,16 +238,16 @@         asinh1    = lift1 asinh $ \x -> recip1 (sqrt1 (one +! square1 x))         acosh1    = lift1 acosh $ \x -> recip1 (sqrt1 (square1 x -! one))         atanh1    = lift1 atanh $ \x -> recip1 (one -! square1 x)-    +         succ1                 = lift1 succ (const one)         pred1                 = lift1 pred (const one)         toEnum1               = lift . toEnum-        fromEnum1             = discrete1 fromEnum +        fromEnum1             = discrete1 fromEnum         enumFrom1 a           = withPrimal a <$> discrete1 enumFrom a         enumFromTo1 a b       = withPrimal a <$> discrete2 enumFromTo a b         enumFromThen1 a b     = zipWith (fromBy a delta) [0..] $ discrete2 enumFromThen a b where delta = b -! a         enumFromThenTo1 a b c = zipWith (fromBy a delta) [0..] $ discrete3 enumFromThenTo a b c where delta = b -! a-    +         toRational1      = discrete1 toRational         floatRadix1      = discrete1 floatRadix         floatDigits1     = discrete1 floatDigits@@ -260,20 +260,20 @@         isNegativeZero1  = discrete1 isNegativeZero         isIEEE1          = discrete1 isIEEE         exponent1 = exponent . primal-        scaleFloat1 n = unary (scaleFloat n) (scaleFloat1 n one) +        scaleFloat1 n = unary (scaleFloat n) (scaleFloat1 n one)         significand1 x =  unary significand (scaleFloat1 (- floatDigits1 x) one) x         atan21 = lift2 atan2 $ \vx vy -> let r = recip1 (square1 vx +! square1 vy) in (vy *! r, negate1 vx *! r)-        properFraction1 a = (w, a `withPrimal` pb) where -             pa = primal a +        properFraction1 a = (w, a `withPrimal` pb) where+             pa = primal a              (w, pb) = properFraction pa         truncate1 = discrete1 truncate         round1    = discrete1 round         ceiling1  = discrete1 ceiling-        floor1    = discrete1 floor +        floor1    = discrete1 floor     |]-    + varA :: Q Type-varA = varT (mkName "a") +varA = varT (mkName "a")  -- | Find all the members defined in the 'Lifted' data type liftedMembers :: Q [String]@@ -308,13 +308,13 @@     instanceD (cxt (f [classP ''Lifted [t], classP n [varA]]))               (conT n `appT` (t' `appT` varA))               (concatMap lower1 ds)-    where +    where         lower1 :: Dec -> [Q Dec]         lower1 (SigD n' _) | p n'' = [valD (varP n') (normalB (varE n'')) []] where n'' = primed n'         lower1 _          = []          primed n' = mkName $ base ++ [prime]-            where +            where                 base = nameBase n'                 h = head base                 prime | isSymbol h || h `elem` "/*-<>" = '!'
Numeric/AD/Directed.hs view
@@ -6,14 +6,14 @@ -- License     :  BSD3 -- Maintainer  :  ekmett@gmail.com -- Stability   :  experimental--- Portability :  GHC only +-- Portability :  GHC only -- -- Allows the choice of AD 'Mode' to be specified at the term level for -- benchmarking or more complicated usage patterns. -----------------------------------------------------------------------------  module Numeric.AD.Directed-    ( +    (     -- * Derivatives       diffUU     , diff2UU@@ -44,11 +44,11 @@  -- TODO: use a data types a la carte approach, so we can expose more methods here -- rather than just the intersection of all of the functionality-data Direction -    = Forward -    | Reverse -    | Tower -    | Mixed +data Direction+    = Forward+    | Reverse+    | Tower+    | Mixed     deriving (Show, Eq, Ord, Read, Bounded, Enum, Ix)  diffUU :: Num a => Direction -> (forall s. Mode s => AD s a -> AD s a) -> a -> a@@ -58,7 +58,7 @@ diffUU Mixed = F.diffUU {-# INLINE diffUU #-} -diff2UU :: Num a => Direction -> (forall s. Mode s => AD s a -> AD s a) -> a -> (a, a) +diff2UU :: Num a => Direction -> (forall s. Mode s => AD s a -> AD s a) -> a -> (a, a) diff2UU Forward = F.diff2UU diff2UU Reverse = R.diff2UU diff2UU Tower = T.diff2UU@@ -69,7 +69,7 @@ diff = diffUU {-# INLINE diff #-} -diff2 :: Num a => Direction -> (forall s. Mode s => AD s a -> AD s a) -> a -> (a, a) +diff2 :: Num a => Direction -> (forall s. Mode s => AD s a -> AD s a) -> a -> (a, a) diff2 = diff2UU {-# INLINE diff2 #-} 
Numeric/AD/Forward.hs view
@@ -6,14 +6,14 @@ -- License     :  BSD3 -- Maintainer  :  ekmett@gmail.com -- Stability   :  experimental--- Portability :  GHC only +-- Portability :  GHC only -- -- Forward mode automatic differentiation -- -----------------------------------------------------------------------------  module Numeric.AD.Forward-    ( +    (     -- * Gradient       grad     , grad2@@ -46,7 +46,7 @@ {-# INLINE diff #-}  -- | The 'diff2' function calculates the result and first derivative of scalar-to-scalar function by 'Forward' 'AD'-diff2 :: Num a => (forall s. Mode s => AD s a -> AD s a) -> a -> (a, a) +diff2 :: Num a => (forall s. Mode s => AD s a -> AD s a) -> a -> (a, a) diff2 = diff2UU {-# INLINE diff2 #-} @@ -56,7 +56,7 @@ {-# INLINE diffUU #-}  -- | The 'diff2UU' function calculates the result and first derivative of scalar-to-scalar function by 'Forward' 'AD'-diff2UU :: Num a => (forall s. Mode s => AD s a -> AD s a) -> a -> (a, a) +diff2UU :: Num a => (forall s. Mode s => AD s a -> AD s a) -> a -> (a, a) diff2UU f a = unbundle $ apply f a {-# INLINE diff2UU #-} @@ -66,7 +66,7 @@ {-# INLINE diffUF #-}  -- | The 'diff2UF' function calculates the result and first derivative of a scalar-to-non-scalar function by 'Forward' 'AD'-diff2UF :: (Functor f, Num a) => (forall s. Mode s => AD s a -> f (AD s a)) -> a -> f (a, a) +diff2UF :: (Functor f, Num a) => (forall s. Mode s => AD s a -> f (AD s a)) -> a -> f (a, a) diff2UF f a = unbundle <$> apply f a {-# INLINE diff2UF #-} @@ -78,15 +78,15 @@  jacobian :: (Traversable f, Traversable g, Num a) => (forall s. Mode s => f (AD s a) -> g (AD s a)) -> f a -> g (f a) jacobian f as = transposeWith (const id) t p-    where -        (p, t) = bind2 (fmap tangent . f) as +    where+        (p, t) = bind2 (fmap tangent . f) as {-# INLINE jacobian #-}  jacobian2 :: (Traversable f, Traversable g, Num a) => (forall s. Mode s => f (AD s a) -> g (AD s a)) -> f a -> g (a, f a) jacobian2 f as = transposeWith row t p-    where -        (p, t) = bind2 f as -        row x as' = (primal x, tangent <$> as') +    where+        (p, t) = bind2 f as+        row x as' = (primal x, tangent <$> as') {-# INLINE jacobian2 #-}  grad :: (Traversable f, Num a) => (forall s. Mode s => f (AD s a) -> AD s a) -> f a -> f a@@ -95,6 +95,6 @@  grad2 :: (Traversable f, Num a) => (forall s. Mode s => f (AD s a) -> AD s a) -> f a -> (a, f a) grad2 f as = (primal b, tangent <$> bs)-    where +    where         (b, bs) = bind2 f as {-# INLINE grad2 #-}
Numeric/AD/Internal.hs view
@@ -1,4 +1,4 @@-{-# LANGUAGE GeneralizedNewtypeDeriving, TemplateHaskell, FlexibleContexts, FlexibleInstances #-}+{-# LANGUAGE GeneralizedNewtypeDeriving, TemplateHaskell, FlexibleContexts, FlexibleInstances, MultiParamTypeClasses #-} ----------------------------------------------------------------------------- -- | -- Module      :  Numeric.AD.Internal@@ -6,7 +6,7 @@ -- License     :  BSD3 -- Maintainer  :  ekmett@gmail.com -- Stability   :  experimental--- Portability :  GHC only +-- Portability :  GHC only -- ----------------------------------------------------------------------------- module Numeric.AD.Internal@@ -15,6 +15,8 @@     , Id(..)     , probe     , unprobe+    , probed+    , unprobed     ) where  import Control.Applicative@@ -24,19 +26,27 @@ import Data.Traversable (Traversable, mapAccumL) import Data.Foldable (Foldable, toList) -zipWithT :: (Foldable f, Traversable g) => (a -> b -> c) -> f a -> g b -> g c +zipWithT :: (Foldable f, Traversable g) => (a -> b -> c) -> f a -> g b -> g c zipWithT f as = snd . mapAccumL (\(a:as') b -> (as', f a b)) (toList as) --- | 'AD' serves as a common wrapper for different 'Mode' instances, exposing a traditional --- numerical tower. Universal quantification is used to limit the actions in user code to +class Iso a b where+    iso :: f a -> f b+    osi :: f b -> f a++instance Iso a a where+    iso = id+    osi = id++-- | 'AD' serves as a common wrapper for different 'Mode' instances, exposing a traditional+-- numerical tower. Universal quantification is used to limit the actions in user code to -- machinery that will return the same answers under all AD modes, allowing us to use modes -- interchangeably as both the type level \"brand\" and dictionary, providing a common API.-newtype AD f a = AD { runAD :: f a } deriving (Lifted, Mode, Primal)+newtype AD f a = AD { runAD :: f a } deriving (Iso (f a), Lifted, Mode, Primal)  let f = varT (mkName "f") in deriveNumeric (conT ''AD `appT` f) f  newtype Id a = Id a deriving-    (Eq, Ord, Show, Enum, Bounded, Num, Real, Fractional, Floating, RealFrac, RealFloat, Monoid)+    (Iso a, Eq, Ord, Show, Enum, Bounded, Num, Real, Fractional, Floating, RealFrac, RealFloat, Monoid)  probe :: a -> AD Id a probe a = AD (Id a)@@ -44,6 +54,18 @@ unprobe :: AD Id a -> a unprobe (AD (Id a)) = a +pid :: f a -> f (Id a)+pid = iso++unpid :: f (Id a) -> f a+unpid = osi++probed :: f a -> f (AD Id a)+probed = iso . pid++unprobed :: f (AD Id a) -> f a+unprobed = unpid . osi+ instance Functor Id where     fmap f (Id a) = Id (f a) @@ -53,7 +75,7 @@  instance Monad Id where     return = Id-    Id a >>= f = f a +    Id a >>= f = f a  instance Lifted Id where     (==!) = (==)@@ -62,14 +84,14 @@     fromInteger1 = fromInteger     (+!) = (+)     (-!) = (-)-    (*!) = (*) +    (*!) = (*)     negate1 = negate     abs1 = abs     signum1 = signum     (/!) = (/)     recip1 = recip     fromRational1 = fromRational-    toRational1 = toRational   +    toRational1 = toRational     pi1 = pi     exp1 = exp     log1 = log
Numeric/AD/Internal/Forward.hs view
@@ -6,7 +6,7 @@ -- License     :  BSD3 -- Maintainer  :  ekmett@gmail.com -- Stability   :  experimental--- Portability :  GHC only +-- Portability :  GHC only -- -- Unsafe and often partial combinators intended for internal usage. --@@ -65,23 +65,23 @@     type D Forward = Id     unary f (Id dadb) (Forward b db) = Forward (f b) (dadb * db)     lift1 f df (Forward b db) = Forward (f b) (dadb * db)-        where +        where             Id dadb = df (Id b)     lift1_ f df (Forward b db) = Forward a da-        where +        where             a = f b             Id da = df (Id a) (Id b) ^* db      binary f (Id dadb) (Id dadc) (Forward b db) (Forward c dc) = Forward (f b c) da-        where +        where             da = dadb * db + dc * dadc     lift2 f df (Forward b db) (Forward c dc) = Forward a da-        where +        where             a = f b c-            (Id dadb, Id dadc) = df (Id b) (Id c) +            (Id dadb, Id dadc) = df (Id b) (Id c)             da = dadb * db + dc * dadc     lift2_ f df (Forward b db) (Forward c dc) = Forward a da-        where +        where             a = f b c             (Id dadb, Id dadc) = df (Id a) (Id b) (Id c)             da = dadb * db + dc * dadc@@ -95,7 +95,7 @@         inner !i !j a = (j + 1, bundle a $ if i == j then 1 else 0)  bind2 :: (Traversable f, Num a) => (f (AD Forward a) -> b) -> f a -> (b, f b)-bind2 f as = dropIx $ mapAccumL outer (0 :: Int, b0) as +bind2 f as = dropIx $ mapAccumL outer (0 :: Int, b0) as     where         outer (!i, _) _ = let b = f $ snd $ mapAccumL (inner i) (0 :: Int) as in ((i + 1, b), b)         inner !i !j a = (j + 1, bundle a $ if i == j then 1 else 0)@@ -106,7 +106,7 @@ -- traversable could be empty. So instead we use one as a 'skeleton' transposeWith :: (Functor f, Foldable f, Traversable g) => (b -> f a -> c) -> f (g a) -> g b -> g c transposeWith f as = snd . mapAccumL go xss0-    where +    where         go xss b = (tail <$> xss, f b (head <$> xss))         xss0 = toList <$> as 
Numeric/AD/Internal/Tower.hs view
@@ -6,7 +6,7 @@ -- License     : BSD3 -- Maintainer  : ekmett@gmail.com -- Stability   : experimental--- Portability : GHC only +-- Portability : GHC only -- ----------------------------------------------------------------------------- @@ -31,7 +31,7 @@ -- Local combinators  zeroPad :: Num a => [a] -> [a]-zeroPad xs = xs ++ repeat 0 +zeroPad xs = xs ++ repeat 0 {-# INLINE zeroPad #-}  d :: Num a => [a] -> a@@ -39,7 +39,7 @@ d _ = 0 {-# INLINE d #-} -d2 :: Num a => [a] -> (a, a) +d2 :: Num a => [a] -> (a, a) d2 (a:da:_) = (a, da) d2 (a:_)    = (a, 0) d2 _        = (0, 0)@@ -73,7 +73,7 @@     Tower [] <+> bs = bs     as <+> Tower [] = as     Tower (a:as) <+> Tower (b:bs) = Tower (c:cs)-        where +        where             c = a + b             Tower cs = Tower as <+> Tower bs @@ -86,16 +86,16 @@     type D Tower = Tower     unary f dadb b = bundle (f (primal b)) (tangents b *! dadb)     lift1 f df b   = bundle (f (primal b)) (tangents b *! df b)-    lift1_ f df b = a where +    lift1_ f df b = a where         a = bundle (f (primal b)) (tangents b *! df a b) -    binary f dadb dadc b c = bundle (f (primal b) (primal c)) (tangents b *! dadb +! tangents c *! dadc) +    binary f dadb dadc b c = bundle (f (primal b) (primal c)) (tangents b *! dadb +! tangents c *! dadc)     lift2 f df b c = bundle (f (primal b) (primal c)) (tangents b *! dadb +! tangents c *! dadc) where-        (dadb, dadc) = df b c -    lift2_ f df b c = a where +        (dadb, dadc) = df b c+    lift2_ f df b c = a where         a0 = f (primal b) (primal c)         da = tangents b *! dadb +! tangents c *! dadc-        a = bundle a0 da +        a = bundle a0 da         (dadb, dadc) = df a b c  deriveLifted (conT ''Tower)
Numeric/AD/Newton.hs view
@@ -6,12 +6,12 @@ -- License     :  BSD3 -- Maintainer  :  ekmett@gmail.com -- Stability   :  experimental--- Portability :  GHC only +-- Portability :  GHC only -- -----------------------------------------------------------------------------  module Numeric.AD.Newton-    ( +    (     -- * Newton's Method (Forward AD)       findZero     , inverse@@ -29,30 +29,62 @@ import Numeric.AD.Internal import Data.Foldable (all) import Data.Traversable (Traversable)-import Numeric.AD.Forward (diff, diff2) -import Numeric.AD.Reverse (grad2) +import Numeric.AD.Forward (diff, diff2)+import Numeric.AD.Reverse (grad2) +-- | The 'findZero' function finds a zero of a scalar function using+-- Newton's method; its output is a stream of increasingly accurate+-- results.  (Modulo the usual caveats.)+--+-- Examples:+--+--  > take 10 $ findZero (\\x->x^2-4) 1  -- converge to 2.0+--+--  > module Data.Complex+--  > take 10 $ findZero ((+1).(^2)) (1 :+ 1)  -- converge to (0 :+ 1)@+-- findZero :: Fractional a => (forall s. Mode s => AD s a -> AD s a) -> a -> [a] findZero f x0 = iterate (\x -> let (y,y') = diff2 f x in x - y/y') x0 {-# INLINE findZero #-} +-- | The 'inverseNewton' function inverts a scalar function using+-- Newton's method; its output is a stream of increasingly accurate+-- results.  (Modulo the usual caveats.)+--+-- Example:+--+-- > take 10 $ inverseNewton sqrt 1 (sqrt 10)  -- converge to 10+-- inverse :: Fractional a => (forall s. Mode s => AD s a -> AD s a) -> a -> a -> [a] inverse f x0 y = findZero (\x -> f x - lift y) x0 {-# INLINE inverse  #-} +-- | The 'fixedPoint' function find a fixedpoint of a scalar+-- function using Newton's method; its output is a stream of+-- increasingly accurate results.  (Modulo the usual caveats.) fixedPoint :: Fractional a => (forall s. Mode s => AD s a -> AD s a) -> a -> [a] fixedPoint f = findZero (\x -> f x - x) {-# INLINE fixedPoint #-} +-- | The 'extremum' function finds an extremum of a scalar+-- function using Newton's method; produces a stream of increasingly+-- accurate results.  (Modulo the usual caveats.) extremum :: Fractional a => (forall t s. (Mode t, Mode s) => AD t (AD s a) -> AD t (AD s a)) -> a -> [a] extremum f x0 = findZero (diff f) x0 {-# INLINE extremum #-} +-- | The 'gradientDescent' function performs a multivariate+-- optimization, based on the naive-gradient-descent in the file+-- @stalingrad\/examples\/flow-tests\/pre-saddle-1a.vlad@ from the+-- VLAD compiler Stalingrad sources.  Its output is a stream of+-- increasingly accurate results.  (Modulo the usual caveats.)+--+-- It uses reverse mode automatic differentiation to compute the gradient. gradientDescent :: (Traversable f, Fractional a, Ord a) => (forall s. Mode s => f (AD s a) -> AD s a) -> f a -> [f a] gradientDescent f x0 = go x0 fx0 gx0 0.1 (0 :: Int)     where         (fx0, gx0) = grad2 f x0-        go x fx gx !eta !i +        go x fx gx !eta !i             | eta == 0     = [] -- step size is 0             | fx1 > fx     = go x fx gx (eta/2) 0 -- we stepped too far             | all (==0) gx = [] -- gradient is 0
Numeric/AD/Reverse.hs view
@@ -6,11 +6,11 @@ -- License     :  BSD3 -- Maintainer  :  ekmett@gmail.com -- Stability   :  experimental--- Portability :  GHC only +-- Portability :  GHC only -- -- Mixed-Mode Automatic Differentiation.--- --- For reverse mode AD we use 'System.Mem.StableName.StableName' to recover sharing information from +--+-- For reverse mode AD we use 'System.Mem.StableName.StableName' to recover sharing information from -- the tape to avoid combinatorial explosion, and thus run asymptotically faster -- than it could without such sharing information, but the use of side-effects -- contained herein is benign.@@ -18,7 +18,7 @@ -----------------------------------------------------------------------------  module Numeric.AD.Reverse-    ( +    (     -- * Gradient       grad     , grad2@@ -57,19 +57,19 @@ grad2 :: (Traversable f, Num a) => (forall s. Mode s => f (AD s a) -> AD s a) -> f a -> (a, f a) grad2 f as = (primal r, unbind vs $ partialArray bds r)     where (vs, bds) = bind as-          r = f vs +          r = f vs {-# INLINE grad2 #-}  -- | The 'jacobian' function calculates the jacobian of a non-scalar-to-non-scalar function with reverse AD lazily in @m@ passes for @m@ outputs. jacobian :: (Traversable f, Functor g, Num a) => (forall s. Mode s => f (AD s a) -> g (AD s a)) -> f a -> g (f a)-jacobian f as = unbind vs . partialArray bds <$> f vs where +jacobian f as = unbind vs . partialArray bds <$> f vs where     (vs, bds) = bind as {-# INLINE jacobian #-}  -- | The 'jacobian2' function calculates both the result and the Jacobian of a nonscalar-to-nonscalar function, using @m@ invocations of reverse AD, -- where @m@ is the output dimensionality. Applying @fmap snd@ to the result will recover the result of 'jacobian' jacobian2 :: (Traversable f, Functor g, Num a) => (forall s. Mode s => f (AD s a) -> g (AD s a)) -> f a -> g (a, f a)-jacobian2 f as = row <$> f vs where +jacobian2 f as = row <$> f vs where     (vs, bds) = bind as     row a = (primal a, unbind vs (partialArray bds a)) {-# INLINE jacobian2 #-}@@ -105,7 +105,7 @@  -- | The 'diff' function is a synonym for 'diffUU'. diff :: Num a => (forall s. Mode s => AD s a -> AD s a) -> a -> a-diff = diffUU +diff = diffUU {-# INLINE diff #-}  -- | The 'diff2' function is a synonym for 'diff2UU'.
Numeric/AD/Tower.hs view
@@ -6,14 +6,14 @@ -- License     : BSD3 -- Maintainer  : ekmett@gmail.com -- Stability   : experimental--- Portability : GHC only +-- Portability : GHC only -- -- Higher order derivatives via a \"dual number tower\". -- -----------------------------------------------------------------------------  module Numeric.AD.Tower-    ( +    (     -- * Taylor Series       taylor, taylor0     , maclaurin, maclaurin0@@ -23,7 +23,7 @@     , diffsUU     , diffs0UU     , diffsUF-    , diffs0UF +    , diffs0UF     -- * Synonyms     , diffs, diffs0     , diff, diff2@@ -40,7 +40,7 @@ import Numeric.AD.Internal.Tower  diffsUU :: Num a => (forall s. Mode s => AD s a -> AD s a) -> a -> [a]-diffsUU f a = getADTower $ apply f a +diffsUU f a = getADTower $ apply f a {-# INLINE diffsUU #-}  diffs0UU :: Num a => (forall s. Mode s => AD s a -> AD s a) -> a -> [a]@@ -74,19 +74,19 @@ {-# INLINE taylor0 #-}  maclaurin :: Fractional a => (forall s. Mode s => AD s a -> AD s a) -> a -> [a]-maclaurin f = taylor f 0 +maclaurin f = taylor f 0 {-# INLINE maclaurin #-}  maclaurin0 :: Fractional a => (forall s. Mode s => AD s a -> AD s a) -> a -> [a]-maclaurin0 f = taylor0 f 0 +maclaurin0 f = taylor0 f 0 {-# INLINE maclaurin0 #-}  diffUU :: Num a => (forall s. Mode s => AD s a -> AD s a) -> a -> a-diffUU f a = d $ diffs f a +diffUU f a = d $ diffs f a {-# INLINE diffUU #-}  diff2UU :: Num a => (forall s. Mode s => AD s a -> AD s a) -> a -> (a, a)-diff2UU f a = d2 $ diffs f a +diff2UU f a = d2 $ diffs f a {-# INLINE diff2UU #-}  diff :: Num a => (forall s. Mode s => AD s a -> AD s a) -> a -> a
ad.cabal view
@@ -1,5 +1,5 @@ Name:         ad-Version:      0.12+Version:      0.13 License:      BSD3 License-File: LICENSE Copyright:    Edward Kmett 2010@@ -8,8 +8,11 @@ Stability:    Experimental Category:     Math Homepage:     http://comonad.com/reader/-Synopsis:     Mixed-Mode Automatic Differentiation.-Description:  Forward, reverse, and higher-order automatic differentiation with a common API+Synopsis:     Automatic Differentiation+Description:  +    Forward, reverse, and higher-order automatic differentiation combinators with a common API.+    . +    Type-level \"branding\" is used to prevent the end user from confusing infinitesimals.  Build-Type:   Simple Build-Depends: