-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Automatic Differentiation -- @package ad @version 4.2.4 module Numeric.AD.Jet -- | A Jet is a tower of all (higher order) partial derivatives of a -- function -- -- At each step, a Jet f is wrapped in another layer -- worth of f. -- --
-- a :- f a :- f (f a) :- f (f (f a)) :- ... --data Jet f a (:-) :: a -> Jet f (f a) -> Jet f a -- | Take the head of a Jet. headJet :: Jet f a -> a -- | Take the tail of a Jet. tailJet :: Jet f a -> Jet f (f a) -- | Construct a Jet by unzipping the layers of a Cofree -- Comonad. jet :: Functor f => Cofree f a -> Jet f a instance Typeable Jet instance Traversable f => Traversable (Jet f) instance Foldable f => Foldable (Jet f) instance Functor f => Functor (Jet f) instance (Functor f, Show (f Showable), Show a) => Show (Jet f a) instance Show Showable module Numeric.AD.Mode class (Num t, Num (Scalar t)) => Mode t where type family Scalar t isKnownConstant _ = False isKnownZero _ = False a *^ b = auto a * b a ^* b = a * auto b a ^/ b = a ^* recip b zero = auto 0 isKnownConstant :: Mode t => t -> Bool isKnownZero :: Mode t => t -> Bool auto :: Mode t => Scalar t -> t (*^) :: Mode t => Scalar t -> t -> t (^*) :: Mode t => t -> Scalar t -> t (^/) :: (Mode t, Fractional (Scalar t)) => t -> Scalar t -> t zero :: Mode t => t instance Integral a => Mode (Ratio a) instance RealFloat a => Mode (Complex a) instance Mode Word64 instance Mode Word32 instance Mode Word16 instance Mode Word8 instance Mode Word instance Mode Natural instance Mode Int64 instance Mode Int32 instance Mode Int16 instance Mode Int8 instance Mode Integer instance Mode Int instance Mode Float instance Mode Double module Numeric.AD.Internal.Identity newtype Id a Id :: a -> Id a runId :: Id a -> a probe :: a -> Id a unprobe :: Id a -> a probed :: Functor f => f a -> f (Id a) unprobed :: Functor f => f (Id a) -> f a instance Typeable Id instance Eq a => Eq (Id a) instance Ord a => Ord (Id a) instance Show a => Show (Id a) instance Enum a => Enum (Id a) instance Bounded a => Bounded (Id a) instance Num a => Num (Id a) instance Real a => Real (Id a) instance Fractional a => Fractional (Id a) instance Floating a => Floating (Id a) instance RealFrac a => RealFrac (Id a) instance RealFloat a => RealFloat (Id a) instance Monoid a => Monoid (Id a) instance Data a => Data (Id a) instance Erf a => Erf (Id a) instance InvErf a => InvErf (Id a) instance Num a => Mode (Id a) module Numeric.AD.Jacobian -- | Jacobian is useful for defining new AD primitives in a fairly -- generic way. class (Mode t, Mode (D t), Num (D t)) => Jacobian t where type family D t :: * unary :: Jacobian t => (Scalar t -> Scalar t) -> D t -> t -> t lift1 :: Jacobian t => (Scalar t -> Scalar t) -> (D t -> D t) -> t -> t lift1_ :: Jacobian t => (Scalar t -> Scalar t) -> (D t -> D t -> D t) -> t -> t binary :: Jacobian t => (Scalar t -> Scalar t -> Scalar t) -> D t -> D t -> t -> t -> t lift2 :: Jacobian t => (Scalar t -> Scalar t -> Scalar t) -> (D t -> D t -> (D t, D t)) -> t -> t -> t lift2_ :: Jacobian t => (Scalar t -> Scalar t -> Scalar t) -> (D t -> D t -> D t -> (D t, D t)) -> t -> t -> t module Numeric.AD.Internal.Tower -- | Tower is an AD Mode that calculates a tangent tower by -- forward AD, and provides fast diffsUU, diffsUF newtype Tower a Tower :: [a] -> Tower a getTower :: Tower a -> [a] zeroPad :: Num a => [a] -> [a] zeroPadF :: (Functor f, Num a) => [f a] -> [f a] transposePadF :: (Foldable f, Functor f) => a -> f [a] -> [f a] d :: Num a => [a] -> a d' :: Num a => [a] -> (a, a) withD :: (a, a) -> Tower a tangents :: Tower a -> Tower a bundle :: a -> Tower a -> Tower a apply :: Num a => (Tower a -> b) -> a -> b getADTower :: Tower a -> [a] tower :: [a] -> Tower a instance Typeable Tower instance Data a => Data (Tower a) instance InvErf a => InvErf (Tower a) instance Erf a => Erf (Tower a) instance RealFrac a => RealFrac (Tower a) instance RealFloat a => RealFloat (Tower a) instance Real a => Real (Tower a) instance (Num a, Enum a) => Enum (Tower a) instance Floating a => Floating (Tower a) instance Fractional a => Fractional (Tower a) instance Num a => Num (Tower a) instance (Num a, Bounded a) => Bounded (Tower a) instance (Num a, Ord a) => Ord (Tower a) instance (Num a, Eq a) => Eq (Tower a) instance Num a => Jacobian (Tower a) instance Num a => Mode (Tower a) instance Show a => Show (Tower a) -- | Dense Forward AD. Useful when the result involves the majority of the -- input elements. Do not use for hessian and beyond, since they -- only contain a small number of unique nth derivatives -- -- (n + k - 1) choose k for functions of k -- inputs rather than the k^n that would be generated by using -- Dense, not to mention the redundant intermediate derivatives -- that would be calculated over and over during that process! -- -- Assumes all instances of f have the same number of elements. -- -- NB: We don't need the full power of Traversable here, we could -- get by with a notion of zippable that can plug in 0's for the missing -- entries. This might allow for gradients where f has -- exponentials like ((->) a) module Numeric.AD.Internal.Dense data Dense f a Lift :: !a -> Dense f a Dense :: !a -> (f a) -> Dense f a Zero :: Dense f a ds :: f a -> Dense f a -> f a ds' :: Num a => f a -> Dense f a -> (a, f a) vars :: (Traversable f, Num a) => f a -> f (Dense f a) apply :: (Traversable f, Num a) => (f (Dense f a) -> b) -> f a -> b instance (Traversable f, InvErf a) => InvErf (Dense f a) instance (Traversable f, Erf a) => Erf (Dense f a) instance (Traversable f, RealFrac a) => RealFrac (Dense f a) instance (Traversable f, RealFloat a) => RealFloat (Dense f a) instance (Traversable f, Real a) => Real (Dense f a) instance (Traversable f, Num a, Enum a) => Enum (Dense f a) instance (Traversable f, Floating a) => Floating (Dense f a) instance (Traversable f, Fractional a) => Fractional (Dense f a) instance (Traversable f, Num a) => Num (Dense f a) instance (Traversable f, Num a, Bounded a) => Bounded (Dense f a) instance (Traversable f, Num a, Ord a) => Ord (Dense f a) instance (Traversable f, Num a, Eq a) => Eq (Dense f a) instance (Traversable f, Num a) => Jacobian (Dense f a) instance (Num a, Traversable f) => Mode (Dense f a) instance Show a => Show (Dense f a) module Numeric.AD.Internal.Forward.Double data ForwardDouble ForwardDouble :: {-# UNPACK #-} !Double -> {-# UNPACK #-} !Double -> ForwardDouble primal :: ForwardDouble -> {-# UNPACK #-} !Double tangent :: ForwardDouble -> {-# UNPACK #-} !Double bundle :: Double -> Double -> ForwardDouble unbundle :: ForwardDouble -> (Double, Double) apply :: (ForwardDouble -> b) -> Double -> b bind :: Traversable f => (f ForwardDouble -> b) -> f Double -> f b bind' :: Traversable f => (f ForwardDouble -> b) -> f Double -> (b, f b) bindWith :: Traversable f => (Double -> b -> c) -> (f ForwardDouble -> b) -> f Double -> f c bindWith' :: Traversable f => (Double -> b -> c) -> (f ForwardDouble -> b) -> f Double -> (b, f c) transposeWith :: (Functor f, Foldable f, Traversable g) => (b -> f a -> c) -> f (g a) -> g b -> g c instance Read ForwardDouble instance Show ForwardDouble instance InvErf ForwardDouble instance Erf ForwardDouble instance RealFrac ForwardDouble instance RealFloat ForwardDouble instance Real ForwardDouble instance Enum ForwardDouble instance Floating ForwardDouble instance Fractional ForwardDouble instance Num ForwardDouble instance Ord ForwardDouble instance Eq ForwardDouble instance Jacobian ForwardDouble instance Mode ForwardDouble module Numeric.AD.Internal.Or -- | The choice between two AD modes is an AD mode in its own right data Or s a b L :: a -> Or F a b R :: b -> Or T a b data F data T runL :: Or F a b -> a runR :: Or T a b -> b class Chosen s choose :: Chosen s => a -> b -> Or s a b chosen :: (a -> r) -> (b -> r) -> Or s a b -> r unary :: (a -> a) -> (b -> b) -> Or s a b -> Or s a b binary :: (a -> a -> a) -> (b -> b -> b) -> Or s a b -> Or s a b -> Or s a b instance Typeable Or instance (Mode a, Mode b, Chosen s, Scalar a ~ Scalar b) => Mode (Or s a b) instance (RealFloat a, RealFloat b, Chosen s) => RealFloat (Or s a b) instance (InvErf a, InvErf b, Chosen s) => InvErf (Or s a b) instance (Erf a, Erf b, Chosen s) => Erf (Or s a b) instance (Floating a, Floating b, Chosen s) => Floating (Or s a b) instance (RealFrac a, RealFrac b, Chosen s) => RealFrac (Or s a b) instance (Fractional a, Fractional b, Chosen s) => Fractional (Or s a b) instance (Real a, Real b, Chosen s) => Real (Or s a b) instance (Num a, Num b, Chosen s) => Num (Or s a b) instance (Bounded a, Bounded b, Chosen s) => Bounded (Or s a b) instance (Enum a, Enum b, Chosen s) => Enum (Or s a b) instance (Ord a, Ord b) => Ord (Or s a b) instance (Eq a, Eq b) => Eq (Or s a b) instance Chosen T instance Chosen F module Numeric.AD.Rank1.Forward.Double data ForwardDouble -- | Compute the gradient of a function using forward mode AD. -- -- Note, this performs O(n) worse than grad for n -- inputs, in exchange for better space utilization. grad :: Traversable f => (f ForwardDouble -> ForwardDouble) -> f Double -> f Double -- | Compute the gradient and answer to a function using forward mode AD. -- -- Note, this performs O(n) worse than grad' for n -- inputs, in exchange for better space utilization. grad' :: Traversable f => (f ForwardDouble -> ForwardDouble) -> f Double -> (Double, f Double) -- | Compute the gradient of a function using forward mode AD and combine -- the result with the input using a user-specified function. -- -- Note, this performs O(n) worse than gradWith for -- n inputs, in exchange for better space utilization. gradWith :: Traversable f => (Double -> Double -> b) -> (f ForwardDouble -> ForwardDouble) -> f Double -> f b -- | Compute the gradient of a function using forward mode AD and the -- answer, and combine the result with the input using a user-specified -- function. -- -- Note, this performs O(n) worse than gradWith' for -- n inputs, in exchange for better space utilization. -- --
-- >>> gradWith' (,) sum [0..4] -- (10.0,[(0.0,1.0),(1.0,1.0),(2.0,1.0),(3.0,1.0),(4.0,1.0)]) --gradWith' :: Traversable f => (Double -> Double -> b) -> (f ForwardDouble -> ForwardDouble) -> f Double -> (Double, f b) -- | Compute the Jacobian using Forward mode AD. This -- must transpose the result, so jacobianT is faster and allows -- more result types. -- --
-- >>> jacobian (\[x,y] -> [y,x,x+y,x*y,exp x * sin y]) [pi,1] -- [[0.0,1.0],[1.0,0.0],[1.0,1.0],[1.0,3.141592653589793],[19.472221418841606,12.502969588876512]] --jacobian :: (Traversable f, Traversable g) => (f ForwardDouble -> g ForwardDouble) -> f Double -> g (f Double) -- | Compute the Jacobian using Forward mode AD along -- with the actual answer. jacobian' :: (Traversable f, Traversable g) => (f ForwardDouble -> g ForwardDouble) -> f Double -> g (Double, f Double) -- | Compute the Jacobian using Forward mode AD and -- combine the output with the input. This must transpose the result, so -- jacobianWithT is faster, and allows more result types. jacobianWith :: (Traversable f, Traversable g) => (Double -> Double -> b) -> (f ForwardDouble -> g ForwardDouble) -> f Double -> g (f b) -- | Compute the Jacobian using Forward mode AD combined -- with the input using a user specified function, along with the actual -- answer. jacobianWith' :: (Traversable f, Traversable g) => (Double -> Double -> b) -> (f ForwardDouble -> g ForwardDouble) -> f Double -> g (Double, f b) -- | A fast, simple, transposed Jacobian computed with forward-mode AD. jacobianT :: (Traversable f, Functor g) => (f ForwardDouble -> g ForwardDouble) -> f Double -> f (g Double) -- | A fast, simple, transposed Jacobian computed with Forward -- mode AD that combines the output with the input. jacobianWithT :: (Traversable f, Functor g) => (Double -> Double -> b) -> (f ForwardDouble -> g ForwardDouble) -> f Double -> f (g b) -- | The diff function calculates the first derivative of a -- scalar-to-scalar function by forward-mode AD -- --
-- >>> diff sin 0 -- 1.0 --diff :: (ForwardDouble -> ForwardDouble) -> Double -> Double -- | The diff' function calculates the result and first derivative -- of scalar-to-scalar function by Forward mode AD -- --
-- diff' sin == sin &&& cos -- diff' f = f &&& d f ---- --
-- >>> diff' sin 0 -- (0.0,1.0) ---- --
-- >>> diff' exp 0 -- (1.0,1.0) --diff' :: (ForwardDouble -> ForwardDouble) -> Double -> (Double, Double) -- | The diffF function calculates the first derivatives of -- scalar-to-nonscalar function by Forward mode AD -- --
-- >>> diffF (\a -> [sin a, cos a]) 0 -- [1.0,-0.0] --diffF :: Functor f => (ForwardDouble -> f ForwardDouble) -> Double -> f Double -- | The diffF' function calculates the result and first derivatives -- of a scalar-to-non-scalar function by Forward mode -- AD -- --
-- >>> diffF' (\a -> [sin a, cos a]) 0 -- [(0.0,1.0),(1.0,-0.0)] --diffF' :: Functor f => (ForwardDouble -> f ForwardDouble) -> Double -> f (Double, Double) -- | Compute the directional derivative of a function given a zipped up -- Functor of the input values and their derivatives du :: Functor f => (f ForwardDouble -> ForwardDouble) -> f (Double, Double) -> Double -- | Compute the answer and directional derivative of a function given a -- zipped up Functor of the input values and their derivatives du' :: Functor f => (f ForwardDouble -> ForwardDouble) -> f (Double, Double) -> (Double, Double) -- | Compute a vector of directional derivatives for a function given a -- zipped up Functor of the input values and their derivatives. duF :: (Functor f, Functor g) => (f ForwardDouble -> g ForwardDouble) -> f (Double, Double) -> g Double -- | Compute a vector of answers and directional derivatives for a function -- given a zipped up Functor of the input values and their -- derivatives. duF' :: (Functor f, Functor g) => (f ForwardDouble -> g ForwardDouble) -> f (Double, Double) -> g (Double, Double) -- | Higher order derivatives via a "dual number tower". module Numeric.AD.Rank1.Tower -- | Tower is an AD Mode that calculates a tangent tower by -- forward AD, and provides fast diffsUU, diffsUF data Tower a -- | Embed a constant auto :: Mode t => Scalar t -> t -- | taylor f x compute the Taylor series of f around -- x. taylor :: Fractional a => (Tower a -> Tower a) -> a -> a -> [a] -- | taylor0 f x compute the Taylor series of f around -- x, zero-padded. taylor0 :: Fractional a => (Tower a -> Tower a) -> a -> a -> [a] -- | maclaurin f compute the Maclaurin series of f maclaurin :: Fractional a => (Tower a -> Tower a) -> a -> [a] -- | maclaurin f compute the Maclaurin series of f, -- zero-padded maclaurin0 :: Fractional a => (Tower a -> Tower a) -> a -> [a] -- | Compute the first derivative of a function (a -> a) diff :: Num a => (Tower a -> Tower a) -> a -> a -- | Compute the answer and first derivative of a function (a -> -- a) diff' :: Num a => (Tower a -> Tower a) -> a -> (a, a) -- | Compute the answer and all derivatives of a function (a -> -- a) diffs :: Num a => (Tower a -> Tower a) -> a -> [a] -- | Compute the zero-padded derivatives of a function (a -> a) diffs0 :: Num a => (Tower a -> Tower a) -> a -> [a] -- | Compute the answer and all derivatives of a function (a -> f -- a) diffsF :: (Functor f, Num a) => (Tower a -> f (Tower a)) -> a -> f [a] -- | Compute the zero-padded derivatives of a function (a -> f -- a) diffs0F :: (Functor f, Num a) => (Tower a -> f (Tower a)) -> a -> f [a] -- | Compute a directional derivative of a function (f a -> a) du :: (Functor f, Num a) => (f (Tower a) -> Tower a) -> f (a, a) -> a -- | Compute the answer and a directional derivative of a function (f a -- -> a) du' :: (Functor f, Num a) => (f (Tower a) -> Tower a) -> f (a, a) -> (a, a) -- | Given a function (f a -> a), and a tower of derivatives, -- compute the corresponding directional derivatives. dus :: (Functor f, Num a) => (f (Tower a) -> Tower a) -> f [a] -> [a] -- | Given a function (f a -> a), and a tower of derivatives, -- compute the corresponding directional derivatives, zero-padded dus0 :: (Functor f, Num a) => (f (Tower a) -> Tower a) -> f [a] -> [a] -- | Compute a directional derivative of a function (f a -> g -- a) duF :: (Functor f, Functor g, Num a) => (f (Tower a) -> g (Tower a)) -> f (a, a) -> g a -- | Compute the answer and a directional derivative of a function (f a -- -> g a) duF' :: (Functor f, Functor g, Num a) => (f (Tower a) -> g (Tower a)) -> f (a, a) -> g (a, a) -- | Given a function (f a -> g a), and a tower of derivatives, -- compute the corresponding directional derivatives dusF :: (Functor f, Functor g, Num a) => (f (Tower a) -> g (Tower a)) -> f [a] -> g [a] -- | Given a function (f a -> g a), and a tower of derivatives, -- compute the corresponding directional derivatives, zero-padded dus0F :: (Functor f, Functor g, Num a) => (f (Tower a) -> g (Tower a)) -> f [a] -> g [a] module Numeric.AD.Internal.Type newtype AD s a AD :: a -> AD s a runAD :: AD s a -> a instance Typeable AD instance Eq a => Eq (AD s a) instance Ord a => Ord (AD s a) instance Show a => Show (AD s a) instance Read a => Read (AD s a) instance Bounded a => Bounded (AD s a) instance Num a => Num (AD s a) instance Real a => Real (AD s a) instance Fractional a => Fractional (AD s a) instance Floating a => Floating (AD s a) instance Enum a => Enum (AD s a) instance RealFrac a => RealFrac (AD s a) instance RealFloat a => RealFloat (AD s a) instance Erf a => Erf (AD s a) instance InvErf a => InvErf (AD s a) instance Mode a => Mode (AD s a) -- | Higher order derivatives via a "dual number tower". module Numeric.AD.Mode.Tower data AD s a -- | Tower is an AD Mode that calculates a tangent tower by -- forward AD, and provides fast diffsUU, diffsUF data Tower a -- | Embed a constant auto :: Mode t => Scalar t -> t taylor :: Fractional a => (forall s. AD s (Tower a) -> AD s (Tower a)) -> a -> a -> [a] taylor0 :: Fractional a => (forall s. AD s (Tower a) -> AD s (Tower a)) -> a -> a -> [a] maclaurin :: Fractional a => (forall s. AD s (Tower a) -> AD s (Tower a)) -> a -> [a] maclaurin0 :: Fractional a => (forall s. AD s (Tower a) -> AD s (Tower a)) -> a -> [a] diff :: Num a => (forall s. AD s (Tower a) -> AD s (Tower a)) -> a -> a diff' :: Num a => (forall s. AD s (Tower a) -> AD s (Tower a)) -> a -> (a, a) diffs :: Num a => (forall s. AD s (Tower a) -> AD s (Tower a)) -> a -> [a] diffs0 :: Num a => (forall s. AD s (Tower a) -> AD s (Tower a)) -> a -> [a] diffsF :: (Functor f, Num a) => (forall s. AD s (Tower a) -> f (AD s (Tower a))) -> a -> f [a] diffs0F :: (Functor f, Num a) => (forall s. AD s (Tower a) -> f (AD s (Tower a))) -> a -> f [a] du :: (Functor f, Num a) => (forall s. f (AD s (Tower a)) -> AD s (Tower a)) -> f (a, a) -> a du' :: (Functor f, Num a) => (forall s. f (AD s (Tower a)) -> AD s (Tower a)) -> f (a, a) -> (a, a) dus :: (Functor f, Num a) => (forall s. f (AD s (Tower a)) -> AD s (Tower a)) -> f [a] -> [a] dus0 :: (Functor f, Num a) => (forall s. f (AD s (Tower a)) -> AD s (Tower a)) -> f [a] -> [a] duF :: (Functor f, Functor g, Num a) => (forall s. f (AD s (Tower a)) -> g (AD s (Tower a))) -> f (a, a) -> g a duF' :: (Functor f, Functor g, Num a) => (forall s. f (AD s (Tower a)) -> g (AD s (Tower a))) -> f (a, a) -> g (a, a) dusF :: (Functor f, Functor g, Num a) => (forall s. f (AD s (Tower a)) -> g (AD s (Tower a))) -> f [a] -> g [a] dus0F :: (Functor f, Functor g, Num a) => (forall s. f (AD s (Tower a)) -> g (AD s (Tower a))) -> f [a] -> g [a] -- | Forward Mode AD specialized to Double. This enables the entire -- structure to be unboxed. module Numeric.AD.Mode.Forward.Double data AD s a data ForwardDouble -- | Compute the gradient of a function using forward mode AD. -- -- Note, this performs O(n) worse than grad for n -- inputs, in exchange for better space utilization. grad :: Traversable f => (forall s. f (AD s ForwardDouble) -> AD s ForwardDouble) -> f Double -> f Double -- | Compute the gradient and answer to a function using forward mode AD. -- -- Note, this performs O(n) worse than grad' for n -- inputs, in exchange for better space utilization. grad' :: Traversable f => (forall s. f (AD s ForwardDouble) -> AD s ForwardDouble) -> f Double -> (Double, f Double) -- | Compute the gradient of a function using forward mode AD and combine -- the result with the input using a user-specified function. -- -- Note, this performs O(n) worse than gradWith for -- n inputs, in exchange for better space utilization. gradWith :: Traversable f => (Double -> Double -> b) -> (forall s. f (AD s ForwardDouble) -> AD s ForwardDouble) -> f Double -> f b -- | Compute the gradient of a function using forward mode AD and the -- answer, and combine the result with the input using a user-specified -- function. -- -- Note, this performs O(n) worse than gradWith' for -- n inputs, in exchange for better space utilization. -- --
-- >>> gradWith' (,) sum [0..4] -- (10.0,[(0.0,1.0),(1.0,1.0),(2.0,1.0),(3.0,1.0),(4.0,1.0)]) --gradWith' :: Traversable f => (Double -> Double -> b) -> (forall s. f (AD s ForwardDouble) -> AD s ForwardDouble) -> f Double -> (Double, f b) -- | Compute the Jacobian using Forward mode AD. This must -- transpose the result, so jacobianT is faster and allows more -- result types. -- --
-- >>> jacobian (\[x,y] -> [y,x,x+y,x*y,exp x * sin y]) [pi,1] -- [[0.0,1.0],[1.0,0.0],[1.0,1.0],[1.0,3.141592653589793],[19.472221418841606,12.502969588876512]] --jacobian :: (Traversable f, Traversable g) => (forall s. f (AD s ForwardDouble) -> g (AD s ForwardDouble)) -> f Double -> g (f Double) -- | Compute the Jacobian using Forward mode AD along with -- the actual answer. jacobian' :: (Traversable f, Traversable g) => (forall s. f (AD s ForwardDouble) -> g (AD s ForwardDouble)) -> f Double -> g (Double, f Double) -- | Compute the Jacobian using Forward mode AD and combine -- the output with the input. This must transpose the result, so -- jacobianWithT is faster, and allows more result types. jacobianWith :: (Traversable f, Traversable g) => (Double -> Double -> b) -> (forall s. f (AD s ForwardDouble) -> g (AD s ForwardDouble)) -> f Double -> g (f b) -- | Compute the Jacobian using Forward mode AD combined -- with the input using a user specified function, along with the actual -- answer. jacobianWith' :: (Traversable f, Traversable g) => (Double -> Double -> b) -> (forall s. f (AD s ForwardDouble) -> g (AD s ForwardDouble)) -> f Double -> g (Double, f b) -- | A fast, simple, transposed Jacobian computed with forward-mode AD. jacobianT :: (Traversable f, Functor g) => (forall s. f (AD s ForwardDouble) -> g (AD s ForwardDouble)) -> f Double -> f (g Double) -- | A fast, simple, transposed Jacobian computed with Forward -- mode AD that combines the output with the input. jacobianWithT :: (Traversable f, Functor g) => (Double -> Double -> b) -> (forall s. f (AD s ForwardDouble) -> g (AD s ForwardDouble)) -> f Double -> f (g b) -- | The diff function calculates the first derivative of a -- scalar-to-scalar function by forward-mode AD -- --
-- >>> diff sin 0 -- 1.0 --diff :: (forall s. AD s ForwardDouble -> AD s ForwardDouble) -> Double -> Double -- | The diff' function calculates the result and first derivative -- of scalar-to-scalar function by Forward mode AD -- --
-- diff' sin == sin &&& cos -- diff' f = f &&& d f ---- --
-- >>> diff' sin 0 -- (0.0,1.0) ---- --
-- >>> diff' exp 0 -- (1.0,1.0) --diff' :: (forall s. AD s ForwardDouble -> AD s ForwardDouble) -> Double -> (Double, Double) -- | The diffF function calculates the first derivatives of -- scalar-to-nonscalar function by Forward mode AD -- --
-- >>> diffF (\a -> [sin a, cos a]) 0 -- [1.0,-0.0] --diffF :: Functor f => (forall s. AD s ForwardDouble -> f (AD s ForwardDouble)) -> Double -> f Double -- | The diffF' function calculates the result and first derivatives -- of a scalar-to-non-scalar function by Forward mode AD -- --
-- >>> diffF' (\a -> [sin a, cos a]) 0 -- [(0.0,1.0),(1.0,-0.0)] --diffF' :: Functor f => (forall s. AD s ForwardDouble -> f (AD s ForwardDouble)) -> Double -> f (Double, Double) -- | Compute the directional derivative of a function given a zipped up -- Functor of the input values and their derivatives du :: Functor f => (forall s. f (AD s ForwardDouble) -> AD s ForwardDouble) -> f (Double, Double) -> Double -- | Compute the answer and directional derivative of a function given a -- zipped up Functor of the input values and their derivatives du' :: Functor f => (forall s. f (AD s ForwardDouble) -> AD s ForwardDouble) -> f (Double, Double) -> (Double, Double) -- | Compute a vector of directional derivatives for a function given a -- zipped up Functor of the input values and their derivatives. duF :: (Functor f, Functor g) => (forall s. f (AD s ForwardDouble) -> g (AD s ForwardDouble)) -> f (Double, Double) -> g Double -- | Compute a vector of answers and directional derivatives for a function -- given a zipped up Functor of the input values and their -- derivatives. duF' :: (Functor f, Functor g) => (forall s. f (AD s ForwardDouble) -> g (AD s ForwardDouble)) -> f (Double, Double) -> g (Double, Double) -- | Unsafe and often partial combinators intended for internal usage. -- -- Handle with care. module Numeric.AD.Internal.Sparse newtype Index Index :: (IntMap Int) -> Index emptyIndex :: Index addToIndex :: Int -> Index -> Index indices :: Index -> [Int] -- | We only store partials in sorted order, so the map contained in a -- partial will only contain partials with equal or greater keys to that -- of the map in which it was found. This should be key for efficiently -- computing sparse hessians. there are only (n + k - 1) choose k -- distinct nth partial derivatives of a function with k inputs. data Sparse a Sparse :: !a -> (IntMap (Sparse a)) -> Sparse a Zero :: Sparse a apply :: (Traversable f, Num a) => (f (Sparse a) -> b) -> f a -> b vars :: (Traversable f, Num a) => f a -> f (Sparse a) d :: (Traversable f, Num a) => f b -> Sparse a -> f a d' :: (Traversable f, Num a) => f a -> Sparse a -> (a, f a) ds :: (Traversable f, Num a) => f b -> Sparse a -> Cofree f a skeleton :: Traversable f => f a -> f Int spartial :: Num a => [Int] -> Sparse a -> Maybe a partial :: Num a => [Int] -> Sparse a -> a vgrad :: Grad i o o' a => i -> o vgrad' :: Grad i o o' a => i -> o' vgrads :: Grads i o a => i -> o class Num a => Grad i o o' a | i -> a o o', o -> a i o', o' -> a i o pack :: Grad i o o' a => i -> [Sparse a] -> Sparse a unpack :: Grad i o o' a => ([a] -> [a]) -> o unpack' :: Grad i o o' a => ([a] -> (a, [a])) -> o' class Num a => Grads i o a | i -> a o, o -> a i packs :: Grads i o a => i -> [Sparse a] -> Sparse a unpacks :: Grads i o a => ([a] -> Cofree [] a) -> o instance Typeable Sparse instance Show a => Show (Sparse a) instance Data a => Data (Sparse a) instance Grads i o a => Grads (Sparse a -> i) (a -> o) a instance Num a => Grads (Sparse a) (Cofree [] a) a instance Grad i o o' a => Grad (Sparse a -> i) (a -> o) (a -> o') a instance Num a => Grad (Sparse a) [a] (a, [a]) a instance InvErf a => InvErf (Sparse a) instance Erf a => Erf (Sparse a) instance RealFrac a => RealFrac (Sparse a) instance RealFloat a => RealFloat (Sparse a) instance Real a => Real (Sparse a) instance (Num a, Enum a) => Enum (Sparse a) instance Floating a => Floating (Sparse a) instance Fractional a => Fractional (Sparse a) instance Num a => Num (Sparse a) instance (Num a, Bounded a) => Bounded (Sparse a) instance (Num a, Ord a) => Ord (Sparse a) instance (Num a, Eq a) => Eq (Sparse a) instance Num a => Jacobian (Sparse a) instance Num a => Mode (Sparse a) -- | Higher order derivatives via a "dual number tower". module Numeric.AD.Rank1.Sparse -- | We only store partials in sorted order, so the map contained in a -- partial will only contain partials with equal or greater keys to that -- of the map in which it was found. This should be key for efficiently -- computing sparse hessians. there are only (n + k - 1) choose k -- distinct nth partial derivatives of a function with k inputs. data Sparse a -- | Embed a constant auto :: Mode t => Scalar t -> t grad :: (Traversable f, Num a) => (f (Sparse a) -> Sparse a) -> f a -> f a grad' :: (Traversable f, Num a) => (f (Sparse a) -> Sparse a) -> f a -> (a, f a) gradWith :: (Traversable f, Num a) => (a -> a -> b) -> (f (Sparse a) -> Sparse a) -> f a -> f b gradWith' :: (Traversable f, Num a) => (a -> a -> b) -> (f (Sparse a) -> Sparse a) -> f a -> (a, f b) class Num a => Grad i o o' a | i -> a o o', o -> a i o', o' -> a i o vgrad :: Grad i o o' a => i -> o grads :: (Traversable f, Num a) => (f (Sparse a) -> Sparse a) -> f a -> Cofree f a class Num a => Grads i o a | i -> a o, o -> a i vgrads :: Grads i o a => i -> o jacobian :: (Traversable f, Functor g, Num a) => (f (Sparse a) -> g (Sparse a)) -> f a -> g (f a) jacobian' :: (Traversable f, Functor g, Num a) => (f (Sparse a) -> g (Sparse a)) -> f a -> g (a, f a) jacobianWith :: (Traversable f, Functor g, Num a) => (a -> a -> b) -> (f (Sparse a) -> g (Sparse a)) -> f a -> g (f b) jacobianWith' :: (Traversable f, Functor g, Num a) => (a -> a -> b) -> (f (Sparse a) -> g (Sparse a)) -> f a -> g (a, f b) jacobians :: (Traversable f, Functor g, Num a) => (f (Sparse a) -> g (Sparse a)) -> f a -> g (Cofree f a) hessian :: (Traversable f, Num a) => (f (Sparse a) -> Sparse a) -> f a -> f (f a) hessian' :: (Traversable f, Num a) => (f (Sparse a) -> Sparse a) -> f a -> (a, f (a, f a)) hessianF :: (Traversable f, Functor g, Num a) => (f (Sparse a) -> g (Sparse a)) -> f a -> g (f (f a)) hessianF' :: (Traversable f, Functor g, Num a) => (f (Sparse a) -> g (Sparse a)) -> f a -> g (a, f (a, f a)) -- | Higher order derivatives via a "dual number tower". module Numeric.AD.Mode.Sparse data AD s a -- | We only store partials in sorted order, so the map contained in a -- partial will only contain partials with equal or greater keys to that -- of the map in which it was found. This should be key for efficiently -- computing sparse hessians. there are only (n + k - 1) choose k -- distinct nth partial derivatives of a function with k inputs. data Sparse a -- | Embed a constant auto :: Mode t => Scalar t -> t grad :: (Traversable f, Num a) => (forall s. f (AD s (Sparse a)) -> AD s (Sparse a)) -> f a -> f a grad' :: (Traversable f, Num a) => (forall s. f (AD s (Sparse a)) -> AD s (Sparse a)) -> f a -> (a, f a) grads :: (Traversable f, Num a) => (forall s. f (AD s (Sparse a)) -> AD s (Sparse a)) -> f a -> Cofree f a gradWith :: (Traversable f, Num a) => (a -> a -> b) -> (forall s. f (AD s (Sparse a)) -> AD s (Sparse a)) -> f a -> f b gradWith' :: (Traversable f, Num a) => (a -> a -> b) -> (forall s. f (AD s (Sparse a)) -> AD s (Sparse a)) -> f a -> (a, f b) jacobian :: (Traversable f, Functor g, Num a) => (forall s. f (AD s (Sparse a)) -> g (AD s (Sparse a))) -> f a -> g (f a) jacobian' :: (Traversable f, Functor g, Num a) => (forall s. f (AD s (Sparse a)) -> g (AD s (Sparse a))) -> f a -> g (a, f a) jacobianWith :: (Traversable f, Functor g, Num a) => (a -> a -> b) -> (forall s. f (AD s (Sparse a)) -> g (AD s (Sparse a))) -> f a -> g (f b) jacobianWith' :: (Traversable f, Functor g, Num a) => (a -> a -> b) -> (forall s. f (AD s (Sparse a)) -> g (AD s (Sparse a))) -> f a -> g (a, f b) jacobians :: (Traversable f, Functor g, Num a) => (forall s. f (AD s (Sparse a)) -> g (AD s (Sparse a))) -> f a -> g (Cofree f a) hessian :: (Traversable f, Num a) => (forall s. f (AD s (Sparse a)) -> AD s (Sparse a)) -> f a -> f (f a) hessian' :: (Traversable f, Num a) => (forall s. f (AD s (Sparse a)) -> AD s (Sparse a)) -> f a -> (a, f (a, f a)) hessianF :: (Traversable f, Functor g, Num a) => (forall s. f (AD s (Sparse a)) -> g (AD s (Sparse a))) -> f a -> g (f (f a)) hessianF' :: (Traversable f, Functor g, Num a) => (forall s. f (AD s (Sparse a)) -> g (AD s (Sparse a))) -> f a -> g (a, f (a, f a)) -- | Reverse-Mode Automatic Differentiation using a single Wengert list (or -- "tape"). -- -- This version uses Data.Reflection to find and update the -- tape. -- -- This is asymptotically faster than using Kahn, which is -- forced to reify and topologically sort the graph, but it requires a -- fairly expensive rendezvous during construction when updated using -- multiple threads. module Numeric.AD.Internal.Reverse data Reverse s a Zero :: Reverse s a Lift :: a -> Reverse s a Reverse :: {-# UNPACK #-} !Int -> a -> Reverse s a newtype Tape Tape :: IORef Head -> Tape getTape :: Tape -> IORef Head data Head Head :: {-# UNPACK #-} !Int -> Cells -> Head data Cells Nil :: Cells Unary :: {-# UNPACK #-} !Int -> a -> Cells -> Cells Binary :: {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> a -> a -> Cells -> Cells -- | Construct a tape that starts with n variables. reifyTape :: Int -> (forall s. Reifies s Tape => Proxy s -> r) -> r -- | Extract the partials from the current chain for a given AD variable. partials :: (Reifies s Tape, Num a) => Reverse s a -> [a] -- | Return an Array of partials given bounds for the -- variable IDs. partialArrayOf :: (Reifies s Tape, Num a) => Proxy s -> (Int, Int) -> Reverse s a -> Array Int a -- | Return an IntMap of sparse partials partialMapOf :: (Reifies s Tape, Num a) => Proxy s -> Reverse s a -> IntMap a -- | Helper that extracts the derivative of a chain when the chain was -- constructed with 1 variable. derivativeOf :: (Reifies s Tape, Num a) => Proxy s -> Reverse s a -> a -- | Helper that extracts both the primal and derivative of a chain when -- the chain was constructed with 1 variable. derivativeOf' :: (Reifies s Tape, Num a) => Proxy s -> Reverse s a -> (a, a) bind :: Traversable f => f a -> (f (Reverse s a), (Int, Int)) unbind :: Functor f => f (Reverse s a) -> Array Int a -> f a unbindMap :: (Functor f, Num a) => f (Reverse s a) -> IntMap a -> f a unbindWith :: (Functor f, Num a) => (a -> b -> c) -> f (Reverse s a) -> Array Int b -> f c unbindMapWithDefault :: (Functor f, Num a) => b -> (a -> b -> c) -> f (Reverse s a) -> IntMap b -> f c var :: a -> Int -> Reverse s a varId :: Reverse s a -> Int primal :: Num a => Reverse s a -> a instance Typeable Reverse instance Show a => Show (Reverse s a) instance (Reifies s Tape, InvErf a) => InvErf (Reverse s a) instance (Reifies s Tape, Erf a) => Erf (Reverse s a) instance (Reifies s Tape, RealFrac a) => RealFrac (Reverse s a) instance (Reifies s Tape, RealFloat a) => RealFloat (Reverse s a) instance (Reifies s Tape, Real a) => Real (Reverse s a) instance (Reifies s Tape, Num a, Enum a) => Enum (Reverse s a) instance (Reifies s Tape, Floating a) => Floating (Reverse s a) instance (Reifies s Tape, Fractional a) => Fractional (Reverse s a) instance (Reifies s Tape, Num a) => Num (Reverse s a) instance (Reifies s Tape, Num a, Bounded a) => Bounded (Reverse s a) instance (Reifies s Tape, Num a, Ord a) => Ord (Reverse s a) instance (Reifies s Tape, Num a, Eq a) => Eq (Reverse s a) instance (Reifies s Tape, Num a) => Jacobian (Reverse s a) instance (Reifies s Tape, Num a) => Mode (Reverse s a) module Numeric.AD.Internal.On -- | The composition of two AD modes is an AD mode in its own right newtype On t On :: t -> On t off :: On t -> t instance Typeable On instance Eq t => Eq (On t) instance Enum t => Enum (On t) instance Ord t => Ord (On t) instance Bounded t => Bounded (On t) instance Num t => Num (On t) instance Real t => Real (On t) instance Fractional t => Fractional (On t) instance RealFrac t => RealFrac (On t) instance Floating t => Floating (On t) instance Erf t => Erf (On t) instance InvErf t => InvErf (On t) instance RealFloat t => RealFloat (On t) instance (Mode t, Mode (Scalar t)) => Mode (On t) -- | Reverse-mode automatic differentiation using Wengert lists and -- Data.Reflection module Numeric.AD.Mode.Reverse data Reverse s a -- | Embed a constant auto :: Mode t => Scalar t -> t -- | The grad function calculates the gradient of a -- non-scalar-to-scalar function with reverse-mode AD in a single pass. -- --
-- >>> grad (\[x,y,z] -> x*y+z) [1,2,3] -- [2,1,1] --grad :: (Traversable f, Num a) => (forall s. Reifies s Tape => f (Reverse s a) -> Reverse s a) -> f a -> f a -- | The grad' function calculates the result and gradient of a -- non-scalar-to-scalar function with reverse-mode AD in a single pass. -- --
-- >>> grad' (\[x,y,z] -> x*y+z) [1,2,3] -- (5,[2,1,1]) --grad' :: (Traversable f, Num a) => (forall s. Reifies s Tape => f (Reverse s a) -> Reverse s a) -> f a -> (a, f a) -- | 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) -- id == gradWith const --gradWith :: (Traversable f, Num a) => (a -> a -> b) -> (forall s. Reifies s Tape => f (Reverse s a) -> Reverse s a) -> f a -> f b -- | grad' g f calculates the result and 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) --gradWith' :: (Traversable f, Num a) => (a -> a -> b) -> (forall s. Reifies s Tape => f (Reverse s a) -> Reverse s a) -> f a -> (a, f b) -- | 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 (\[x,y] -> [y,x,x*y]) [2,1] -- [[0,1],[1,0],[1,2]] --jacobian :: (Traversable f, Functor g, Num a) => (forall s. Reifies s Tape => f (Reverse s a) -> g (Reverse s a)) -> f a -> g (f a) -- | 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 | An alias for gradF' -- --
-- >>> jacobian' (\[x,y] -> [y,x,x*y]) [2,1] -- [(1,[0,1]),(2,[1,0]),(2,[1,2])] --jacobian' :: (Traversable f, Functor g, Num a) => (forall s. Reifies s Tape => f (Reverse s a) -> g (Reverse s a)) -> f a -> g (a, f a) -- | '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) --jacobianWith :: (Traversable f, Functor g, Num a) => (a -> a -> b) -> (forall s. Reifies s Tape => f (Reverse s a) -> g (Reverse s a)) -> f a -> g (f b) -- | 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. -- --
-- jacobian' == jacobianWith' (_ dx -> dx) --jacobianWith' :: (Traversable f, Functor g, Num a) => (a -> a -> b) -> (forall s. Reifies s Tape => f (Reverse s a) -> g (Reverse s a)) -> f a -> g (a, f b) -- | Compute the hessian via the jacobian of the gradient. gradient is -- computed in reverse mode and then the jacobian is computed in reverse -- mode. -- -- However, since the grad f :: f a -> f a is square -- this is not as fast as using the forward-mode Jacobian of a reverse -- mode gradient provided by hessian. -- --
-- >>> hessian (\[x,y] -> x*y) [1,2] -- [[0,1],[1,0]] --hessian :: (Traversable f, Num a) => (forall s s'. (Reifies s Tape, Reifies s' Tape) => f (On (Reverse s (Reverse s' a))) -> (On (Reverse s (Reverse s' a)))) -> f a -> f (f a) -- | Compute the order 3 Hessian tensor on a non-scalar-to-non-scalar -- function via the reverse-mode Jacobian of the reverse-mode Jacobian of -- the function. -- -- Less efficient than hessianF. -- --
-- >>> hessianF (\[x,y] -> [x*y,x+y,exp x*cos y]) [1,2] -- [[[0.0,1.0],[1.0,0.0]],[[0.0,0.0],[0.0,0.0]],[[-1.1312043837568135,-2.4717266720048188],[-2.4717266720048188,1.1312043837568135]]] --hessianF :: (Traversable f, Functor g, Num a) => (forall s s'. (Reifies s Tape, Reifies s' Tape) => f (On (Reverse s (Reverse s' a))) -> g (On (Reverse s (Reverse s' a)))) -> f a -> g (f (f a)) -- | Compute the derivative of a function. -- --
-- >>> diff sin 0 -- 1.0 --diff :: Num a => (forall s. Reifies s Tape => Reverse s a -> Reverse s a) -> a -> a -- | The diff' function calculates the result and derivative, as a -- pair, of a scalar-to-scalar function. -- --
-- >>> diff' sin 0 -- (0.0,1.0) ---- --
-- >>> diff' exp 0 -- (1.0,1.0) --diff' :: Num a => (forall s. Reifies s Tape => Reverse s a -> Reverse s a) -> a -> (a, a) -- | Compute the derivatives of each result of a scalar-to-vector function -- with regards to its input. -- --
-- >>> diffF (\a -> [sin a, cos a]) 0 -- [1.0,0.0] --diffF :: (Functor f, Num a) => (forall s. Reifies s Tape => Reverse s a -> f (Reverse s a)) -> a -> f a -- | Compute the derivatives of each result of a scalar-to-vector function -- with regards to its input along with the answer. -- --
-- >>> diffF' (\a -> [sin a, cos a]) 0 -- [(0.0,1.0),(1.0,0.0)] --diffF' :: (Functor f, Num a) => (forall s. Reifies s Tape => Reverse s a -> f (Reverse s a)) -> a -> f (a, a) -- | This module provides reverse-mode Automatic Differentiation -- implementation using linear time topological sorting after the fact. -- -- For this form of reverse-mode AD we use 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. module Numeric.AD.Internal.Kahn -- | Kahn is a Mode using reverse-mode automatic -- differentiation that provides fast diffFU, diff2FU, -- grad, grad2 and a fast jacobian when you -- have a significantly smaller number of outputs than inputs. newtype Kahn a Kahn :: (Tape a (Kahn a)) -> Kahn a -- | A Tape records the information needed back propagate from the -- output to each input during reverse Mode AD. data Tape a t Zero :: Tape a t Lift :: !a -> Tape a t Var :: !a -> {-# UNPACK #-} !Int -> Tape a t Binary :: !a -> a -> a -> t -> t -> Tape a t Unary :: !a -> a -> t -> Tape a t -- | This returns a list of contributions to the partials. The variable ids -- returned in the list are likely not unique! partials :: Num a => Kahn a -> [(Int, a)] -- | Return an Array of partials given bounds for the -- variable IDs. partialArray :: Num a => (Int, Int) -> Kahn a -> Array Int a -- | Return an IntMap of sparse partials partialMap :: Num a => Kahn a -> IntMap a derivative :: Num a => Kahn a -> a derivative' :: Num a => Kahn a -> (a, a) vgrad :: Grad i o o' a => i -> o vgrad' :: Grad i o o' a => i -> o' class Num a => Grad i o o' a | i -> a o o', o -> a i o', o' -> a i o pack :: Grad i o o' a => i -> [Kahn a] -> Kahn a unpack :: Grad i o o' a => ([a] -> [a]) -> o unpack' :: Grad i o o' a => ([a] -> (a, [a])) -> o' bind :: Traversable f => f a -> (f (Kahn a), (Int, Int)) unbind :: Functor f => f (Kahn a) -> Array Int a -> f a unbindMap :: (Functor f, Num a) => f (Kahn a) -> IntMap a -> f a unbindWith :: (Functor f, Num a) => (a -> b -> c) -> f (Kahn a) -> Array Int b -> f c unbindMapWithDefault :: (Functor f, Num a) => b -> (a -> b -> c) -> f (Kahn a) -> IntMap b -> f c primal :: Num a => Kahn a -> a var :: a -> Int -> Kahn a varId :: Kahn a -> Int instance Typeable Tape instance Typeable Kahn instance (Show a, Show t) => Show (Tape a t) instance (Data a, Data t) => Data (Tape a t) instance Show a => Show (Kahn a) instance Grad i o o' a => Grad (Kahn a -> i) (a -> o) (a -> o') a instance Num a => Grad (Kahn a) [a] (a, [a]) a instance InvErf a => InvErf (Kahn a) instance Erf a => Erf (Kahn a) instance RealFrac a => RealFrac (Kahn a) instance RealFloat a => RealFloat (Kahn a) instance Real a => Real (Kahn a) instance (Num a, Enum a) => Enum (Kahn a) instance Floating a => Floating (Kahn a) instance Fractional a => Fractional (Kahn a) instance Num a => Num (Kahn a) instance (Num a, Bounded a) => Bounded (Kahn a) instance (Num a, Ord a) => Ord (Kahn a) instance (Num a, Eq a) => Eq (Kahn a) instance Num a => Jacobian (Kahn a) instance Num a => Mode (Kahn a) instance MuRef (Kahn a) -- | This module provides reverse-mode Automatic Differentiation using -- post-hoc linear time topological sorting. -- -- For reverse mode AD we use 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. module Numeric.AD.Rank1.Kahn -- | Kahn is a Mode using reverse-mode automatic -- differentiation that provides fast diffFU, diff2FU, -- grad, grad2 and a fast jacobian when you -- have a significantly smaller number of outputs than inputs. data Kahn a -- | Embed a constant auto :: Mode t => Scalar t -> t -- | The grad function calculates the gradient of a -- non-scalar-to-scalar function with kahn-mode AD in a single pass. -- --
-- >>> grad (\[x,y,z] -> x*y+z) [1,2,3] -- [2,1,1] --grad :: (Traversable f, Num a) => (f (Kahn a) -> Kahn a) -> f a -> f a -- | The grad' function calculates the result and gradient of a -- non-scalar-to-scalar function with kahn-mode AD in a single pass. -- --
-- >>> grad' (\[x,y,z] -> 4*x*exp y+cos z) [1,2,3] -- (28.566231899122155,[29.5562243957226,29.5562243957226,-0.1411200080598672]) --grad' :: (Traversable f, Num a) => (f (Kahn a) -> Kahn a) -> f a -> (a, f a) -- | grad g f function calculates the gradient of a -- non-scalar-to-scalar function f with kahn-mode AD in a single -- pass. The gradient is combined element-wise with the argument using -- the function g. -- --
-- grad = gradWith (_ dx -> dx) -- id = gradWith const --gradWith :: (Traversable f, Num a) => (a -> a -> b) -> (f (Kahn a) -> Kahn a) -> f a -> f b -- | grad' g f calculates the result and gradient of a -- non-scalar-to-scalar function f with kahn-mode AD in a single -- pass the gradient is combined element-wise with the argument using the -- function g. -- --
-- grad' == gradWith' (_ dx -> dx) --gradWith' :: (Traversable f, Num a) => (a -> a -> b) -> (f (Kahn a) -> Kahn a) -> f a -> (a, f b) -- | The jacobian function calculates the jacobian of a -- non-scalar-to-non-scalar function with kahn AD lazily in m -- passes for m outputs. -- --
-- >>> jacobian (\[x,y] -> [y,x,x*y]) [2,1] -- [[0,1],[1,0],[1,2]] ---- --
-- >>> jacobian (\[x,y] -> [exp y,cos x,x+y]) [1,2] -- [[0.0,7.38905609893065],[-0.8414709848078965,0.0],[1.0,1.0]] --jacobian :: (Traversable f, Functor g, Num a) => (f (Kahn a) -> g (Kahn a)) -> f a -> g (f a) -- | The jacobian' function calculates both the result and the -- Jacobian of a nonscalar-to-nonscalar function, using m -- invocations of kahn AD, where m is the output dimensionality. -- Applying fmap snd to the result will recover the result of -- jacobian | An alias for gradF' -- -- ghci> jacobian' ([x,y] -> [y,x,x*y]) [2,1] -- [(1,[0,1]),(2,[1,0]),(2,[1,2])] jacobian' :: (Traversable f, Functor g, Num a) => (f (Kahn a) -> g (Kahn a)) -> f a -> g (a, f a) -- | 'jacobianWith g f' calculates the Jacobian of a -- non-scalar-to-non-scalar function f with kahn 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) --jacobianWith :: (Traversable f, Functor g, Num a) => (a -> a -> b) -> (f (Kahn a) -> g (Kahn a)) -> f a -> g (f b) -- | jacobianWith g f' calculates both the result and the Jacobian -- of a nonscalar-to-nonscalar function f, using m -- invocations of kahn 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. -- --
-- jacobian' == jacobianWith' (_ dx -> dx) --jacobianWith' :: (Traversable f, Functor g, Num a) => (a -> a -> b) -> (f (Kahn a) -> g (Kahn a)) -> f a -> g (a, f b) -- | Compute the hessian via the jacobian of the gradient. -- gradient is computed in Kahn mode and then the jacobian -- is computed in Kahn mode. -- -- However, since the grad f :: f a -> f a is square -- this is not as fast as using the forward-mode jacobian of a -- reverse mode gradient provided by hessian. -- --
-- >>> hessian (\[x,y] -> x*y) [1,2] -- [[0,1],[1,0]] --hessian :: (Traversable f, Num a) => (f (On (Kahn (Kahn a))) -> (On (Kahn (Kahn a)))) -> f a -> f (f a) -- | Compute the order 3 Hessian tensor on a non-scalar-to-non-scalar -- function via the Kahn-mode Jacobian of the Kahn-mode -- Jacobian of the function. -- -- Less efficient than hessianF. -- --
-- >>> hessianF (\[x,y] -> [x*y,x+y,exp x*cos y]) [1,2] -- [[[0.0,1.0],[1.0,0.0]],[[0.0,0.0],[0.0,0.0]],[[-1.1312043837568135,-2.4717266720048188],[-2.4717266720048188,1.1312043837568135]]] --hessianF :: (Traversable f, Functor g, Num a) => (f (On (Kahn (Kahn a))) -> g (On (Kahn (Kahn a)))) -> f a -> g (f (f a)) -- | Compute the derivative of a function. -- --
-- >>> diff sin 0 -- 1.0 ---- --
-- >>> cos 0 -- 1.0 --diff :: Num a => (Kahn a -> Kahn a) -> a -> a -- | The diff' function calculates the value and derivative, as a -- pair, of a scalar-to-scalar function. -- --
-- >>> diff' sin 0 -- (0.0,1.0) --diff' :: Num a => (Kahn a -> Kahn a) -> a -> (a, a) -- | Compute the derivatives of a function that returns a vector with -- regards to its single input. -- --
-- >>> diffF (\a -> [sin a, cos a]) 0 -- [1.0,0.0] --diffF :: (Functor f, Num a) => (Kahn a -> f (Kahn a)) -> a -> f a -- | Compute the derivatives of a function that returns a vector with -- regards to its single input as well as the primal answer. -- --
-- >>> diffF' (\a -> [sin a, cos a]) 0 -- [(0.0,1.0),(1.0,0.0)] --diffF' :: (Functor f, Num a) => (Kahn a -> f (Kahn a)) -> a -> f (a, a) vgrad :: Grad i o o' a => i -> o vgrad' :: Grad i o o' a => i -> o' class Num a => Grad i o o' a | i -> a o o', o -> a i o', o' -> a i o -- | This module provides reverse-mode Automatic Differentiation using -- post-hoc linear time topological sorting. -- -- For reverse mode AD we use 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. module Numeric.AD.Mode.Kahn data AD s a -- | Kahn is a Mode using reverse-mode automatic -- differentiation that provides fast diffFU, diff2FU, -- grad, grad2 and a fast jacobian when you -- have a significantly smaller number of outputs than inputs. data Kahn a -- | Embed a constant auto :: Mode t => Scalar t -> t -- | The grad function calculates the gradient of a -- non-scalar-to-scalar function with kahn-mode AD in a single pass. -- --
-- >>> grad (\[x,y,z] -> x*y+z) [1,2,3] -- [2,1,1] --grad :: (Traversable f, Num a) => (forall s. f (AD s (Kahn a)) -> AD s (Kahn a)) -> f a -> f a -- | The grad' function calculates the result and gradient of a -- non-scalar-to-scalar function with kahn-mode AD in a single pass. -- --
-- >>> grad' (\[x,y,z] -> 4*x*exp y+cos z) [1,2,3] -- (28.566231899122155,[29.5562243957226,29.5562243957226,-0.1411200080598672]) --grad' :: (Traversable f, Num a) => (forall s. f (AD s (Kahn a)) -> AD s (Kahn a)) -> f a -> (a, f a) -- | grad g f function calculates the gradient of a -- non-scalar-to-scalar function f with kahn-mode AD in a single -- pass. The gradient is combined element-wise with the argument using -- the function g. -- --
-- grad = gradWith (_ dx -> dx) -- id = gradWith const --gradWith :: (Traversable f, Num a) => (a -> a -> b) -> (forall s. f (AD s (Kahn a)) -> AD s (Kahn a)) -> f a -> f b -- | grad' g f calculates the result and gradient of a -- non-scalar-to-scalar function f with kahn-mode AD in a single -- pass the gradient is combined element-wise with the argument using the -- function g. -- --
-- grad' == gradWith' (_ dx -> dx) --gradWith' :: (Traversable f, Num a) => (a -> a -> b) -> (forall s. f (AD s (Kahn a)) -> AD s (Kahn a)) -> f a -> (a, f b) -- | The jacobian function calculates the jacobian of a -- non-scalar-to-non-scalar function with kahn AD lazily in m -- passes for m outputs. -- --
-- >>> jacobian (\[x,y] -> [y,x,x*y]) [2,1] -- [[0,1],[1,0],[1,2]] ---- --
-- >>> jacobian (\[x,y] -> [exp y,cos x,x+y]) [1,2] -- [[0.0,7.38905609893065],[-0.8414709848078965,0.0],[1.0,1.0]] --jacobian :: (Traversable f, Functor g, Num a) => (forall s. f (AD s (Kahn a)) -> g (AD s (Kahn a))) -> f a -> g (f a) -- | The jacobian' function calculates both the result and the -- Jacobian of a nonscalar-to-nonscalar function, using m -- invocations of kahn AD, where m is the output dimensionality. -- Applying fmap snd to the result will recover the result of -- jacobian | An alias for gradF' -- -- ghci> jacobian' ([x,y] -> [y,x,x*y]) [2,1] -- [(1,[0,1]),(2,[1,0]),(2,[1,2])] jacobian' :: (Traversable f, Functor g, Num a) => (forall s. f (AD s (Kahn a)) -> g (AD s (Kahn a))) -> f a -> g (a, f a) -- | 'jacobianWith g f' calculates the Jacobian of a -- non-scalar-to-non-scalar function f with kahn 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) --jacobianWith :: (Traversable f, Functor g, Num a) => (a -> a -> b) -> (forall s. f (AD s (Kahn a)) -> g (AD s (Kahn a))) -> f a -> g (f b) -- | jacobianWith g f' calculates both the result and the Jacobian -- of a nonscalar-to-nonscalar function f, using m -- invocations of kahn 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. -- --
-- jacobian' == jacobianWith' (_ dx -> dx) --jacobianWith' :: (Traversable f, Functor g, Num a) => (a -> a -> b) -> (forall s. f (AD s (Kahn a)) -> g (AD s (Kahn a))) -> f a -> g (a, f b) -- | Compute the hessian via the jacobian of the gradient. -- gradient is computed in Kahn mode and then the jacobian -- is computed in Kahn mode. -- -- However, since the grad f :: f a -> f a is square -- this is not as fast as using the forward-mode jacobian of a -- reverse mode gradient provided by hessian. -- --
-- >>> hessian (\[x,y] -> x*y) [1,2] -- [[0,1],[1,0]] --hessian :: (Traversable f, Num a) => (forall s. f (AD s (On (Kahn (Kahn a)))) -> AD s (On (Kahn (Kahn a)))) -> f a -> f (f a) -- | Compute the order 3 Hessian tensor on a non-scalar-to-non-scalar -- function via the Kahn-mode Jacobian of the Kahn-mode -- Jacobian of the function. -- -- Less efficient than hessianF. -- --
-- >>> hessianF (\[x,y] -> [x*y,x+y,exp x*cos y]) [1,2] -- [[[0.0,1.0],[1.0,0.0]],[[0.0,0.0],[0.0,0.0]],[[-1.1312043837568135,-2.4717266720048188],[-2.4717266720048188,1.1312043837568135]]] --hessianF :: (Traversable f, Functor g, Num a) => (forall s. f (AD s (On (Kahn (Kahn a)))) -> g (AD s (On (Kahn (Kahn a))))) -> f a -> g (f (f a)) -- | Compute the derivative of a function. -- --
-- >>> diff sin 0 -- 1.0 ---- --
-- >>> cos 0 -- 1.0 --diff :: Num a => (forall s. AD s (Kahn a) -> AD s (Kahn a)) -> a -> a -- | The diff' function calculates the value and derivative, as a -- pair, of a scalar-to-scalar function. -- --
-- >>> diff' sin 0 -- (0.0,1.0) --diff' :: Num a => (forall s. AD s (Kahn a) -> AD s (Kahn a)) -> a -> (a, a) -- | Compute the derivatives of a function that returns a vector with -- regards to its single input. -- --
-- >>> diffF (\a -> [sin a, cos a]) 0 -- [1.0,0.0] --diffF :: (Functor f, Num a) => (forall s. AD s (Kahn a) -> f (AD s (Kahn a))) -> a -> f a -- | Compute the derivatives of a function that returns a vector with -- regards to its single input as well as the primal answer. -- --
-- >>> diffF' (\a -> [sin a, cos a]) 0 -- [(0.0,1.0),(1.0,0.0)] --diffF' :: (Functor f, Num a) => (forall s. AD s (Kahn a) -> f (AD s (Kahn a))) -> a -> f (a, a) -- | Unsafe and often partial combinators intended for internal usage. -- -- Handle with care. module Numeric.AD.Internal.Forward -- | Forward mode AD data Forward a Forward :: !a -> a -> Forward a Lift :: !a -> Forward a Zero :: Forward a primal :: Num a => Forward a -> a -- | Calculate the tangent using forward mode AD. tangent :: Num a => Forward a -> a bundle :: a -> a -> Forward a unbundle :: Num a => Forward a -> (a, a) apply :: Num a => (Forward a -> b) -> a -> b bind :: (Traversable f, Num a) => (f (Forward a) -> b) -> f a -> f b bind' :: (Traversable f, Num a) => (f (Forward a) -> b) -> f a -> (b, f b) bindWith :: (Traversable f, Num a) => (a -> b -> c) -> (f (Forward a) -> b) -> f a -> f c bindWith' :: (Traversable f, Num a) => (a -> b -> c) -> (f (Forward a) -> b) -> f a -> (b, f c) transposeWith :: (Functor f, Foldable f, Traversable g) => (b -> f a -> c) -> f (g a) -> g b -> g c instance Typeable Forward instance Show a => Show (Forward a) instance Data a => Data (Forward a) instance InvErf a => InvErf (Forward a) instance Erf a => Erf (Forward a) instance RealFrac a => RealFrac (Forward a) instance RealFloat a => RealFloat (Forward a) instance Real a => Real (Forward a) instance (Num a, Enum a) => Enum (Forward a) instance Floating a => Floating (Forward a) instance Fractional a => Fractional (Forward a) instance Num a => Num (Forward a) instance (Num a, Bounded a) => Bounded (Forward a) instance (Num a, Ord a) => Ord (Forward a) instance (Num a, Eq a) => Eq (Forward a) instance Num a => Jacobian (Forward a) instance Num a => Mode (Forward a) -- | Forward mode automatic differentiation module Numeric.AD.Rank1.Forward -- | Forward mode AD data Forward a -- | Embed a constant auto :: Mode t => Scalar t -> t -- | Compute the gradient of a function using forward mode AD. -- -- Note, this performs O(n) worse than grad for n -- inputs, in exchange for better space utilization. grad :: (Traversable f, Num a) => (f (Forward a) -> Forward a) -> f a -> f a -- | Compute the gradient and answer to a function using forward mode AD. -- -- Note, this performs O(n) worse than grad' for n -- inputs, in exchange for better space utilization. grad' :: (Traversable f, Num a) => (f (Forward a) -> Forward a) -> f a -> (a, f a) -- | Compute the gradient of a function using forward mode AD and combine -- the result with the input using a user-specified function. -- -- Note, this performs O(n) worse than gradWith for -- n inputs, in exchange for better space utilization. gradWith :: (Traversable f, Num a) => (a -> a -> b) -> (f (Forward a) -> Forward a) -> f a -> f b -- | Compute the gradient of a function using forward mode AD and the -- answer, and combine the result with the input using a user-specified -- function. -- -- Note, this performs O(n) worse than gradWith' for -- n inputs, in exchange for better space utilization. -- --
-- >>> gradWith' (,) sum [0..4] -- (10,[(0,1),(1,1),(2,1),(3,1),(4,1)]) --gradWith' :: (Traversable f, Num a) => (a -> a -> b) -> (f (Forward a) -> Forward a) -> f a -> (a, f b) -- | Compute the Jacobian using Forward mode AD. This must -- transpose the result, so jacobianT is faster and allows more -- result types. -- --
-- >>> jacobian (\[x,y] -> [y,x,x+y,x*y,exp x * sin y]) [pi,1] -- [[0.0,1.0],[1.0,0.0],[1.0,1.0],[1.0,3.141592653589793],[19.472221418841606,12.502969588876512]] --jacobian :: (Traversable f, Traversable g, Num a) => (f (Forward a) -> g (Forward a)) -> f a -> g (f a) -- | Compute the Jacobian using Forward mode AD along with -- the actual answer. jacobian' :: (Traversable f, Traversable g, Num a) => (f (Forward a) -> g (Forward a)) -> f a -> g (a, f a) -- | Compute the Jacobian using Forward mode AD and combine -- the output with the input. This must transpose the result, so -- jacobianWithT is faster, and allows more result types. jacobianWith :: (Traversable f, Traversable g, Num a) => (a -> a -> b) -> (f (Forward a) -> g (Forward a)) -> f a -> g (f b) -- | Compute the Jacobian using Forward mode AD combined -- with the input using a user specified function, along with the actual -- answer. jacobianWith' :: (Traversable f, Traversable g, Num a) => (a -> a -> b) -> (f (Forward a) -> g (Forward a)) -> f a -> g (a, f b) -- | A fast, simple, transposed Jacobian computed with forward-mode AD. jacobianT :: (Traversable f, Functor g, Num a) => (f (Forward a) -> g (Forward a)) -> f a -> f (g a) -- | A fast, simple, transposed Jacobian computed with Forward mode -- AD that combines the output with the input. jacobianWithT :: (Traversable f, Functor g, Num a) => (a -> a -> b) -> (f (Forward a) -> g (Forward a)) -> f a -> f (g b) -- | Compute the product of a vector with the Hessian using -- forward-on-forward-mode AD. hessianProduct :: (Traversable f, Num a) => (f (On (Forward (Forward a))) -> On (Forward (Forward a))) -> f (a, a) -> f a -- | Compute the gradient and hessian product using forward-on-forward-mode -- AD. hessianProduct' :: (Traversable f, Num a) => (f (On (Forward (Forward a))) -> On (Forward (Forward a))) -> f (a, a) -> f (a, a) -- | The diff function calculates the first derivative of a -- scalar-to-scalar function by forward-mode AD -- --
-- >>> diff sin 0 -- 1.0 --diff :: Num a => (Forward a -> Forward a) -> a -> a -- | The diff' function calculates the result and first derivative -- of scalar-to-scalar function by Forward mode AD -- --
-- diff' sin == sin &&& cos -- diff' f = f &&& d f ---- --
-- >>> diff' sin 0 -- (0.0,1.0) ---- --
-- >>> diff' exp 0 -- (1.0,1.0) --diff' :: Num a => (Forward a -> Forward a) -> a -> (a, a) -- | The diffF function calculates the first derivatives of -- scalar-to-nonscalar function by Forward mode AD -- --
-- >>> diffF (\a -> [sin a, cos a]) 0 -- [1.0,-0.0] --diffF :: (Functor f, Num a) => (Forward a -> f (Forward a)) -> a -> f a -- | The diffF' function calculates the result and first derivatives -- of a scalar-to-non-scalar function by Forward mode AD -- --
-- >>> diffF' (\a -> [sin a, cos a]) 0 -- [(0.0,1.0),(1.0,-0.0)] --diffF' :: (Functor f, Num a) => (Forward a -> f (Forward a)) -> a -> f (a, a) -- | Compute the directional derivative of a function given a zipped up -- Functor of the input values and their derivatives du :: (Functor f, Num a) => (f (Forward a) -> Forward a) -> f (a, a) -> a -- | Compute the answer and directional derivative of a function given a -- zipped up Functor of the input values and their derivatives du' :: (Functor f, Num a) => (f (Forward a) -> Forward a) -> f (a, a) -> (a, a) -- | Compute a vector of directional derivatives for a function given a -- zipped up Functor of the input values and their derivatives. duF :: (Functor f, Functor g, Num a) => (f (Forward a) -> g (Forward a)) -> f (a, a) -> g a -- | Compute a vector of answers and directional derivatives for a function -- given a zipped up Functor of the input values and their -- derivatives. duF' :: (Functor f, Functor g, Num a) => (f (Forward a) -> g (Forward a)) -> f (a, a) -> g (a, a) module Numeric.AD.Rank1.Newton -- | 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.) If the stream becomes constant -- ("it converges"), no further elements are returned. -- -- Examples: -- --
-- >>> take 10 $ findZero (\x->x^2-4) 1 -- [1.0,2.5,2.05,2.000609756097561,2.0000000929222947,2.000000000000002,2.0] ---- --
-- >>> last $ take 10 $ findZero ((+1).(^2)) (1 :+ 1) -- 0.0 :+ 1.0 --findZero :: (Fractional a, Eq a) => (Forward a -> Forward a) -> a -> [a] -- | The inverse function inverts a scalar function using Newton's -- method; its output is a stream of increasingly accurate results. -- (Modulo the usual caveats.) If the stream becomes constant ("it -- converges"), no further elements are returned. -- -- Example: -- --
-- >>> last $ take 10 $ inverse sqrt 1 (sqrt 10) -- 10.0 --inverse :: (Fractional a, Eq a) => (Forward a -> Forward a) -> a -> a -> [a] -- | 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.) -- -- If the stream becomes constant ("it converges"), no further elements -- are returned. -- --
-- >>> last $ take 10 $ fixedPoint cos 1 -- 0.7390851332151607 --fixedPoint :: (Fractional a, Eq a) => (Forward a -> Forward a) -> a -> [a] -- | 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.) If the stream becomes constant -- ("it converges"), no further elements are returned. -- --
-- >>> last $ take 10 $ extremum cos 1 -- 0.0 --extremum :: (Fractional a, Eq a) => (On (Forward (Forward a)) -> On (Forward (Forward a))) -> a -> [a] -- | 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) => (f (Kahn a) -> Kahn a) -> f a -> [f a] -- | Perform a gradient descent using reverse mode automatic -- differentiation to compute the gradient. gradientAscent :: (Traversable f, Fractional a, Ord a) => (f (Kahn a) -> Kahn a) -> f a -> [f a] module Numeric.AD.Rank1.Newton.Double -- | 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.) If the stream becomes constant -- ("it converges"), no further elements are returned. -- -- Examples: -- --
-- >>> take 10 $ findZero (\x->x^2-4) 1 -- [1.0,2.5,2.05,2.000609756097561,2.0000000929222947,2.000000000000002,2.0] --findZero :: (ForwardDouble -> ForwardDouble) -> Double -> [Double] -- | The inverse function inverts a scalar function using Newton's -- method; its output is a stream of increasingly accurate results. -- (Modulo the usual caveats.) If the stream becomes constant ("it -- converges"), no further elements are returned. -- -- Example: -- --
-- >>> last $ take 10 $ inverse sqrt 1 (sqrt 10) -- 10.0 --inverse :: (ForwardDouble -> ForwardDouble) -> Double -> Double -> [Double] -- | 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.) -- -- If the stream becomes constant ("it converges"), no further elements -- are returned. -- --
-- >>> last $ take 10 $ fixedPoint cos 1 -- 0.7390851332151607 --fixedPoint :: (ForwardDouble -> ForwardDouble) -> Double -> [Double] -- | 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.) If the stream becomes constant -- ("it converges"), no further elements are returned. -- --
-- >>> last $ take 10 $ extremum cos 1 -- 0.0 --extremum :: (On (Forward ForwardDouble) -> On (Forward ForwardDouble)) -> Double -> [Double] -- | Forward mode automatic differentiation module Numeric.AD.Mode.Forward data AD s a -- | Forward mode AD data Forward a -- | Embed a constant auto :: Mode t => Scalar t -> t -- | Compute the gradient of a function using forward mode AD. -- -- Note, this performs O(n) worse than grad for n -- inputs, in exchange for better space utilization. grad :: (Traversable f, Num a) => (forall s. f (AD s (Forward a)) -> AD s (Forward a)) -> f a -> f a -- | Compute the gradient and answer to a function using forward mode AD. -- -- Note, this performs O(n) worse than grad' for n -- inputs, in exchange for better space utilization. grad' :: (Traversable f, Num a) => (forall s. f (AD s (Forward a)) -> AD s (Forward a)) -> f a -> (a, f a) -- | Compute the gradient of a function using forward mode AD and combine -- the result with the input using a user-specified function. -- -- Note, this performs O(n) worse than gradWith for -- n inputs, in exchange for better space utilization. gradWith :: (Traversable f, Num a) => (a -> a -> b) -> (forall s. f (AD s (Forward a)) -> AD s (Forward a)) -> f a -> f b -- | Compute the gradient of a function using forward mode AD and the -- answer, and combine the result with the input using a user-specified -- function. -- -- Note, this performs O(n) worse than gradWith' for -- n inputs, in exchange for better space utilization. -- --
-- >>> gradWith' (,) sum [0..4] -- (10,[(0,1),(1,1),(2,1),(3,1),(4,1)]) --gradWith' :: (Traversable f, Num a) => (a -> a -> b) -> (forall s. f (AD s (Forward a)) -> AD s (Forward a)) -> f a -> (a, f b) -- | Compute the Jacobian using Forward mode AD. This must -- transpose the result, so jacobianT is faster and allows more -- result types. -- --
-- >>> jacobian (\[x,y] -> [y,x,x+y,x*y,exp x * sin y]) [pi,1] -- [[0.0,1.0],[1.0,0.0],[1.0,1.0],[1.0,3.141592653589793],[19.472221418841606,12.502969588876512]] --jacobian :: (Traversable f, Traversable g, Num a) => (forall s. f (AD s (Forward a)) -> g (AD s (Forward a))) -> f a -> g (f a) -- | Compute the Jacobian using Forward mode AD along with -- the actual answer. jacobian' :: (Traversable f, Traversable g, Num a) => (forall s. f (AD s (Forward a)) -> g (AD s (Forward a))) -> f a -> g (a, f a) -- | Compute the Jacobian using Forward mode AD and combine -- the output with the input. This must transpose the result, so -- jacobianWithT is faster, and allows more result types. jacobianWith :: (Traversable f, Traversable g, Num a) => (a -> a -> b) -> (forall s. f (AD s (Forward a)) -> g (AD s (Forward a))) -> f a -> g (f b) -- | Compute the Jacobian using Forward mode AD combined with -- the input using a user specified function, along with the actual -- answer. jacobianWith' :: (Traversable f, Traversable g, Num a) => (a -> a -> b) -> (forall s. f (AD s (Forward a)) -> g (AD s (Forward a))) -> f a -> g (a, f b) -- | A fast, simple, transposed Jacobian computed with forward-mode AD. jacobianT :: (Traversable f, Functor g, Num a) => (forall s. f (AD s (Forward a)) -> g (AD s (Forward a))) -> f a -> f (g a) -- | A fast, simple, transposed Jacobian computed with Forward mode -- AD that combines the output with the input. jacobianWithT :: (Traversable f, Functor g, Num a) => (a -> a -> b) -> (forall s. f (AD s (Forward a)) -> g (AD s (Forward a))) -> f a -> f (g b) -- | Compute the product of a vector with the Hessian using -- forward-on-forward-mode AD. hessianProduct :: (Traversable f, Num a) => (forall s. f (AD s (On (Forward (Forward a)))) -> AD s (On (Forward (Forward a)))) -> f (a, a) -> f a -- | Compute the gradient and hessian product using forward-on-forward-mode -- AD. hessianProduct' :: (Traversable f, Num a) => (forall s. f (AD s (On (Forward (Forward a)))) -> AD s (On (Forward (Forward a)))) -> f (a, a) -> f (a, a) -- | The diff function calculates the first derivative of a -- scalar-to-scalar function by forward-mode AD -- --
-- >>> diff sin 0 -- 1.0 --diff :: Num a => (forall s. AD s (Forward a) -> AD s (Forward a)) -> a -> a -- | The diff' function calculates the result and first derivative -- of scalar-to-scalar function by Forward mode AD -- --
-- diff' sin == sin &&& cos -- diff' f = f &&& d f ---- --
-- >>> diff' sin 0 -- (0.0,1.0) ---- --
-- >>> diff' exp 0 -- (1.0,1.0) --diff' :: Num a => (forall s. AD s (Forward a) -> AD s (Forward a)) -> a -> (a, a) -- | The diffF function calculates the first derivatives of -- scalar-to-nonscalar function by Forward mode AD -- --
-- >>> diffF (\a -> [sin a, cos a]) 0 -- [1.0,-0.0] --diffF :: (Functor f, Num a) => (forall s. AD s (Forward a) -> f (AD s (Forward a))) -> a -> f a -- | The diffF' function calculates the result and first derivatives -- of a scalar-to-non-scalar function by Forward mode AD -- --
-- >>> diffF' (\a -> [sin a, cos a]) 0 -- [(0.0,1.0),(1.0,-0.0)] --diffF' :: (Functor f, Num a) => (forall s. AD s (Forward a) -> f (AD s (Forward a))) -> a -> f (a, a) -- | Compute the directional derivative of a function given a zipped up -- Functor of the input values and their derivatives du :: (Functor f, Num a) => (forall s. f (AD s (Forward a)) -> AD s (Forward a)) -> f (a, a) -> a -- | Compute the answer and directional derivative of a function given a -- zipped up Functor of the input values and their derivatives du' :: (Functor f, Num a) => (forall s. f (AD s (Forward a)) -> AD s (Forward a)) -> f (a, a) -> (a, a) -- | Compute a vector of directional derivatives for a function given a -- zipped up Functor of the input values and their derivatives. duF :: (Functor f, Functor g, Num a) => (forall s. f (AD s (Forward a)) -> g (AD s (Forward a))) -> f (a, a) -> g a -- | Compute a vector of answers and directional derivatives for a function -- given a zipped up Functor of the input values and their -- derivatives. duF' :: (Functor f, Functor g, Num a) => (forall s. f (AD s (Forward a)) -> g (AD s (Forward a))) -> f (a, a) -> g (a, a) module Numeric.AD.Newton -- | 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.) If the stream becomes constant -- ("it converges"), no further elements are returned. -- -- Examples: -- --
-- >>> take 10 $ findZero (\x->x^2-4) 1 -- [1.0,2.5,2.05,2.000609756097561,2.0000000929222947,2.000000000000002,2.0] ---- --
-- >>> last $ take 10 $ findZero ((+1).(^2)) (1 :+ 1) -- 0.0 :+ 1.0 --findZero :: (Fractional a, Eq a) => (forall s. AD s (Forward a) -> AD s (Forward a)) -> a -> [a] -- | The inverse function inverts a scalar function using Newton's -- method; its output is a stream of increasingly accurate results. -- (Modulo the usual caveats.) If the stream becomes constant ("it -- converges"), no further elements are returned. -- -- Example: -- --
-- >>> last $ take 10 $ inverse sqrt 1 (sqrt 10) -- 10.0 --inverse :: (Fractional a, Eq a) => (forall s. AD s (Forward a) -> AD s (Forward a)) -> a -> a -> [a] -- | 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.) -- -- If the stream becomes constant ("it converges"), no further elements -- are returned. -- --
-- >>> last $ take 10 $ fixedPoint cos 1 -- 0.7390851332151607 --fixedPoint :: (Fractional a, Eq a) => (forall s. AD s (Forward a) -> AD s (Forward a)) -> a -> [a] -- | 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.) If the stream becomes constant -- ("it converges"), no further elements are returned. -- --
-- >>> last $ take 10 $ extremum cos 1 -- 0.0 --extremum :: (Fractional a, Eq a) => (forall s. AD s (On (Forward (Forward a))) -> AD s (On (Forward (Forward a)))) -> a -> [a] -- | 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. Reifies s Tape => f (Reverse s a) -> Reverse s a) -> f a -> [f a] -- | Perform a gradient descent using reverse mode automatic -- differentiation to compute the gradient. gradientAscent :: (Traversable f, Fractional a, Ord a) => (forall s. Reifies s Tape => f (Reverse s a) -> Reverse s a) -> f a -> [f a] -- | Perform a conjugate gradient descent using reverse mode automatic -- differentiation to compute the gradient, and using forward-on-forward -- mode for computing extrema. -- --
-- >>> let sq x = x * x -- -- >>> let rosenbrock [x,y] = sq (1 - x) + 100 * sq (y - sq x) -- -- >>> rosenbrock [0,0] -- 1 -- -- >>> rosenbrock (conjugateGradientDescent rosenbrock [0, 0] !! 5) < 0.1 -- True --conjugateGradientDescent :: (Traversable f, Ord a, Fractional a) => (forall s. Chosen s => f (Or s (On (Forward (Forward a))) (Kahn a)) -> Or s (On (Forward (Forward a))) (Kahn a)) -> f a -> [f a] -- | Perform a conjugate gradient ascent using reverse mode automatic -- differentiation to compute the gradient. conjugateGradientAscent :: (Traversable f, Ord a, Fractional a) => (forall s. Chosen s => f (Or s (On (Forward (Forward a))) (Kahn a)) -> Or s (On (Forward (Forward a))) (Kahn a)) -> f a -> [f a] -- | The stochasticGradientDescent function approximates the true -- gradient of the constFunction by a gradient at a single example. As -- the algorithm sweeps through the training set, it performs the update -- for each training example. -- -- It uses reverse mode automatic differentiation to compute the gradient -- The learning rate is constant through out, and is set to 0.001 stochasticGradientDescent :: (Traversable f, Fractional a, Ord a) => (forall s. Reifies s Tape => f (Scalar a) -> f (Reverse s a) -> Reverse s a) -> [f (Scalar a)] -> f a -> [f a] -- | Root finding using Halley's rational method (the second in the class -- of Householder methods). Assumes the function is three times -- continuously differentiable and converges cubically when progress can -- be made. module Numeric.AD.Rank1.Halley -- | The findZero function finds a zero of a scalar function using -- Halley's method; its output is a stream of increasingly accurate -- results. (Modulo the usual caveats.) If the stream becomes constant -- ("it converges"), no further elements are returned. -- -- Examples: -- --
-- >>> take 10 $ findZero (\x->x^2-4) 1 -- [1.0,1.8571428571428572,1.9997967892704736,1.9999999999994755,2.0] ---- --
-- >>> last $ take 10 $ findZero ((+1).(^2)) (1 :+ 1) -- 0.0 :+ 1.0 --findZero :: (Fractional a, Eq a) => (Tower a -> Tower a) -> a -> [a] -- | The inverse function inverts a scalar function using Halley's -- method; its output is a stream of increasingly accurate results. -- (Modulo the usual caveats.) If the stream becomes constant ("it -- converges"), no further elements are returned. -- -- Note: the take 10 $ inverse sqrt 1 (sqrt 10) example that -- works for Newton's method fails with Halley's method because the -- preconditions do not hold! inverse :: (Fractional a, Eq a) => (Tower a -> Tower a) -> a -> a -> [a] -- | The fixedPoint function find a fixedpoint of a scalar function -- using Halley's method; its output is a stream of increasingly accurate -- results. (Modulo the usual caveats.) -- -- If the stream becomes constant ("it converges"), no further elements -- are returned. -- --
-- >>> last $ take 10 $ fixedPoint cos 1 -- 0.7390851332151607 --fixedPoint :: (Fractional a, Eq a) => (Tower a -> Tower a) -> a -> [a] -- | The extremum function finds an extremum of a scalar function -- using Halley's method; produces a stream of increasingly accurate -- results. (Modulo the usual caveats.) If the stream becomes constant -- ("it converges"), no further elements are returned. -- --
-- >>> take 10 $ extremum cos 1 -- [1.0,0.29616942658570555,4.59979519460002e-3,1.6220740159042513e-8,0.0] --extremum :: (Fractional a, Eq a) => (On (Forward (Tower a)) -> On (Forward (Tower a))) -> a -> [a] -- | Root finding using Halley's rational method (the second in the class -- of Householder methods). Assumes the function is three times -- continuously differentiable and converges cubically when progress can -- be made. module Numeric.AD.Halley -- | The findZero function finds a zero of a scalar function using -- Halley's method; its output is a stream of increasingly accurate -- results. (Modulo the usual caveats.) If the stream becomes constant -- ("it converges"), no further elements are returned. -- -- Examples: -- --
-- >>> take 10 $ findZero (\x->x^2-4) 1 -- [1.0,1.8571428571428572,1.9997967892704736,1.9999999999994755,2.0] ---- --
-- >>> last $ take 10 $ findZero ((+1).(^2)) (1 :+ 1) -- 0.0 :+ 1.0 --findZero :: (Fractional a, Eq a) => (forall s. AD s (Tower a) -> AD s (Tower a)) -> a -> [a] -- | The inverse function inverts a scalar function using Halley's -- method; its output is a stream of increasingly accurate results. -- (Modulo the usual caveats.) If the stream becomes constant ("it -- converges"), no further elements are returned. -- -- Note: the take 10 $ inverse sqrt 1 (sqrt 10) example that -- works for Newton's method fails with Halley's method because the -- preconditions do not hold! inverse :: (Fractional a, Eq a) => (forall s. AD s (Tower a) -> AD s (Tower a)) -> a -> a -> [a] -- | The fixedPoint function find a fixedpoint of a scalar function -- using Halley's method; its output is a stream of increasingly accurate -- results. (Modulo the usual caveats.) -- -- If the stream becomes constant ("it converges"), no further elements -- are returned. -- --
-- >>> last $ take 10 $ fixedPoint cos 1 -- 0.7390851332151607 --fixedPoint :: (Fractional a, Eq a) => (forall s. AD s (Tower a) -> AD s (Tower a)) -> a -> [a] -- | The extremum function finds an extremum of a scalar function -- using Halley's method; produces a stream of increasingly accurate -- results. (Modulo the usual caveats.) If the stream becomes constant -- ("it converges"), no further elements are returned. -- --
-- >>> take 10 $ extremum cos 1 -- [1.0,0.29616942658570555,4.59979519460002e-3,1.6220740159042513e-8,0.0] --extremum :: (Fractional a, Eq a) => (forall s. AD s (On (Forward (Tower a))) -> AD s (On (Forward (Tower a)))) -> a -> [a] module Numeric.AD.Newton.Double -- | 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.) If the stream becomes constant -- ("it converges"), no further elements are returned. -- -- Examples: -- --
-- >>> take 10 $ findZero (\x->x^2-4) 1 -- [1.0,2.5,2.05,2.000609756097561,2.0000000929222947,2.000000000000002,2.0] --findZero :: (forall s. AD s ForwardDouble -> AD s ForwardDouble) -> Double -> [Double] -- | The inverse function inverts a scalar function using Newton's -- method; its output is a stream of increasingly accurate results. -- (Modulo the usual caveats.) If the stream becomes constant ("it -- converges"), no further elements are returned. -- -- Example: -- --
-- >>> last $ take 10 $ inverse sqrt 1 (sqrt 10) -- 10.0 --inverse :: (forall s. AD s ForwardDouble -> AD s ForwardDouble) -> Double -> Double -> [Double] -- | 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.) -- -- If the stream becomes constant ("it converges"), no further elements -- are returned. -- --
-- >>> last $ take 10 $ fixedPoint cos 1 -- 0.7390851332151607 --fixedPoint :: (forall s. AD s ForwardDouble -> AD s ForwardDouble) -> Double -> [Double] -- | 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.) If the stream becomes constant -- ("it converges"), no further elements are returned. -- --
-- >>> last $ take 10 $ extremum cos 1 -- 0.0 --extremum :: (forall s. AD s (On (Forward ForwardDouble)) -> AD s (On (Forward ForwardDouble))) -> Double -> [Double] -- | Perform a conjugate gradient descent using reverse mode automatic -- differentiation to compute the gradient, and using forward-on-forward -- mode for computing extrema. -- --
-- >>> let sq x = x * x -- -- >>> let rosenbrock [x,y] = sq (1 - x) + 100 * sq (y - sq x) -- -- >>> rosenbrock [0,0] -- 1 -- -- >>> rosenbrock (conjugateGradientDescent rosenbrock [0, 0] !! 5) < 0.1 -- True --conjugateGradientDescent :: Traversable f => (forall s. Chosen s => f (Or s (On (Forward ForwardDouble)) (Kahn Double)) -> Or s (On (Forward ForwardDouble)) (Kahn Double)) -> f Double -> [f Double] -- | Perform a conjugate gradient ascent using reverse mode automatic -- differentiation to compute the gradient. conjugateGradientAscent :: Traversable f => (forall s. Chosen s => f (Or s (On (Forward ForwardDouble)) (Kahn Double)) -> Or s (On (Forward ForwardDouble)) (Kahn Double)) -> f Double -> [f Double] -- | Mixed-Mode Automatic Differentiation. -- -- Each combinator exported from this module chooses an appropriate AD -- mode. The following basic operations are supported, modified as -- appropriate by the suffixes below: -- --
-- >>> grad (\[x,y,z] -> x*y+z) [1,2,3] -- [2,1,1] --grad :: (Traversable f, Num a) => (forall s. Reifies s Tape => f (Reverse s a) -> Reverse s a) -> f a -> f a -- | The grad' function calculates the result and gradient of a -- non-scalar-to-scalar function with reverse-mode AD in a single pass. -- --
-- >>> grad' (\[x,y,z] -> x*y+z) [1,2,3] -- (5,[2,1,1]) --grad' :: (Traversable f, Num a) => (forall s. Reifies s Tape => f (Reverse s a) -> Reverse s a) -> f a -> (a, f a) -- | 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) -- id == gradWith const --gradWith :: (Traversable f, Num a) => (a -> a -> b) -> (forall s. Reifies s Tape => f (Reverse s a) -> Reverse s a) -> f a -> f b -- | grad' g f calculates the result and 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) --gradWith' :: (Traversable f, Num a) => (a -> a -> b) -> (forall s. Reifies s Tape => f (Reverse s a) -> Reverse s a) -> f a -> (a, f b) grads :: (Traversable f, Num a) => (forall s. f (AD s (Sparse a)) -> AD s (Sparse a)) -> f a -> Cofree f a class Num a => Grad i o o' a | i -> a o o', o -> a i o', o' -> a i o vgrad :: Grad i o o' a => i -> o vgrad' :: Grad i o o' a => i -> o' class Num a => Grads i o a | i -> a o, o -> a i vgrads :: Grads i o a => i -> o -- | 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 (\[x,y] -> [y,x,x*y]) [2,1] -- [[0,1],[1,0],[1,2]] --jacobian :: (Traversable f, Functor g, Num a) => (forall s. Reifies s Tape => f (Reverse s a) -> g (Reverse s a)) -> f a -> g (f a) -- | 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 | An alias for gradF' -- --
-- >>> jacobian' (\[x,y] -> [y,x,x*y]) [2,1] -- [(1,[0,1]),(2,[1,0]),(2,[1,2])] --jacobian' :: (Traversable f, Functor g, Num a) => (forall s. Reifies s Tape => f (Reverse s a) -> g (Reverse s a)) -> f a -> g (a, f a) -- | '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) --jacobianWith :: (Traversable f, Functor g, Num a) => (a -> a -> b) -> (forall s. Reifies s Tape => f (Reverse s a) -> g (Reverse s a)) -> f a -> g (f b) -- | 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. -- --
-- jacobian' == jacobianWith' (_ dx -> dx) --jacobianWith' :: (Traversable f, Functor g, Num a) => (a -> a -> b) -> (forall s. Reifies s Tape => f (Reverse s a) -> g (Reverse s a)) -> f a -> g (a, f b) jacobians :: (Traversable f, Functor g, Num a) => (forall s. f (AD s (Sparse a)) -> g (AD s (Sparse a))) -> f a -> g (Cofree f a) -- | A fast, simple, transposed Jacobian computed with forward-mode AD. jacobianT :: (Traversable f, Functor g, Num a) => (forall s. f (AD s (Forward a)) -> g (AD s (Forward a))) -> f a -> f (g a) -- | A fast, simple, transposed Jacobian computed with Forward mode -- AD that combines the output with the input. jacobianWithT :: (Traversable f, Functor g, Num a) => (a -> a -> b) -> (forall s. f (AD s (Forward a)) -> g (AD s (Forward a))) -> f a -> f (g b) -- | Compute the Hessian via the Jacobian of the gradient. gradient is -- computed in reverse mode and then the Jacobian is computed in sparse -- (forward) mode. -- --
-- >>> hessian (\[x,y] -> x*y) [1,2] -- [[0,1],[1,0]] --hessian :: (Traversable f, Num a) => (forall s. Reifies s Tape => f (On (Reverse s (Sparse a))) -> On (Reverse s (Sparse a))) -> f a -> f (f a) hessian' :: (Traversable f, Num a) => (forall s. f (AD s (Sparse a)) -> AD s (Sparse a)) -> f a -> (a, f (a, f a)) -- | Compute the order 3 Hessian tensor on a non-scalar-to-non-scalar -- function using 'Sparse'-on-'Reverse' -- --
-- >>> hessianF (\[x,y] -> [x*y,x+y,exp x*cos y]) [1,2] -- [[[0.0,1.0],[1.0,0.0]],[[0.0,0.0],[0.0,0.0]],[[-1.1312043837568135,-2.4717266720048188],[-2.4717266720048188,1.1312043837568135]]] --hessianF :: (Traversable f, Functor g, Num a) => (forall s. Reifies s Tape => f (On (Reverse s (Sparse a))) -> g (On (Reverse s (Sparse a)))) -> f a -> g (f (f a)) hessianF' :: (Traversable f, Functor g, Num a) => (forall s. f (AD s (Sparse a)) -> g (AD s (Sparse a))) -> f a -> g (a, f (a, f a)) -- | hessianProduct f wv computes the product of the -- hessian H of a non-scalar-to-scalar function f at -- w = fst $ wv with a vector v = snd $ -- wv using "Pearlmutter's method" from -- http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.29.6143, -- which states: -- --
-- H v = (d/dr) grad_w (w + r v) | r = 0 ---- -- Or in other words, we take the directional derivative of the gradient. -- The gradient is calculated in reverse mode, then the directional -- derivative is calculated in forward mode. hessianProduct :: (Traversable f, Num a) => (forall s. Reifies s Tape => f (On (Reverse s (Forward a))) -> On (Reverse s (Forward a))) -> f (a, a) -> f a -- | hessianProduct' f wv computes both the gradient of a -- non-scalar-to-scalar f at w = fst $ wv -- and the product of the hessian H at w with a vector -- v = snd $ wv using "Pearlmutter's method". The outputs -- are returned wrapped in the same functor. -- --
-- H v = (d/dr) grad_w (w + r v) | r = 0 ---- -- Or in other words, we return the gradient and the directional -- derivative of the gradient. The gradient is calculated in reverse -- mode, then the directional derivative is calculated in forward mode. hessianProduct' :: (Traversable f, Num a) => (forall s. Reifies s Tape => f (On (Reverse s (Forward a))) -> On (Reverse s (Forward a))) -> f (a, a) -> f (a, a) -- | The diff function calculates the first derivative of a -- scalar-to-scalar function by forward-mode AD -- --
-- >>> diff sin 0 -- 1.0 --diff :: Num a => (forall s. AD s (Forward a) -> AD s (Forward a)) -> a -> a -- | The diffF function calculates the first derivatives of -- scalar-to-nonscalar function by Forward mode AD -- --
-- >>> diffF (\a -> [sin a, cos a]) 0 -- [1.0,-0.0] --diffF :: (Functor f, Num a) => (forall s. AD s (Forward a) -> f (AD s (Forward a))) -> a -> f a -- | The diff' function calculates the result and first derivative -- of scalar-to-scalar function by Forward mode AD -- --
-- diff' sin == sin &&& cos -- diff' f = f &&& d f ---- --
-- >>> diff' sin 0 -- (0.0,1.0) ---- --
-- >>> diff' exp 0 -- (1.0,1.0) --diff' :: Num a => (forall s. AD s (Forward a) -> AD s (Forward a)) -> a -> (a, a) -- | The diffF' function calculates the result and first derivatives -- of a scalar-to-non-scalar function by Forward mode AD -- --
-- >>> diffF' (\a -> [sin a, cos a]) 0 -- [(0.0,1.0),(1.0,-0.0)] --diffF' :: (Functor f, Num a) => (forall s. AD s (Forward a) -> f (AD s (Forward a))) -> a -> f (a, a) diffs :: Num a => (forall s. AD s (Tower a) -> AD s (Tower a)) -> a -> [a] diffsF :: (Functor f, Num a) => (forall s. AD s (Tower a) -> f (AD s (Tower a))) -> a -> f [a] diffs0 :: Num a => (forall s. AD s (Tower a) -> AD s (Tower a)) -> a -> [a] diffs0F :: (Functor f, Num a) => (forall s. AD s (Tower a) -> f (AD s (Tower a))) -> a -> f [a] -- | Compute the directional derivative of a function given a zipped up -- Functor of the input values and their derivatives du :: (Functor f, Num a) => (forall s. f (AD s (Forward a)) -> AD s (Forward a)) -> f (a, a) -> a -- | Compute the answer and directional derivative of a function given a -- zipped up Functor of the input values and their derivatives du' :: (Functor f, Num a) => (forall s. f (AD s (Forward a)) -> AD s (Forward a)) -> f (a, a) -> (a, a) -- | Compute a vector of directional derivatives for a function given a -- zipped up Functor of the input values and their derivatives. duF :: (Functor f, Functor g, Num a) => (forall s. f (AD s (Forward a)) -> g (AD s (Forward a))) -> f (a, a) -> g a -- | Compute a vector of answers and directional derivatives for a function -- given a zipped up Functor of the input values and their -- derivatives. duF' :: (Functor f, Functor g, Num a) => (forall s. f (AD s (Forward a)) -> g (AD s (Forward a))) -> f (a, a) -> g (a, a) dus :: (Functor f, Num a) => (forall s. f (AD s (Tower a)) -> AD s (Tower a)) -> f [a] -> [a] dus0 :: (Functor f, Num a) => (forall s. f (AD s (Tower a)) -> AD s (Tower a)) -> f [a] -> [a] dusF :: (Functor f, Functor g, Num a) => (forall s. f (AD s (Tower a)) -> g (AD s (Tower a))) -> f [a] -> g [a] dus0F :: (Functor f, Functor g, Num a) => (forall s. f (AD s (Tower a)) -> g (AD s (Tower a))) -> f [a] -> g [a] taylor :: Fractional a => (forall s. AD s (Tower a) -> AD s (Tower a)) -> a -> a -> [a] taylor0 :: Fractional a => (forall s. AD s (Tower a) -> AD s (Tower a)) -> a -> a -> [a] maclaurin :: Fractional a => (forall s. AD s (Tower a) -> AD s (Tower a)) -> a -> [a] maclaurin0 :: Fractional a => (forall s. AD s (Tower a) -> AD s (Tower a)) -> a -> [a] -- | 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. Reifies s Tape => f (Reverse s a) -> Reverse s a) -> f a -> [f a] -- | Perform a gradient descent using reverse mode automatic -- differentiation to compute the gradient. gradientAscent :: (Traversable f, Fractional a, Ord a) => (forall s. Reifies s Tape => f (Reverse s a) -> Reverse s a) -> f a -> [f a] -- | Perform a conjugate gradient descent using reverse mode automatic -- differentiation to compute the gradient, and using forward-on-forward -- mode for computing extrema. -- --
-- >>> let sq x = x * x -- -- >>> let rosenbrock [x,y] = sq (1 - x) + 100 * sq (y - sq x) -- -- >>> rosenbrock [0,0] -- 1 -- -- >>> rosenbrock (conjugateGradientDescent rosenbrock [0, 0] !! 5) < 0.1 -- True --conjugateGradientDescent :: (Traversable f, Ord a, Fractional a) => (forall s. Chosen s => f (Or s (On (Forward (Forward a))) (Kahn a)) -> Or s (On (Forward (Forward a))) (Kahn a)) -> f a -> [f a] -- | Perform a conjugate gradient ascent using reverse mode automatic -- differentiation to compute the gradient. conjugateGradientAscent :: (Traversable f, Ord a, Fractional a) => (forall s. Chosen s => f (Or s (On (Forward (Forward a))) (Kahn a)) -> Or s (On (Forward (Forward a))) (Kahn a)) -> f a -> [f a] -- | The stochasticGradientDescent function approximates the true -- gradient of the constFunction by a gradient at a single example. As -- the algorithm sweeps through the training set, it performs the update -- for each training example. -- -- It uses reverse mode automatic differentiation to compute the gradient -- The learning rate is constant through out, and is set to 0.001 stochasticGradientDescent :: (Traversable f, Fractional a, Ord a) => (forall s. Reifies s Tape => f (Scalar a) -> f (Reverse s a) -> Reverse s a) -> [f (Scalar a)] -> f a -> [f a]