{-# LANGUAGE OverloadedStrings #-}
{-# OPTIONS_GHC -fno-warn-orphans #-}
{-# OPTIONS_HADDOCK show-extensions #-}

-- | Module    :  Debug.LoggingBackprop
-- Copyright   :  (C) 2023 Alexey Tochin
-- License     :  BSD3 (see the file LICENSE)
-- Maintainer  :  Alexey Tochin <Alexey.Tochin@gmail.com>
--
-- Basics for simple expressions equipped with Monadic behaviour.
-- In particular, basic functions with logging for debug and illustration purposes.
-- See [this tutorial section](InfBackprop.Tutorial#differentiation_monadic_types) for details.
module Debug.LoggingBackprop
  ( -- * Generic logging functions
    unitConst,
    initUnaryFunc,
    initBinaryFunc,
    pureKleisli,
    backpropExpr,
    loggingBackpropExpr,

    -- * Logging functions examples
    const,
    linear,
    negate,
    (+),
    (*),
    pow,
    exp,
    sin,
    cos,
  )
where

import Control.Arrow (Kleisli (Kleisli))
import Control.CatBifunctor (first, second, (***))
import Control.Category ((.), (>>>))
import Control.Monad.Logger (MonadLogger, logInfoN)
import Data.Text (pack)
import Debug.SimpleExpr.Expr (SimpleExpr, unaryFunc)
import InfBackprop.Common (Backprop (MkBackprop), BackpropFunc)
import IsomorphismClass.Isomorphism (iso)
import NumHask (Additive, Distributive, Divisive, ExpField, Multiplicative, Subtractive, TrigField, fromInteger, zero)
import qualified NumHask as NH
import qualified NumHask.Prelude as NHP
import qualified Prelude.InfBackprop
import Prelude (Monad, Show, String, pure, return, show, ($), (<>))
import qualified Prelude as P

-- | Logging constant function.
--
-- ==== __Examples of usage__
--
-- >>> import Control.Arrow (runKleisli)
-- >>> import Control.Monad.Logger (runStdoutLoggingT)
--
-- >>> runStdoutLoggingT $ runKleisli (unitConst 42) ()
-- [Info] Initializing 42
-- 42
unitConst :: (Show a, MonadLogger m) => a -> Kleisli m () a
unitConst :: forall a (m :: * -> *).
(Show a, MonadLogger m) =>
a -> Kleisli m () a
unitConst a
a = forall (m :: * -> *) a b. (a -> m b) -> Kleisli m a b
Kleisli forall a b. (a -> b) -> a -> b
$ \() -> do
  forall (m :: * -> *). MonadLogger m => Text -> m ()
logInfoN forall a b. (a -> b) -> a -> b
$ Text
"Initializing " forall a. Semigroup a => a -> a -> a
<> String -> Text
pack (forall a. Show a => a -> String
show a
a)
  forall (f :: * -> *) a. Applicative f => a -> f a
pure a
a

-- | Logging single argument function.
--
-- ==== __Examples of usage__
--
-- >>> import qualified Prelude as P
-- >>> import Control.Arrow (runKleisli)
-- >>> import Control.Monad.Logger (runStdoutLoggingT)
--
-- >>> plusTwo = initUnaryFunc "+2" (P.+2)
-- >>> runStdoutLoggingT $ runKleisli plusTwo 3
-- [Info] Calculating +2 of 3 => 5
-- 5
initUnaryFunc :: (Show a, Show b, MonadLogger m) => String -> (a -> b) -> Kleisli m a b
initUnaryFunc :: forall a b (m :: * -> *).
(Show a, Show b, MonadLogger m) =>
String -> (a -> b) -> Kleisli m a b
initUnaryFunc String
msg a -> b
f = forall (m :: * -> *) a b. (a -> m b) -> Kleisli m a b
Kleisli forall a b. (a -> b) -> a -> b
$ \a
a -> do
  let b :: b
b = a -> b
f a
a
  forall (m :: * -> *). MonadLogger m => Text -> m ()
logInfoN forall a b. (a -> b) -> a -> b
$ Text
"Calculating " forall a. Semigroup a => a -> a -> a
<> String -> Text
pack String
msg forall a. Semigroup a => a -> a -> a
<> Text
" of " forall a. Semigroup a => a -> a -> a
<> String -> Text
pack (forall a. Show a => a -> String
show a
a) forall a. Semigroup a => a -> a -> a
<> Text
" => " forall a. Semigroup a => a -> a -> a
<> String -> Text
pack (forall a. Show a => a -> String
show b
b)
  forall (f :: * -> *) a. Applicative f => a -> f a
pure b
b

-- | Logging two argument (binary) function.
--
-- ==== __Examples of usage__
--
-- >>> import qualified Prelude as P
-- >>> import Control.Arrow (runKleisli)
-- >>> import Control.Monad.Logger (runStdoutLoggingT)
--
-- >>> loggingProduct = initBinaryFunc "product" (P.*)
-- >>> runStdoutLoggingT $ runKleisli loggingProduct (6, 7)
-- [Info] Calculating product of 6 and 7 => 42
-- 42
initBinaryFunc :: (Show a, Show b, Show c, MonadLogger m) => String -> (a -> b -> c) -> Kleisli m (a, b) c
initBinaryFunc :: forall a b c (m :: * -> *).
(Show a, Show b, Show c, MonadLogger m) =>
String -> (a -> b -> c) -> Kleisli m (a, b) c
initBinaryFunc String
msg a -> b -> c
f = forall (m :: * -> *) a b. (a -> m b) -> Kleisli m a b
Kleisli forall a b. (a -> b) -> a -> b
$ \(a
a, b
b) -> do
  let c :: c
c = a -> b -> c
f a
a b
b
  forall (m :: * -> *). MonadLogger m => Text -> m ()
logInfoN forall a b. (a -> b) -> a -> b
$
    Text
"Calculating "
      forall a. Semigroup a => a -> a -> a
<> String -> Text
pack String
msg
      forall a. Semigroup a => a -> a -> a
<> Text
" of "
      forall a. Semigroup a => a -> a -> a
<> String -> Text
pack (forall a. Show a => a -> String
show a
a)
      forall a. Semigroup a => a -> a -> a
<> Text
" and "
      forall a. Semigroup a => a -> a -> a
<> String -> Text
pack (forall a. Show a => a -> String
show b
b)
      forall a. Semigroup a => a -> a -> a
<> Text
" => "
      forall a. Semigroup a => a -> a -> a
<> String -> Text
pack (forall a. Show a => a -> String
show c
c)
  forall (m :: * -> *) a. Monad m => a -> m a
return c
c

-- | Returns pure Kleisli morphism given a map.
--
-- ==== __Examples of usage__
--
-- >>> import Control.Arrow (runKleisli)
-- >>> import Control.Monad.Logger (runStdoutLoggingT)
--
-- >>> loggingDup = pureKleisli (\x -> (x, x))
-- >>> runStdoutLoggingT $ runKleisli loggingDup 42
-- (42,42)
pureKleisli :: Monad m => (a -> b) -> Kleisli m a b
pureKleisli :: forall (m :: * -> *) a b. Monad m => (a -> b) -> Kleisli m a b
pureKleisli a -> b
f = forall (m :: * -> *) a b. (a -> m b) -> Kleisli m a b
Kleisli forall a b. (a -> b) -> a -> b
$ forall (f :: * -> *) a. Applicative f => a -> f a
pure forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. a -> b
f

-- Differentiable functions.

-- | Returns symbolically differentiable Simple Expression.
--
-- ==== __Examples of usage__
--
-- >>> import Control.Arrow (runKleisli)
-- >>> import Control.Monad.Logger (runStdoutLoggingT)
-- >>> import Debug.SimpleExpr.Expr (variable)
-- >>> import InfBackprop (call, derivative, backpropExpr)
--
-- >>> x = variable "x"
-- >>> f = backpropExpr "f"
-- >>> call f x
-- f(x)
--
-- >>> derivative f x
-- 1·f'(x)
backpropExpr :: String -> BackpropFunc SimpleExpr SimpleExpr
backpropExpr :: String -> BackpropFunc SimpleExpr SimpleExpr
backpropExpr String
funcName = forall (cat :: * -> * -> *) input output cache.
cat input output
-> Backprop cat input (output, cache)
-> Backprop cat (output, cache) input
-> Backprop cat input output
MkBackprop SimpleExpr -> SimpleExpr
call_ Backprop (->) SimpleExpr (SimpleExpr, SimpleExpr)
forward_ Backprop (->) (SimpleExpr, SimpleExpr) SimpleExpr
backward_
  where
    call_ :: SimpleExpr -> SimpleExpr
call_ = String -> SimpleExpr -> SimpleExpr
unaryFunc String
funcName
    forward_ :: Backprop (->) SimpleExpr (SimpleExpr, SimpleExpr)
forward_ = forall x. Additive x => BackpropFunc x (x, x)
Prelude.InfBackprop.dup forall {k} (cat :: k -> k -> *) (a :: k) (b :: k) (c :: k).
Category cat =>
cat a b -> cat b c -> cat a c
>>> forall (p :: * -> * -> *) (cat :: * -> * -> *) a b c.
CatBiFunctor p cat =>
cat a b -> cat (p a c) (p b c)
first (String -> BackpropFunc SimpleExpr SimpleExpr
backpropExpr String
funcName :: BackpropFunc SimpleExpr SimpleExpr)
    backward_ :: Backprop (->) (SimpleExpr, SimpleExpr) SimpleExpr
backward_ = forall (p :: * -> * -> *) (cat :: * -> * -> *) a b c.
CatBiFunctor p cat =>
cat a b -> cat (p c a) (p c b)
second (String -> BackpropFunc SimpleExpr SimpleExpr
backpropExpr (String
funcName forall a. Semigroup a => a -> a -> a
<> String
"'")) forall {k} (cat :: k -> k -> *) (a :: k) (b :: k) (c :: k).
Category cat =>
cat a b -> cat b c -> cat a c
>>> forall x. Distributive x => BackpropFunc (x, x) x
(Prelude.InfBackprop.*)

-- | Returns symbolically differentiable logging symbolic function.
--
-- ==== __Examples of usage__
--
-- >>> import Control.Arrow (runKleisli)
-- >>> import Control.Monad.Logger (runStdoutLoggingT)
-- >>> import Debug.SimpleExpr.Expr (variable)
-- >>> import InfBackprop (call, derivative)
--
-- >>> x = variable "x"
-- >>> f = loggingBackpropExpr "f"
-- >>> runStdoutLoggingT $ runKleisli (call f) x
-- [Info] Calculating f of x => f(x)
-- f(x)
--
-- >>> runStdoutLoggingT $ runKleisli (derivative f) x
-- [Info] Calculating f of x => f(x)
-- [Info] Calculating f' of x => f'(x)
-- [Info] Calculating multiplication of 1 and f'(x) => 1·f'(x)
-- 1·f'(x)
loggingBackpropExpr :: forall m. (MonadLogger m) => String -> Backprop (Kleisli m) SimpleExpr SimpleExpr
loggingBackpropExpr :: forall (m :: * -> *).
MonadLogger m =>
String -> Backprop (Kleisli m) SimpleExpr SimpleExpr
loggingBackpropExpr String
funcName = forall (cat :: * -> * -> *) input output cache.
cat input output
-> Backprop cat input (output, cache)
-> Backprop cat (output, cache) input
-> Backprop cat input output
MkBackprop Kleisli m SimpleExpr SimpleExpr
call' Backprop (Kleisli m) SimpleExpr (SimpleExpr, SimpleExpr)
forward' Backprop (Kleisli m) (SimpleExpr, SimpleExpr) SimpleExpr
backward'
  where
    call' :: Kleisli m SimpleExpr SimpleExpr
    call' :: Kleisli m SimpleExpr SimpleExpr
call' = forall a b (m :: * -> *).
(Show a, Show b, MonadLogger m) =>
String -> (a -> b) -> Kleisli m a b
initUnaryFunc String
funcName (String -> SimpleExpr -> SimpleExpr
unaryFunc String
funcName)

    forward' :: Backprop (Kleisli m) SimpleExpr (SimpleExpr, SimpleExpr)
    forward' :: Backprop (Kleisli m) SimpleExpr (SimpleExpr, SimpleExpr)
forward' = forall x (m :: * -> *).
(Show x, Additive x, MonadLogger m) =>
Backprop (Kleisli m) x (x, x)
dup forall {k} (cat :: k -> k -> *) (a :: k) (b :: k) (c :: k).
Category cat =>
cat a b -> cat b c -> cat a c
>>> forall (p :: * -> * -> *) (cat :: * -> * -> *) a b c.
CatBiFunctor p cat =>
cat a b -> cat (p a c) (p b c)
first (forall (m :: * -> *).
MonadLogger m =>
String -> Backprop (Kleisli m) SimpleExpr SimpleExpr
loggingBackpropExpr String
funcName :: Backprop (Kleisli m) SimpleExpr SimpleExpr)

    backward' :: Backprop (Kleisli m) (SimpleExpr, SimpleExpr) SimpleExpr
    backward' :: Backprop (Kleisli m) (SimpleExpr, SimpleExpr) SimpleExpr
backward' = forall (p :: * -> * -> *) (cat :: * -> * -> *) a b c.
CatBiFunctor p cat =>
cat a b -> cat (p c a) (p c b)
second (forall (m :: * -> *).
MonadLogger m =>
String -> Backprop (Kleisli m) SimpleExpr SimpleExpr
loggingBackpropExpr (String
funcName forall a. Semigroup a => a -> a -> a
<> String
"'")) forall {k} (cat :: k -> k -> *) (a :: k) (b :: k) (c :: k).
Category cat =>
cat a b -> cat b c -> cat a c
>>> forall x (m :: * -> *).
(Show x, Additive x, Multiplicative x, MonadLogger m) =>
Backprop (Kleisli m) (x, x) x
(*)

-- | Differentiable logging constant function.
--
-- ==== __Examples of usage__
--
-- >>> import Control.Arrow (runKleisli)
-- >>> import Control.Monad.Logger (runStdoutLoggingT)
-- >>> import Debug.SimpleExpr.Expr (variable)
-- >>> import InfBackprop (call, derivative)
--
-- >>> runStdoutLoggingT $ runKleisli (call (const 42)) ()
-- 42
const ::
  forall c x m.
  (Additive c, Additive x, Show c, Show x, Monad m) =>
  c ->
  Backprop (Kleisli m) x c
const :: forall c x (m :: * -> *).
(Additive c, Additive x, Show c, Show x, Monad m) =>
c -> Backprop (Kleisli m) x c
const c
c = forall (cat :: * -> * -> *) input output cache.
cat input output
-> Backprop cat input (output, cache)
-> Backprop cat (output, cache) input
-> Backprop cat input output
MkBackprop Kleisli m x c
call' Backprop (Kleisli m) x (c, ())
forward' Backprop (Kleisli m) (c, ()) x
backward'
  where
    call' :: Kleisli m x c
    call' :: Kleisli m x c
call' = forall (m :: * -> *) a b. (a -> m b) -> Kleisli m a b
Kleisli forall a b. (a -> b) -> a -> b
$ forall a b. a -> b -> a
P.const (forall (f :: * -> *) a. Applicative f => a -> f a
pure c
c)

    forward' :: Backprop (Kleisli m) x (c, ())
    forward' :: Backprop (Kleisli m) x (c, ())
forward' = forall c x (m :: * -> *).
(Additive c, Additive x, Show c, Show x, Monad m) =>
c -> Backprop (Kleisli m) x c
const c
c forall {k} (cat :: k -> k -> *) (a :: k) (b :: k) (c :: k).
Category cat =>
cat a b -> cat b c -> cat a c
>>> (forall (c :: * -> * -> *) a b.
(Isomorphism c, IsomorphicTo a b) =>
c a b
iso :: Backprop (Kleisli m) c (c, ()))

    backward' :: Backprop (Kleisli m) (c, ()) x
    backward' :: Backprop (Kleisli m) (c, ()) x
backward' = forall c x (m :: * -> *).
(Additive c, Additive x, Show c, Show x, Monad m) =>
c -> Backprop (Kleisli m) x c
const forall a. Additive a => a
zero

-- | Differentiable dup logging function.
dup :: forall x m. (Show x, Additive x, MonadLogger m) => Backprop (Kleisli m) x (x, x)
dup :: forall x (m :: * -> *).
(Show x, Additive x, MonadLogger m) =>
Backprop (Kleisli m) x (x, x)
dup = forall (cat :: * -> * -> *) input output cache.
cat input output
-> Backprop cat input (output, cache)
-> Backprop cat (output, cache) input
-> Backprop cat input output
MkBackprop Kleisli m x (x, x)
call' Backprop (Kleisli m) x ((x, x), ())
forward' Backprop (Kleisli m) ((x, x), ()) x
backward'
  where
    call' :: Kleisli m x (x, x)
    call' :: Kleisli m x (x, x)
call' = forall (m :: * -> *) a b. Monad m => (a -> b) -> Kleisli m a b
pureKleisli (\x
x -> (x
x, x
x))

    forward' :: Backprop (Kleisli m) x ((x, x), ())
    forward' :: Backprop (Kleisli m) x ((x, x), ())
forward' = forall x (m :: * -> *).
(Show x, Additive x, MonadLogger m) =>
Backprop (Kleisli m) x (x, x)
dup forall {k} (cat :: k -> k -> *) (a :: k) (b :: k) (c :: k).
Category cat =>
cat a b -> cat b c -> cat a c
>>> (forall (c :: * -> * -> *) a b.
(Isomorphism c, IsomorphicTo a b) =>
c a b
iso :: Backprop (Kleisli m) y (y, ()))

    backward' :: Backprop (Kleisli m) ((x, x), ()) x
    backward' :: Backprop (Kleisli m) ((x, x), ()) x
backward' = (forall (c :: * -> * -> *) a b.
(Isomorphism c, IsomorphicTo a b) =>
c a b
iso :: Backprop (Kleisli m) (y, ()) y) forall {k} (cat :: k -> k -> *) (a :: k) (b :: k) (c :: k).
Category cat =>
cat a b -> cat b c -> cat a c
>>> forall x (m :: * -> *).
(Show x, Additive x, MonadLogger m) =>
Backprop (Kleisli m) (x, x) x
(+)

-- | Differentiable logging sum function.
--
-- ==== __Examples of usage__
--
-- >>> import Control.Arrow (runKleisli)
-- >>> import Control.Monad.Logger (runStdoutLoggingT)
-- >>> import InfBackprop (call)
--
-- >>> runStdoutLoggingT $ runKleisli (call (+)) (2, 2)
-- [Info] Calculating sum of 2 and 2 => 4
-- 4
(+) :: forall x m. (Show x, Additive x, MonadLogger m) => Backprop (Kleisli m) (x, x) x
+ :: forall x (m :: * -> *).
(Show x, Additive x, MonadLogger m) =>
Backprop (Kleisli m) (x, x) x
(+) = forall (cat :: * -> * -> *) input output cache.
cat input output
-> Backprop cat input (output, cache)
-> Backprop cat (output, cache) input
-> Backprop cat input output
MkBackprop Kleisli m (x, x) x
call' Backprop (Kleisli m) (x, x) (x, ())
forward' Backprop (Kleisli m) (x, ()) (x, x)
backward'
  where
    call' :: Kleisli m (x, x) x
    call' :: Kleisli m (x, x) x
call' = forall a b c (m :: * -> *).
(Show a, Show b, Show c, MonadLogger m) =>
String -> (a -> b -> c) -> Kleisli m (a, b) c
initBinaryFunc String
"sum" forall a. Additive a => a -> a -> a
(NH.+)

    forward' :: Backprop (Kleisli m) (x, x) (x, ())
    forward' :: Backprop (Kleisli m) (x, x) (x, ())
forward' = forall x (m :: * -> *).
(Show x, Additive x, MonadLogger m) =>
Backprop (Kleisli m) (x, x) x
(+) forall {k} (cat :: k -> k -> *) (a :: k) (b :: k) (c :: k).
Category cat =>
cat a b -> cat b c -> cat a c
>>> (forall (c :: * -> * -> *) a b.
(Isomorphism c, IsomorphicTo a b) =>
c a b
iso :: Backprop (Kleisli m) y (y, ()))

    backward' :: Backprop (Kleisli m) (x, ()) (x, x)
    backward' :: Backprop (Kleisli m) (x, ()) (x, x)
backward' = (forall (c :: * -> * -> *) a b.
(Isomorphism c, IsomorphicTo a b) =>
c a b
iso :: Backprop (Kleisli m) (x, ()) x) forall {k} (cat :: k -> k -> *) (a :: k) (b :: k) (c :: k).
Category cat =>
cat a b -> cat b c -> cat a c
>>> forall x (m :: * -> *).
(Show x, Additive x, MonadLogger m) =>
Backprop (Kleisli m) x (x, x)
dup

-- | Differentiable logging multiplication function.
--
-- ==== __Examples of usage__
--
-- >>> import Control.Arrow (runKleisli)
-- >>> import Control.Monad.Logger (runStdoutLoggingT)
-- >>> import InfBackprop (call)
--
-- >>> runStdoutLoggingT $ runKleisli (call (*)) (6, 7)
-- [Info] Calculating multiplication of 6 and 7 => 42
-- 42
(*) ::
  forall x m.
  (Show x, Additive x, Multiplicative x, MonadLogger m) =>
  Backprop (Kleisli m) (x, x) x
* :: forall x (m :: * -> *).
(Show x, Additive x, Multiplicative x, MonadLogger m) =>
Backprop (Kleisli m) (x, x) x
(*) = forall (cat :: * -> * -> *) input output cache.
cat input output
-> Backprop cat input (output, cache)
-> Backprop cat (output, cache) input
-> Backprop cat input output
MkBackprop Kleisli m (x, x) x
call' Backprop (Kleisli m) (x, x) (x, (x, x))
forward' Backprop (Kleisli m) (x, (x, x)) (x, x)
backward'
  where
    call' :: Kleisli m (x, x) x
    call' :: Kleisli m (x, x) x
call' = forall a b c (m :: * -> *).
(Show a, Show b, Show c, MonadLogger m) =>
String -> (a -> b -> c) -> Kleisli m (a, b) c
initBinaryFunc String
"multiplication" forall a. Multiplicative a => a -> a -> a
(NH.*)

    forward' :: Backprop (Kleisli m) (x, x) (x, (x, x))
    forward' :: Backprop (Kleisli m) (x, x) (x, (x, x))
forward' = forall x (m :: * -> *).
(Show x, Additive x, MonadLogger m) =>
Backprop (Kleisli m) x (x, x)
dup forall {k} (cat :: k -> k -> *) (a :: k) (b :: k) (c :: k).
Category cat =>
cat a b -> cat b c -> cat a c
>>> forall (p :: * -> * -> *) (cat :: * -> * -> *) a b c.
CatBiFunctor p cat =>
cat a b -> cat (p a c) (p b c)
first forall x (m :: * -> *).
(Show x, Additive x, Multiplicative x, MonadLogger m) =>
Backprop (Kleisli m) (x, x) x
(*)

    backward' :: Backprop (Kleisli m) (x, (x, x)) (x, x)
    backward' :: Backprop (Kleisli m) (x, (x, x)) (x, x)
backward' =
      forall (p :: * -> * -> *) (cat :: * -> * -> *) a b c.
CatBiFunctor p cat =>
cat a b -> cat (p a c) (p b c)
first forall x (m :: * -> *).
(Show x, Additive x, MonadLogger m) =>
Backprop (Kleisli m) x (x, x)
dup
        forall {k} (cat :: k -> k -> *) (a :: k) (b :: k) (c :: k).
Category cat =>
cat a b -> cat b c -> cat a c
>>> (forall (c :: * -> * -> *) a b.
(Isomorphism c, IsomorphicTo a b) =>
c a b
iso :: Backprop (Kleisli m) ((dy, dy), (x1, x2)) ((dy, x1), (dy, x2)))
        forall {k} (cat :: k -> k -> *) (a :: k) (b :: k) (c :: k).
Category cat =>
cat a b -> cat b c -> cat a c
>>> (forall (c :: * -> * -> *) a b.
(Isomorphism c, IsomorphicTo a b) =>
c a b
iso :: Backprop (Kleisli m) (a, b) (b, a))
        forall {k} (cat :: k -> k -> *) (a :: k) (b :: k) (c :: k).
Category cat =>
cat a b -> cat b c -> cat a c
>>> (forall x (m :: * -> *).
(Show x, Additive x, Multiplicative x, MonadLogger m) =>
Backprop (Kleisli m) (x, x) x
(*) forall (p :: * -> * -> *) (cat :: * -> * -> *) a1 b1 a2 b2.
CatBiFunctor p cat =>
cat a1 b1 -> cat a2 b2 -> cat (p a1 a2) (p b1 b2)
*** forall x (m :: * -> *).
(Show x, Additive x, Multiplicative x, MonadLogger m) =>
Backprop (Kleisli m) (x, x) x
(*))

-- | Differentiable logging linear function.
linear ::
  forall x m.
  (Show x, NH.Distributive x, MonadLogger m) =>
  x ->
  Backprop (Kleisli m) x x
linear :: forall x (m :: * -> *).
(Show x, Distributive x, MonadLogger m) =>
x -> Backprop (Kleisli m) x x
linear x
c = forall (cat :: * -> * -> *) input output cache.
cat input output
-> Backprop cat input (output, cache)
-> Backprop cat (output, cache) input
-> Backprop cat input output
MkBackprop Kleisli m x x
call' Backprop (Kleisli m) x (x, ())
forward' Backprop (Kleisli m) (x, ()) x
backward'
  where
    call' :: Kleisli m x x
    call' :: Kleisli m x x
call' = forall a b (m :: * -> *).
(Show a, Show b, MonadLogger m) =>
String -> (a -> b) -> Kleisli m a b
initUnaryFunc (String
"linear " forall a. Semigroup a => a -> a -> a
<> forall a. Show a => a -> String
show x
c) (x
c forall a. Multiplicative a => a -> a -> a
NH.*)

    forward' :: Backprop (Kleisli m) x (x, ())
    forward' :: Backprop (Kleisli m) x (x, ())
forward' = forall x (m :: * -> *).
(Show x, Distributive x, MonadLogger m) =>
x -> Backprop (Kleisli m) x x
linear x
c forall {k} (cat :: k -> k -> *) (a :: k) (b :: k) (c :: k).
Category cat =>
cat a b -> cat b c -> cat a c
>>> (forall (c :: * -> * -> *) a b.
(Isomorphism c, IsomorphicTo a b) =>
c a b
iso :: Backprop (Kleisli m) y (y, ()))

    backward' :: Backprop (Kleisli m) (x, ()) x
    backward' :: Backprop (Kleisli m) (x, ()) x
backward' = (forall (c :: * -> * -> *) a b.
(Isomorphism c, IsomorphicTo a b) =>
c a b
iso :: Backprop (Kleisli m) (x, ()) x) forall {k} (cat :: k -> k -> *) (a :: k) (b :: k) (c :: k).
Category cat =>
cat a b -> cat b c -> cat a c
>>> forall x (m :: * -> *).
(Show x, Distributive x, MonadLogger m) =>
x -> Backprop (Kleisli m) x x
linear x
c

-- | Differentiable logging negate function.
negate ::
  forall x m.
  (Show x, Subtractive x, MonadLogger m) =>
  Backprop (Kleisli m) x x
negate :: forall x (m :: * -> *).
(Show x, Subtractive x, MonadLogger m) =>
Backprop (Kleisli m) x x
negate = forall (cat :: * -> * -> *) input output cache.
cat input output
-> Backprop cat input (output, cache)
-> Backprop cat (output, cache) input
-> Backprop cat input output
MkBackprop Kleisli m x x
call' Backprop (Kleisli m) x (x, ())
forward' Backprop (Kleisli m) (x, ()) x
backward'
  where
    call' :: Kleisli m x x
    call' :: Kleisli m x x
call' = forall a b (m :: * -> *).
(Show a, Show b, MonadLogger m) =>
String -> (a -> b) -> Kleisli m a b
initUnaryFunc String
"negate" forall a. Subtractive a => a -> a
NH.negate

    forward' :: Backprop (Kleisli m) x (x, ())
    forward' :: Backprop (Kleisli m) x (x, ())
forward' = forall x (m :: * -> *).
(Show x, Subtractive x, MonadLogger m) =>
Backprop (Kleisli m) x x
negate forall {k} (cat :: k -> k -> *) (a :: k) (b :: k) (c :: k).
Category cat =>
cat a b -> cat b c -> cat a c
>>> (forall (c :: * -> * -> *) a b.
(Isomorphism c, IsomorphicTo a b) =>
c a b
iso :: Backprop (Kleisli m) y (y, ()))

    backward' :: Backprop (Kleisli m) (x, ()) x
    backward' :: Backprop (Kleisli m) (x, ()) x
backward' = (forall (c :: * -> * -> *) a b.
(Isomorphism c, IsomorphicTo a b) =>
c a b
iso :: Backprop (Kleisli m) (y, ()) y) forall {k} (cat :: k -> k -> *) (a :: k) (b :: k) (c :: k).
Category cat =>
cat a b -> cat b c -> cat a c
>>> forall x (m :: * -> *).
(Show x, Subtractive x, MonadLogger m) =>
Backprop (Kleisli m) x x
negate

-- | Differentiable logging exponent function.
exp ::
  forall x m.
  (ExpField x, Show x, MonadLogger m) =>
  Backprop (Kleisli m) x x
exp :: forall x (m :: * -> *).
(ExpField x, Show x, MonadLogger m) =>
Backprop (Kleisli m) x x
exp = forall (cat :: * -> * -> *) input output cache.
cat input output
-> Backprop cat input (output, cache)
-> Backprop cat (output, cache) input
-> Backprop cat input output
MkBackprop Kleisli m x x
call' Backprop (Kleisli m) x (x, x)
forward' Backprop (Kleisli m) (x, x) x
backward'
  where
    call' :: Kleisli m x x
    call' :: Kleisli m x x
call' = forall a b (m :: * -> *).
(Show a, Show b, MonadLogger m) =>
String -> (a -> b) -> Kleisli m a b
initUnaryFunc String
"exp" forall a. ExpField a => a -> a
NH.exp

    forward' :: Backprop (Kleisli m) x (x, x)
    forward' :: Backprop (Kleisli m) x (x, x)
forward' = (forall x (m :: * -> *).
(ExpField x, Show x, MonadLogger m) =>
Backprop (Kleisli m) x x
exp :: Backprop (Kleisli m) x x) forall {k} (cat :: k -> k -> *) (a :: k) (b :: k) (c :: k).
Category cat =>
cat a b -> cat b c -> cat a c
>>> forall x (m :: * -> *).
(Show x, Additive x, MonadLogger m) =>
Backprop (Kleisli m) x (x, x)
dup

    backward' :: Backprop (Kleisli m) (x, x) x
    backward' :: Backprop (Kleisli m) (x, x) x
backward' = forall x (m :: * -> *).
(Show x, Additive x, Multiplicative x, MonadLogger m) =>
Backprop (Kleisli m) (x, x) x
(*)

-- | Differentiable logging power function.
pow ::
  forall x m.
  (Show x, Divisive x, Distributive x, Subtractive x, NH.FromIntegral x NHP.Integer, MonadLogger m) =>
  NHP.Integer ->
  Backprop (Kleisli m) x x
pow :: forall x (m :: * -> *).
(Show x, Divisive x, Distributive x, Subtractive x,
 FromIntegral x Integer, MonadLogger m) =>
Integer -> Backprop (Kleisli m) x x
pow Integer
n = forall (cat :: * -> * -> *) input output cache.
cat input output
-> Backprop cat input (output, cache)
-> Backprop cat (output, cache) input
-> Backprop cat input output
MkBackprop Kleisli m x x
call' Backprop (Kleisli m) x (x, x)
forward' Backprop (Kleisli m) (x, x) x
backward'
  where
    call' :: Kleisli m x x
    call' :: Kleisli m x x
call' = forall a b (m :: * -> *).
(Show a, Show b, MonadLogger m) =>
String -> (a -> b) -> Kleisli m a b
initUnaryFunc (String
"pow " forall a. Semigroup a => a -> a -> a
<> forall a. Show a => a -> String
show Integer
n) (forall a. Divisive a => a -> Int -> a
NH.^ forall a. FromInteger a => Integer -> a
fromInteger Integer
n)

    forward' :: Backprop (Kleisli m) x (x, x)
    forward' :: Backprop (Kleisli m) x (x, x)
forward' = forall x (m :: * -> *).
(Show x, Additive x, MonadLogger m) =>
Backprop (Kleisli m) x (x, x)
dup forall {k} (cat :: k -> k -> *) (a :: k) (b :: k) (c :: k).
Category cat =>
cat a b -> cat b c -> cat a c
>>> forall (p :: * -> * -> *) (cat :: * -> * -> *) a b c.
CatBiFunctor p cat =>
cat a b -> cat (p a c) (p b c)
first (forall x (m :: * -> *).
(Show x, Divisive x, Distributive x, Subtractive x,
 FromIntegral x Integer, MonadLogger m) =>
Integer -> Backprop (Kleisli m) x x
pow Integer
n :: Backprop (Kleisli m) x x)

    backward' :: Backprop (Kleisli m) (x, x) x
    backward' :: Backprop (Kleisli m) (x, x) x
backward' = forall (p :: * -> * -> *) (cat :: * -> * -> *) a b c.
CatBiFunctor p cat =>
cat a b -> cat (p c a) (p c b)
second (forall x (m :: * -> *).
(Show x, Divisive x, Distributive x, Subtractive x,
 FromIntegral x Integer, MonadLogger m) =>
Integer -> Backprop (Kleisli m) x x
pow (Integer
n forall a. Num a => a -> a -> a
P.- Integer
1) forall {k} (cat :: k -> k -> *) (a :: k) (b :: k) (c :: k).
Category cat =>
cat a b -> cat b c -> cat a c
>>> forall x (m :: * -> *).
(Show x, Distributive x, MonadLogger m) =>
x -> Backprop (Kleisli m) x x
linear (forall a b. FromIntegral a b => b -> a
NH.fromIntegral Integer
n)) forall {k} (cat :: k -> k -> *) (a :: k) (b :: k) (c :: k).
Category cat =>
cat a b -> cat b c -> cat a c
>>> forall x (m :: * -> *).
(Show x, Additive x, Multiplicative x, MonadLogger m) =>
Backprop (Kleisli m) (x, x) x
(*)

-- | Differentiable logging sin function.
sin ::
  forall x m.
  (Show x, TrigField x, MonadLogger m) =>
  Backprop (Kleisli m) x x
sin :: forall x (m :: * -> *).
(Show x, TrigField x, MonadLogger m) =>
Backprop (Kleisli m) x x
sin = forall (cat :: * -> * -> *) input output cache.
cat input output
-> Backprop cat input (output, cache)
-> Backprop cat (output, cache) input
-> Backprop cat input output
MkBackprop Kleisli m x x
call' Backprop (Kleisli m) x (x, x)
forward' Backprop (Kleisli m) (x, x) x
backward'
  where
    call' :: Kleisli m x x
    call' :: Kleisli m x x
call' = forall a b (m :: * -> *).
(Show a, Show b, MonadLogger m) =>
String -> (a -> b) -> Kleisli m a b
initUnaryFunc String
"sin" forall a. TrigField a => a -> a
NH.sin

    forward' :: Backprop (Kleisli m) x (x, x)
    forward' :: Backprop (Kleisli m) x (x, x)
forward' = forall x (m :: * -> *).
(Show x, Additive x, MonadLogger m) =>
Backprop (Kleisli m) x (x, x)
dup forall {k} (cat :: k -> k -> *) (a :: k) (b :: k) (c :: k).
Category cat =>
cat a b -> cat b c -> cat a c
>>> forall (p :: * -> * -> *) (cat :: * -> * -> *) a b c.
CatBiFunctor p cat =>
cat a b -> cat (p a c) (p b c)
first (forall x (m :: * -> *).
(Show x, TrigField x, MonadLogger m) =>
Backprop (Kleisli m) x x
sin :: Backprop (Kleisli m) x x)

    backward' :: Backprop (Kleisli m) (x, x) x
    backward' :: Backprop (Kleisli m) (x, x) x
backward' = forall (p :: * -> * -> *) (cat :: * -> * -> *) a b c.
CatBiFunctor p cat =>
cat a b -> cat (p c a) (p c b)
second (forall x (m :: * -> *).
(Show x, TrigField x, MonadLogger m) =>
Backprop (Kleisli m) x x
cos :: Backprop (Kleisli m) x x) forall {k} (cat :: k -> k -> *) (a :: k) (b :: k) (c :: k).
Category cat =>
cat a b -> cat b c -> cat a c
>>> forall x (m :: * -> *).
(Show x, Additive x, Multiplicative x, MonadLogger m) =>
Backprop (Kleisli m) (x, x) x
(*)

-- | Differentiable logging cos function.
cos ::
  forall x m.
  (Show x, TrigField x, MonadLogger m) =>
  Backprop (Kleisli m) x x
cos :: forall x (m :: * -> *).
(Show x, TrigField x, MonadLogger m) =>
Backprop (Kleisli m) x x
cos = forall (cat :: * -> * -> *) input output cache.
cat input output
-> Backprop cat input (output, cache)
-> Backprop cat (output, cache) input
-> Backprop cat input output
MkBackprop Kleisli m x x
call' Backprop (Kleisli m) x (x, x)
forward' Backprop (Kleisli m) (x, x) x
backward'
  where
    call' :: Kleisli m x x
    call' :: Kleisli m x x
call' = forall a b (m :: * -> *).
(Show a, Show b, MonadLogger m) =>
String -> (a -> b) -> Kleisli m a b
initUnaryFunc String
"cos" forall a. TrigField a => a -> a
NH.cos

    forward' :: Backprop (Kleisli m) x (x, x)
    forward' :: Backprop (Kleisli m) x (x, x)
forward' = forall x (m :: * -> *).
(Show x, Additive x, MonadLogger m) =>
Backprop (Kleisli m) x (x, x)
dup forall {k} (cat :: k -> k -> *) (a :: k) (b :: k) (c :: k).
Category cat =>
cat a b -> cat b c -> cat a c
>>> forall (p :: * -> * -> *) (cat :: * -> * -> *) a b c.
CatBiFunctor p cat =>
cat a b -> cat (p a c) (p b c)
first (forall x (m :: * -> *).
(Show x, TrigField x, MonadLogger m) =>
Backprop (Kleisli m) x x
sin :: Backprop (Kleisli m) x x)

    backward' :: Backprop (Kleisli m) (x, x) x
    backward' :: Backprop (Kleisli m) (x, x) x
backward' = forall (p :: * -> * -> *) (cat :: * -> * -> *) a b c.
CatBiFunctor p cat =>
cat a b -> cat (p c a) (p c b)
second (forall x (m :: * -> *).
(Show x, TrigField x, MonadLogger m) =>
Backprop (Kleisli m) x x
sin forall {k} (cat :: k -> k -> *) (a :: k) (b :: k) (c :: k).
Category cat =>
cat a b -> cat b c -> cat a c
>>> forall x (m :: * -> *).
(Show x, Subtractive x, MonadLogger m) =>
Backprop (Kleisli m) x x
negate :: Backprop (Kleisli m) x x) forall {k} (cat :: k -> k -> *) (a :: k) (b :: k) (c :: k).
Category cat =>
cat a b -> cat b c -> cat a c
>>> forall x (m :: * -> *).
(Show x, Additive x, Multiplicative x, MonadLogger m) =>
Backprop (Kleisli m) (x, x) x
(*)