| Copyright | (C) 2025 Alexey Tochin |
|---|---|
| License | BSD3 (see the file LICENSE) |
| Maintainer | Alexey Tochin <Alexey.Tochin@gmail.com> |
| Safe Haskell | None |
| Language | Haskell2010 |
Numeric.InfBackprop.Core
Description
Backpropagation differentiation core types and functions.
Synopsis
- type family Tangent a
- type family Dual x
- type Cotangent a = Dual (Tangent a)
- type CT a = Cotangent a
- data RevDiff a b c = MkRevDiff {}
- type RevDiff' a b = RevDiff (CT a) (CT b) b
- type DifferentiableFunc a b = forall t. RevDiff t (CT a) a -> RevDiff t (CT b) b
- initDiff :: a -> RevDiff b b a
- call :: (RevDiff' a a -> RevDiff' a b) -> a -> b
- derivativeOp :: (RevDiff' a a -> RevDiff' a b) -> a -> CT b -> CT a
- toLensOps :: (RevDiff ca ca a -> RevDiff ca cb b) -> a -> (b, cb -> ca)
- constDiff :: Additive a => c -> RevDiff a b c
- class StopDiff a b where
- stopDiff :: a -> b
- class HasConstant a b c d where
- simpleDifferentiableFunc :: Multiplicative b => (b -> b) -> (b -> b) -> RevDiff a b b -> RevDiff a b b
- toLens :: (RevDiff b b a -> RevDiff b d c) -> Lens a b c d
- fromLens :: Lens a (CT a) b (CT b) -> RevDiff' a a -> RevDiff' a b
- fromProfunctors :: (forall (p :: Type -> Type -> Type). Costrong p => p (CT a) a -> p (CT b) b) -> DifferentiableFunc a b
- toProfunctors :: Costrong p => DifferentiableFunc a b -> p (CT a) a -> p (CT b) b
- fromVanLaarhoven :: forall a b. (forall (f :: Type -> Type). Functor f => (b -> f (CT b)) -> a -> f (CT a)) -> DifferentiableFunc a b
- toVanLaarhoven :: Functor f => DifferentiableFunc a b -> (b -> f (CT b)) -> a -> f (CT a)
- class (Additive (DerivativeRoot a), Additive (DerivativeCoarg a)) => AutoDifferentiableArgument a
- type family DerivativeRoot a
- type family DerivativeCoarg a
- type family DerivativeArg a
- class AutoDifferentiableValue a
- type family DerivativeValue a
- autoArg :: AutoDifferentiableArgument a => RevDiff (DerivativeRoot a) (DerivativeCoarg a) (DerivativeArg a) -> a
- autoVal :: AutoDifferentiableValue a => a -> DerivativeValue a
- sameTypeDerivative :: Multiplicative (CT a) => (RevDiff (CT a) (CT a) a -> RevDiff (CT a) (CT a) a) -> a -> CT a
- simpleDerivative :: forall a b. Multiplicative (CT b) => (RevDiff' a a -> RevDiff' a b) -> a -> CT a
- simpleValueAndDerivative :: forall a b. Multiplicative (CT b) => (RevDiff' a a -> RevDiff' a b) -> a -> (b, CT a)
- customArgDerivative :: AutoDifferentiableValue c => (RevDiff (CT a) (CT a) a -> b) -> (b -> c) -> a -> DerivativeValue c
- customValDerivative :: (DerivativeRoot b ~ CT (DerivativeArg b), DerivativeCoarg b ~ CT (DerivativeArg b), AutoDifferentiableArgument b) => (c -> d) -> (b -> c) -> DerivativeArg b -> d
- customArgValDerivative :: (RevDiff (CT a) (CT a) a -> b) -> (c -> d) -> (b -> c) -> a -> d
- differentiableSum :: Additive c => RevDiff a (b, b) (c, c) -> RevDiff a b c
- differentiableSub :: (Subtractive b, Subtractive c) => RevDiff a (b, b) (c, c) -> RevDiff a b c
- differentiableNegate :: (Subtractive a, Subtractive c) => RevDiff a b c -> RevDiff a b c
- differentiableMult :: Multiplicative b => RevDiff a (b, b) (b, b) -> RevDiff a b b
- differentiableDiv :: (Subtractive b, Divisive b) => RevDiff a (b, b) (b, b) -> RevDiff a b b
- differentiableRecip :: (Divisive b, Subtractive b, IntegerPower b) => RevDiff a b b -> RevDiff a b b
- differentiableMultAction :: (MultiplicativeAction a b, MultiplicativeAction a cb, Convolution b cb ca) => RevDiff ct (ca, cb) (a, b) -> RevDiff ct cb b
- differentiableConv :: (Convolution a b c, Convolution cc b ca, Convolution a cc cb) => RevDiff ct (ca, cb) (a, b) -> RevDiff ct cc c
- differentiablePow :: ExpField b => RevDiff a (b, b) (b, b) -> RevDiff a b b
- differentiableExp :: ExpField b => RevDiff a b b -> RevDiff a b b
- differentiableLog :: ExpField b => RevDiff a b b -> RevDiff a b b
- differentiableLogBase :: (ExpField b, IntegerPower b) => RevDiff a (b, b) (b, b) -> RevDiff a b b
- differentiableSqrt :: ExpField b => RevDiff a b b -> RevDiff a b b
- differentiableSin :: TrigField b => RevDiff a b b -> RevDiff a b b
- differentiableCos :: TrigField b => RevDiff a b b -> RevDiff a b b
- differentiableTan :: (TrigField b, IntegerPower b) => RevDiff a b b -> RevDiff a b b
- differentiableSinh :: TrigField b => RevDiff a b b -> RevDiff a b b
- differentiableCosh :: TrigField b => RevDiff a b b -> RevDiff a b b
- differentiableTanh :: (TrigField b, IntegerPower b) => RevDiff a b b -> RevDiff a b b
- differentiableAsin :: (TrigField b, ExpField b, IntegerPower b) => RevDiff a b b -> RevDiff a b b
- differentiableAcos :: (TrigField b, ExpField b, IntegerPower b) => RevDiff a b b -> RevDiff a b b
- differentiableAtan :: (TrigField b, IntegerPower b) => RevDiff a b b -> RevDiff a b b
- differentiableAtan2 :: (TrigField b, IntegerPower b) => RevDiff a (b, b) (b, b) -> RevDiff a b b
- differentiableAsinh :: (TrigField b, ExpField b, IntegerPower b) => RevDiff a b b -> RevDiff a b b
- differentiableAcosh :: (TrigField b, ExpField b, IntegerPower b) => RevDiff a b b -> RevDiff a b b
- differentiableAtanh :: (TrigField b, IntegerPower b) => RevDiff a b b -> RevDiff a b b
- scalarArg :: RevDiff a b c -> RevDiff a b c
- scalarVal :: Multiplicative b => RevDiff a b c -> a
- scalarArgDerivative :: AutoDifferentiableValue c => (RevDiff' a a -> c) -> a -> DerivativeValue c
- scalarValDerivative :: (DerivativeRoot b ~ CT a, DerivativeCoarg b ~ CT a, DerivativeArg b ~ a, Multiplicative (CT c), AutoDifferentiableArgument b) => (b -> RevDiff d (CT c) c) -> a -> d
- mkTupleArg :: (Additive b0, Additive b1) => RevDiffArg a b0 c0 d0 -> RevDiffArg a b1 c1 d1 -> RevDiffArg a (b0, b1) (c0, c1) (d0, d1)
- tupleArg :: (Additive b0, Additive b1) => RevDiff a (b0, b1) (c0, c1) -> (RevDiff a b0 c0, RevDiff a b1 c1)
- tupleArgDerivative :: (Additive (CT a0), Additive (CT a1), AutoDifferentiableValue b) => ((RevDiff' (a0, a1) a0, RevDiff' (a0, a1) a1) -> b) -> (a0, a1) -> DerivativeValue b
- tupleDerivativeOverX :: (AutoDifferentiableValue b, Additive (CT a0)) => ((RevDiff' a0 a0, RevDiff' a0 a1) -> b) -> (a0, a1) -> DerivativeValue b
- tupleDerivativeOverY :: (Additive (CT a1), AutoDifferentiableValue b) => ((RevDiff' a1 a0, RevDiff' a1 a1) -> b) -> (a0, a1) -> DerivativeValue b
- twoArgsDerivative :: (Additive (CT a0), Additive (CT a1), AutoDifferentiableValue b) => (RevDiff' (a0, a1) a0 -> RevDiff' (a0, a1) a1 -> b) -> a0 -> a1 -> DerivativeValue b
- twoArgsDerivativeOverX :: (Additive (CT a0), AutoDifferentiableValue b) => (RevDiff' a0 a0 -> RevDiff' a0 a1 -> b) -> a0 -> a1 -> DerivativeValue b
- twoArgsDerivativeOverY :: (Additive (CT a1), AutoDifferentiableValue b) => (RevDiff' a1 a0 -> RevDiff' a1 a1 -> b) -> a0 -> a1 -> DerivativeValue b
- mkTupleVal :: (a0 -> b0) -> (a1 -> b1) -> (a0, a1) -> (b0, b1)
- tupleVal :: (Multiplicative b0, Multiplicative b1) => (RevDiff a0 b0 c0, RevDiff a1 b1 c1) -> (a0, a1)
- tupleValDerivative :: (AutoDifferentiableArgument a, Multiplicative c0, Multiplicative c1, DerivativeCoarg a ~ CT (DerivativeArg a), DerivativeRoot a ~ CT (DerivativeArg a)) => (a -> (RevDiff b0 c0 d0, RevDiff b1 c1 d1)) -> DerivativeArg a -> (b0, b1)
- threeArgsToTriple :: Additive a => RevDiff a b0 c0 -> RevDiff a b1 c1 -> RevDiff a b2 c2 -> RevDiff a (b0, b1, b2) (c0, c1, c2)
- tripleArg :: (Additive b0, Additive b1, Additive b2) => RevDiff a (b0, b1, b2) (c0, c1, c2) -> (RevDiff a b0 c0, RevDiff a b1 c1, RevDiff a b2 c2)
- mkTripleArg :: (Additive b0, Additive b1, Additive b2) => RevDiffArg a b0 c0 d0 -> RevDiffArg a b1 c1 d1 -> RevDiffArg a b2 c2 d2 -> RevDiffArg a (b0, b1, b2) (c0, c1, c2) (d0, d1, d2)
- tripleArgDerivative :: (Additive (CT a0), Additive (CT a1), Additive (CT a2), AutoDifferentiableValue b) => ((RevDiff' (a0, a1, a2) a0, RevDiff' (a0, a1, a2) a1, RevDiff' (a0, a1, a2) a2) -> b) -> (a0, a1, a2) -> DerivativeValue b
- tripleDerivativeOverX :: (AutoDifferentiableValue b, Additive (CT a0)) => ((RevDiff' a0 a0, RevDiff' a0 a1, RevDiff' a0 a2) -> b) -> (a0, a1, a2) -> DerivativeValue b
- tripleDerivativeOverY :: (AutoDifferentiableValue b, Additive (CT a1)) => ((RevDiff' a1 a0, RevDiff' a1 a1, RevDiff' a1 a2) -> b) -> (a0, a1, a2) -> DerivativeValue b
- tripleDerivativeOverZ :: (AutoDifferentiableValue b, Additive (CT a2)) => ((RevDiff' a2 a0, RevDiff' a2 a1, RevDiff' a2 a2) -> b) -> (a0, a1, a2) -> DerivativeValue b
- threeArgsDerivative :: (AutoDifferentiableValue b, Additive (CT a0), Additive (CT a1), Additive (CT a2)) => (RevDiff' (a0, a1, a2) a0 -> RevDiff' (a0, a1, a2) a1 -> RevDiff' (a0, a1, a2) a2 -> b) -> a0 -> a1 -> a2 -> DerivativeValue b
- derivative3ArgsOverX :: (AutoDifferentiableValue b, Additive (CT a0)) => (RevDiff' a0 a0 -> RevDiff' a0 a1 -> RevDiff' a0 a2 -> b) -> a0 -> a1 -> a2 -> DerivativeValue b
- derivative3ArgsOverY :: (AutoDifferentiableValue b, Additive (CT a1)) => (RevDiff' a1 a0 -> RevDiff' a1 a1 -> RevDiff' a1 a2 -> b) -> a0 -> a1 -> a2 -> DerivativeValue b
- derivative3ArgsOverZ :: (AutoDifferentiableValue b, Additive (CT a2)) => (RevDiff' a2 a0 -> RevDiff' a2 a1 -> RevDiff' a2 a2 -> b) -> a0 -> a1 -> a2 -> DerivativeValue b
- mkTripleVal :: (a0 -> b0) -> (a1 -> b1) -> (a2 -> b2) -> (a0, a1, a2) -> (b0, b1, b2)
- tripleVal :: (Multiplicative b0, Multiplicative b1, Multiplicative b2) => (RevDiff a0 b0 c0, RevDiff a1 b1 c1, RevDiff a2 b2 c2) -> (a0, a1, a2)
- tripleValDerivative :: (AutoDifferentiableArgument a, Multiplicative c0, Multiplicative c1, Multiplicative c2, DerivativeCoarg a ~ CT (DerivativeArg a), DerivativeRoot a ~ CT (DerivativeArg a)) => (a -> (RevDiff b0 c0 d0, RevDiff b1 c1 d1, RevDiff b2 c2 d2)) -> DerivativeArg a -> (b0, b1, b2)
- boxedVectorArg :: forall b (n :: Nat) a c. (Additive b, KnownNat n) => RevDiff a (BoxedVector n b) (BoxedVector n c) -> BoxedVector n (RevDiff a b c)
- mkBoxedVectorArg :: forall b (n :: Nat) a c d. (Additive b, KnownNat n) => RevDiffArg a b c d -> RevDiffArg a (BoxedVector n b) (BoxedVector n c) (BoxedVector n d)
- boxedVectorArgDerivative :: forall (n :: Nat) b a. (KnownNat n, AutoDifferentiableValue b, Additive (CT a)) => (BoxedVector n (RevDiff' (BoxedVector n a) a) -> b) -> BoxedVector n a -> DerivativeValue b
- boxedVectorVal :: forall b (n :: Nat) a c. Multiplicative b => BoxedVector n (RevDiff a b c) -> BoxedVector n a
- mkBoxedVectorVal :: forall a b (n :: Nat). (a -> b) -> BoxedVector n a -> BoxedVector n b
- boxedVectorValDerivative :: forall a c (n :: Nat) b d. (AutoDifferentiableArgument a, Multiplicative c, DerivativeCoarg a ~ CT (DerivativeArg a), DerivativeRoot a ~ CT (DerivativeArg a)) => (a -> BoxedVector n (RevDiff b c d)) -> DerivativeArg a -> BoxedVector n b
- streamArg :: Additive b => RevDiff a (FiniteSupportStream b) (Stream c) -> Stream (RevDiff a b c)
- mkStreamArg :: Additive b => (RevDiff a b c -> d) -> RevDiff a (FiniteSupportStream b) (Stream c) -> Stream d
- streamArgDerivative :: (AutoDifferentiableValue b, Additive (CT a)) => (Stream (RevDiff' (Stream a) a) -> b) -> Stream a -> DerivativeValue b
- streamVal :: Multiplicative b => Stream (RevDiff a b c) -> Stream a
- mkStreamVal :: (a -> b) -> Stream a -> Stream b
- streamValDerivative :: (AutoDifferentiableArgument a, Multiplicative c, DerivativeCoarg a ~ CT (DerivativeArg a), DerivativeRoot a ~ CT (DerivativeArg a)) => (a -> Stream (RevDiff b c d)) -> DerivativeArg a -> Stream b
- finiteSupportStreamArg :: Additive b => RevDiff a (Stream b) (FiniteSupportStream c) -> FiniteSupportStream (RevDiff a b c)
- mkFiniteSupportStreamArg :: Additive b => (RevDiff a b c -> d) -> RevDiff a (Stream b) (FiniteSupportStream c) -> FiniteSupportStream d
- finiteSupportStreamArgDerivative :: (AutoDifferentiableValue b, Additive (CT a)) => (FiniteSupportStream (RevDiff' (FiniteSupportStream a) a) -> b) -> FiniteSupportStream a -> DerivativeValue b
- finiteSupportStreamVal :: Multiplicative b => FiniteSupportStream (RevDiff a b c) -> FiniteSupportStream a
- mkFiniteSupportStreamVal :: (a -> b) -> FiniteSupportStream a -> FiniteSupportStream b
- finiteSupportStreamValDerivative :: (AutoDifferentiableArgument a, Multiplicative c, DerivativeCoarg a ~ CT (DerivativeArg a), DerivativeRoot a ~ CT (DerivativeArg a)) => (a -> FiniteSupportStream (RevDiff b c d)) -> DerivativeArg a -> FiniteSupportStream b
- maybeArg :: RevDiff a (Maybe b) (Maybe c) -> Maybe (RevDiff a b c)
- mkMaybeArg :: (RevDiff a b c -> d) -> RevDiff a (Maybe b) (Maybe c) -> Maybe d
- maybeArgDerivative :: AutoDifferentiableValue b => (Maybe (RevDiff' (Maybe a) a) -> b) -> Maybe a -> DerivativeValue b
- maybeVal :: Multiplicative b => Maybe (RevDiff a b c) -> Maybe a
- mkMaybeVal :: (a -> b) -> Maybe a -> Maybe b
- maybeValDerivative :: (AutoDifferentiableArgument a, Multiplicative c, DerivativeCoarg a ~ CT (DerivativeArg a), DerivativeRoot a ~ CT (DerivativeArg a)) => (a -> Maybe (RevDiff b c d)) -> DerivativeArg a -> Maybe b
Common
Base
type family Tangent a Source #
Converts a type into its tangent space type.
Instances
| type Tangent SimpleExpr Source # | |
Defined in Numeric.InfBackprop.Core type Tangent SimpleExpr = SimpleExpr | |
| type Tangent Integer Source # | |
Defined in Numeric.InfBackprop.Core | |
| type Tangent Float Source # | |
Defined in Numeric.InfBackprop.Core | |
| type Tangent (Stream a) Source # | |
Defined in Numeric.InfBackprop.Core | |
| type Tangent (FiniteSupportStream a) Source # | |
Defined in Numeric.InfBackprop.Core | |
| type Tangent (Complex a) Source # | |
Defined in Numeric.InfBackprop.Core | |
| type Tangent (Traced a) Source # | |
Defined in Numeric.InfBackprop.Core | |
| type Tangent (Maybe a) Source # | |
Defined in Numeric.InfBackprop.Core | |
| type Tangent [a] Source # | |
Defined in Numeric.InfBackprop.Core | |
| type Tangent (Vec n a) Source # | |
Defined in Numeric.InfBackprop.Core | |
| type Tangent (a0, a1) Source # | |
Defined in Numeric.InfBackprop.Core | |
| type Tangent (RevDiff a b c) Source # | |
| type Tangent (Vector v n a) Source # | |
Defined in Numeric.InfBackprop.Core | |
| type Tangent (a0, a1, a2) Source # | |
Defined in Numeric.InfBackprop.Core | |
Converts a type into its dual space type.
Instances
| type Dual SimpleExpr Source # | |
Defined in Numeric.InfBackprop.Core type Dual SimpleExpr = SimpleExpr | |
| type Dual Integer Source # | |
Defined in Numeric.InfBackprop.Core | |
| type Dual Float Source # | |
Defined in Numeric.InfBackprop.Core | |
| type Dual (Stream a) Source # | |
Defined in Numeric.InfBackprop.Core | |
| type Dual (FiniteSupportStream a) Source # | |
Defined in Numeric.InfBackprop.Core | |
| type Dual (Complex a) Source # | |
Defined in Numeric.InfBackprop.Core | |
| type Dual (SimpleExprF a) Source # | |
Defined in Numeric.InfBackprop.Core | |
| type Dual (Traced a) Source # | |
Defined in Numeric.InfBackprop.Core | |
| type Dual (Maybe a) Source # | |
Defined in Numeric.InfBackprop.Core | |
| type Dual [a] Source # | |
Defined in Numeric.InfBackprop.Core | |
| type Dual (Vec n a) Source # | |
Defined in Numeric.InfBackprop.Core | |
| type Dual (a, b) Source # | |
Defined in Numeric.InfBackprop.Core | |
| type Dual (RevDiff a b c) Source # | |
| type Dual (Vector v n a) Source # | |
Defined in Numeric.InfBackprop.Core | |
| type Dual (a, b, c) Source # | |
Defined in Numeric.InfBackprop.Core | |
Base type for differentiable instances with the backpropagation.
Examples
>>>:{differentiableSin_ :: RevDiff t Float Float -> RevDiff t Float Float differentiableSin_ (MkRevDiff v bp) = MkRevDiff (sin v) (bp . (cos v *)) :}
>>>value $ differentiableSin_ (MkRevDiff 0.0 id)0.0
>>>backprop (differentiableSin_ (MkRevDiff 0.0 id)) 1.01.0
Num typeclass instance
This instance enables the use of standard numeric operations and literals
directly with RevDiff values, simplifying the syntax for
automatic differentiation computations.--
The instance supports Num operations including arithmetic
operators (+), (-), (*), comparison functions (abs, signum), and automatic
conversion from integer literals via fromInteger.
Examples
>>>import Debug.SimpleExpr (variable, SE, simplify)>>>import GHC.Integer (Integer)
>>>x = variable "x"
Using numeric literals in automatic differentiation
This instance allows RevDiff values to be created directly from integer
literals, eliminating the need for explicit conversion functions.
Consider computing the partial derivative:
\[ \left.\frac{\partial}{\partial y} (x \cdot y)\right|_{y=2} \]
Without the Num instance, we would need explicit conversion:
>>>simplify $ twoArgsDerivativeOverY (*) x (stopDiff $ number 2) :: SEx
With the Num instance for RevDiff, this simplifies to:
>>>simplify $ twoArgsDerivativeOverY (*) x (number 2) :: SEx
And combined with the Num instance for SE,
we achieve the most concise form:
>>>simplify $ twoArgsDerivativeOverY (*) x 2x
This progression shows how the typeclass instances work together to enable increasingly natural mathematical notation.
Power function differentiation
The instance enables natural exponentiation syntax with automatic differentiation:
>>>x ** 3 :: SEx^3>>>simplify $ simpleDerivative (** 3) x :: SE3*(x^2)>>>simplify $ simpleDerivative (simpleDerivative (** 3)) x :: SE(2*x)*3
Absolute value and signum functions
The instance provides symbolic differentiation for absolute value and signum:
>>>simplify $ simpleDerivative GHCN.abs (variable "x") :: SEsign(x)
>>>simplify $ simpleDerivative GHCN.signum (variable "x") :: SE0
For numeric evaluation, the second derivative of absolute value at a point gives the expected result:
>>>(simpleDerivative (simpleDerivative GHCN.abs)) (1 :: Float) :: Float0.0
Notice that the signum function returns zero for all values, including zero.
>>>simpleDerivative GHCN.signum (0 :: Float) :: Float0.0
>>>simplify $ (simpleDerivative (simpleDerivative GHCN.abs)) (variable "x") :: SE0
Fractional typeclass instance
Thank to this instance we can use numerical literals like '1.0', '2.0', etc., see the examples below.
Examples
>>>import GHC.Float (Float)>>>import Debug.SimpleExpr (variable, SE, simplify)
>>>f x = 8 / x>>>simpleDerivative f (2.0 :: Float)-2.0>>>simplify $ simpleDerivative f (variable "x") :: SE-((8/x)/x)
Instances
type RevDiff' a b = RevDiff (CT a) (CT b) b Source #
Type alias for common case where the backpropagation is in the cotangent space.
type DifferentiableFunc a b = forall t. RevDiff t (CT a) a -> RevDiff t (CT b) b Source #
Type DifferentiableFunc a b may be associated with the differentiable
functions from a to b.
Composition (.) of
DifferentiableFunc b c and DifferentiableFunc a b is DifferentiableFunc a c
by definition.
See fromProfunctors, toProfunctors, fromVanLaarhoven and fromVanLaarhoven
for illustraing how to use this type.
Examples
>>>:{differentiableCos_ :: DifferentiableFunc Float Float differentiableCos_ (MkRevDiff x bpc) = MkRevDiff (cos x) (bpc . ((negate $ sin x) *)) :}
>>>call differentiableCos_ 0.01.0
>>>simpleDerivative differentiableCos_ 0.0-0.0
initDiff :: a -> RevDiff b b a Source #
Initializes a MkRevDiff instance with given value
and identity backpropagation function.
This is useful for starting the backpropagation chain.
Examples
>>>:{differentiableCos_ :: RevDiff t Float Float -> RevDiff t Float Float differentiableCos_ (MkRevDiff v bp) = MkRevDiff (cos v) (bp . negate . (sin v *)) :}
>>>value $ differentiableCos_ (initDiff 0.0)1.0
>>>backprop (differentiableCos_ (initDiff 0.0)) 1.0-0.0
call :: (RevDiff' a a -> RevDiff' a b) -> a -> b Source #
Converts a differentiable function into a regular function.
Examples
>>>import Debug.SimpleExpr (variable)>>>import Debug.DiffExpr (unarySymbolicFunc)
>>>:{differentiableCos_ :: RevDiff t Float Float -> RevDiff t Float Float differentiableCos_ (MkRevDiff v bp) = MkRevDiff (cos v) (bp . negate . (sin v *)) :}
>>>call differentiableCos_ 0.01.0
>>>x = variable "x">>>f = unarySymbolicFunc "f">>>f xf(x)
>>>call f xf(x)
derivativeOp :: (RevDiff' a a -> RevDiff' a b) -> a -> CT b -> CT a Source #
Converts a differentiable function into into its derivative in the form of multiplicative operator.
Examples
>>>import Debug.SimpleExpr (variable)>>>import Debug.DiffExpr (unarySymbolicFunc)
>>>:{differentiableSin_ :: RevDiff t Float Float -> RevDiff t Float Float differentiableSin_ (MkRevDiff v bp) = MkRevDiff (sin v) (bp . (cos v *)) :}
>>>(derivativeOp differentiableSin_ 0.0) 1.01.0
>>>c = variable "c">>>x = variable "x">>>f = unarySymbolicFunc "f">>>f xf(x)>>>(derivativeOp f x) cf'(x)*c
toLensOps :: (RevDiff ca ca a -> RevDiff ca cb b) -> a -> (b, cb -> ca) Source #
Converts a function into a pair of its value and backpropagation function, which are the lense get and set functions, respectively.
constDiff :: Additive a => c -> RevDiff a b c Source #
Creates a constant differentiable function. The derivative of a constant function is always zero.
Examples
>>>value (constDiff 42.0 :: RevDiff' Float Float)42.0
>>>backprop (constDiff 42.0 :: RevDiff' Float Float) 1.00.0
class StopDiff a b where Source #
Typeclass for the automatic iterrupt of the backpropagation.
Examples
>>>:{simpleDerivative (\x -> x * twoArgsDerivativeOverY (+) x (stopDiff (1 :: Float))) (2024 :: Float) :} 1.0
Methods
Stops differentiation by converting a nested RevDiff type
into a non-differentiable type.
class HasConstant a b c d where Source #
Typeclass for creating constant differentiable functions.
Instances
| HasConstant a b a b Source # | Base case: constant function for the same type. |
Defined in Numeric.InfBackprop.Core | |
| (HasConstant a b c d, Additive t, e ~ CT c, f ~ CT d) => HasConstant a b (RevDiff t e c) (RevDiff t f d) Source # | Recursive case: constant function for |
simpleDifferentiableFunc :: Multiplicative b => (b -> b) -> (b -> b) -> RevDiff a b b -> RevDiff a b b Source #
Creates a differentiable function from a function and its derivative. This is a convenience function for defining new differentiable operations.
Examples
>>>:{differentiableCos_ :: RevDiff t Float Float -> RevDiff t Float Float differentiableCos_ = simpleDifferentiableFunc cos (negate . sin) :}
>>>call differentiableCos_ 0.01.0
>>>simpleDerivative differentiableCos_ 0.0-0.0
Relation to lens and profunctors
toLens :: (RevDiff b b a -> RevDiff b d c) -> Lens a b c d Source #
Converts a differentiable function into a law-breaking Lens.
This is mutually inverse with fromLens.
Examples
>>>import Optics (Lens', lens, view, set, getting, (%))>>>import Debug.SimpleExpr (variable, SE)
>>>sinLens = toLens sin :: Lens' SE SE>>>x = variable "x">>>c = variable "c">>>(view . getting) sinLens xsin(x)>>>set sinLens c xcos(x)*c>>>squareLens = toLens (^2) :: Lens' SE SE>>>(view . getting) (squareLens % sinLens) xsin(x^2)
fromLens :: Lens a (CT a) b (CT b) -> RevDiff' a a -> RevDiff' a b Source #
Converts a law-breaking Lens into a differentiable function.
This is mutually inverse with toLens.
Examples
>>>import Optics (lens)>>>import Debug.SimpleExpr (variable, SE, simplify)
>>>sinV2 = fromLens $ lens sin (\x -> (cos x *))>>>x = variable "x">>>c = variable "c">>>call sinV2 xsin(x)>>>simplify $ simpleDerivative sinV2 x :: SEcos(x)
fromProfunctors :: (forall (p :: Type -> Type -> Type). Costrong p => p (CT a) a -> p (CT b) b) -> DifferentiableFunc a b Source #
Transorfms profunctor (Costrong) map into a RevDiff map.
Inverse of toProfunctors.
toProfunctors :: Costrong p => DifferentiableFunc a b -> p (CT a) a -> p (CT b) b Source #
Profunctor representation of the RevDiff like for lens map in the spirit of optics.
Inverse of fromProfunctors.
fromVanLaarhoven :: forall a b. (forall (f :: Type -> Type). Functor f => (b -> f (CT b)) -> a -> f (CT a)) -> DifferentiableFunc a b Source #
Converts a Van Laarhoven representation to a function over RevDiff types
Inverse of toVanLaarhoven.
toVanLaarhoven :: Functor f => DifferentiableFunc a b -> (b -> f (CT b)) -> a -> f (CT a) Source #
Converts a function over RevDiff types into a Van Laarhoven representation.
Inverse of fromVanLaarhoven.
Derivative operators
class (Additive (DerivativeRoot a), Additive (DerivativeCoarg a)) => AutoDifferentiableArgument a Source #
Typeclass needed for the automatic agrument descriptor derivation.
See instance implementations for RevDiff, tuple and BoxedVector below.
Examples
>>>:{sphericToVector :: (TrigField a) => (a, a) -> BoxedVector 3 a sphericToVector (theta, phi) = DVGS.fromTuple (cos theta * cos phi, cos theta * sin phi, sin theta) :}
>>>sphericToVector' = customArgValDerivative autoArg boxedVectorVal sphericToVector>>>sphericToVector' (0 :: Float, 0 :: Float)Vector [(0.0,0.0),(0.0,1.0),(1.0,0.0)]
Minimal complete definition
Instances
| AutoDifferentiableArgument a => AutoDifferentiableArgument (Stream a) Source # |
| ||||||||||||
Defined in Numeric.InfBackprop.Core Associated Types
Methods autoArg :: RevDiff (DerivativeRoot (Stream a)) (DerivativeCoarg (Stream a)) (DerivativeArg (Stream a)) -> Stream a Source # | |||||||||||||
| AutoDifferentiableArgument a => AutoDifferentiableArgument (FiniteSupportStream a) Source # |
| ||||||||||||
Defined in Numeric.InfBackprop.Core Associated Types
Methods autoArg :: RevDiff (DerivativeRoot (FiniteSupportStream a)) (DerivativeCoarg (FiniteSupportStream a)) (DerivativeArg (FiniteSupportStream a)) -> FiniteSupportStream a Source # | |||||||||||||
| AutoDifferentiableArgument a => AutoDifferentiableArgument (Maybe a) Source # |
| ||||||||||||
Defined in Numeric.InfBackprop.Core Associated Types
Methods autoArg :: RevDiff (DerivativeRoot (Maybe a)) (DerivativeCoarg (Maybe a)) (DerivativeArg (Maybe a)) -> Maybe a Source # | |||||||||||||
| (AutoDifferentiableArgument a, KnownNat n) => AutoDifferentiableArgument (BoxedVector n a) Source # |
| ||||||||||||
Defined in Numeric.InfBackprop.Core Associated Types
Methods autoArg :: RevDiff (DerivativeRoot (BoxedVector n a)) (DerivativeCoarg (BoxedVector n a)) (DerivativeArg (BoxedVector n a)) -> BoxedVector n a Source # | |||||||||||||
| (AutoDifferentiableArgument a0, AutoDifferentiableArgument a1, DerivativeRoot a0 ~ DerivativeRoot a1) => AutoDifferentiableArgument (a0, a1) Source # | Tuple instance for | ||||||||||||
Defined in Numeric.InfBackprop.Core Associated Types
Methods autoArg :: RevDiff (DerivativeRoot (a0, a1)) (DerivativeCoarg (a0, a1)) (DerivativeArg (a0, a1)) -> (a0, a1) Source # | |||||||||||||
| (Additive a, Additive b) => AutoDifferentiableArgument (RevDiff a b c) Source # |
| ||||||||||||
Defined in Numeric.InfBackprop.Core Associated Types
Methods autoArg :: RevDiff (DerivativeRoot (RevDiff a b c)) (DerivativeCoarg (RevDiff a b c)) (DerivativeArg (RevDiff a b c)) -> RevDiff a b c Source # | |||||||||||||
| (AutoDifferentiableArgument a0, AutoDifferentiableArgument a1, AutoDifferentiableArgument a2, DerivativeRoot a0 ~ DerivativeRoot a1, DerivativeRoot a0 ~ DerivativeRoot a2) => AutoDifferentiableArgument (a0, a1, a2) Source # | Triple instance for | ||||||||||||
Defined in Numeric.InfBackprop.Core Associated Types
Methods autoArg :: RevDiff (DerivativeRoot (a0, a1, a2)) (DerivativeCoarg (a0, a1, a2)) (DerivativeArg (a0, a1, a2)) -> (a0, a1, a2) Source # | |||||||||||||
type family DerivativeRoot a Source #
Differentiable function root
Instances
| type DerivativeRoot (Stream a) Source # | |
Defined in Numeric.InfBackprop.Core | |
| type DerivativeRoot (FiniteSupportStream a) Source # | |
Defined in Numeric.InfBackprop.Core | |
| type DerivativeRoot (Maybe a) Source # | |
Defined in Numeric.InfBackprop.Core | |
| type DerivativeRoot (BoxedVector n a) Source # | |
Defined in Numeric.InfBackprop.Core | |
| type DerivativeRoot (a0, a1) Source # | |
Defined in Numeric.InfBackprop.Core | |
| type DerivativeRoot (RevDiff a b c) Source # | |
Defined in Numeric.InfBackprop.Core | |
| type DerivativeRoot (a0, a1, a2) Source # | |
Defined in Numeric.InfBackprop.Core | |
type family DerivativeCoarg a Source #
Differentiable function coargument
Instances
| type DerivativeCoarg (Stream a) Source # | |
Defined in Numeric.InfBackprop.Core | |
| type DerivativeCoarg (FiniteSupportStream a) Source # | |
Defined in Numeric.InfBackprop.Core | |
| type DerivativeCoarg (Maybe a) Source # | |
Defined in Numeric.InfBackprop.Core | |
| type DerivativeCoarg (BoxedVector n a) Source # | |
Defined in Numeric.InfBackprop.Core | |
| type DerivativeCoarg (a0, a1) Source # | |
Defined in Numeric.InfBackprop.Core | |
| type DerivativeCoarg (RevDiff a b c) Source # | |
Defined in Numeric.InfBackprop.Core | |
| type DerivativeCoarg (a0, a1, a2) Source # | |
Defined in Numeric.InfBackprop.Core | |
type family DerivativeArg a Source #
Differentiable functin argument
Instances
| type DerivativeArg (Stream a) Source # | |
Defined in Numeric.InfBackprop.Core | |
| type DerivativeArg (FiniteSupportStream a) Source # | |
Defined in Numeric.InfBackprop.Core | |
| type DerivativeArg (Maybe a) Source # | |
Defined in Numeric.InfBackprop.Core | |
| type DerivativeArg (BoxedVector n a) Source # | |
Defined in Numeric.InfBackprop.Core | |
| type DerivativeArg (a0, a1) Source # | |
Defined in Numeric.InfBackprop.Core | |
| type DerivativeArg (RevDiff a b c) Source # | |
Defined in Numeric.InfBackprop.Core | |
| type DerivativeArg (a0, a1, a2) Source # | |
Defined in Numeric.InfBackprop.Core | |
class AutoDifferentiableValue a Source #
Typeclass needed for the automatic value term derivation.
Examples
>>>:{sphericToVector :: (TrigField a) => (a, a) -> BoxedVector 3 a sphericToVector (theta, phi) = DVGS.fromTuple (cos theta * cos phi, cos theta * sin phi, sin theta) :}
>>>sphericToVector' = customArgValDerivative tupleArg autoVal sphericToVector>>>sphericToVector' (0 :: Float, 0 :: Float)Vector [(0.0,0.0),(0.0,1.0),(1.0,0.0)]
Minimal complete definition
Instances
| AutoDifferentiableValue a => AutoDifferentiableValue (Stream a) Source # |
| ||||
Defined in Numeric.InfBackprop.Core Associated Types
| |||||
| AutoDifferentiableValue a => AutoDifferentiableValue (FiniteSupportStream a) Source # |
| ||||
Defined in Numeric.InfBackprop.Core Associated Types
Methods autoVal :: FiniteSupportStream a -> DerivativeValue (FiniteSupportStream a) Source # | |||||
| AutoDifferentiableValue a => AutoDifferentiableValue (Maybe a) Source # |
| ||||
Defined in Numeric.InfBackprop.Core Associated Types
| |||||
| AutoDifferentiableValue a => AutoDifferentiableValue (BoxedVector n a) Source # |
| ||||
Defined in Numeric.InfBackprop.Core Associated Types
Methods autoVal :: BoxedVector n a -> DerivativeValue (BoxedVector n a) Source # | |||||
| (AutoDifferentiableValue a0, AutoDifferentiableValue a1) => AutoDifferentiableValue (a0, a1) Source # | Tuple instance for | ||||
Defined in Numeric.InfBackprop.Core Associated Types
Methods autoVal :: (a0, a1) -> DerivativeValue (a0, a1) Source # | |||||
| Multiplicative b => AutoDifferentiableValue (RevDiff a b c) Source # |
| ||||
Defined in Numeric.InfBackprop.Core Associated Types
| |||||
| (AutoDifferentiableValue a0, AutoDifferentiableValue a1, AutoDifferentiableValue a2) => AutoDifferentiableValue (a0, a1, a2) Source # | Triple instance for | ||||
Defined in Numeric.InfBackprop.Core Associated Types
Methods autoVal :: (a0, a1, a2) -> DerivativeValue (a0, a1, a2) Source # | |||||
type family DerivativeValue a Source #
Differentiable function value type.
Instances
| type DerivativeValue (Stream a) Source # | |
Defined in Numeric.InfBackprop.Core | |
| type DerivativeValue (FiniteSupportStream a) Source # | |
Defined in Numeric.InfBackprop.Core | |
| type DerivativeValue (Maybe a) Source # | |
Defined in Numeric.InfBackprop.Core | |
| type DerivativeValue (BoxedVector n a) Source # | |
Defined in Numeric.InfBackprop.Core | |
| type DerivativeValue (a0, a1) Source # | |
Defined in Numeric.InfBackprop.Core | |
| type DerivativeValue (RevDiff a b c) Source # | |
Defined in Numeric.InfBackprop.Core | |
| type DerivativeValue (a0, a1, a2) Source # | |
Defined in Numeric.InfBackprop.Core | |
autoArg :: AutoDifferentiableArgument a => RevDiff (DerivativeRoot a) (DerivativeCoarg a) (DerivativeArg a) -> a Source #
Automatic argument descriptor.
autoVal :: AutoDifferentiableValue a => a -> DerivativeValue a Source #
Automatic value descriptor.
sameTypeDerivative :: Multiplicative (CT a) => (RevDiff (CT a) (CT a) a -> RevDiff (CT a) (CT a) a) -> a -> CT a Source #
Derivative of a function from any type to the same type. The type structure of the input and output values must be the same.
Examples
>>>f = sin :: TrigField a => a -> a>>>f' = sameTypeDerivative f :: Float -> Float
>>>f' 0.01.0
simpleDerivative :: forall a b. Multiplicative (CT b) => (RevDiff' a a -> RevDiff' a b) -> a -> CT a Source #
Derivative for a scalar-to-scalar function.
Examples
>>>import Debug.SimpleExpr (variable, simplify, SimpleExpr)>>>import Debug.DiffExpr (unarySymbolicFunc)
>>>simpleDerivative sin (0.0 :: Float)1.0
>>>x = variable "x"
>>>simplify $ simpleDerivative (^ 2) x2*x
>>>f = unarySymbolicFunc "f"
>>>simplify $ simpleDerivative f x :: SimpleExprf'(x)
simpleValueAndDerivative :: forall a b. Multiplicative (CT b) => (RevDiff' a a -> RevDiff' a b) -> a -> (b, CT a) Source #
Returns both the value and the derivative for a scalar-to-scalar function.
Examples
>>>import Debug.SimpleExpr (variable, simplify, SimpleExpr)>>>import Debug.DiffExpr (unarySymbolicFunc)
>>>simpleValueAndDerivative sin (0.0 :: Float)(0.0,1.0)
>>>x = variable "x">>>f = unarySymbolicFunc "f"
>>>simplify $ simpleValueAndDerivative f x :: (SimpleExpr, SimpleExpr)(f(x),f'(x))
customArgDerivative :: AutoDifferentiableValue c => (RevDiff (CT a) (CT a) a -> b) -> (b -> c) -> a -> DerivativeValue c Source #
Derivative operator for a function with a specified argument type, but with the value type derived automatically.
Examples
>>>:{sphericToVec :: (TrigField a) => (a, a) -> BoxedVector 3 a sphericToVec (theta, phi) = DVGS.fromTuple (cos theta * cos phi, cos theta * sin phi, sin theta) :}
>>>sphericToVec' = customArgDerivative tupleArg sphericToVec
Here tupleArg indicates that the argument type is a tuple.
>>>sphericToVec' (0 :: Float, 0 :: Float)Vector [(0.0,0.0),(0.0,1.0),(1.0,0.0)]
customValDerivative :: (DerivativeRoot b ~ CT (DerivativeArg b), DerivativeCoarg b ~ CT (DerivativeArg b), AutoDifferentiableArgument b) => (c -> d) -> (b -> c) -> DerivativeArg b -> d Source #
Derivative operator for a function with specified argument type but automatically derived value type.
Examples
>>>:{sphericToVector :: (TrigField a) => (a, a) -> BoxedVector 3 a sphericToVector (theta, phi) = DVGS.fromTuple (cos theta * cos phi, cos theta * sin phi, sin theta) :}
>>>sphericToVector' = customValDerivative boxedVectorVal sphericToVector
The term boxedVectorVal specifies that the output value type is a boxed vector.
>>>sphericToVector' (0 :: Float, 0 :: Float)Vector [(0.0,0.0),(0.0,1.0),(1.0,0.0)]
customArgValDerivative :: (RevDiff (CT a) (CT a) a -> b) -> (c -> d) -> (b -> c) -> a -> d Source #
Derivative of a function from any type to any type. The type structure of the input and output values must be specified in the first and second arguments, respectively. The output value type of the derivative is infereced automatically.
Examples
>>>:{sphericToVec :: (TrigField a) => (a, a) -> BoxedVector 3 a sphericToVec (theta, phi) = DVGS.fromTuple (cos theta * cos phi, cos theta * sin phi, sin theta) :}
>>>sphericToVec' = customArgValDerivative tupleArg boxedVectorVal sphericToVec
Here tupleArg manifests that the argument type is a tuple.
The second term boxedVectorVal specifies that the output value type is a boxed vector.
>>>sphericToVec' (0 :: Float, 0 :: Float)Vector [(0.0,0.0),(0.0,1.0),(1.0,0.0)]
Differentiable functions
Basic
differentiableSub :: (Subtractive b, Subtractive c) => RevDiff a (b, b) (c, c) -> RevDiff a b c Source #
differentiableNegate :: (Subtractive a, Subtractive c) => RevDiff a b c -> RevDiff a b c Source #
differentiableMult :: Multiplicative b => RevDiff a (b, b) (b, b) -> RevDiff a b b Source #
differentiableDiv :: (Subtractive b, Divisive b) => RevDiff a (b, b) (b, b) -> RevDiff a b b Source #
Differentiable version of division (/) for the RevDiff type.
Implements the quotient rule: \[ \frac{d}{dx} (f(x)/g(x)) = \frac{\frac{df(x)}{dx} \cdot g(x) - f(x) \cdot \frac{dg(x)}{dx}}{g^2(x)}. \] The numerator receives gradient divided by the denominator, while the denominator receives negative gradient scaled by the quotient divided by itself.
differentiableRecip :: (Divisive b, Subtractive b, IntegerPower b) => RevDiff a b b -> RevDiff a b b Source #
differentiableMultAction :: (MultiplicativeAction a b, MultiplicativeAction a cb, Convolution b cb ca) => RevDiff ct (ca, cb) (a, b) -> RevDiff ct cb b Source #
Differentiable version of multiplicative action (*|) for the RevDiff type.
Implements the product rule for scalar \( f \) and, for example, vector \( g_i \):
\[ \frac{d}{dx} \left( f(x) \cdot g_i(x) \right) = f(x) \cdot \frac{d g_i(x)}{dx} + \frac{df(x)}{dx} \cdot g_i(x). \] Each operand receives the gradient multiplied by the value of the other operand.
differentiableConv :: (Convolution a b c, Convolution cc b ca, Convolution a cc cb) => RevDiff ct (ca, cb) (a, b) -> RevDiff ct cc c Source #
Differentiable version of convolution (|*|) for the RevDiff type.
Implements the product rule for, for example, vectors \( f_i \) and \( g_i \):
\[ \frac{d}{dx} \sum_i f_i(x) \cdot g_i(x) = \sum_i f_i(x) \cdot \frac{d g_i(x)}{dx} + \frac{d f_i(x)}{dx} \cdot g_i(x) \] Each operand receives the gradient multiplied by the value of the other operand.
Exponential and logarithmic functions
differentiableLog :: ExpField b => RevDiff a b b -> RevDiff a b b Source #
Differentiable version of natural logarithm for the RevDiff type.
Implements \[ \frac{d}{dx} \log \left| f(x) \right| = \frac{1}{f(x)} \cdot \frac{df(x)}{dx}. \] For real numbers, this computes the derivative of \(\log |x|\), which is defined for all non-zero values.
Unsafety note: This function and derivative will raise an error if f is zero, as the
logarithm and recip from numhask is undefined at zero point.
Examples
>>>import Debug.SimpleExpr (variable, SE, simplify)
>>>simplify $ simpleDerivative differentiableLog (variable "x") :: SE1/x
differentiableLogBase :: (ExpField b, IntegerPower b) => RevDiff a (b, b) (b, b) -> RevDiff a b b Source #
Trigonometric functions
differentiableSin :: TrigField b => RevDiff a b b -> RevDiff a b b Source #
Differentiable version of sine function for the RevDiff type.
Implements \[ d\frac{d}{dx} \sin f(x) = \cos f(x) * \frac{df(x)}{dx} \] using the standard trigonometric derivative.
Examples
>>>call differentiableSin 0.0 :: Float0.0>>>simpleDerivative differentiableSin 0.0 :: Float1.0
differentiableCos :: TrigField b => RevDiff a b b -> RevDiff a b b Source #
Differentiable version of cosine function for the RevDiff type.
Implements \[ \frac{d}{dx} \cos f(x) = -\sin f(x) \cdot \frac{df(x)}{dx} \] using the standard trigonometric derivative.
Examples
>>>call differentiableCos 0.0 :: Float1.0>>>simpleDerivative differentiableCos 0.0 :: Float-0.0
differentiableTan :: (TrigField b, IntegerPower b) => RevDiff a b b -> RevDiff a b b Source #
Differentiable version of tangent function for the RevDiff type.
Implements \[ \frac{d]{dx} \tg f(x) = \sec^2 f(x) * \frac{df(x)}{dx} = \frac{1}{cos^2 f(x)} \cdot \frac{df(x)}{dx}. \]
Examples
>>>call differentiableTan 0.0 :: Float0.0>>>simpleDerivative differentiableTan 0.0 :: Float1.0
differentiableSinh :: TrigField b => RevDiff a b b -> RevDiff a b b Source #
Differentiable version of hyperbolic sine function for the RevDiff type.
Implements \[ \frac{d}{dx} \sinh f(x) = \cosh f(x) \cdot \frac{df(x)}{dx}. \]
Examples
>>>call differentiableSinh 0.0 :: Float0.0>>>simpleDerivative differentiableSinh 0.0 :: Float1.0
differentiableCosh :: TrigField b => RevDiff a b b -> RevDiff a b b Source #
Differentiable version of hyperbolic cosine function for the RevDiff type.
Implements \[ \frac{d}{dx} \mathrm{csch} f(x) = \mathrm{sh} f(x) \cdot \frac{df(x)}{dx}. \]
Examples
>>>call differentiableCosh 0.0 :: Float1.0>>>simpleDerivative differentiableCosh 0.0 :: Float0.0
differentiableTanh :: (TrigField b, IntegerPower b) => RevDiff a b b -> RevDiff a b b Source #
Differentiable version of hyperbolic tangent function for the RevDiff type.
Implements \[ \frac{d}{dx} \mathrm{th} f(x) = \mathrm{sech}^2 f(x) \cdot \frac{df}{dx} = \frac{1}{\mathrm{ch}^2 f(x)} \cdot \frac{df}{dx}. \]
Examples
>>>call differentiableTanh 0.0 :: Float0.0>>>simpleDerivative differentiableTanh 0.0 :: Float1.0
differentiableAsin :: (TrigField b, ExpField b, IntegerPower b) => RevDiff a b b -> RevDiff a b b Source #
Differentiable version of arcsine function for the RevDiff type.
Implements \[ \frac{d}{dx} \arcsin f(x) = \frac{1}{\sqrt{1-f^2(x)}} \cdot \frac{df(x)}{dx}. \]
Examples
>>>call differentiableAsin 0.0 :: Float0.0>>>simpleDerivative differentiableAsin 0.0 :: Float1.0
differentiableAcos :: (TrigField b, ExpField b, IntegerPower b) => RevDiff a b b -> RevDiff a b b Source #
Differentiable version of arccosine function for the RevDiff type.
Implements \[ \frac{d}{dx} \arccos f(x) = -\frac{1}{\sqrt{1-f^2(x)}} \cdot \frac{df(x)}{dx}. \]
Examples
>>>call differentiableAcos 0.0 :: Float1.5707964>>>simpleDerivative differentiableAcos 0.0 :: Float-1.0
differentiableAtan :: (TrigField b, IntegerPower b) => RevDiff a b b -> RevDiff a b b Source #
Differentiable version of arctangent function for the RevDiff type.
Implements \[ \frac{d}{dx} \mathrm{arctg} f(x) = \frac{1}{1 + f^2(x)} \cdot \frac{df(x)}{dx}. \]
Examples
>>>call differentiableAtan 0.0 :: Float0.0>>>simpleDerivative differentiableAtan 0.0 :: Float1.0
differentiableAtan2 :: (TrigField b, IntegerPower b) => RevDiff a (b, b) (b, b) -> RevDiff a b b Source #
Differentiable version of atan2 for the RevDiff type.
Computes the two-argument arctangent function: \[ \mathrm{arctg2}(y, x) = \arctg\left(\frac{y}{x}\right) \]
The gradient computation accounts for both arguments using the formula: \[ \frac{d}{dx} \mathrm{arctg2}(f(x),g(x)) = - \frac{g(x)}{f(x)^2+g(x)^2} \cdot \frac{df(x)}{dx} + \frac{f(x)}{f(x)^2+g(x)^2} \cdot \frac{dg(x)}{dx} \]
differentiableAsinh :: (TrigField b, ExpField b, IntegerPower b) => RevDiff a b b -> RevDiff a b b Source #
Differentiable version of inverse hyperbolic sine function for the RevDiff type.
Implements \[ \DeclareMathOperator{\arcsh}{arcsh} \frac{d}{dx} \arcsh f(x) = \frac{1}{\sqrt{1 + f^2 (x)}} \cdot \frac{df}{dx}. \]
Examples
>>>call differentiableAsinh 0.0 :: Float0.0>>>simpleDerivative differentiableAsinh 0.0 :: Float1.0
differentiableAcosh :: (TrigField b, ExpField b, IntegerPower b) => RevDiff a b b -> RevDiff a b b Source #
Differentiable version of inverse hyperbolic cosine function for the RevDiff type.
Implements \[ \DeclareMathOperator{\arcch}{arcch} \frac{d}{dx} \arcch f(x) = \frac{1}{f^2(x) - 1} \cdot \frac{df}{dx}. \]
differentiableAtanh :: (TrigField b, IntegerPower b) => RevDiff a b b -> RevDiff a b b Source #
Differentiable version of inverse hyperbolic tangent function for the RevDiff type.
Implements [ frac{d}{dx} arcth f(x) = frac{1}{1 - f^2 (x)} cdot frac{df}{dx}.
Examples
>>>call differentiableAtanh 0.0 :: Float0.0>>>simpleDerivative differentiableAtanh 0.0 :: Float1.0
Differentiable types
Scalar
scalarArg :: RevDiff a b c -> RevDiff a b c Source #
Scalar (trivial) argument descriptor for differentiable functions.
Examples
>>>import Debug.DiffExpr (unarySymbolicFunc, SymbolicFunc)>>>import Debug.SimpleExpr (variable, SimpleExpr, simplify, SE)
>>>scalarArgDerivative = customArgDerivative scalarArg
>>>t = variable "t">>>:{v :: SymbolicFunc a => a -> BoxedVector 3 a v t = DVGS.fromTuple ( unarySymbolicFunc "v_x" t, unarySymbolicFunc "v_y" t, unarySymbolicFunc "v_z" t ) :}
>>>v tVector [v_x(t),v_y(t),v_z(t)]
>>>v' = simplify . scalarArgDerivative v :: SE -> BoxedVector 3 SE>>>v' tVector [v_x'(t),v_y'(t),v_z'(t)]
scalarVal :: Multiplicative b => RevDiff a b c -> a Source #
Scalar value term.
Examples
>>>:{product :: (Multiplicative a) => (a, a) -> a product (x, y) = x * y :}
>>>product' = customArgValDerivative tupleArg scalarVal product
>>>product' (2 :: Float, 3 :: Float)(3.0,2.0)
>>>import Debug.SimpleExpr (variable, simplify, SimpleExpr)>>>x = variable "x">>>y = variable "y">>>simplify $ product' (x, y) :: (SimpleExpr, SimpleExpr)(y,x)
scalarArgDerivative :: AutoDifferentiableValue c => (RevDiff' a a -> c) -> a -> DerivativeValue c Source #
Derivative operator for a function from a scalar to any supported value type.
Examples
>>>import Debug.SimpleExpr (variable, simplify, SE)
>>>:{f :: TrigField a => a -> (a, a) f t = (cos t, sin t) :}
>>>f' = scalarArgDerivative f
>>>f (0 :: Float)(1.0,0.0)>>>f' (0 :: Float)(-0.0,1.0)
>>>t = variable "t">>>f t(cos(t),sin(t))>>>simplify $ scalarArgDerivative f t :: (SE, SE)(-(sin(t)),cos(t))
scalarValDerivative :: (DerivativeRoot b ~ CT a, DerivativeCoarg b ~ CT a, DerivativeArg b ~ a, Multiplicative (CT c), AutoDifferentiableArgument b) => (b -> RevDiff d (CT c) c) -> a -> d Source #
Derivative operator for a function from any supported argument type to a scalar value.
Examples
>>>import Debug.SimpleExpr (variable, simplify, SE)
>>>:{f :: Additive a => (a, a) -> a f (x, y) = x + y :}
>>>f (2 :: Float, 3 :: Float)5.0>>>x = variable "x">>>y = variable "y">>>f (x, y)x+y
>>>:{f' :: (Additive a, Distributive (CT a)) => (a, a) -> (CT a, CT a) f' = scalarValDerivative f :}
>>>f' (2 :: Float, 3 :: Float)(1.0,1.0)>>>simplify $ f' (x, y) :: (SE, SE)(1,1)
Tuple
mkTupleArg :: (Additive b0, Additive b1) => RevDiffArg a b0 c0 d0 -> RevDiffArg a b1 c1 d1 -> RevDiffArg a (b0, b1) (c0, c1) (d0, d1) Source #
Tuple argument descriptor builder. See this tutorial section for details and examples.
tupleArg :: (Additive b0, Additive b1) => RevDiff a (b0, b1) (c0, c1) -> (RevDiff a b0 c0, RevDiff a b1 c1) Source #
Tuple argument descriptor for differentiable functions.
Transforms a RevDiff instances of a tuple into a tuple of RevDiff instances.
This allows applying differentiable operations to both elements of the tuple.
Examples
>>>import Debug.SimpleExpr (variable, SE, simplify)>>>import Debug.DiffExpr (SymbolicFunc, unarySymbolicFunc)
>>>:{f :: Multiplicative a => (a, a) -> a f (x, y) = x * y :}
>>>:{f' :: (Distributive a, CT a ~ a) => (a, a) -> (a, a) f' = customArgDerivative tupleArg f :}
>>>simplify $ f' (variable "x", variable "y")(y,x)
tupleArgDerivative :: (Additive (CT a0), Additive (CT a1), AutoDifferentiableValue b) => ((RevDiff' (a0, a1) a0, RevDiff' (a0, a1) a1) -> b) -> (a0, a1) -> DerivativeValue b Source #
Differentiable operator for functions with tuple argument
and any supported by AutoDifferentiableValue value type.
This function is equivalent to twoArgsDerivative up to the curring.
Examples
>>>import Debug.SimpleExpr (variable, simplify, SE)>>>import Debug.DiffExpr (SymbolicFunc, unarySymbolicFunc)
>>>:{x = variable "x" y = variable "y" f :: SymbolicFunc a => a -> a f = unarySymbolicFunc "f" g :: SymbolicFunc a => a -> a g = unarySymbolicFunc "g" h :: (SymbolicFunc a, Multiplicative a) => (a, a) -> a h (x, y) = f x * g y :}
>>>f(x)*g(y)f(x)*g(y)
>>>:{h' :: (SE, SE) -> (SE, SE) h' = simplify . tupleArgDerivative h :}
>>>h' (x, y)(f'(x)*g(y),g'(y)*f(x))
>>>:{h'' :: (SE, SE) -> ((SE, SE), (SE, SE)) h'' = simplify . tupleArgDerivative (tupleArgDerivative h) :}
>>>h'' (x, y)((f''(x)*g(y),g'(y)*f'(x)),(f'(x)*g'(y),g''(y)*f(x)))
tupleDerivativeOverX :: (AutoDifferentiableValue b, Additive (CT a0)) => ((RevDiff' a0 a0, RevDiff' a0 a1) -> b) -> (a0, a1) -> DerivativeValue b Source #
Differentiable operator for functions over tuple argument with respect to the first argument.
Examples
>>>import Debug.SimpleExpr (variable, simplify, SE)>>>import Debug.DiffExpr (SymbolicFunc, unarySymbolicFunc)
>>>:{x = variable "x" y = variable "y" f :: SymbolicFunc a => a -> a f = unarySymbolicFunc "f" g :: SymbolicFunc a => a -> a g = unarySymbolicFunc "g" h :: (SymbolicFunc a, Multiplicative a) => (a, a) -> a h (x, y) = f x * g y :}
>>>f(x)*g(y)f(x)*g(y)
>>>:{h' :: (SE, SE) -> SE h' = simplify . tupleDerivativeOverX h :}
>>>h' (x, y)f'(x)*g(y)
>>>:{h'' :: (SE, SE) -> SE h'' = simplify . tupleDerivativeOverX (tupleDerivativeOverX h) :}
>>>h'' (x, y)f''(x)*g(y)
tupleDerivativeOverY :: (Additive (CT a1), AutoDifferentiableValue b) => ((RevDiff' a1 a0, RevDiff' a1 a1) -> b) -> (a0, a1) -> DerivativeValue b Source #
Differentiable operator for functions over tuple argument with respect to the second argument.
Examples
>>>import Debug.SimpleExpr (variable, simplify, SE)>>>import Debug.DiffExpr (SymbolicFunc, unarySymbolicFunc)
>>>:{x = variable "x" y = variable "y" f :: SymbolicFunc a => a -> a f = unarySymbolicFunc "f" g :: SymbolicFunc a => a -> a g = unarySymbolicFunc "g" h :: (SymbolicFunc a, Multiplicative a) => (a, a) -> a h (x, y) = f x * g y :}
>>>f(x)*g(y)f(x)*g(y)
>>>:{h' :: (SE, SE) -> SE h' = simplify . tupleDerivativeOverY h :}
>>>h' (x, y)g'(y)*f(x)
>>>:{h'' :: (SE, SE) -> SE h'' = simplify . tupleDerivativeOverY (tupleDerivativeOverY h) :}
>>>h'' (x, y)g''(y)*f(x)
twoArgsDerivative :: (Additive (CT a0), Additive (CT a1), AutoDifferentiableValue b) => (RevDiff' (a0, a1) a0 -> RevDiff' (a0, a1) a1 -> b) -> a0 -> a1 -> DerivativeValue b Source #
Differentiable operator for functions over two arguments
and any supported by AutoDifferentiableValue value type.
Equivalent to tupleArgDerivative up to the curring.
Examples
>>>import Debug.SimpleExpr (variable, simplify, SE)>>>import Debug.DiffExpr (SymbolicFunc, unarySymbolicFunc)
>>>:{x = variable "x" y = variable "y" f :: SymbolicFunc a => a -> a f = unarySymbolicFunc "f" g :: SymbolicFunc a => a -> a g = unarySymbolicFunc "g" h :: (SymbolicFunc a, Multiplicative a) => a -> a -> a h x y = f x * g y :}
>>>f(x)*g(y)f(x)*g(y)
>>>:{h' :: SE -> SE -> (SE, SE) h' = simplify . twoArgsDerivative h :}
>>>h' x y(f'(x)*g(y),g'(y)*f(x))
>>>:{h'' :: SE -> SE -> ((SE, SE), (SE, SE)) h'' = simplify . twoArgsDerivative (twoArgsDerivative h) :}
>>>h'' x y((f''(x)*g(y),g'(y)*f'(x)),(f'(x)*g'(y),g''(y)*f(x)))
twoArgsDerivativeOverX :: (Additive (CT a0), AutoDifferentiableValue b) => (RevDiff' a0 a0 -> RevDiff' a0 a1 -> b) -> a0 -> a1 -> DerivativeValue b Source #
Differentiable operator for functions over two arguments
with respect to the first argument.
Equivalent to tupleDerivativeOverX up to the curring.
Examples
>>>import Debug.SimpleExpr (variable, simplify, SE)>>>import Debug.DiffExpr (SymbolicFunc, unarySymbolicFunc)
>>>:{x = variable "x" y = variable "y" f :: SymbolicFunc a => a -> a f = unarySymbolicFunc "f" g :: SymbolicFunc a => a -> a g = unarySymbolicFunc "g" h :: (SymbolicFunc a, Multiplicative a) => a -> a -> a h x y = f x * g y :}
>>>f(x)*g(y)f(x)*g(y)
>>>:{h' :: SE -> SE -> SE h' = simplify . twoArgsDerivativeOverX h :}
>>>h' x yf'(x)*g(y)
>>>:{h'' :: SE -> SE -> SE h'' = simplify . twoArgsDerivativeOverX (twoArgsDerivativeOverX h) :}
>>>h'' x yf''(x)*g(y)
twoArgsDerivativeOverY :: (Additive (CT a1), AutoDifferentiableValue b) => (RevDiff' a1 a0 -> RevDiff' a1 a1 -> b) -> a0 -> a1 -> DerivativeValue b Source #
Differentiable operator for functions over two arguments
with respect to the second argument.
Equivalent to tupleDerivativeOverY up to the curring.
mkTupleVal :: (a0 -> b0) -> (a1 -> b1) -> (a0, a1) -> (b0, b1) Source #
Tuple differentiable value builder See this tutorial section for details and examples.
tupleVal :: (Multiplicative b0, Multiplicative b1) => (RevDiff a0 b0 c0, RevDiff a1 b1 c1) -> (a0, a1) Source #
Tuple differentiable value descriptor. See this tutorial section for details and examples.
tupleValDerivative :: (AutoDifferentiableArgument a, Multiplicative c0, Multiplicative c1, DerivativeCoarg a ~ CT (DerivativeArg a), DerivativeRoot a ~ CT (DerivativeArg a)) => (a -> (RevDiff b0 c0 d0, RevDiff b1 c1 d1)) -> DerivativeArg a -> (b0, b1) Source #
Differentiable operator for functions with tuple value and any supported by
AutoDifferentiableArgument argument type.
Examples
>>>import Debug.SimpleExpr (variable, simplify, SE)
>>>:{f :: TrigField a => a -> (a, a) f x = (sin x, cos x) :}
>>>f (variable "x")(sin(x),cos(x))
>>>:{f' :: SE -> (SE, SE) f' = simplify . tupleValDerivative f :}
>>>f' (variable "x")(cos(x),-(sin(x)))
Triple
threeArgsToTriple :: Additive a => RevDiff a b0 c0 -> RevDiff a b1 c1 -> RevDiff a b2 c2 -> RevDiff a (b0, b1, b2) (c0, c1, c2) Source #
tripleArg :: (Additive b0, Additive b1, Additive b2) => RevDiff a (b0, b1, b2) (c0, c1, c2) -> (RevDiff a b0 c0, RevDiff a b1 c1, RevDiff a b2 c2) Source #
Triple argument descriptor for differentiable functions.
Transforms a RevDiff instances of a triple into a triple of RevDiff instances.
This allows applying differentiable operations to each element of the triple.
Examples
>>>import Debug.SimpleExpr (variable, SE, simplify)>>>import Debug.DiffExpr (SymbolicFunc, unarySymbolicFunc)
>>>:{f :: Multiplicative a => (a, a, a) -> a f (x, y, z) = x * y * z :}
>>>:{f' :: (Distributive a, CT a ~ a) => (a, a, a) -> (a, a, a) f' = customArgDerivative tripleArg f :}
>>>simplify $ f' (variable "x", variable "y", variable "z")(y*z,x*z,x*y)
mkTripleArg :: (Additive b0, Additive b1, Additive b2) => RevDiffArg a b0 c0 d0 -> RevDiffArg a b1 c1 d1 -> RevDiffArg a b2 c2 d2 -> RevDiffArg a (b0, b1, b2) (c0, c1, c2) (d0, d1, d2) Source #
Triple argument builder. See this tutorial section for details and examples for the tuple.
tripleArgDerivative :: (Additive (CT a0), Additive (CT a1), Additive (CT a2), AutoDifferentiableValue b) => ((RevDiff' (a0, a1, a2) a0, RevDiff' (a0, a1, a2) a1, RevDiff' (a0, a1, a2) a2) -> b) -> (a0, a1, a2) -> DerivativeValue b Source #
Differentiable operator for functions with triple argument
and any supported by AutoDifferentiableValue value type.
The output is a triple of corresponding partial derivatives.
This function is equivalent to threeArgsDerivative up to the curring.
Examples
>>>import Debug.SimpleExpr (variable, simplify, SE)>>>import Debug.SimpleExpr.Utils.Algebra (AlgebraicPower, square, MultiplicativeAction)>>>import Debug.DiffExpr (SymbolicFunc)
>>>:{x = variable "x" y = variable "y" z = variable "z" norm :: (AlgebraicPower Integer a, Additive a) => (a, a, a) -> a norm (x, y, z) = square x + square y + square z :}
>>>norm (x, y, z)((x^2)+(y^2))+(z^2)
>>>:{norm' :: (SE, SE, SE) -> (SE, SE, SE) norm' = simplify . tripleArgDerivative norm :}
>>>simplify $ norm' (x, y, z)(2*x,2*y,2*z)
>>>:{norm'' :: (SE, SE, SE) -> ((SE, SE, SE), (SE, SE, SE), (SE, SE, SE)) norm'' = simplify . tripleArgDerivative (tripleArgDerivative norm) :}
>>>norm'' (x, y, z)((2,0,0),(0,2,0),(0,0,2))
tripleDerivativeOverX :: (AutoDifferentiableValue b, Additive (CT a0)) => ((RevDiff' a0 a0, RevDiff' a0 a1, RevDiff' a0 a2) -> b) -> (a0, a1, a2) -> DerivativeValue b Source #
Differentiable operator for functions over triple arguments with respect to the first argument.
tripleDerivativeOverY :: (AutoDifferentiableValue b, Additive (CT a1)) => ((RevDiff' a1 a0, RevDiff' a1 a1, RevDiff' a1 a2) -> b) -> (a0, a1, a2) -> DerivativeValue b Source #
Differentiable operator for functions over triple arguments with respect to the second argument.
tripleDerivativeOverZ :: (AutoDifferentiableValue b, Additive (CT a2)) => ((RevDiff' a2 a0, RevDiff' a2 a1, RevDiff' a2 a2) -> b) -> (a0, a1, a2) -> DerivativeValue b Source #
Differentiable operator for functions over triple arguments with respect to the third argument.
threeArgsDerivative :: (AutoDifferentiableValue b, Additive (CT a0), Additive (CT a1), Additive (CT a2)) => (RevDiff' (a0, a1, a2) a0 -> RevDiff' (a0, a1, a2) a1 -> RevDiff' (a0, a1, a2) a2 -> b) -> a0 -> a1 -> a2 -> DerivativeValue b Source #
Differentiable operator for functions over three argument.
and any supported by AutoDifferentiableValue value type.
The output is a triple of corresponding partial derivatives.
This function is equivalent to tripleArgDerivative up to the curring.
derivative3ArgsOverX :: (AutoDifferentiableValue b, Additive (CT a0)) => (RevDiff' a0 a0 -> RevDiff' a0 a1 -> RevDiff' a0 a2 -> b) -> a0 -> a1 -> a2 -> DerivativeValue b Source #
Differentiable operator for functions over three argument
with respect to the first argument.
and any supported by AutoDifferentiableValue value type.
derivative3ArgsOverY :: (AutoDifferentiableValue b, Additive (CT a1)) => (RevDiff' a1 a0 -> RevDiff' a1 a1 -> RevDiff' a1 a2 -> b) -> a0 -> a1 -> a2 -> DerivativeValue b Source #
Differentiable operator for functions over three argument
with respect to the second argument.
and any supported by AutoDifferentiableValue value type.
derivative3ArgsOverZ :: (AutoDifferentiableValue b, Additive (CT a2)) => (RevDiff' a2 a0 -> RevDiff' a2 a1 -> RevDiff' a2 a2 -> b) -> a0 -> a1 -> a2 -> DerivativeValue b Source #
Differentiable operator for functions over three argument
with respect to the third argument.
and any supported by AutoDifferentiableValue value type.
mkTripleVal :: (a0 -> b0) -> (a1 -> b1) -> (a2 -> b2) -> (a0, a1, a2) -> (b0, b1, b2) Source #
Triple differentiable value builder See this tutorial section for details and examples for tuple.
tripleVal :: (Multiplicative b0, Multiplicative b1, Multiplicative b2) => (RevDiff a0 b0 c0, RevDiff a1 b1 c1, RevDiff a2 b2 c2) -> (a0, a1, a2) Source #
Triple differentiable value descriptor. See this tutorial section for details and examples.
tripleValDerivative :: (AutoDifferentiableArgument a, Multiplicative c0, Multiplicative c1, Multiplicative c2, DerivativeCoarg a ~ CT (DerivativeArg a), DerivativeRoot a ~ CT (DerivativeArg a)) => (a -> (RevDiff b0 c0 d0, RevDiff b1 c1 d1, RevDiff b2 c2 d2)) -> DerivativeArg a -> (b0, b1, b2) Source #
Differentiable operator for functions with tuple value and any supported by
AutoDifferentiableArgument argument type.
Examples
>>>import Debug.SimpleExpr (variable, simplify, SE)
>>>:{f :: (Multiplicative a, IntegerPower a) => a -> (a, a, a) f x = (one, x^1, x^2) :}
>>>f (variable "x")(1,x^1,x^2)
>>>:{f' :: SE -> (SE, SE, SE) f' = simplify . tripleValDerivative f :}
>>>f' (variable "x")(0,1,2*x)
BoxedVector
boxedVectorArg :: forall b (n :: Nat) a c. (Additive b, KnownNat n) => RevDiff a (BoxedVector n b) (BoxedVector n c) -> BoxedVector n (RevDiff a b c) Source #
Boxed vector argument descriptor for differentiable functions.
Transforms a RevDiff instances of a boxed vector into a boxed vectror
of RevDiff instances.
This allows applying differentiable operations to each element of the boxed Vector.
Examples
>>>import Debug.SimpleExpr (variable, SE, simplify)>>>import Debug.DiffExpr (SymbolicFunc, unarySymbolicFunc)
>>>:{f :: Additive a => BoxedVector 3 a -> a f = boxedVectorSum :}
>>>:{f' :: (Distributive a, CT a ~ a) => BoxedVector 3 a -> BoxedVector 3 a f' = customArgDerivative boxedVectorArg f :}
>>>simplify $ f' (DVGS.fromTuple (variable "x", variable "y", variable "z"))Vector [1,1,1]
mkBoxedVectorArg :: forall b (n :: Nat) a c d. (Additive b, KnownNat n) => RevDiffArg a b c d -> RevDiffArg a (BoxedVector n b) (BoxedVector n c) (BoxedVector n d) Source #
BoxedVector argument descriptor builder.
boxedVectorArgDerivative :: forall (n :: Nat) b a. (KnownNat n, AutoDifferentiableValue b, Additive (CT a)) => (BoxedVector n (RevDiff' (BoxedVector n a) a) -> b) -> BoxedVector n a -> DerivativeValue b Source #
Differentiable operator for functions with boxed array argument
and any supported by AutoDifferentiableValue value type.
The output is a boxed array of corresponding partial derivatives (i.e. gradient).
Examples
>>>import Debug.SimpleExpr (variable, simplify, SE)>>>import Debug.DiffExpr (SymbolicFunc)>>>import Numeric.InfBackprop.Utils.SizedVector (BoxedVector, boxedVectorSum)>>>import Debug.SimpleExpr.Utils.Algebra (AlgebraicPower, (^))
>>>:{x = variable "x" y = variable "y" z = variable "z" r = DVGS.fromTuple (x, y, z) :: BoxedVector 3 SE norm2 :: (AlgebraicPower Integer a, Additive a) => BoxedVector 3 a -> a norm2 v = boxedVectorSum (v^2) :}
>>>simplify $ norm2 r((x^2)+(y^2))+(z^2)
>>>:{norm2' :: BoxedVector 3 SE -> BoxedVector 3 SE norm2' = simplify . boxedVectorArgDerivative norm2 :}
>>>norm2' rVector [2*x,2*y,2*z]
>>>:{norm2'' :: BoxedVector 3 SE -> BoxedVector 3 (BoxedVector 3 SE) norm2'' = simplify . boxedVectorArgDerivative (boxedVectorArgDerivative norm2) :}
>>>norm2'' rVector [Vector [2,0,0],Vector [0,2,0],Vector [0,0,2]]
boxedVectorVal :: forall b (n :: Nat) a c. Multiplicative b => BoxedVector n (RevDiff a b c) -> BoxedVector n a Source #
Boxed array differentiable value descriptor. See this tutorial section for details and examples.
Examples
>>>import Debug.SimpleExpr (variable, SE, simplify)>>>import Debug.DiffExpr (unarySymbolicFunc, SymbolicFunc)
>>>:{v :: SymbolicFunc a => a -> BoxedVector 3 a v t = DVGS.fromTuple ( unarySymbolicFunc "v_x" t, unarySymbolicFunc "v_y" t, unarySymbolicFunc "v_z" t ) :}
>>>t = variable "t">>>v tVector [v_x(t),v_y(t),v_z(t)]
>>>v' = simplify . customValDerivative boxedVectorVal v :: SE -> BoxedVector 3 SE>>>v' tVector [v_x'(t),v_y'(t),v_z'(t)]
mkBoxedVectorVal :: forall a b (n :: Nat). (a -> b) -> BoxedVector n a -> BoxedVector n b Source #
BoxedVector differentiable value builder
See this tutorial section
for details and examples.
boxedVectorValDerivative :: forall a c (n :: Nat) b d. (AutoDifferentiableArgument a, Multiplicative c, DerivativeCoarg a ~ CT (DerivativeArg a), DerivativeRoot a ~ CT (DerivativeArg a)) => (a -> BoxedVector n (RevDiff b c d)) -> DerivativeArg a -> BoxedVector n b Source #
Differentiable operator for functions with BoxedVector argument
and any supported by AutoDifferentiableValue value type.
The output is a BoxedVector instamce of corresponding drivatives.
Examples
>>>import Debug.SimpleExpr (variable, SE, simplify)>>>import Debug.DiffExpr (unarySymbolicFunc, SymbolicFunc)
>>>:{v :: SymbolicFunc a => a -> BoxedVector 3 a v t = DVGS.fromTuple ( unarySymbolicFunc "v_x" t, unarySymbolicFunc "v_y" t, unarySymbolicFunc "v_z" t ) :}
>>>t = variable "t">>>v tVector [v_x(t),v_y(t),v_z(t)]
>>>v' = simplify . boxedVectorValDerivative v :: SE -> BoxedVector 3 SE>>>v' tVector [v_x'(t),v_y'(t),v_z'(t)]
Stream
streamArg :: Additive b => RevDiff a (FiniteSupportStream b) (Stream c) -> Stream (RevDiff a b c) Source #
Stream argument descriptor for differentiable functions.
Transforms a RevDiff instances of a stream into a stream of RevDiff instances.
This allows applying differentiable operations to each element of the Stream.
Examples
>>>import Debug.SimpleExpr (variable, SE, simplify)>>>import GHC.Base ((<>))
>>>:{f :: Additive a => Stream a -> a f = NumHask.sum . Data.Stream.take 4 :: Additive a => Data.Stream.Stream a -> a :}
>>>:{f' :: (Distributive a, CT a ~ a) => Stream a -> FiniteSupportStream a f' = customArgDerivative streamArg f :}
>>>s = Data.Stream.fromList [variable ("s_" <> show n) | n <- [0 :: Int ..]] :: Data.Stream.Stream SE>>>simplify $ f' s[1,1,1,1,0,0,0,...
mkStreamArg :: Additive b => (RevDiff a b c -> d) -> RevDiff a (FiniteSupportStream b) (Stream c) -> Stream d Source #
Stream argument builder. See this tutorial section for details and examples for the tuple.
streamArgDerivative :: (AutoDifferentiableValue b, Additive (CT a)) => (Stream (RevDiff' (Stream a) a) -> b) -> Stream a -> DerivativeValue b Source #
Differentiable operator for functions with Stream argument
and any supported by AutoDifferentiableValue value type.
The output is a boxed array of corresponding partial derivatives (i.e. gradient).
Examples
>>>import GHC.Base ((<>))>>>import Debug.SimpleExpr (variable, simplify, SE)>>>import Debug.DiffExpr (SymbolicFunc)>>>import Data.Stream (Stream, fromList, take)
>>>s = fromList [variable ("s_" <> show n) | n <- [0 :: Int ..]] :: Stream SE
>>>take4Sum = NumHask.sum . take 4 :: Additive a => Stream a -> a>>>simplify $ take4Sum s :: SEs_0+(s_1+(s_2+s_3))
>>>:{take4Sum' :: (Distributive a, CT a ~ a) => Stream a -> FiniteSupportStream (CT a) take4Sum' = streamArgDerivative take4Sum :}
>>>simplify $ take4Sum' s[1,1,1,1,0,0,0,...
>>>:{take4Sum'' :: (Distributive a, CT a ~ a) => Stream a -> FiniteSupportStream (FiniteSupportStream (CT a)) take4Sum'' = streamArgDerivative (streamArgDerivative take4Sum) :}
>>>simplify $ take4Sum'' s[[0,0,0,...,[0,0,0,...,[0,0,0,...,...
streamVal :: Multiplicative b => Stream (RevDiff a b c) -> Stream a Source #
Stream value structure for differentiable functions.
Examples
>>>import GHC.Base ((<>))>>>import Data.Stream (Stream, fromList, take)>>>import Debug.SimpleExpr (variable, SE, simplify)>>>import Debug.DiffExpr (unarySymbolicFunc, SymbolicFunc)
>>>:{s :: SymbolicFunc a => a -> Stream a s t = fromList [unarySymbolicFunc ("s_" <> show n) t | n <- [0..]] :}
>>>t = variable "t">>>take 5 (s t)[s_0(t),s_1(t),s_2(t),s_3(t),s_4(t)]
>>>:{s' :: SE -> Stream SE s' = simplify . customValDerivative streamVal s :}
>>>take 5 (s' t)[s_0'(t),s_1'(t),s_2'(t),s_3'(t),s_4'(t)]
mkStreamVal :: (a -> b) -> Stream a -> Stream b Source #
Stream differentiable value builder See this tutorial section for details and examples.
streamValDerivative :: (AutoDifferentiableArgument a, Multiplicative c, DerivativeCoarg a ~ CT (DerivativeArg a), DerivativeRoot a ~ CT (DerivativeArg a)) => (a -> Stream (RevDiff b c d)) -> DerivativeArg a -> Stream b Source #
Derivative operator for a function from any supported argument type to a Stream.
FiniteSupportStream
finiteSupportStreamArg :: Additive b => RevDiff a (Stream b) (FiniteSupportStream c) -> FiniteSupportStream (RevDiff a b c) Source #
Finite support stream argument descriptor for differentiable functions.
Transforms a RevDiff instances of a finite support stream into
a finite support stream of RevDiff instances.
Examples
>>>import Debug.SimpleExpr (variable, SE, simplify)>>>import Data.FiniteSupportStream (unsafeFromList, toVector)
>>>:{f :: Additive a => FiniteSupportStream a -> a f = NumHask.sum . toVector :}
>>>f (unsafeFromList [1, 2, 3])6
>>>:{f' :: (Distributive a, CT a ~ a) => FiniteSupportStream a -> Stream a f' = customArgDerivative finiteSupportStreamArg f :}
>>>Data.Stream.take 5 $ f' (unsafeFromList [1, 2, 3])[1,1,1,0,0]
mkFiniteSupportStreamArg :: Additive b => (RevDiff a b c -> d) -> RevDiff a (Stream b) (FiniteSupportStream c) -> FiniteSupportStream d Source #
Finite support stream argument descriptor builder. See this tutorial section for details and examples. It is expected that the argument function is linear or at least maps zero to zero.
finiteSupportStreamArgDerivative :: (AutoDifferentiableValue b, Additive (CT a)) => (FiniteSupportStream (RevDiff' (FiniteSupportStream a) a) -> b) -> FiniteSupportStream a -> DerivativeValue b Source #
Differentiable operator for functions that take a FiniteSupportStream argument
and return any value type supported by AutoDifferentiableValue.
The output is a stream of corresponding partial derivatives,
computing the gradient of the function with respect to each stream element.
See also
"Tangent and Cotangent Spaces" tutorial section
for the connection beetwen streams and finite support streams.
Examples
>>>import Debug.SimpleExpr (variable, simplify, SE)>>>import Debug.DiffExpr (SymbolicFunc)>>>import Data.Stream (Stream, take)>>>import Data.FiniteSupportStream (FiniteSupportStream, unsafeFromList, toVector)>>>import NumHask (sum)
Define a finite support stream with support length 4 containing 4 symbolic variables.
>>>s = unsafeFromList [variable "s_0", variable "s_1", variable "s_2", variable "s_3"] :: FiniteSupportStream SE>>>s[s_0,s_1,s_2,s_3,0,0,0,...
Now we'll define a function that sums all elements of a finite support stream.
>>>finiteSupportStreamSum = sum . toVector :: Additive a => FiniteSupportStream a -> a>>>simplify $ finiteSupportStreamSum s :: SEs_0+(s_1+(s_2+s_3))
We compute the gradient of this function.
>>>:{finiteSupportStreamSum' :: (Distributive a, CT a ~ a) => FiniteSupportStream a -> Stream (CT a) finiteSupportStreamSum' = finiteSupportStreamArgDerivative finiteSupportStreamSum :}
Let's compute the gradient at point s. It is an infinite stream and we take first 7 elements:
>>>take 7 $ simplify $ finiteSupportStreamSum' s[1,1,1,1,0,0,0]
As expected, the gradient is a stream with 1's in the first four positions (corresponding to our four variables and the fixed support length 4) and 0's elsewhere:
We can compute the second derivative (Hessian matrix) that is stream of streams in our case.
>>>:{finiteSupportStreamSum'' :: (Distributive a, CT a ~ a) => FiniteSupportStream a -> Stream (Stream (CT a)) finiteSupportStreamSum'' = finiteSupportStreamArgDerivative (finiteSupportStreamArgDerivative finiteSupportStreamSum) :}
All second derivatives should all be zero. We take first 7 rows and 4 columns of the inifinite Hessian matrix:
>>>take 7 $ fmap (take 4) $ simplify $ finiteSupportStreamSum'' s[[0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0]]
finiteSupportStreamVal :: Multiplicative b => FiniteSupportStream (RevDiff a b c) -> FiniteSupportStream a Source #
Finite support stream value structure for differentiable functions.
Examples
>>>import Debug.SimpleExpr (variable, SE, simplify)>>>import Debug.DiffExpr (unarySymbolicFunc, SymbolicFunc)>>>import Data.FiniteSupportStream (unsafeFromList, FiniteSupportStream)
>>>:{fss :: (Multiplicative a, IntegerPower a) => a -> FiniteSupportStream a fss t = unsafeFromList [t^3, t^2, t, one] :}
>>>t = variable "t">>>fss t[t^3,t^2,t,1,0,0,0,...
>>>:{fss' :: SE -> FiniteSupportStream SE fss' = simplify . customValDerivative finiteSupportStreamVal fss :}
>>>(fss' t)[3*(t^2),2*t,1,0,0,0,...
mkFiniteSupportStreamVal :: (a -> b) -> FiniteSupportStream a -> FiniteSupportStream b Source #
Finite support stream differentiable value builder See this tutorial section for details and examples. It is expected that the argument function is linear or at least maps zero to zero.
finiteSupportStreamValDerivative :: (AutoDifferentiableArgument a, Multiplicative c, DerivativeCoarg a ~ CT (DerivativeArg a), DerivativeRoot a ~ CT (DerivativeArg a)) => (a -> FiniteSupportStream (RevDiff b c d)) -> DerivativeArg a -> FiniteSupportStream b Source #
Derivative operator for a function from any supported argument type to
a FiniteSupportStream instance.
Examples
>>>import Debug.SimpleExpr (variable, SE, simplify)>>>import Debug.DiffExpr (unarySymbolicFunc, SymbolicFunc)>>>import Data.FiniteSupportStream (unsafeFromList, FiniteSupportStream)
>>>:{fss :: (Multiplicative a, IntegerPower a) => a -> FiniteSupportStream a fss t = unsafeFromList [t^3, t^2, t, one] :}
>>>t = variable "t">>>fss t[t^3,t^2,t,1,0,0,0,...
>>>:{fss' :: SE -> FiniteSupportStream SE fss' = simplify . finiteSupportStreamValDerivative fss :}
>>>fss' t[3*(t^2),2*t,1,0,0,0,...
Maybe
maybeArg :: RevDiff a (Maybe b) (Maybe c) -> Maybe (RevDiff a b c) Source #
Argument descriptor for differentiable functions with optional argument.
Transforms a RevDiff instances of an otional type into
an optional of RevDiff instances.
This allows applying differentiable operations to the optiona value.
Argument descriptor for differentiable functions with optional (Maybe) values.
Transforms a RevDiff instance containing an optional type into an optional
RevDiff instance. This transformation enables applying differentiable
operations to values that may or may not be present, while preserving
gradient flow when values exist.
When the wrapped value is `Just x`, the function extracts the value and
wraps it in a new RevDiff instance with appropriately transformed
backpropagation. When the value is Nothing, the result is Nothing,
effectively short-circuiting the computation.
Examples
>>>:{f :: Additive a => Maybe a -> a f (Just x) = x f Nothing = zero :}
>>>customArgDerivative maybeArg f (Just 3 :: Maybe Float) :: Maybe FloatJust 1.0
maybeArgDerivative :: AutoDifferentiableValue b => (Maybe (RevDiff' (Maybe a) a) -> b) -> Maybe a -> DerivativeValue b Source #
Differentiable operator for functions that take a Maybe (a value or none) argument
and return any value type supported by AutoDifferentiableValue.
The output is Maybe of corresponding derivatives over the inner type.
Examples
>>>import Debug.SimpleExpr (variable, simplify, SE)>>>import Debug.DiffExpr (SymbolicFunc)>>>import qualified GHC.Num as GHCN
>>>:{maybeF :: TrigField a => Maybe a -> a maybeF (Just x) = sin x maybeF Nothing = zero :}
>>>maybeF (Just 0.0 :: Maybe Float)0.0
>>>maybeF (Nothing :: Maybe Float)0.0
>>>maybeArgDerivative maybeF (Just 0.0 :: Maybe Float)Just 1.0
>>>maybeArgDerivative maybeF (Nothing :: Maybe Float)Just 0.0
maybeVal :: Multiplicative b => Maybe (RevDiff a b c) -> Maybe a Source #
Maybe value structure for differentiable functions.
Extracts the derivative with respect to the original function for Maybe types.
Examples
>>>:{class SafeRecip a where safeRecip :: a -> Maybe a instance SafeRecip Float where safeRecip x = if x == 0.0 then Nothing else Just (recip x) instance (SafeRecip b, Subtractive b, Multiplicative b, IntegerPower b) => SafeRecip (RevDiff a b b) where safeRecip (MkRevDiff v bp) = fmap (\r -> MkRevDiff r (bp . negate . (r^2 *))) (safeRecip v) :}
>>>safeRecip (2.0 :: Float) :: Maybe FloatJust 0.5>>>safeRecip (0.0 :: Float) :: Maybe FloatNothing
>>>customValDerivative maybeVal safeRecip (2.0 :: Float)Just (-0.25)>>>customValDerivative maybeVal safeRecip (0.0 :: Float)Nothing
mkMaybeVal :: (a -> b) -> Maybe a -> Maybe b Source #
Maybe differentiable value builder. Creates a mapping function for Maybe types. See this tutorial section for details and examples.
maybeValDerivative :: (AutoDifferentiableArgument a, Multiplicative c, DerivativeCoarg a ~ CT (DerivativeArg a), DerivativeRoot a ~ CT (DerivativeArg a)) => (a -> Maybe (RevDiff b c d)) -> DerivativeArg a -> Maybe b Source #
Derivative operator for functions with Maybe arguments. This allows computing derivatives of functions that returns Maybe values as output, handling the case when the value is Nothing appropriately.
Examples
>>>:{class SafeRecip a where safeRecip :: a -> Maybe a instance SafeRecip Float where safeRecip x = if x == 0.0 then Nothing else Just (recip x) instance (SafeRecip b, Subtractive b, Multiplicative b, IntegerPower b) => SafeRecip (RevDiff a b b) where safeRecip (MkRevDiff v bp) = fmap (\r -> MkRevDiff r (bp . negate . (r^2 *))) (safeRecip v) :}
>>>safeRecip (2.0 :: Float) :: Maybe FloatJust 0.5>>>safeRecip (0.0 :: Float) :: Maybe FloatNothing
>>>maybeValDerivative safeRecip (2.0 :: Float)Just (-0.25)>>>maybeValDerivative safeRecip (0.0 :: Float)Nothing