packages feed

ad 0.15 → 0.17

raw patch · 10 files changed

+306/−284 lines, 10 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

- Numeric.AD: diff2 :: (Num a) => (forall s. (Mode s) => AD s a -> AD s a) -> a -> (a, a)
- Numeric.AD: diff2FU :: (Traversable f, Num a) => (forall s. (Mode s) => f (AD s a) -> AD s a) -> f a -> (a, f a)
- Numeric.AD: diff2UF :: (Functor f, Num a) => (forall s. (Mode s) => AD s a -> f (AD s a)) -> a -> f (a, a)
- Numeric.AD: diff2UU :: (Num a) => (forall s. (Mode s) => AD s a -> AD s a) -> a -> (a, a)
- Numeric.AD: diffFU :: (Traversable f, Num a) => (forall s. (Mode s) => f (AD s a) -> AD s a) -> f a -> f a
- Numeric.AD: diffUF :: (Functor f, Num a) => (forall s. (Mode s) => AD s a -> f (AD s a)) -> a -> f a
- Numeric.AD: diffUU :: (Num a) => (forall s. (Mode s) => AD s a -> AD s a) -> a -> a
- Numeric.AD: diffs0UF :: (Functor f, Num a) => (forall s. (Mode s) => AD s a -> f (AD s a)) -> a -> f [a]
- Numeric.AD: diffs0UU :: (Num a) => (forall s. (Mode s) => AD s a -> AD s a) -> a -> [a]
- Numeric.AD: diffsUF :: (Functor f, Num a) => (forall s. (Mode s) => AD s a -> f (AD s a)) -> a -> f [a]
- Numeric.AD: diffsUU :: (Num a) => (forall s. (Mode s) => AD s a -> AD s a) -> a -> [a]
- Numeric.AD: grad2 :: (Traversable f, Num a) => (forall s. (Mode s) => f (AD s a) -> AD s a) -> f a -> (a, f a)
- Numeric.AD: gradWith2 :: (Traversable f, Num a) => (a -> a -> b) -> (forall s. (Mode s) => f (AD s a) -> AD s a) -> f a -> (a, f b)
- Numeric.AD: 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)
- Numeric.AD: jacobianWith2 :: (Traversable f, Traversable g, Num a) => (a -> a -> b) -> (forall s. (Mode s) => f (AD s a) -> g (AD s a)) -> f a -> g (a, f b)
- Numeric.AD.Directed: diff2 :: (Num a) => Direction -> (forall s. (Mode s) => AD s a -> AD s a) -> a -> (a, a)
- Numeric.AD.Directed: diff2UU :: (Num a) => Direction -> (forall s. (Mode s) => AD s a -> AD s a) -> a -> (a, a)
- Numeric.AD.Directed: diffUU :: (Num a) => Direction -> (forall s. (Mode s) => AD s a -> AD s a) -> a -> a
- Numeric.AD.Directed: grad2 :: (Traversable f, Num a) => Direction -> (forall s. (Mode s) => f (AD s a) -> AD s a) -> f a -> (a, f a)
- Numeric.AD.Directed: jacobian2 :: (Traversable f, Traversable g, Num a) => Direction -> (forall s. (Mode s) => f (AD s a) -> g (AD s a)) -> f a -> g (a, f a)
- Numeric.AD.Forward: diff2 :: (Num a) => (forall s. (Mode s) => AD s a -> AD s a) -> a -> (a, a)
- Numeric.AD.Forward: diff2MU :: (Functor f, Num a) => (forall s. (Mode s) => f (AD s a) -> AD s a) -> f (a, a) -> (a, a)
- Numeric.AD.Forward: diff2UF :: (Functor f, Num a) => (forall s. (Mode s) => AD s a -> f (AD s a)) -> a -> f (a, a)
- Numeric.AD.Forward: diff2UU :: (Num a) => (forall s. (Mode s) => AD s a -> AD s a) -> a -> (a, a)
- Numeric.AD.Forward: diffMU :: (Functor f, Num a) => (forall s. (Mode s) => f (AD s a) -> AD s a) -> f (a, a) -> a
- Numeric.AD.Forward: diffUF :: (Functor f, Num a) => (forall s. (Mode s) => AD s a -> f (AD s a)) -> a -> f a
- Numeric.AD.Forward: diffUU :: (Num a) => (forall s. (Mode s) => AD s a -> AD s a) -> a -> a
- Numeric.AD.Forward: grad2 :: (Traversable f, Num a) => (forall s. (Mode s) => f (AD s a) -> AD s a) -> f a -> (a, f a)
- Numeric.AD.Forward: gradWith2 :: (Traversable f, Num a) => (a -> a -> b) -> (forall s. (Mode s) => f (AD s a) -> AD s a) -> f a -> (a, f b)
- Numeric.AD.Forward: 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)
- Numeric.AD.Forward: jacobianWith2 :: (Traversable f, Traversable g, Num a) => (a -> a -> b) -> (forall s. (Mode s) => f (AD s a) -> g (AD s a)) -> f a -> g (a, f b)
- Numeric.AD.Internal.Forward: bind2 :: (Traversable f, Num a) => (f (AD Forward a) -> b) -> f a -> (b, f b)
- Numeric.AD.Internal.Forward: bindWith2 :: (Traversable f, Num a) => (a -> b -> c) -> (f (AD Forward a) -> b) -> f a -> (b, f c)
- Numeric.AD.Internal.Reverse: derivative2 :: (Num a) => AD Reverse a -> (a, a)
- Numeric.AD.Internal.Tower: d2 :: (Num a) => [a] -> (a, a)
- Numeric.AD.Reverse: diff2 :: (Num a) => (forall s. (Mode s) => AD s a -> AD s a) -> a -> (a, a)
- Numeric.AD.Reverse: diff2FU :: (Traversable f, Num a) => (forall s. (Mode s) => f (AD s a) -> AD s a) -> f a -> (a, f a)
- Numeric.AD.Reverse: diff2UF :: (Functor f, Num a) => (forall s. (Mode s) => AD s a -> f (AD s a)) -> a -> f (a, a)
- Numeric.AD.Reverse: diff2UU :: (Num a) => (forall s. (Mode s) => AD s a -> AD s a) -> a -> (a, a)
- Numeric.AD.Reverse: diffFU :: (Traversable f, Num a) => (forall s. (Mode s) => f (AD s a) -> AD s a) -> f a -> f a
- Numeric.AD.Reverse: diffUF :: (Functor f, Num a) => (forall s. (Mode s) => AD s a -> f (AD s a)) -> a -> f a
- Numeric.AD.Reverse: diffUU :: (Num a) => (forall s. (Mode s) => AD s a -> AD s a) -> a -> a
- Numeric.AD.Reverse: grad2 :: (Traversable f, Num a) => (forall s. (Mode s) => f (AD s a) -> AD s a) -> f a -> (a, f a)
- Numeric.AD.Reverse: gradWith2 :: (Traversable f, Num a) => (a -> a -> b) -> (forall s. (Mode s) => f (AD s a) -> AD s a) -> f a -> (a, f b)
- Numeric.AD.Reverse: 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)
- Numeric.AD.Reverse: jacobianWith2 :: (Traversable f, Functor g, Num a) => (a -> a -> b) -> (forall s. (Mode s) => f (AD s a) -> g (AD s a)) -> f a -> g (a, f b)
- Numeric.AD.Tower: diff2 :: (Num a) => (forall s. (Mode s) => AD s a -> AD s a) -> a -> (a, a)
- Numeric.AD.Tower: diff2UU :: (Num a) => (forall s. (Mode s) => AD s a -> AD s a) -> a -> (a, a)
- Numeric.AD.Tower: diffUU :: (Num a) => (forall s. (Mode s) => AD s a -> AD s a) -> a -> a
- Numeric.AD.Tower: diffs0UF :: (Functor f, Num a) => (forall s. (Mode s) => AD s a -> f (AD s a)) -> a -> f [a]
- Numeric.AD.Tower: diffs0UU :: (Num a) => (forall s. (Mode s) => AD s a -> AD s a) -> a -> [a]
- Numeric.AD.Tower: diffsUF :: (Functor f, Num a) => (forall s. (Mode s) => AD s a -> f (AD s a)) -> a -> f [a]
- Numeric.AD.Tower: diffsUU :: (Num a) => (forall s. (Mode s) => AD s a -> AD s a) -> a -> [a]
+ Numeric.AD: diff' :: (Num a) => (forall s. (Mode s) => AD s a -> AD s a) -> a -> (a, a)
+ Numeric.AD: diffF :: (Functor f, Num a) => (forall s. (Mode s) => AD s a -> f (AD s a)) -> a -> f a
+ Numeric.AD: diffF' :: (Functor f, Num a) => (forall s. (Mode s) => AD s a -> f (AD s a)) -> a -> f (a, a)
+ Numeric.AD: diffM :: (Monad m, Num a) => (forall s. (Mode s) => AD s a -> m (AD s a)) -> a -> m a
+ Numeric.AD: diffM' :: (Monad m, Num a) => (forall s. (Mode s) => AD s a -> m (AD s a)) -> a -> m (a, a)
+ Numeric.AD: diffs0F :: (Functor f, Num a) => (forall s. (Mode s) => AD s a -> f (AD s a)) -> a -> f [a]
+ Numeric.AD: diffsF :: (Functor f, Num a) => (forall s. (Mode s) => AD s a -> f (AD s a)) -> a -> f [a]
+ Numeric.AD: du :: (Functor f, Num a) => (forall s. (Mode s) => f (AD s a) -> AD s a) -> f (a, a) -> a
+ Numeric.AD: du' :: (Functor f, Num a) => (forall s. (Mode s) => f (AD s a) -> AD s a) -> f (a, a) -> (a, a)
+ Numeric.AD: duF :: (Functor f, Functor g, Num a) => (forall s. (Mode s) => f (AD s a) -> g (AD s a)) -> f (a, a) -> g a
+ Numeric.AD: duF' :: (Functor f, Functor g, Num a) => (forall s. (Mode s) => f (AD s a) -> g (AD s a)) -> f (a, a) -> g (a, a)
+ Numeric.AD: grad' :: (Traversable f, Num a) => (forall s. (Mode s) => f (AD s a) -> AD s a) -> f a -> (a, f a)
+ Numeric.AD: gradM :: (Traversable f, Monad m, Num a) => (forall s. (Mode s) => f (AD s a) -> m (AD s a)) -> f a -> m (f a)
+ Numeric.AD: gradM' :: (Traversable f, Monad m, Num a) => (forall s. (Mode s) => f (AD s a) -> m (AD s a)) -> f a -> m (a, f a)
+ Numeric.AD: gradWith' :: (Traversable f, Num a) => (a -> a -> b) -> (forall s. (Mode s) => f (AD s a) -> AD s a) -> f a -> (a, f b)
+ Numeric.AD: gradWithM :: (Traversable f, Monad m, Num a) => (a -> a -> b) -> (forall s. (Mode s) => f (AD s a) -> m (AD s a)) -> f a -> m (f b)
+ Numeric.AD: gradWithM' :: (Traversable f, Monad m, Num a) => (a -> a -> b) -> (forall s. (Mode s) => f (AD s a) -> m (AD s a)) -> f a -> m (a, f b)
+ Numeric.AD: jacobian' :: (Traversable f, Traversable g, Num a) => (forall s. (Mode s) => f (AD s a) -> g (AD s a)) -> f a -> g (a, f a)
+ Numeric.AD: jacobianWith' :: (Traversable f, Traversable g, Num a) => (a -> a -> b) -> (forall s. (Mode s) => f (AD s a) -> g (AD s a)) -> f a -> g (a, f b)
+ Numeric.AD: maclaurin :: (Fractional a) => (forall s. (Mode s) => AD s a -> AD s a) -> a -> [a]
+ Numeric.AD: maclaurin0 :: (Fractional a) => (forall s. (Mode s) => AD s a -> AD s a) -> a -> [a]
+ Numeric.AD.Directed: diff' :: (Num a) => Direction -> (forall s. (Mode s) => AD s a -> AD s a) -> a -> (a, a)
+ Numeric.AD.Directed: grad' :: (Traversable f, Num a) => Direction -> (forall s. (Mode s) => f (AD s a) -> AD s a) -> f a -> (a, f a)
+ Numeric.AD.Directed: jacobian' :: (Traversable f, Traversable g, Num a) => Direction -> (forall s. (Mode s) => f (AD s a) -> g (AD s a)) -> f a -> g (a, f a)
+ Numeric.AD.Forward: diff' :: (Num a) => (forall s. (Mode s) => AD s a -> AD s a) -> a -> (a, a)
+ Numeric.AD.Forward: diffF :: (Functor f, Num a) => (forall s. (Mode s) => AD s a -> f (AD s a)) -> a -> f a
+ Numeric.AD.Forward: diffF' :: (Functor f, Num a) => (forall s. (Mode s) => AD s a -> f (AD s a)) -> a -> f (a, a)
+ Numeric.AD.Forward: diffM :: (Monad m, Num a) => (forall s. (Mode s) => AD s a -> m (AD s a)) -> a -> m a
+ Numeric.AD.Forward: diffM' :: (Monad m, Num a) => (forall s. (Mode s) => AD s a -> m (AD s a)) -> a -> m (a, a)
+ Numeric.AD.Forward: du :: (Functor f, Num a) => (forall s. (Mode s) => f (AD s a) -> AD s a) -> f (a, a) -> a
+ Numeric.AD.Forward: du' :: (Functor f, Num a) => (forall s. (Mode s) => f (AD s a) -> AD s a) -> f (a, a) -> (a, a)
+ Numeric.AD.Forward: duF :: (Functor f, Functor g, Num a) => (forall s. (Mode s) => f (AD s a) -> g (AD s a)) -> f (a, a) -> g a
+ Numeric.AD.Forward: duF' :: (Functor f, Functor g, Num a) => (forall s. (Mode s) => f (AD s a) -> g (AD s a)) -> f (a, a) -> g (a, a)
+ Numeric.AD.Forward: grad' :: (Traversable f, Num a) => (forall s. (Mode s) => f (AD s a) -> AD s a) -> f a -> (a, f a)
+ Numeric.AD.Forward: gradWith' :: (Traversable f, Num a) => (a -> a -> b) -> (forall s. (Mode s) => f (AD s a) -> AD s a) -> f a -> (a, f b)
+ Numeric.AD.Forward: jacobian' :: (Traversable f, Traversable g, Num a) => (forall s. (Mode s) => f (AD s a) -> g (AD s a)) -> f a -> g (a, f a)
+ Numeric.AD.Forward: jacobianWith' :: (Traversable f, Traversable g, Num a) => (a -> a -> b) -> (forall s. (Mode s) => f (AD s a) -> g (AD s a)) -> f a -> g (a, f b)
+ Numeric.AD.Internal.Forward: bind' :: (Traversable f, Num a) => (f (AD Forward a) -> b) -> f a -> (b, f b)
+ Numeric.AD.Internal.Forward: bindWith' :: (Traversable f, Num a) => (a -> b -> c) -> (f (AD Forward a) -> b) -> f a -> (b, f c)
+ Numeric.AD.Internal.Reverse: derivative' :: (Num a) => AD Reverse a -> (a, a)
+ Numeric.AD.Internal.Tower: d' :: (Num a) => [a] -> (a, a)
+ Numeric.AD.Reverse: diff' :: (Num a) => (forall s. (Mode s) => AD s a -> AD s a) -> a -> (a, a)
+ Numeric.AD.Reverse: diffF :: (Functor f, Num a) => (forall s. (Mode s) => AD s a -> f (AD s a)) -> a -> f a
+ Numeric.AD.Reverse: diffF' :: (Functor f, Num a) => (forall s. (Mode s) => AD s a -> f (AD s a)) -> a -> f (a, a)
+ Numeric.AD.Reverse: diffM :: (Monad m, Num a) => (forall s. (Mode s) => AD s a -> m (AD s a)) -> a -> m a
+ Numeric.AD.Reverse: diffM' :: (Monad m, Num a) => (forall s. (Mode s) => AD s a -> m (AD s a)) -> a -> m (a, a)
+ Numeric.AD.Reverse: grad' :: (Traversable f, Num a) => (forall s. (Mode s) => f (AD s a) -> AD s a) -> f a -> (a, f a)
+ Numeric.AD.Reverse: gradM :: (Traversable f, Monad m, Num a) => (forall s. (Mode s) => f (AD s a) -> m (AD s a)) -> f a -> m (f a)
+ Numeric.AD.Reverse: gradM' :: (Traversable f, Monad m, Num a) => (forall s. (Mode s) => f (AD s a) -> m (AD s a)) -> f a -> m (a, f a)
+ Numeric.AD.Reverse: gradWith' :: (Traversable f, Num a) => (a -> a -> b) -> (forall s. (Mode s) => f (AD s a) -> AD s a) -> f a -> (a, f b)
+ Numeric.AD.Reverse: gradWithM :: (Traversable f, Monad m, Num a) => (a -> a -> b) -> (forall s. (Mode s) => f (AD s a) -> m (AD s a)) -> f a -> m (f b)
+ Numeric.AD.Reverse: gradWithM' :: (Traversable f, Monad m, Num a) => (a -> a -> b) -> (forall s. (Mode s) => f (AD s a) -> m (AD s a)) -> f a -> m (a, f b)
+ Numeric.AD.Reverse: jacobian' :: (Traversable f, Functor g, Num a) => (forall s. (Mode s) => f (AD s a) -> g (AD s a)) -> f a -> g (a, f a)
+ Numeric.AD.Reverse: jacobianWith' :: (Traversable f, Functor g, Num a) => (a -> a -> b) -> (forall s. (Mode s) => f (AD s a) -> g (AD s a)) -> f a -> g (a, f b)
+ Numeric.AD.Tower: diff' :: (Num a) => (forall s. (Mode s) => AD s a -> AD s a) -> a -> (a, a)
+ Numeric.AD.Tower: diffs0F :: (Functor f, Num a) => (forall s. (Mode s) => AD s a -> f (AD s a)) -> a -> f [a]
+ Numeric.AD.Tower: diffs0M :: (Monad m, Num a) => (forall s. (Mode s) => AD s a -> m (AD s a)) -> a -> m [a]
+ Numeric.AD.Tower: diffsF :: (Functor f, Num a) => (forall s. (Mode s) => AD s a -> f (AD s a)) -> a -> f [a]
+ Numeric.AD.Tower: diffsM :: (Monad m, Num a) => (forall s. (Mode s) => AD s a -> m (AD s a)) -> a -> m [a]

Files

Numeric/AD.hs view
@@ -16,41 +16,49 @@ module Numeric.AD     (     -- * Gradients-      grad, grad2-    , gradWith, gradWith2+      grad, grad'+    , gradWith, gradWith'      -- * Jacobians-    , jacobian, jacobian2-    , jacobianWith, jacobianWith2--    -- * Synonyms-    , diff-    , diff2-    , diffs-    , diffs0+    , jacobian, jacobian'+    , jacobianWith, jacobianWith'      -- * Derivatives (Forward)-    , diffUU-    , diffUF--    , diff2UU-    , diff2UF+    , diff+    , diffF -    -- * Derivatives (Reverse)-    , diffFU-    , diff2FU+    , diff'+    , diffF'      -- * Derivatives (Tower)-    , diffsUU-    , diffsUF+    , diffs+    , diffsF -    , diffs0UU-    , diffs0UF+    , diffs0+    , diffs0F +    -- * Directional Derivatives (Forward)+    , du+    , du'+    , duF+    , duF'+     -- * Taylor Series (Tower)     , taylor     , taylor0+    , maclaurin+    , maclaurin0 +    -- * Monadic Combinators (Forward)+    , diffM+    , diffM'++    -- * Monadic Combinators (Reverse)+    , gradM+    , gradM'+    , gradWithM+    , gradWithM'+     -- * Exposed Types     , AD(..)     , Mode(..)@@ -61,50 +69,59 @@ import Control.Applicative import Numeric.AD.Classes  (Mode(..)) 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.Reverse  (diffFU, diff2FU, grad, grad2, gradWith, gradWith2)+import Numeric.AD.Forward  (diff, diff', diffF, diffF', du, du', duF, duF', diffM, diffM') +import Numeric.AD.Tower    (diffsF, diffs0F , diffs, diffs0, taylor, taylor0, maclaurin, maclaurin0)+import Numeric.AD.Reverse  (grad, grad', gradWith, gradWith', gradM, gradM', gradWithM, gradWithM')  import qualified Numeric.AD.Forward as Forward import qualified Numeric.AD.Reverse as Reverse --- | Calculate the Jacobian of a non-scalar-to-non-scalar function, automatically choosing between forward and reverse mode AD based on the number of inputs and outputs+-- | Calculate the Jacobian of a non-scalar-to-non-scalar function, automatically choosing between forward and reverse mode AD based on the number of inputs and outputs.+--+-- If you need to support functions where the output is only a 'Functor' or 'Monad', consider 'Numeric.AD.Reverse.jacobian' or 'Numeric.AD.Reverse.gradM' from "Numeric.AD.Reverse". 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 bs = snd <$> jacobian2 f bs+jacobian f bs = snd <$> jacobian' f bs {-# INLINE jacobian #-} --- | Calculate the answer and Jacobian of a non-scalar-to-non-scalar function, automatically choosing between forward- and reverse- mode AD based on the relative, number of inputs and outputs. If you need to support functions where the output is only a 'Functor', consider using 'jacobianT' from "Numeric.AD.Forward" or 'jacobian2' from "Numeric.AD.Reverse" directly.-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 bs | n == 0    = fmap (\x -> (unprobe x, bs)) as-               | n > m     = Reverse.jacobian2 f bs-               | otherwise = Forward.jacobian2 f bs+-- | Calculate both the answer and Jacobian of a non-scalar-to-non-scalar function, automatically choosing between forward- and reverse- mode AD based on the relative, number of inputs and outputs.+--+-- If you need to support functions where the output is only a 'Functor' or 'Monad', consider 'Numeric.AD.Reverse.jacobian'' or 'Numeric.AD.Reverse.gradM'' from "Numeric.AD.Reverse".+jacobian' :: (Traversable f, Traversable g, Num a) => (forall s. Mode s => f (AD s a) -> g (AD s a)) -> f a -> g (a, f a)+jacobian' f bs | n == 0    = fmap (\x -> (unprobe x, bs)) as+               | n > m     = Reverse.jacobian' f bs+               | otherwise = Forward.jacobian' f bs     where         as = f (probed bs)         n = size bs         m = size as         size :: Foldable f => f a -> Int         size = foldr' (\_ b -> 1 + b) 0-{-# INLINE jacobian2 #-}+{-# INLINE jacobian' #-}  -- | @'jacobianWith' g f@ calculates the Jacobian of a non-scalar-to-non-scalar function, automatically choosing between forward and reverse mode AD based on the number of inputs and outputs.--- --- The resulting Jacobian matrix is then recombined element-wise with the input using @g@. +--+-- The resulting Jacobian matrix is then recombined element-wise with the input using @g@.+--+-- If you need to support functions where the output is only a 'Functor' or 'Monad', consider 'Numeric.AD.Reverse.jacobianWith' or 'Numeric.AD.Reverse.gradWithM' from "Numeric.AD.Reverse". jacobianWith :: (Traversable f, Traversable g, Num a) => (a -> a -> b) -> (forall s. Mode s => f (AD s a) -> g (AD s a)) -> f a -> g (f b)-jacobianWith g f bs = snd <$> jacobianWith2 g f bs+jacobianWith g f bs = snd <$> jacobianWith' g f bs {-# INLINE jacobianWith #-} --- | @'jacobianWith2' g f@ calculates the answer and Jacobian of a non-scalar-to-non-scalar function, automatically choosing between forward and reverse mode AD based on the number of inputs and outputs.+-- | @'jacobianWith'' g f@ calculates the answer and Jacobian of a non-scalar-to-non-scalar function, automatically choosing between forward and reverse mode AD based on the number of inputs and outputs. ----- The resulting Jacobian matrix is then recombined element-wise with the input using @g@. -jacobianWith2 :: (Traversable f, Traversable g, Num a) => (a -> a -> b) -> (forall s. Mode s => f (AD s a) -> g (AD s a)) -> f a -> g (a, f b)-jacobianWith2 g f bs +-- The resulting Jacobian matrix is then recombined element-wise with the input using @g@.+--+-- If you need to support functions where the output is only a 'Functor' or 'Monad', consider 'Numeric.AD.Reverse.jacobianWith'' or 'Numeric.AD.Reverse.gradWithM'' from "Numeric.AD.Reverse".+jacobianWith' :: (Traversable f, Traversable g, Num a) => (a -> a -> b) -> (forall s. Mode s => f (AD s a) -> g (AD s a)) -> f a -> g (a, f b)+jacobianWith' g f bs     | n == 0    = fmap (\x -> (unprobe x, undefined <$> bs)) as-    | n > m     = Reverse.jacobianWith2 g f bs-    | otherwise = Forward.jacobianWith2 g f bs+    | n > m     = Reverse.jacobianWith' g f bs+    | otherwise = Forward.jacobianWith' g f bs     where         as = f (probed bs)         n = size bs         m = size as         size :: Foldable f => f a -> Int         size = foldr' (\_ b -> 1 + b) 0-{-# INLINE jacobianWith2 #-}+{-# INLINE jacobianWith' #-}+
Numeric/AD/Directed.hs view
@@ -14,18 +14,15 @@  module Numeric.AD.Directed     (-    -- * Derivatives-      diffUU-    , diff2UU-    -- * Common access patterns-    , diff-    , diff2+    -- * Gradients+      grad+    , grad'     -- * Jacobians     , jacobian-    , jacobian2-    -- * Gradients-    , grad-    , grad2+    , jacobian'+    -- * Derivatives+    , diff+    , diff'     -- * Exposed Types     , Direction(..)     , Mode(..)@@ -51,53 +48,45 @@     | 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-diffUU Forward = F.diffUU-diffUU Reverse = R.diffUU-diffUU Tower = T.diffUU-diffUU Mixed = F.diffUU-{-# INLINE diffUU #-}--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-diff2UU Mixed = F.diff2UU-{-# INLINE diff2UU #-}- diff :: Num a => Direction -> (forall s. Mode s => AD s a -> AD s a) -> a -> a-diff = diffUU+diff Forward = F.diff+diff Reverse = R.diff+diff Tower = T.diff+diff Mixed = F.diff {-# INLINE diff #-} -diff2 :: Num a => Direction -> (forall s. Mode s => AD s a -> AD s a) -> a -> (a, a)-diff2 = diff2UU-{-# INLINE diff2 #-}+diff' :: Num a => Direction -> (forall s. Mode s => AD s a -> AD s a) -> a -> (a, a)+diff' Forward = F.diff'+diff' Reverse = R.diff'+diff' Tower = T.diff'+diff' Mixed = F.diff'+{-# INLINE diff' #-}  jacobian :: (Traversable f, Traversable g, Num a) => Direction -> (forall s. Mode s => f (AD s a) -> g (AD s a)) -> f a -> g (f a) jacobian Forward = F.jacobian jacobian Reverse = R.jacobian-jacobian Tower = error "jacobian Tower: unimplemented"+jacobian Tower = F.jacobian -- error "jacobian Tower: unimplemented" jacobian Mixed = M.jacobian {-# INLINE jacobian #-} -jacobian2 :: (Traversable f, Traversable g, Num a) => Direction -> (forall s. Mode s => f (AD s a) -> g (AD s a)) -> f a -> g (a, f a)-jacobian2 Forward = F.jacobian2-jacobian2 Reverse = R.jacobian2-jacobian2 Tower = error "jacobian2 Tower: unimplemented"-jacobian2 Mixed = M.jacobian2-{-# INLINE jacobian2 #-}+jacobian' :: (Traversable f, Traversable g, Num a) => Direction -> (forall s. Mode s => f (AD s a) -> g (AD s a)) -> f a -> g (a, f a)+jacobian' Forward = F.jacobian'+jacobian' Reverse = R.jacobian'+jacobian' Tower = F.jacobian' -- error "jacobian' Tower: unimplemented"+jacobian' Mixed = M.jacobian'+{-# INLINE jacobian' #-}  grad :: (Traversable f, Num a) => Direction -> (forall s. Mode s => f (AD s a) -> AD s a) -> f a -> f a grad Forward = F.grad grad Reverse = R.grad-grad Tower   = error "grad Tower: unimplemented"+grad Tower   = F.grad -- error "grad Tower: unimplemented" grad Mixed   = M.grad {-# INLINE grad #-} -grad2 :: (Traversable f, Num a) => Direction -> (forall s. Mode s => f (AD s a) -> AD s a) -> f a -> (a, f a)-grad2 Forward = F.grad2-grad2 Reverse = R.grad2-grad2 Tower   = error "grad2 Tower: unimplemented"-grad2 Mixed   = M.grad2-{-# INLINE grad2 #-}+grad' :: (Traversable f, Num a) => Direction -> (forall s. Mode s => f (AD s a) -> AD s a) -> f a -> (a, f a)+grad' Forward = F.grad'+grad' Reverse = R.grad'+grad' Tower   = F.grad' -- error "grad' Tower: unimplemented"+grad' Mixed   = M.grad'+{-# INLINE grad' #-} 
Numeric/AD/Forward.hs view
@@ -16,27 +16,30 @@     (     -- * Gradient       grad-    , grad2+    , grad'     , gradWith-    , gradWith2+    , gradWith'     -- * Jacobian     , jacobian-    , jacobian2-    , jacobianT+    , jacobian'     , jacobianWith-    , jacobianWith2+    , jacobianWith'+    -- * Transposed Jacobian+    , jacobianT     , jacobianWithT     -- * Derivatives-    , diffUU-    , diff2UU-    , diffUF-    , diff2UF-    -- * Directional Derivatives-    , diffMU -    , diff2MU-    -- * Synonyms     , diff-    , diff2+    , diff'+    , diffF+    , diffF'+    -- * Directional Derivatives+    , du+    , du'+    , duF+    , duF'+    -- * Monadic Combinators+    , diffM+    , diffM'     -- * Exposed Types     , AD(..)     , Mode(..)@@ -44,103 +47,115 @@  import Data.Traversable (Traversable) import Control.Applicative+import Control.Monad (liftM) import Numeric.AD.Classes import Numeric.AD.Internal import Numeric.AD.Internal.Forward -diffMU :: (Functor f, Num a) => (forall s. Mode s => f (AD s a) -> AD s a) -> f (a, a) -> a-diffMU f = tangent . f . fmap (uncurry bundle)-{-# INLINE diffMU #-}+du :: (Functor f, Num a) => (forall s. Mode s => f (AD s a) -> AD s a) -> f (a, a) -> a+du f = tangent . f . fmap (uncurry bundle)+{-# INLINE du #-} -diff2MU :: (Functor f, Num a) => (forall s. Mode s => f (AD s a) -> AD s a) -> f (a, a) -> (a, a)-diff2MU f = unbundle . f . fmap (uncurry bundle)-{-# INLINE diff2MU #-}+du' :: (Functor f, Num a) => (forall s. Mode s => f (AD s a) -> AD s a) -> f (a, a) -> (a, a)+du' f = unbundle . f . fmap (uncurry bundle)+{-# INLINE du' #-} --- | The 'diff2' function calculates the first derivative of scalar-to-scalar function by 'Forward' 'AD'+duF :: (Functor f, Functor g, Num a) => (forall s. Mode s => f (AD s a) -> g (AD s a)) -> f (a, a) -> g a+duF f = fmap tangent . f . fmap (uncurry bundle)+{-# INLINE duF #-}++duF' :: (Functor f, Functor g, Num a) => (forall s. Mode s => f (AD s a) -> g (AD s a)) -> f (a, a) -> g (a, a)+duF' f = fmap unbundle . f . fmap (uncurry bundle)+{-# INLINE duF' #-}++-- | The 'diff' function calculates the first derivative of a scalar-to-scalar function by forward-mode 'AD'+--+-- > diff sin == cos diff :: Num a => (forall s. Mode s => AD s a -> AD s a) -> a -> a-diff = diffUU+diff f a = tangent $ apply f a {-# 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 = diff2UU-{-# INLINE diff2 #-}+-- | The 'd'UU' function calculates the result and first derivative of scalar-to-scalar function by F'orward' 'AD'+-- +-- > d' sin == sin &&& cos+-- > d' f = f &&& d f+diff' :: Num a => (forall s. Mode s => AD s a -> AD s a) -> a -> (a, a)+diff' f a = unbundle $ apply f a+{-# INLINE diff' #-} --- | The 'diffUU' function calculates the first derivative of a scalar-to-scalar function by 'Forward' 'AD'-diffUU :: Num a => (forall s. Mode s => AD s a -> AD s a) -> a -> a-diffUU f a = tangent $ apply f a-{-# INLINE diffUU #-}+-- | The 'diffF' function calculates the first derivative of scalar-to-nonscalar function by F'orward' 'AD'+diffF :: (Functor f, Num a) => (forall s. Mode s => AD s a -> f (AD s a)) -> a -> f a+diffF f a = tangent <$> apply f a+{-# INLINE diffF #-} --- | 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 f a = unbundle $ apply f a-{-# INLINE diff2UU #-}+-- | The 'diffF'' function calculates the result and first derivative of a scalar-to-non-scalar function by F'orward' 'AD'+diffF' :: (Functor f, Num a) => (forall s. Mode s => AD s a -> f (AD s a)) -> a -> f (a, a)+diffF' f a = unbundle <$> apply f a+{-# INLINE diffF' #-} --- | The 'diffUF' function calculates the first derivative of scalar-to-nonscalar function by 'Forward' 'AD'-diffUF :: (Functor f, Num a) => (forall s. Mode s => AD s a -> f (AD s a)) -> a -> f a-diffUF f a = tangent <$> apply f a-{-# INLINE diffUF #-}+-- | The 'dUM' function calculates the first derivative of scalar-to-scalar monadic function by F'orward' 'AD'+diffM :: (Monad m, Num a) => (forall s. Mode s => AD s a -> m (AD s a)) -> a -> m a+diffM f a = tangent `liftM` apply f a+{-# INLINE diffM #-} --- | 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 f a = unbundle <$> apply f a-{-# INLINE diff2UF #-}+-- | The 'd'UM' function calculates the result and first derivative of a scalar-to-scalar monadic function by F'orward' 'AD'+diffM' :: (Monad m, Num a) => (forall s. Mode s => AD s a -> m (AD s a)) -> a -> m (a, a)+diffM' f a = unbundle `liftM` apply f a+{-# INLINE diffM' #-}  -- | A fast, simple transposed Jacobian computed with forward-mode AD. jacobianT :: (Traversable f, Functor g, Num a) => (forall s. Mode s => f (AD s a) -> g (AD s a)) -> f a -> f (g a) jacobianT f = bind (fmap tangent . f)--- jacobianT f as = fmap tangent <$> bind f as {-# INLINE jacobianT #-}  -- | A fast, simple transposed Jacobian computed with forward-mode AD. jacobianWithT :: (Traversable f, Functor g, Num a) => (a -> a -> b) -> (forall s. Mode s => f (AD s a) -> g (AD s a)) -> f a -> f (g b)-jacobianWithT g f = bindWith g' f -    where g' a ga = g a . tangent <$> ga +jacobianWithT g f = bindWith g' f+    where g' a ga = g a . tangent <$> ga {-# INLINE jacobianWithT #-}  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+        (p, t) = bind' (fmap tangent . f) as {-# INLINE jacobian #-}  jacobianWith :: (Traversable f, Traversable g, Num a) => (a -> a -> b) -> (forall s. Mode s => f (AD s a) -> g (AD s a)) -> f a -> g (f b) jacobianWith g f as = transposeWith (const id) t p     where-        (p, t) = bindWith2 g' f as-        g' a ga = g a . tangent <$> ga +        (p, t) = bindWith' g' f as+        g' a ga = g a . tangent <$> ga {-# INLINE jacobianWith #-} -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+jacobian' :: (Traversable f, Traversable g, Num a) => (forall s. Mode s => f (AD s a) -> g (AD s a)) -> f a -> g (a, f a)+jacobian' f as = transposeWith row t p     where-        (p, t) = bind2 f as+        (p, t) = bind' f as         row x as' = (primal x, tangent <$> as')-{-# INLINE jacobian2 #-}+{-# INLINE jacobian' #-} -jacobianWith2 :: (Traversable f, Traversable g, Num a) => (a -> a -> b) -> (forall s. Mode s => f (AD s a) -> g (AD s a)) -> f a -> g (a, f b)-jacobianWith2 g f as = transposeWith row t p+jacobianWith' :: (Traversable f, Traversable g, Num a) => (a -> a -> b) -> (forall s. Mode s => f (AD s a) -> g (AD s a)) -> f a -> g (a, f b)+jacobianWith' g f as = transposeWith row t p     where-        (p, t) = bindWith2 g' f as+        (p, t) = bindWith' g' f as         row x as' = (primal x, as')-        g' a ga = g a . tangent <$> ga -{-# INLINE jacobianWith2 #-}+        g' a ga = g a . tangent <$> ga+{-# INLINE jacobianWith' #-}  grad :: (Traversable f, Num a) => (forall s. Mode s => f (AD s a) -> AD s a) -> f a -> f a grad f = bind (tangent . f) {-# INLINE grad #-} --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)+grad' :: (Traversable f, Num a) => (forall s. Mode s => f (AD s a) -> AD s a) -> f a -> (a, f a)+grad' f as = (primal b, tangent <$> bs)     where-        (b, bs) = bind2 f as-{-# INLINE grad2 #-}+        (b, bs) = bind' f as+{-# INLINE grad' #-}  gradWith :: (Traversable f, Num a) => (a -> a -> b) -> (forall s. Mode s => f (AD s a) -> AD s a) -> f a -> f b gradWith g f = bindWith g (tangent . f) {-# INLINE gradWith #-} -gradWith2 :: (Traversable f, Num a) => (a -> a -> b) -> (forall s. Mode s => f (AD s a) -> AD s a) -> f a -> (a, f b)-gradWith2 g f = bindWith2 g (tangent . f)-{-# INLINE gradWith2 #-}+gradWith' :: (Traversable f, Num a) => (a -> a -> b) -> (forall s. Mode s => f (AD s a) -> AD s a) -> f a -> (a, f b)+gradWith' g f = bindWith' g (tangent . f)+{-# INLINE gradWith' #-}
Numeric/AD/Internal/Forward.hs view
@@ -20,9 +20,9 @@     , unbundle     , apply     , bind-    , bind2+    , bind'     , bindWith-    , bindWith2+    , bindWith'     , transposeWith     ) where @@ -96,8 +96,8 @@         outer !i _ = (i + 1, f $ snd $ mapAccumL (inner i) 0 as)         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+bind' :: (Traversable f, Num a) => (f (AD Forward a) -> b) -> f a -> (b, f b)+bind' 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)@@ -110,8 +110,8 @@         outer !i a = (i + 1, g a $ f $ snd $ mapAccumL (inner i) 0 as)         inner !i !j a = (j + 1, bundle a $ if i == j then 1 else 0) -bindWith2 :: (Traversable f, Num a) => (a -> b -> c) -> (f (AD Forward a) -> b) -> f a -> (b, f c)-bindWith2 g f as = dropIx $ mapAccumL outer (0 :: Int, b0) as+bindWith' :: (Traversable f, Num a) => (a -> b -> c) -> (f (AD Forward a) -> b) -> f a -> (b, f c)+bindWith' g f as = dropIx $ mapAccumL outer (0 :: Int, b0) as     where         outer (!i, _) a = let b = f $ snd $ mapAccumL (inner i) (0 :: Int) as in ((i + 1, b), g a b)         inner !i !j a = (j + 1, bundle a $ if i == j then 1 else 0)
Numeric/AD/Internal/Reverse.hs view
@@ -24,7 +24,7 @@     , partialArray     , partialMap     , derivative-    , derivative2+    , derivative'     , Var(..)     , bind     , unbind@@ -118,9 +118,9 @@ derivative = sum . map snd . partials {-# INLINE derivative #-} -derivative2 :: Num a => AD Reverse a -> (a, a)-derivative2 r = (primal r, derivative r)-{-# INLINE derivative2 #-}+derivative' :: Num a => AD Reverse a -> (a, a)+derivative' r = (primal r, derivative r)+{-# INLINE derivative' #-}  -- | back propagate sensitivities along a tape. backPropagate :: Num a => (Vertex -> (Tape a Int, Int, [Int])) -> STArray s Int a -> Vertex -> ST s ()@@ -204,10 +204,10 @@ unbind xs ys = fmap (\v -> ys ! varId v) xs  unbindWith :: (Functor f, Var v, Num a) => (a -> b -> c) -> f (v a) -> Array Int b -> f c-unbindWith f xs ys = fmap (\v -> f (primal v) (ys ! varId v)) xs +unbindWith f xs ys = fmap (\v -> f (primal v) (ys ! varId v)) xs  unbindMap :: (Functor f, Var v, Num a) => f (v a) -> IntMap a -> f a unbindMap xs ys = fmap (\v -> findWithDefault 0 (varId v) ys) xs  unbindMapWithDefault :: (Functor f, Var v, Num a) => b -> (a -> b -> c) -> f (v a) -> IntMap b -> f c-unbindMapWithDefault z f xs ys = fmap (\v -> f (primal v) $ findWithDefault z (varId v) ys) xs +unbindMapWithDefault z f xs ys = fmap (\v -> f (primal v) $ findWithDefault z (varId v) ys) xs
Numeric/AD/Internal/Tower.hs view
@@ -14,7 +14,7 @@     ( Tower(..)     , zeroPad     , d-    , d2+    , d'     , tangents     , bundle     , apply@@ -39,11 +39,11 @@ d _ = 0 {-# INLINE d #-} -d2 :: Num a => [a] -> (a, a)-d2 (a:da:_) = (a, da)-d2 (a:_)    = (a, 0)-d2 _        = (0, 0)-{-# INLINE d2 #-}+d' :: Num a => [a] -> (a, a)+d' (a:da:_) = (a, da)+d' (a:_)    = (a, 0)+d' _        = (0, 0)+{-# INLINE d' #-}  tangents :: Tower a -> Tower a tangents (Tower []) = Tower []
Numeric/AD/Newton.hs view
@@ -29,8 +29,8 @@ import Numeric.AD.Internal import Data.Foldable (all) import Data.Traversable (Traversable)-import Numeric.AD.Forward (diff, diff2)-import Numeric.AD.Reverse (gradWith2)+import Numeric.AD.Forward (diff, diff')+import Numeric.AD.Reverse (gradWith')  -- | The 'findZero' function finds a zero of a scalar function using -- Newton's method; its output is a stream of increasingly accurate@@ -44,7 +44,7 @@ --  > 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+findZero f x0 = iterate (\x -> let (y,y') = diff' f x in x - y/y') x0 {-# INLINE findZero #-}  -- | The 'inverseNewton' function inverts a scalar function using@@ -83,7 +83,7 @@ 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 xgx0 0.1 (0 :: Int)     where-        (fx0, xgx0) = gradWith2 (,) f x0+        (fx0, xgx0) = gradWith' (,) f x0         go x fx xgx !eta !i             | eta == 0     = [] -- step size is 0             | fx1 > fx     = go x fx xgx (eta/2) 0 -- we stepped too far@@ -94,6 +94,6 @@             where                 zeroGrad = all (\(_,g) -> g == 0)                 x1 = fmap (\(xi,gxi) -> xi - eta * gxi) xgx-                (fx1, xgx1) = gradWith2 (,) f x1-                +                (fx1, xgx1) = gradWith' (,) f x1+ {-# INLINE gradientDescent #-}
Numeric/AD/Reverse.hs view
@@ -21,30 +21,33 @@     (     -- * Gradient       grad-    , grad2+    , grad'     , gradWith-    , gradWith2+    , gradWith'     -- * Jacobian     , jacobian-    , jacobian2+    , jacobian'     , jacobianWith-    , jacobianWith2+    , jacobianWith'     -- * Derivatives-    , diffUU-    , diff2UU-    , diffFU-    , diff2FU-    , diffUF-    , diff2UF-    -- * Synonyms     , diff-    , diff2+    , diff'+    , diffF+    , diffF'+    -- * Monadic Combinators+    , diffM+    , diffM'+    , gradM+    , gradM'+    , gradWithM+    , gradWithM'     -- * Exposed Types     , AD(..)     , Mode(..)     ) where -import Control.Applicative ((<$>))+import Control.Monad (liftM)+import Control.Applicative (WrappedMonad(..),(<$>)) import Data.Traversable (Traversable)  import Numeric.AD.Classes@@ -57,32 +60,32 @@     where (vs,bds) = bind as {-# INLINE grad #-} --- | The 'grad2' function calculates the result and gradient of a non-scalar-to-scalar function with 'Reverse' AD in a single pass.-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)+-- | The 'grad'' function calculates the result and gradient of a non-scalar-to-scalar function with 'Reverse' AD in a single pass.+grad' :: (Traversable f, Num a) => (forall s. Mode s => f (AD s a) -> AD s a) -> f a -> (a, f a)+grad' f as = (primal r, unbind vs $ partialArray bds r)     where (vs, bds) = bind as           r = f vs-{-# INLINE grad2 #-}+{-# INLINE grad' #-}  -- | @'grad' g f@ function calculates the gradient of a non-scalar-to-scalar function @f@ with reverse-mode AD in a single pass. -- The gradient is combined element-wise with the argument using the function @g@. ----- > grad == gradWith (\_ dx -> dx) +-- > grad == gradWith (\_ dx -> dx) -- > id == gradWith const gradWith :: (Traversable f, Num a) => (a -> a -> b) -> (forall s. Mode s => f (AD s a) -> AD s a) -> f a -> f b gradWith g f as = unbindWith g vs (partialArray bds $ f vs)     where (vs,bds) = bind as {-# INLINE gradWith #-} --- | @'grad2' g f@ calculates the result and gradient of a non-scalar-to-scalar function @f@ with 'Reverse' AD in a single pass+-- | @'grad'' g f@ calculates the result and gradient of a non-scalar-to-scalar function @f@ with 'Reverse' AD in a single pass -- the gradient is combined element-wise with the argument using the function @g@.--- --- > grad2 == gradWith2 (\_ dx -> dx)-gradWith2 :: (Traversable f, Num a) => (a -> a -> b) -> (forall s. Mode s => f (AD s a) -> AD s a) -> f a -> (a, f b)-gradWith2 g f as = (primal r, unbindWith g vs $ partialArray bds r)+--+-- > grad' == gradWith' (\_ dx -> dx)+gradWith' :: (Traversable f, Num a) => (a -> a -> b) -> (forall s. Mode s => f (AD s a) -> AD s a) -> f a -> (a, f b)+gradWith' g f as = (primal r, unbindWith g vs $ partialArray bds r)     where (vs, bds) = bind as           r = f vs-{-# INLINE gradWith2 #-}+{-# INLINE gradWith' #-}  -- | 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)@@ -90,18 +93,18 @@     (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,+-- | The 'jacobian'' 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+jacobian' :: (Traversable f, Functor g, Num a) => (forall s. Mode s => f (AD s a) -> g (AD s a)) -> f a -> g (a, f a)+jacobian' f as = row <$> f vs where     (vs, bds) = bind as     row a = (primal a, unbind vs (partialArray bds a))-{-# INLINE jacobian2 #-}+{-# INLINE jacobian' #-}  -- | 'jacobianWith g f' calculates the jacobian of a non-scalar-to-non-scalar function @f@ with reverse AD lazily in @m@ passes for @m@ outputs. -- -- Instead of returning the Jacobian matrix, the elements of the matrix are combined with the input using the @g@.--- +-- -- > jacobian == jacobianWith (\_ dx -> dx) -- > jacobianWith const == (\f x -> const x <$> f x) --@@ -110,55 +113,58 @@     (vs, bds) = bind as {-# INLINE jacobianWith #-} --- | 'jacobianWith2 g f' calculates both the result and the Jacobian of a nonscalar-to-nonscalar function @f@, using @m@ invocations of reverse AD,+-- | 'jacobianWith' g f' calculates both the result and the Jacobian of a nonscalar-to-nonscalar function @f@, using @m@ invocations of reverse AD, -- where @m@ is the output dimensionality. Applying @fmap snd@ to the result will recover the result of 'jacobianWith'--- +-- -- Instead of returning the Jacobian matrix, the elements of the matrix are combined with the input using the @g@. ----- > jacobian2 == jacobianWith2 (\_ dx -> dx)+-- > jacobian' == jacobianWith' (\_ dx -> dx) ---jacobianWith2 :: (Traversable f, Functor g, Num a) => (a -> a -> b) -> (forall s. Mode s => f (AD s a) -> g (AD s a)) -> f a -> g (a, f b)-jacobianWith2 g f as = row <$> f vs where+jacobianWith' :: (Traversable f, Functor g, Num a) => (a -> a -> b) -> (forall s. Mode s => f (AD s a) -> g (AD s a)) -> f a -> g (a, f b)+jacobianWith' g f as = row <$> f vs where     (vs, bds) = bind as     row a = (primal a, unbindWith g vs (partialArray bds a))-{-# INLINE jacobianWith2 #-}--diffUU :: Num a => (forall s. Mode s => AD s a -> AD s a) -> a -> a-diffUU f a = derivative $ f (var a 0)-{-# INLINE diffUU #-}+{-# INLINE jacobianWith' #-} -diffUF :: (Functor f, Num a) => (forall s. Mode s => AD s a -> f (AD s a)) -> a -> f a-diffUF f a = derivative <$> f (var a 0)-{-# INLINE diffUF #-}+diff :: Num a => (forall s. Mode s => AD s a -> AD s a) -> a -> a+diff f a = derivative $ f (var a 0)+{-# INLINE diff #-} --- | The 'diff2UU' function calculates the value and derivative, as a+-- | The 'd'' function calculates the value and derivative, as a -- pair, of a scalar-to-scalar function.-diff2UU :: Num a => (forall s. Mode s => AD s a -> AD s a) -> a -> (a, a)-diff2UU f a = derivative2 $ f (var a 0)-{-# INLINE diff2UU #-}+diff' :: Num a => (forall s. Mode s => AD s a -> AD s a) -> a -> (a, a)+diff' f a = derivative' $ f (var a 0)+{-# INLINE diff' #-} -diff2UF :: (Functor f, Num a) => (forall s. Mode s => AD s a -> f (AD s a)) -> a -> f (a, a)-diff2UF f a = derivative2 <$> f (var a 0)-{-# INLINE diff2UF #-}+diffF :: (Functor f, Num a) => (forall s. Mode s => AD s a -> f (AD s a)) -> a -> f a+diffF f a = derivative <$> f (var a 0)+{-# INLINE diffF #-} -diffFU :: (Traversable f, Num a) => (forall s. Mode s => f (AD s a) -> AD s a) -> f a -> f a-diffFU f as = unbind vs $ partialArray bds (f vs)-    where (vs, bds) = bind as-{-# INLINE diffFU #-}+diffF' :: (Functor f, Num a) => (forall s. Mode s => AD s a -> f (AD s a)) -> a -> f (a, a)+diffF' f a = derivative' <$> f (var a 0)+{-# INLINE diffF' #-} -diff2FU :: (Traversable f, Num a) => (forall s. Mode s => f (AD s a) -> AD s a) -> f a -> (a, f a)-diff2FU f as = (primal result, unbind vs $ partialArray bds result)-    where (vs, bds) = bind as-          result = f vs-{-# INLINE diff2FU #-}+-- * Monadic Combinators --- | 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-{-# INLINE diff #-}+diffM :: (Monad m, Num a) => (forall s. Mode s => AD s a -> m (AD s a)) -> a -> m a+diffM f a = liftM derivative $ f (var a 0)+{-# INLINE diffM #-} --- | The 'diff2' function is a synonym for 'diff2UU'.-diff2 :: Num a => (forall s. Mode s => AD s a -> AD s a) -> a -> (a, a)-diff2 = diff2UU-{-# INLINE diff2 #-}+diffM' :: (Monad m, Num a) => (forall s. Mode s => AD s a -> m (AD s a)) -> a -> m (a, a)+diffM' f a = liftM derivative' $ f (var a 0)+{-# INLINE diffM' #-}++gradM :: (Traversable f, Monad m, Num a) => (forall s. Mode s => f (AD s a) -> m (AD s a)) -> f a -> m (f a)+gradM f = unwrapMonad . jacobian (WrapMonad . f)+{-# INLINE gradM #-}++gradM' :: (Traversable f, Monad m, Num a) => (forall s. Mode s => f (AD s a) -> m (AD s a)) -> f a -> m (a, f a)+gradM' f = unwrapMonad . jacobian' (WrapMonad . f)+{-# INLINE gradM' #-}++gradWithM :: (Traversable f, Monad m, Num a) => (a -> a -> b) -> (forall s. Mode s => f (AD s a) -> m (AD s a)) -> f a -> m (f b)+gradWithM g f = unwrapMonad . jacobianWith g (WrapMonad . f)++gradWithM' :: (Traversable f, Monad m, Num a) => (a -> a -> b) -> (forall s. Mode s => f (AD s a) -> m (AD s a)) -> f a -> m (a, f b)+gradWithM' g f = unwrapMonad . jacobianWith' g (WrapMonad . f) 
Numeric/AD/Tower.hs view
@@ -15,54 +15,56 @@ module Numeric.AD.Tower     (     -- * Taylor Series-      taylor, taylor0-    , maclaurin, maclaurin0+      taylor+    , taylor0+    -- * Maclaurin Series+    , maclaurin+    , maclaurin0     -- * Derivatives-    , diffUU-    , diff2UU-    , diffsUU-    , diffs0UU-    , diffsUF-    , diffs0UF-    -- * Synonyms-    , diffs, diffs0-    , diff, diff2+    , diff+    , diff'+    , diffs+    , diffs0+    , diffsF+    , diffs0F+    -- * Monadic Combinators+    , diffsM+    , diffs0M     -- * Exposed Types     , Mode(..)     , AD(..)     ) where --- TODO: argminNaiveGradient-+import Control.Monad (liftM) import Control.Applicative ((<$>)) import Numeric.AD.Classes import Numeric.AD.Internal 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-{-# INLINE diffsUU #-}--diffs0UU :: Num a => (forall s. Mode s => AD s a -> AD s a) -> a -> [a]-diffs0UU f a = zeroPad (diffsUU f a)-{-# INLINE diffs0UU #-}--diffs0UF :: (Functor f, Num a) => (forall s. Mode s => AD s a -> f (AD s a)) -> a -> f [a]-diffs0UF f a = (zeroPad . getADTower) <$> apply f a-{-# INLINE diffs0UF #-}--diffsUF :: (Functor f, Num a) => (forall s. Mode s => AD s a -> f (AD s a)) -> a -> f [a]-diffsUF f a = getADTower <$> apply f a-{-# INLINE diffsUF #-}- diffs :: Num a => (forall s. Mode s => AD s a -> AD s a) -> a -> [a]-diffs = diffsUU+diffs f a = getADTower $ apply f a {-# INLINE diffs #-}  diffs0 :: Num a => (forall s. Mode s => AD s a -> AD s a) -> a -> [a]-diffs0 = diffs0UU+diffs0 f a = zeroPad (diffs f a) {-# INLINE diffs0 #-} +diffsF :: (Functor f, Num a) => (forall s. Mode s => AD s a -> f (AD s a)) -> a -> f [a]+diffsF f a = getADTower <$> apply f a+{-# INLINE diffsF #-}++diffs0F :: (Functor f, Num a) => (forall s. Mode s => AD s a -> f (AD s a)) -> a -> f [a]+diffs0F f a = (zeroPad . getADTower) <$> apply f a+{-# INLINE diffs0F #-}++diffsM :: (Monad m, Num a) => (forall s. Mode s => AD s a -> m (AD s a)) -> a -> m [a]+diffsM f a = getADTower `liftM` apply f a+{-# INLINE diffsM #-}++diffs0M :: (Monad m, Num a) => (forall s. Mode s => AD s a -> m (AD s a)) -> a -> m [a]+diffs0M f a = (zeroPad . getADTower) `liftM` apply f a+{-# INLINE diffs0M #-}+ taylor :: Fractional a => (forall s. Mode s => AD s a -> AD s a) -> a -> a -> [a] taylor f x dx = go 1 1 (diffs f x)     where@@ -81,18 +83,11 @@ 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-{-# 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-{-# INLINE diff2UU #-}- diff :: Num a => (forall s. Mode s => AD s a -> AD s a) -> a -> a-diff = diffUU+diff f a = d $ diffs f a {-# INLINE diff #-} -diff2 :: Num a => (forall s. Mode s => AD s a -> AD s a) -> a -> (a, a)-diff2 = diff2UU-{-# INLINE diff2 #-}+diff' :: Num a => (forall s. Mode s => AD s a -> AD s a) -> a -> (a, a)+diff' f a = d' $ diffs f a+{-# INLINE diff' #-}+
ad.cabal view
@@ -1,5 +1,5 @@ Name:         ad-Version:      0.15+Version:      0.17 License:      BSD3 License-File: LICENSE Copyright:    Edward Kmett 2010