inf-backprop-0.2.0.0: Automatic differentiation and backpropagation.
Copyright(C) 2025 Alexey Tochin
LicenseBSD3 (see the file LICENSE)
MaintainerAlexey Tochin <Alexey.Tochin@gmail.com>
Safe HaskellNone
LanguageHaskell2010

Numeric.InfBackprop.Core

Description

Backpropagation differentiation core types and functions.

Synopsis

Common

Base

type family Tangent a Source #

Converts a type into its tangent space type.

Instances

Instances details
type Tangent SimpleExpr Source # 
Instance details

Defined in Numeric.InfBackprop.Core

type Tangent SimpleExpr = SimpleExpr
type Tangent Integer Source # 
Instance details

Defined in Numeric.InfBackprop.Core

type Tangent Float Source # 
Instance details

Defined in Numeric.InfBackprop.Core

type Tangent (Stream a) Source # 
Instance details

Defined in Numeric.InfBackprop.Core

type Tangent (Stream a) = Stream (Tangent a)
type Tangent (FiniteSupportStream a) Source # 
Instance details

Defined in Numeric.InfBackprop.Core

type Tangent (Complex a) Source # 
Instance details

Defined in Numeric.InfBackprop.Core

type Tangent (Traced a) Source # 
Instance details

Defined in Numeric.InfBackprop.Core

type Tangent (Traced a) = Traced (Tangent a)
type Tangent (Maybe a) Source # 
Instance details

Defined in Numeric.InfBackprop.Core

type Tangent (Maybe a) = Maybe (Tangent a)
type Tangent [a] Source # 
Instance details

Defined in Numeric.InfBackprop.Core

type Tangent [a] = [Tangent a]
type Tangent (Vec n a) Source # 
Instance details

Defined in Numeric.InfBackprop.Core

type Tangent (Vec n a) = Vec n (Tangent a)
type Tangent (a0, a1) Source # 
Instance details

Defined in Numeric.InfBackprop.Core

type Tangent (a0, a1) = (Tangent a0, Tangent a1)
type Tangent (RevDiff a b c) Source # 
Instance details

Defined in Numeric.InfBackprop.Core

type Tangent (RevDiff a b c) = RevDiff a (Tangent b) (Tangent c)
type Tangent (Vector v n a) Source # 
Instance details

Defined in Numeric.InfBackprop.Core

type Tangent (Vector v n a) = Vector v n (Tangent a)
type Tangent (a0, a1, a2) Source # 
Instance details

Defined in Numeric.InfBackprop.Core

type Tangent (a0, a1, a2) = (Tangent a0, Tangent a1, Tangent a2)

type family Dual x Source #

Converts a type into its dual space type.

Instances

Instances details
type Dual SimpleExpr Source # 
Instance details

Defined in Numeric.InfBackprop.Core

type Dual SimpleExpr = SimpleExpr
type Dual Integer Source # 
Instance details

Defined in Numeric.InfBackprop.Core

type Dual Float Source # 
Instance details

Defined in Numeric.InfBackprop.Core

type Dual (Stream a) Source # 
Instance details

Defined in Numeric.InfBackprop.Core

type Dual (FiniteSupportStream a) Source # 
Instance details

Defined in Numeric.InfBackprop.Core

type Dual (Complex a) Source # 
Instance details

Defined in Numeric.InfBackprop.Core

type Dual (Complex a) = Complex (Dual a)
type Dual (SimpleExprF a) Source # 
Instance details

Defined in Numeric.InfBackprop.Core

type Dual (SimpleExprF a) = SimpleExprF (Dual a)
type Dual (Traced a) Source # 
Instance details

Defined in Numeric.InfBackprop.Core

type Dual (Traced a) = Traced (Dual a)
type Dual (Maybe a) Source # 
Instance details

Defined in Numeric.InfBackprop.Core

type Dual (Maybe a) = Maybe (Dual a)
type Dual [a] Source # 
Instance details

Defined in Numeric.InfBackprop.Core

type Dual [a] = [Dual a]
type Dual (Vec n a) Source # 
Instance details

Defined in Numeric.InfBackprop.Core

type Dual (Vec n a) = Vec n (Dual a)
type Dual (a, b) Source # 
Instance details

Defined in Numeric.InfBackprop.Core

type Dual (a, b) = (Dual a, Dual b)
type Dual (RevDiff a b c) Source # 
Instance details

Defined in Numeric.InfBackprop.Core

type Dual (RevDiff a b c) = RevDiff a (Dual b) (Dual c)
type Dual (Vector v n a) Source # 
Instance details

Defined in Numeric.InfBackprop.Core

type Dual (Vector v n a) = Vector v n (Dual a)
type Dual (a, b, c) Source # 
Instance details

Defined in Numeric.InfBackprop.Core

type Dual (a, b, c) = (Dual a, Dual b, Dual c)

type Cotangent a = Dual (Tangent a) Source #

Cotangent type alias.

type CT a = Cotangent a Source #

Cotangent type alias.

data RevDiff a b c Source #

Base type for differentiable instances with the backpropagation.

Examples

Expand
>>> :{
 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.0
1.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

Expand
>>> 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) :: SE
x

With the Num instance for RevDiff, this simplifies to:

>>> simplify $ twoArgsDerivativeOverY (*) x (number 2) :: SE
x

And combined with the Num instance for SE, we achieve the most concise form:

>>> simplify $ twoArgsDerivativeOverY (*) x 2
x

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 :: SE
x^3
>>> simplify $ simpleDerivative (** 3) x :: SE
3*(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") :: SE
sign(x)
>>> simplify $ simpleDerivative GHCN.signum (variable "x") :: SE
0

For numeric evaluation, the second derivative of absolute value at a point gives the expected result:

>>> (simpleDerivative (simpleDerivative GHCN.abs)) (1 :: Float) :: Float
0.0

Notice that the signum function returns zero for all values, including zero.

>>> simpleDerivative GHCN.signum (0 :: Float) :: Float
0.0
>>> simplify $ (simpleDerivative (simpleDerivative GHCN.abs)) (variable "x") :: SE
0

Fractional typeclass instance

Thank to this instance we can use numerical literals like '1.0', '2.0', etc., see the examples below.

Examples

Expand
>>> 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)

Constructors

MkRevDiff 

Fields

Instances

Instances details
(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 RevDiff type.

Instance details

Defined in Numeric.InfBackprop.Core

Methods

constant :: Proxy a -> b -> RevDiff t e c -> RevDiff t f d Source #

(StopDiff a d, Additive b) => StopDiff a (RevDiff b c d) Source #

Recursive case: stopping differentiation for RevDiff type.

Instance details

Defined in Numeric.InfBackprop.Core

Methods

stopDiff :: a -> RevDiff b c d Source #

(AlgebraicPower Integer a, MultiplicativeAction Integer a, Multiplicative a) => AlgebraicPower Integer (RevDiff c a a) Source # 
Instance details

Defined in Numeric.InfBackprop.Core

Methods

(^^) :: RevDiff c a a -> Integer -> RevDiff c a a

(AlgebraicPower Int a, MultiplicativeAction Int a, Multiplicative a) => AlgebraicPower Int (RevDiff c a a) Source # 
Instance details

Defined in Numeric.InfBackprop.Core

Methods

(^^) :: RevDiff c a a -> Int -> RevDiff c a a

(MultiplicativeAction Integer b, MultiplicativeAction Integer cb) => MultiplicativeAction Integer (RevDiff ct cb b) Source # 
Instance details

Defined in Numeric.InfBackprop.Core

Methods

(*|) :: Integer -> RevDiff ct cb b -> RevDiff ct cb b

Costrong (RevDiff t) Source #

Costrong instance for RevDiff.

Instance details

Defined in Numeric.InfBackprop.Core

Methods

unfirst :: RevDiff t (a, d) (b, d) -> RevDiff t a b #

unsecond :: RevDiff t (d, a) (d, b) -> RevDiff t a b #

Profunctor (RevDiff t) Source #

Profunctor instance for RevDiff.

Instance details

Defined in Numeric.InfBackprop.Core

Methods

dimap :: (a -> b) -> (c -> d) -> RevDiff t b c -> RevDiff t a d #

lmap :: (a -> b) -> RevDiff t b c -> RevDiff t a c #

rmap :: (b -> c) -> RevDiff t a b -> RevDiff t a c #

(#.) :: forall a b c q. Coercible c b => q b c -> RevDiff t a b -> RevDiff t a c #

(.#) :: forall a b c q. Coercible b a => RevDiff t b c -> q a b -> RevDiff t a c #

Generic (RevDiff a b c) Source # 
Instance details

Defined in Numeric.InfBackprop.Core

Associated Types

type Rep (RevDiff a b c) 
Instance details

Defined in Numeric.InfBackprop.Core

type Rep (RevDiff a b c) = D1 ('MetaData "RevDiff" "Numeric.InfBackprop.Core" "inf-backprop-0.2.0.0-inplace" 'False) (C1 ('MetaCons "MkRevDiff" 'PrefixI 'True) (S1 ('MetaSel ('Just "value") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 c) :*: S1 ('MetaSel ('Just "backprop") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 (b -> a))))

Methods

from :: RevDiff a b c -> Rep (RevDiff a b c) x #

to :: Rep (RevDiff a b c) x -> RevDiff a b c #

(Additive a, Subtractive a, Num b, Subtractive b, Multiplicative b) => Num (RevDiff a b b) Source #

RevDiff instance for the Num typeclass.

Instance details

Defined in Numeric.InfBackprop.Core

Methods

(+) :: RevDiff a b b -> RevDiff a b b -> RevDiff a b b #

(-) :: RevDiff a b b -> RevDiff a b b -> RevDiff a b b #

(*) :: RevDiff a b b -> RevDiff a b b -> RevDiff a b b #

negate :: RevDiff a b b -> RevDiff a b b #

abs :: RevDiff a b b -> RevDiff a b b #

signum :: RevDiff a b b -> RevDiff a b b #

fromInteger :: Integer -> RevDiff a b b #

(Additive a, Subtractive a, Subtractive b, Divisive b, Fractional b, IntegerPower b) => Fractional (RevDiff a b b) Source #

RevDiff instance for the Fractional typeclass.

Instance details

Defined in Numeric.InfBackprop.Core

Methods

(/) :: RevDiff a b b -> RevDiff a b b -> RevDiff a b b #

recip :: RevDiff a b b -> RevDiff a b b #

fromRational :: Rational -> RevDiff a b b #

(Show (b -> a), Show c) => Show (RevDiff a b c) Source #

RevDiff instance for the Show typeclass.

Instance details

Defined in Numeric.InfBackprop.Core

Methods

showsPrec :: Int -> RevDiff a b c -> ShowS #

show :: RevDiff a b c -> String #

showList :: [RevDiff a b c] -> ShowS #

(BinarySymbolicFunc a, Distributive a, Additive t) => BinarySymbolicFunc (RevDiff t a a) Source #

RevDiff instance of BinarySymbolicFunc typeclass.

Instance details

Defined in Debug.DiffExpr

Methods

binarySymbolicFunc :: String -> RevDiff t a a -> RevDiff t a a -> RevDiff t a a Source #

(SymbolicFunc a, Multiplicative a) => SymbolicFunc (RevDiff t a a) Source #

RevDiff instance of SymbolicFunc typeclass.

Instance details

Defined in Debug.DiffExpr

Methods

unarySymbolicFunc :: String -> RevDiff t a a -> RevDiff t a a Source #

(Additive a, Additive b) => AutoDifferentiableArgument (RevDiff a b c) Source #

AutoDifferentiableArgument instance for the scalar argument term.

Instance details

Defined in Numeric.InfBackprop.Core

Associated Types

type DerivativeRoot (RevDiff a b c) 
Instance details

Defined in Numeric.InfBackprop.Core

type DerivativeRoot (RevDiff a b c) = a
type DerivativeCoarg (RevDiff a b c) 
Instance details

Defined in Numeric.InfBackprop.Core

type DerivativeCoarg (RevDiff a b c) = b
type DerivativeArg (RevDiff a b c) 
Instance details

Defined in Numeric.InfBackprop.Core

type DerivativeArg (RevDiff a b c) = c
Multiplicative b => AutoDifferentiableValue (RevDiff a b c) Source #

AutoDifferentiableValue instance for the scalar value term.

Instance details

Defined in Numeric.InfBackprop.Core

Associated Types

type DerivativeValue (RevDiff a b c) 
Instance details

Defined in Numeric.InfBackprop.Core

type DerivativeValue (RevDiff a b c) = a

Methods

autoVal :: RevDiff a b c -> DerivativeValue (RevDiff a b c) Source #

(Additive a, Additive c) => Additive (RevDiff a b c) Source #

Additive instance for the RevDiff type.

Instance details

Defined in Numeric.InfBackprop.Core

Methods

(+) :: RevDiff a b c -> RevDiff a b c -> RevDiff a b c #

zero :: RevDiff a b c #

(Additive a, Subtractive a, Subtractive b, Subtractive c) => Subtractive (RevDiff a b c) Source #

Subtractive instance for the RevDiff type.

Instance details

Defined in Numeric.InfBackprop.Core

Methods

negate :: RevDiff a b c -> RevDiff a b c #

(-) :: RevDiff a b c -> RevDiff a b c -> RevDiff a b c #

(ExpField b, Additive a, Subtractive a, IntegerPower b) => ExpField (RevDiff a b b) Source #

ExpField instance for the RevDiff type.

Instance details

Defined in Numeric.InfBackprop.Core

Methods

exp :: RevDiff a b b -> RevDiff a b b #

log :: RevDiff a b b -> RevDiff a b b #

(**) :: RevDiff a b b -> RevDiff a b b -> RevDiff a b b #

logBase :: RevDiff a b b -> RevDiff a b b -> RevDiff a b b #

sqrt :: RevDiff a b b -> RevDiff a b b #

(Additive a, Subtractive a, ExpField b, TrigField b, IntegerPower b) => TrigField (RevDiff a b b) Source #

TrigField instance for the RevDiff type.

Instance details

Defined in Numeric.InfBackprop.Core

Methods

pi :: RevDiff a b b #

sin :: RevDiff a b b -> RevDiff a b b #

cos :: RevDiff a b b -> RevDiff a b b #

tan :: RevDiff a b b -> RevDiff a b b #

asin :: RevDiff a b b -> RevDiff a b b #

acos :: RevDiff a b b -> RevDiff a b b #

atan :: RevDiff a b b -> RevDiff a b b #

atan2 :: RevDiff a b b -> RevDiff a b b -> RevDiff a b b #

sinh :: RevDiff a b b -> RevDiff a b b #

cosh :: RevDiff a b b -> RevDiff a b b #

tanh :: RevDiff a b b -> RevDiff a b b #

asinh :: RevDiff a b b -> RevDiff a b b #

acosh :: RevDiff a b b -> RevDiff a b b #

atanh :: RevDiff a b b -> RevDiff a b b #

(Additive a, Divisive b, Subtractive b, IntegerPower b) => Divisive (RevDiff a b b) Source #

Divisive instance for the RevDiff type.

Instance details

Defined in Numeric.InfBackprop.Core

Methods

recip :: RevDiff a b b -> RevDiff a b b #

(/) :: RevDiff a b b -> RevDiff a b b -> RevDiff a b b #

(Additive a, Multiplicative b) => Multiplicative (RevDiff a b b) Source #

Multiplicative instance for the RevDiff type.

Instance details

Defined in Numeric.InfBackprop.Core

Methods

(*) :: RevDiff a b b -> RevDiff a b b -> RevDiff a b b #

one :: RevDiff a b b #

(FromInteger c, Additive a) => FromInteger (RevDiff a b c) Source #

RevDiff instance of the FromInteger typeclass.

Instance details

Defined in Numeric.InfBackprop.Core

Methods

fromInteger :: Integer -> RevDiff a b c #

(FromIntegral c Int16, Additive a) => FromIntegral (RevDiff a b c) Int16 Source #

RevDiff and Int16 instance of the FromIntegral typeclass.

Instance details

Defined in Numeric.InfBackprop.Core

Methods

fromIntegral :: Int16 -> RevDiff a b c #

(FromIntegral c Int32, Additive a) => FromIntegral (RevDiff a b c) Int32 Source #

RevDiff and Int32 instance of the FromIntegral typeclass.

Instance details

Defined in Numeric.InfBackprop.Core

Methods

fromIntegral :: Int32 -> RevDiff a b c #

(FromIntegral c Int64, Additive a) => FromIntegral (RevDiff a b c) Int64 Source #

RevDiff and Int64 instance of the FromIntegral typeclass.

Instance details

Defined in Numeric.InfBackprop.Core

Methods

fromIntegral :: Int64 -> RevDiff a b c #

(FromIntegral c Int8, Additive a) => FromIntegral (RevDiff a b c) Int8 Source #

RevDiff and Int8 instance of the FromIntegral typeclass.

Instance details

Defined in Numeric.InfBackprop.Core

Methods

fromIntegral :: Int8 -> RevDiff a b c #

(FromIntegral c Word16, Additive a) => FromIntegral (RevDiff a b c) Word16 Source #

RevDiff and Word16 instance of the FromIntegral typeclass.

Instance details

Defined in Numeric.InfBackprop.Core

Methods

fromIntegral :: Word16 -> RevDiff a b c #

(FromIntegral c Word32, Additive a) => FromIntegral (RevDiff a b c) Word32 Source #

RevDiff and Word32 instance of the FromIntegral typeclass.

Instance details

Defined in Numeric.InfBackprop.Core

Methods

fromIntegral :: Word32 -> RevDiff a b c #

(FromIntegral c Word64, Additive a) => FromIntegral (RevDiff a b c) Word64 Source #

RevDiff and Word64 instance of the FromIntegral typeclass.

Instance details

Defined in Numeric.InfBackprop.Core

Methods

fromIntegral :: Word64 -> RevDiff a b c #

(FromIntegral c Word8, Additive a) => FromIntegral (RevDiff a b c) Word8 Source #

RevDiff and Word8 instance of the FromIntegral typeclass.

Instance details

Defined in Numeric.InfBackprop.Core

Methods

fromIntegral :: Word8 -> RevDiff a b c #

(FromIntegral c Integer, Additive a) => FromIntegral (RevDiff a b c) Integer Source #

RevDiff and Integer instance of the FromIntegral typeclass.

Instance details

Defined in Numeric.InfBackprop.Core

Methods

fromIntegral :: Integer -> RevDiff a b c #

(FromIntegral c Natural, Additive a) => FromIntegral (RevDiff a b c) Natural Source #

RevDiff and Natural instance of the FromIntegral typeclass.

Instance details

Defined in Numeric.InfBackprop.Core

Methods

fromIntegral :: Natural -> RevDiff a b c #

(FromIntegral c Int, Additive a) => FromIntegral (RevDiff a b c) Int Source #

RevDiff and Int instance of the FromIntegral typeclass.

Instance details

Defined in Numeric.InfBackprop.Core

Methods

fromIntegral :: Int -> RevDiff a b c #

(FromIntegral c Word, Additive a) => FromIntegral (RevDiff a b c) Word Source #

RevDiff and Word instance of the FromIntegral typeclass.

Instance details

Defined in Numeric.InfBackprop.Core

Methods

fromIntegral :: Word -> RevDiff a b c #

(MultiplicativeAction a b, MultiplicativeAction a cb, Convolution b cb ca, Additive ct) => MultiplicativeAction (RevDiff ct ca a) (RevDiff ct cb b) Source # 
Instance details

Defined in Numeric.InfBackprop.Core

Methods

(*|) :: RevDiff ct ca a -> RevDiff ct cb b -> RevDiff ct cb b

(Convolution a b c, Convolution cc b ca, Convolution a cc cb, Additive ct) => Convolution (RevDiff ct ca a) (RevDiff ct cb b) (RevDiff ct cc c) Source # 
Instance details

Defined in Numeric.InfBackprop.Core

Methods

(|*|) :: RevDiff ct ca a -> RevDiff ct cb b -> RevDiff ct cc c

type Rep (RevDiff a b c) Source # 
Instance details

Defined in Numeric.InfBackprop.Core

type Rep (RevDiff a b c) = D1 ('MetaData "RevDiff" "Numeric.InfBackprop.Core" "inf-backprop-0.2.0.0-inplace" 'False) (C1 ('MetaCons "MkRevDiff" 'PrefixI 'True) (S1 ('MetaSel ('Just "value") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 c) :*: S1 ('MetaSel ('Just "backprop") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 (b -> a))))
type DerivativeArg (RevDiff a b c) Source # 
Instance details

Defined in Numeric.InfBackprop.Core

type DerivativeArg (RevDiff a b c) = c
type DerivativeCoarg (RevDiff a b c) Source # 
Instance details

Defined in Numeric.InfBackprop.Core

type DerivativeCoarg (RevDiff a b c) = b
type DerivativeRoot (RevDiff a b c) Source # 
Instance details

Defined in Numeric.InfBackprop.Core

type DerivativeRoot (RevDiff a b c) = a
type DerivativeValue (RevDiff a b c) Source # 
Instance details

Defined in Numeric.InfBackprop.Core

type DerivativeValue (RevDiff a b c) = a
type Dual (RevDiff a b c) Source # 
Instance details

Defined in Numeric.InfBackprop.Core

type Dual (RevDiff a b c) = RevDiff a (Dual b) (Dual c)
type Tangent (RevDiff a b c) Source # 
Instance details

Defined in Numeric.InfBackprop.Core

type Tangent (RevDiff a b c) = RevDiff a (Tangent b) (Tangent c)

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

Expand
>>> :{
 differentiableCos_ :: DifferentiableFunc Float Float
 differentiableCos_ (MkRevDiff x bpc) = MkRevDiff (cos x) (bpc . ((negate $ sin x) *))
:}
>>> call differentiableCos_ 0.0
1.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

Expand
>>> :{
  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

Expand
>>> 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.0
1.0
>>> x = variable "x"
>>> f = unarySymbolicFunc "f"
>>> f x
f(x)
>>> call f x
f(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

Expand
>>> 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.0
1.0
>>> c = variable "c"
>>> x = variable "x"
>>> f = unarySymbolicFunc "f"
>>> f x
f(x)
>>> (derivativeOp f x) c
f'(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

Expand
>>> value (constDiff 42.0 :: RevDiff' Float Float)
42.0
>>> backprop (constDiff 42.0 :: RevDiff' Float Float) 1.0
0.0

class StopDiff a b where Source #

Typeclass for the automatic iterrupt of the backpropagation.

Examples

Expand
>>> :{
   simpleDerivative
     (\x -> x * twoArgsDerivativeOverY (+) x (stopDiff (1 :: Float)))
     (2024 :: Float)
:}
1.0

Methods

stopDiff :: a -> b Source #

Stops differentiation by converting a nested RevDiff type into a non-differentiable type.

Instances

Instances details
StopDiff a a Source #

Base case: stopping differentiation for the same type.

Instance details

Defined in Numeric.InfBackprop.Core

Methods

stopDiff :: a -> a Source #

(StopDiff a d, Additive b) => StopDiff a (RevDiff b c d) Source #

Recursive case: stopping differentiation for RevDiff type.

Instance details

Defined in Numeric.InfBackprop.Core

Methods

stopDiff :: a -> RevDiff b c d Source #

class HasConstant a b c d where Source #

Typeclass for creating constant differentiable functions.

Methods

constant :: Proxy a -> b -> c -> d Source #

Instances

Instances details
HasConstant a b a b Source #

Base case: constant function for the same type.

Instance details

Defined in Numeric.InfBackprop.Core

Methods

constant :: Proxy a -> b -> a -> b Source #

(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 RevDiff type.

Instance details

Defined in Numeric.InfBackprop.Core

Methods

constant :: Proxy a -> b -> RevDiff t e c -> RevDiff t f d Source #

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

Expand
>>> :{
 differentiableCos_ :: RevDiff t Float Float -> RevDiff t Float Float
 differentiableCos_ = simpleDifferentiableFunc cos (negate . sin)
:}
>>> call differentiableCos_ 0.0
1.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

Expand
>>> 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 x
sin(x)
>>> set sinLens c x
cos(x)*c
>>> squareLens = toLens (^2) :: Lens' SE SE
>>> (view . getting) (squareLens % sinLens) x
sin(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

Expand
>>> import Optics (lens)
>>> import Debug.SimpleExpr (variable, SE, simplify)
>>> sinV2 = fromLens $ lens sin (\x -> (cos x *))
>>> x = variable "x"
>>> c = variable "c"
>>> call sinV2 x
sin(x)
>>> simplify $ simpleDerivative sinV2 x :: SE
cos(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

Expand
>>> :{
 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

autoArg

Instances

Instances details
AutoDifferentiableArgument a => AutoDifferentiableArgument (Stream a) Source #

Stream instance for AutoDifferentiableArgument typeclass.

Instance details

Defined in Numeric.InfBackprop.Core

Associated Types

type DerivativeRoot (Stream a) 
Instance details

Defined in Numeric.InfBackprop.Core

type DerivativeCoarg (Stream a) 
Instance details

Defined in Numeric.InfBackprop.Core

type DerivativeArg (Stream a) 
Instance details

Defined in Numeric.InfBackprop.Core

AutoDifferentiableArgument a => AutoDifferentiableArgument (FiniteSupportStream a) Source #

FiniteSupportStream instance for AutoDifferentiableArgument typeclass.

Instance details

Defined in Numeric.InfBackprop.Core

AutoDifferentiableArgument a => AutoDifferentiableArgument (Maybe a) Source #

Maybe instance of AutoDifferentiableArgument.

Instance details

Defined in Numeric.InfBackprop.Core

Associated Types

type DerivativeRoot (Maybe a) 
Instance details

Defined in Numeric.InfBackprop.Core

type DerivativeCoarg (Maybe a) 
Instance details

Defined in Numeric.InfBackprop.Core

type DerivativeArg (Maybe a) 
Instance details

Defined in Numeric.InfBackprop.Core

(AutoDifferentiableArgument a, KnownNat n) => AutoDifferentiableArgument (BoxedVector n a) Source #

BoxedVector instance for AutoDifferentiableArgument typeclass.

Instance details

Defined in Numeric.InfBackprop.Core

Associated Types

type DerivativeRoot (BoxedVector n a) 
Instance details

Defined in Numeric.InfBackprop.Core

type DerivativeCoarg (BoxedVector n a) 
Instance details

Defined in Numeric.InfBackprop.Core

type DerivativeArg (BoxedVector n a) 
Instance details

Defined in Numeric.InfBackprop.Core

(AutoDifferentiableArgument a0, AutoDifferentiableArgument a1, DerivativeRoot a0 ~ DerivativeRoot a1) => AutoDifferentiableArgument (a0, a1) Source #

Tuple instance for AutoDifferentiableArgument typeclass. It makes it possible to differntiate tuple argument funcitons.

Instance details

Defined in Numeric.InfBackprop.Core

Associated Types

type DerivativeRoot (a0, a1) 
Instance details

Defined in Numeric.InfBackprop.Core

type DerivativeRoot (a0, a1) = DerivativeRoot a0
type DerivativeCoarg (a0, a1) 
Instance details

Defined in Numeric.InfBackprop.Core

type DerivativeArg (a0, a1) 
Instance details

Defined in Numeric.InfBackprop.Core

type DerivativeArg (a0, a1) = (DerivativeArg a0, DerivativeArg a1)

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 #

AutoDifferentiableArgument instance for the scalar argument term.

Instance details

Defined in Numeric.InfBackprop.Core

Associated Types

type DerivativeRoot (RevDiff a b c) 
Instance details

Defined in Numeric.InfBackprop.Core

type DerivativeRoot (RevDiff a b c) = a
type DerivativeCoarg (RevDiff a b c) 
Instance details

Defined in Numeric.InfBackprop.Core

type DerivativeCoarg (RevDiff a b c) = b
type DerivativeArg (RevDiff a b c) 
Instance details

Defined in Numeric.InfBackprop.Core

type DerivativeArg (RevDiff a b c) = c
(AutoDifferentiableArgument a0, AutoDifferentiableArgument a1, AutoDifferentiableArgument a2, DerivativeRoot a0 ~ DerivativeRoot a1, DerivativeRoot a0 ~ DerivativeRoot a2) => AutoDifferentiableArgument (a0, a1, a2) Source #

Triple instance for AutoDifferentiableArgument typeclass. It makes it possible to differntiate triple argument funcitons.

Instance details

Defined in Numeric.InfBackprop.Core

Associated Types

type DerivativeRoot (a0, a1, a2) 
Instance details

Defined in Numeric.InfBackprop.Core

type DerivativeRoot (a0, a1, a2) = DerivativeRoot a0
type DerivativeCoarg (a0, a1, a2) 
Instance details

Defined in Numeric.InfBackprop.Core

type DerivativeArg (a0, a1, a2) 
Instance details

Defined in Numeric.InfBackprop.Core

type DerivativeArg (a0, a1, a2) = (DerivativeArg a0, DerivativeArg a1, DerivativeArg a2)

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

Instances details
type DerivativeRoot (Stream a) Source # 
Instance details

Defined in Numeric.InfBackprop.Core

type DerivativeRoot (FiniteSupportStream a) Source # 
Instance details

Defined in Numeric.InfBackprop.Core

type DerivativeRoot (Maybe a) Source # 
Instance details

Defined in Numeric.InfBackprop.Core

type DerivativeRoot (BoxedVector n a) Source # 
Instance details

Defined in Numeric.InfBackprop.Core

type DerivativeRoot (a0, a1) Source # 
Instance details

Defined in Numeric.InfBackprop.Core

type DerivativeRoot (a0, a1) = DerivativeRoot a0
type DerivativeRoot (RevDiff a b c) Source # 
Instance details

Defined in Numeric.InfBackprop.Core

type DerivativeRoot (RevDiff a b c) = a
type DerivativeRoot (a0, a1, a2) Source # 
Instance details

Defined in Numeric.InfBackprop.Core

type DerivativeRoot (a0, a1, a2) = DerivativeRoot a0

type family DerivativeCoarg a Source #

Differentiable function coargument

Instances

Instances details
type DerivativeCoarg (Stream a) Source # 
Instance details

Defined in Numeric.InfBackprop.Core

type DerivativeCoarg (FiniteSupportStream a) Source # 
Instance details

Defined in Numeric.InfBackprop.Core

type DerivativeCoarg (Maybe a) Source # 
Instance details

Defined in Numeric.InfBackprop.Core

type DerivativeCoarg (BoxedVector n a) Source # 
Instance details

Defined in Numeric.InfBackprop.Core

type DerivativeCoarg (a0, a1) Source # 
Instance details

Defined in Numeric.InfBackprop.Core

type DerivativeCoarg (RevDiff a b c) Source # 
Instance details

Defined in Numeric.InfBackprop.Core

type DerivativeCoarg (RevDiff a b c) = b
type DerivativeCoarg (a0, a1, a2) Source # 
Instance details

Defined in Numeric.InfBackprop.Core

type family DerivativeArg a Source #

Differentiable functin argument

Instances

Instances details
type DerivativeArg (Stream a) Source # 
Instance details

Defined in Numeric.InfBackprop.Core

type DerivativeArg (FiniteSupportStream a) Source # 
Instance details

Defined in Numeric.InfBackprop.Core

type DerivativeArg (Maybe a) Source # 
Instance details

Defined in Numeric.InfBackprop.Core

type DerivativeArg (BoxedVector n a) Source # 
Instance details

Defined in Numeric.InfBackprop.Core

type DerivativeArg (a0, a1) Source # 
Instance details

Defined in Numeric.InfBackprop.Core

type DerivativeArg (a0, a1) = (DerivativeArg a0, DerivativeArg a1)
type DerivativeArg (RevDiff a b c) Source # 
Instance details

Defined in Numeric.InfBackprop.Core

type DerivativeArg (RevDiff a b c) = c
type DerivativeArg (a0, a1, a2) Source # 
Instance details

Defined in Numeric.InfBackprop.Core

type DerivativeArg (a0, a1, a2) = (DerivativeArg a0, DerivativeArg a1, DerivativeArg a2)

class AutoDifferentiableValue a Source #

Typeclass needed for the automatic value term derivation.

Examples

Expand
>>> :{
   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

autoVal

Instances

Instances details
AutoDifferentiableValue a => AutoDifferentiableValue (Stream a) Source #

Stream instance for AutoDifferentiableValue typeclass.

Instance details

Defined in Numeric.InfBackprop.Core

Associated Types

type DerivativeValue (Stream a) 
Instance details

Defined in Numeric.InfBackprop.Core

AutoDifferentiableValue a => AutoDifferentiableValue (FiniteSupportStream a) Source #

FiniteSupportStream instance for AutoDifferentiableValue typeclass.

Instance details

Defined in Numeric.InfBackprop.Core

AutoDifferentiableValue a => AutoDifferentiableValue (Maybe a) Source #

Maybe instance of AutoDifferentiableValue.

Instance details

Defined in Numeric.InfBackprop.Core

Associated Types

type DerivativeValue (Maybe a) 
Instance details

Defined in Numeric.InfBackprop.Core

AutoDifferentiableValue a => AutoDifferentiableValue (BoxedVector n a) Source #

BoxedVector instance for AutoDifferentiableValue typeclass.

Instance details

Defined in Numeric.InfBackprop.Core

Associated Types

type DerivativeValue (BoxedVector n a) 
Instance details

Defined in Numeric.InfBackprop.Core

(AutoDifferentiableValue a0, AutoDifferentiableValue a1) => AutoDifferentiableValue (a0, a1) Source #

Tuple instance for AutoDifferentiableValue typeclass. It makes it possible to differntiate tuple value funcitons.

Instance details

Defined in Numeric.InfBackprop.Core

Associated Types

type DerivativeValue (a0, a1) 
Instance details

Defined in Numeric.InfBackprop.Core

Methods

autoVal :: (a0, a1) -> DerivativeValue (a0, a1) Source #

Multiplicative b => AutoDifferentiableValue (RevDiff a b c) Source #

AutoDifferentiableValue instance for the scalar value term.

Instance details

Defined in Numeric.InfBackprop.Core

Associated Types

type DerivativeValue (RevDiff a b c) 
Instance details

Defined in Numeric.InfBackprop.Core

type DerivativeValue (RevDiff a b c) = a

Methods

autoVal :: RevDiff a b c -> DerivativeValue (RevDiff a b c) Source #

(AutoDifferentiableValue a0, AutoDifferentiableValue a1, AutoDifferentiableValue a2) => AutoDifferentiableValue (a0, a1, a2) Source #

Triple instance for AutoDifferentiableValue typeclass.

Instance details

Defined in Numeric.InfBackprop.Core

Associated Types

type DerivativeValue (a0, a1, a2) 
Instance details

Defined in Numeric.InfBackprop.Core

Methods

autoVal :: (a0, a1, a2) -> DerivativeValue (a0, a1, a2) Source #

type family DerivativeValue a Source #

Differentiable function value type.

Instances

Instances details
type DerivativeValue (Stream a) Source # 
Instance details

Defined in Numeric.InfBackprop.Core

type DerivativeValue (FiniteSupportStream a) Source # 
Instance details

Defined in Numeric.InfBackprop.Core

type DerivativeValue (Maybe a) Source # 
Instance details

Defined in Numeric.InfBackprop.Core

type DerivativeValue (BoxedVector n a) Source # 
Instance details

Defined in Numeric.InfBackprop.Core

type DerivativeValue (a0, a1) Source # 
Instance details

Defined in Numeric.InfBackprop.Core

type DerivativeValue (RevDiff a b c) Source # 
Instance details

Defined in Numeric.InfBackprop.Core

type DerivativeValue (RevDiff a b c) = a
type DerivativeValue (a0, a1, a2) Source # 
Instance details

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

Expand
>>> f = sin :: TrigField a => a -> a
>>> f' = sameTypeDerivative f :: Float -> Float
>>> f' 0.0
1.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

Expand
>>> import Debug.SimpleExpr (variable, simplify, SimpleExpr)
>>> import Debug.DiffExpr (unarySymbolicFunc)
>>> simpleDerivative sin (0.0 :: Float)
1.0
>>> x = variable "x"
>>> simplify $ simpleDerivative (^ 2) x
2*x
>>> f = unarySymbolicFunc "f"
>>> simplify $ simpleDerivative f x :: SimpleExpr
f'(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

Expand
>>> 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

Expand
>>> :{
   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

Expand
>>> :{
   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

Expand
>>> :{
   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

differentiableSum :: Additive c => RevDiff a (b, b) (c, c) -> RevDiff a b c Source #

Differentiable version of sum (+) for the RevDiff type.

This function implements automatic differentiation for addition by applying the sum rule: \[ \frac{d}{dx} (f(x) + g(x)) = \frac{df(x)}{dx} + \frac{dg(x)}{dx} \]. The gradient flows equally to both operands during backpropagation.

differentiableSub :: (Subtractive b, Subtractive c) => RevDiff a (b, b) (c, c) -> RevDiff a b c Source #

Differentiable version of subtraction (-) for the RevDiff type.

Implements the difference rule: \[ \frac{d}{dx} (f(x) - g(x)) = \frac{df(x)}{dx} - \frac{dg(x)}{dx}. \] Duringt the backpropagation, the gradient flows positively to the first operand and negatively to the second operand.

differentiableNegate :: (Subtractive a, Subtractive c) => RevDiff a b c -> RevDiff a b c Source #

Differentiable version of sign change function negate for RevDiff type.

Implements the negation rule: \[ \frac{d}{dx} (-f(x)) = -\frac{df(x)}{dx}. \] The gradient is simply negated during backpropagation.

differentiableMult :: Multiplicative b => RevDiff a (b, b) (b, b) -> RevDiff a b b Source #

Differentiable version of commutative multiplication (*) for the RevDiff type.

Implements the product rule: \[ \frac{d}{dx} (f(x) \cdot g(x)) = f(x) \cdot \frac{d g(x)}{dx} + \frac{df(x)}{dx} \cdot g(x). \] Each operand receives the gradient multiplied by the value of the other operand.

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 #

Differentiable version of recip for RevDiff type.

Implements \[ \frac{d}{dx} \frac{1}{f(x)} = -\frac{1}{f^2(x)} \cdot \frac{df(x)}{dx}. \] The gradient is scaled by the negative square of the reciprocal.

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

differentiablePow :: ExpField b => RevDiff a (b, b) (b, b) -> RevDiff a b b Source #

Differentiable version of exponentiation (**) for the RevDiff type.

Implements \[ \frac{d}{dx} f^{g(x)}(x) = f^{g(x)}(x) \cdot (\log f(x) \cdot \frac{dg(x)}{dx} + \frac{g(x)}{f(x)} \cdot \frac{df(x)}{dx}), \] handling both base and exponent dependencies in the gradient computation.

differentiableExp :: ExpField b => RevDiff a b b -> RevDiff a b b Source #

Differentiable version of exp for the RevDiff type.

Implements \[ \frac{d}{dx} \exp{f(x)} = \exp{f(x)} \cdot \frac{df(x)}{dx}. \] The exponential function is its own derivative, making the gradient computation particularly elegant.

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

Expand
>>> import Debug.SimpleExpr (variable, SE, simplify)
>>> simplify $ simpleDerivative differentiableLog (variable "x") :: SE
1/x

differentiableLogBase :: (ExpField b, IntegerPower b) => RevDiff a (b, b) (b, b) -> RevDiff a b b Source #

Differentiable version of logBase for the RevDiff type.

Implements \[ \frac{d}{dx} \log_b f(x) \] where both base and argument may be differentiable. Uses the change of base formula and applies the chain rule appropriately.

differentiableSqrt :: ExpField b => RevDiff a b b -> RevDiff a b b Source #

Differentiable version of sqrt for the RevDiff type.

Implements [ frac{d}{dx} sqrt{f(x)} = frac{1}{2 sqrt {f(x)}} cdot frac{df(x)}{dx}. The gradient is scaled by the reciprocal of twice the square root of the input.

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

Expand
>>> call differentiableSin 0.0 :: Float
0.0
>>> simpleDerivative differentiableSin 0.0 :: Float
1.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

Expand
>>> call differentiableCos 0.0 :: Float
1.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

Expand
>>> call differentiableTan 0.0 :: Float
0.0
>>> simpleDerivative differentiableTan 0.0 :: Float
1.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

Expand
>>> call differentiableSinh 0.0 :: Float
0.0
>>> simpleDerivative differentiableSinh 0.0 :: Float
1.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

Expand
>>> call differentiableCosh 0.0 :: Float
1.0
>>> simpleDerivative differentiableCosh 0.0 :: Float
0.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

Expand
>>> call differentiableTanh 0.0 :: Float
0.0
>>> simpleDerivative differentiableTanh 0.0 :: Float
1.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

Expand
>>> call differentiableAsin 0.0 :: Float
0.0
>>> simpleDerivative differentiableAsin 0.0 :: Float
1.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

Expand
>>> call differentiableAcos 0.0 :: Float
1.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

Expand
>>> call differentiableAtan 0.0 :: Float
0.0
>>> simpleDerivative differentiableAtan 0.0 :: Float
1.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

Expand
>>> call differentiableAsinh 0.0 :: Float
0.0
>>> simpleDerivative differentiableAsinh 0.0 :: Float
1.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

Expand
>>> call differentiableAtanh 0.0 :: Float
0.0
>>> simpleDerivative differentiableAtanh 0.0 :: Float
1.0

Differentiable types

Scalar

scalarArg :: RevDiff a b c -> RevDiff a b c Source #

Scalar (trivial) argument descriptor for differentiable functions.

Examples

Expand
>>> 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 t
Vector [v_x(t),v_y(t),v_z(t)]
>>> v' = simplify . scalarArgDerivative v :: SE -> BoxedVector 3 SE
>>> v' t
Vector [v_x'(t),v_y'(t),v_z'(t)]

scalarVal :: Multiplicative b => RevDiff a b c -> a Source #

Scalar value term.

Examples

Expand
>>> :{
   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

Expand
>>> 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

Expand
>>> 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

Expand
>>> 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

Expand
>>> 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

Expand
>>> 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

Expand
>>> 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

Expand
>>> 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

Expand
>>> 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 y
f'(x)*g(y)
>>> :{
 h'' :: SE -> SE -> SE
 h'' = simplify . twoArgsDerivativeOverX (twoArgsDerivativeOverX h)
:}
>>> h'' x y
f''(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

Expand
>>> 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 #

Transforms three RevDiff instances into a RevDiff instances of a triple. The inverese operation is tripleArg.

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

Expand
>>> 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

Expand
>>> 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

Expand
>>> 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

Expand
>>> 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

Expand
>>> 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' r
Vector [2*x,2*y,2*z]
>>> :{
 norm2'' :: BoxedVector 3 SE -> BoxedVector 3 (BoxedVector 3 SE)
 norm2'' = simplify . boxedVectorArgDerivative (boxedVectorArgDerivative norm2)
:}
>>> norm2'' r
Vector [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

Expand
>>> 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 t
Vector [v_x(t),v_y(t),v_z(t)]
>>> v' = simplify . customValDerivative boxedVectorVal v :: SE -> BoxedVector 3 SE
>>> v' t
Vector [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

Expand
>>> 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 t
Vector [v_x(t),v_y(t),v_z(t)]
>>> v' = simplify . boxedVectorValDerivative v :: SE -> BoxedVector 3 SE
>>> v' t
Vector [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

Expand
>>> 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

Expand
>>> 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 :: SE
s_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

Expand
>>> 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

Expand
>>> 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

Expand
>>> 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 :: SE
s_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

Expand
>>> 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

Expand
>>> 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

Expand
>>> :{
 f :: Additive a => Maybe a -> a
 f (Just x) = x
 f Nothing = zero
:}
>>> customArgDerivative maybeArg f (Just 3 :: Maybe Float) :: Maybe Float
Just 1.0

mkMaybeArg :: (RevDiff a b c -> d) -> RevDiff a (Maybe b) (Maybe c) -> Maybe d Source #

Maybe argument builder. Applies a function to Maybe value obtained from a RevDiff.

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

Expand
>>> 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

Expand
>>> :{
 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 Float
Just 0.5
>>> safeRecip (0.0 :: Float) :: Maybe Float
Nothing
>>> 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

Expand
>>> :{
 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 Float
Just 0.5
>>> safeRecip (0.0 :: Float) :: Maybe Float
Nothing
>>> maybeValDerivative safeRecip (2.0 :: Float)
Just (-0.25)
>>> maybeValDerivative safeRecip (0.0 :: Float)
Nothing