{-# LANGUAGE DataKinds #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE RankNTypes #-}
{-# OPTIONS_HADDOCK not-home #-}

-- |
-- Module      : Numeric.Backprop.Num
-- Copyright   : (c) Justin Le 2023
-- License     : BSD3
--
-- Maintainer  : justin@jle.im
-- Stability   : experimental
-- Portability : non-portable
--
-- Provides the exact same API as "Numeric.Backprop", except requiring
-- 'Num' instances for all types involved instead of 'Backprop' instances.
--
-- This was the original API of the library (for version 0.1).
--
-- 'Num' is strictly more powerful than 'Backprop', and is a stronger
-- constraint on types than is necessary for proper backpropagating.  In
-- particular, 'fromInteger' is a problem for many types, preventing useful
-- backpropagation for lists, variable-length vectors (like "Data.Vector")
-- and variable-size matrices from linear algebra libraries like /hmatrix/
-- and /accelerate/.
--
-- However, this module might be useful in situations where you are working
-- with external types with 'Num' instances, and you want to avoid writing
-- orphan instances for external types.
--
-- If you have external types that are not 'Num' instances, consider
-- instead "Numeric.Backprop.External".
--
-- If you need a 'Num' instance for tuples, you can use the orphan
-- instances in the <https://hackage.haskell.org/package/NumInstances
-- NumInstances> package (in particular, "Data.NumInstances.Tuple") if you
-- are writing an application and do not have to worry about orphan
-- instances.
--
-- See "Numeric.Backprop" for fuller documentation on using these
-- functions.
--
-- @since 0.2.0.0
module Numeric.Backprop.Num (
  -- * Types
  BVar,
  W,

  -- * Running
  backprop,
  E.evalBP,
  gradBP,
  backpropWith,

  -- ** Multiple inputs
  E.evalBP0,
  backprop2,
  E.evalBP2,
  gradBP2,
  backpropWith2,
  backpropN,
  E.evalBPN,
  gradBPN,
  backpropWithN,

  -- * Manipulating 'BVar'
  E.constVar,
  E.auto,
  E.coerceVar,
  (^^.),
  (.~~),
  (%~~),
  (^^?),
  (^^..),
  (^^?!),
  viewVar,
  setVar,
  overVar,
  sequenceVar,
  collectVar,
  previewVar,
  toListOfVar,

  -- ** With Isomorphisms
  isoVar,
  isoVar2,
  isoVar3,
  isoVarN,

  -- ** With 'Op's
  liftOp,
  liftOp1,
  liftOp2,
  liftOp3,

  -- * 'Op'
  Op (..),

  -- ** Creation
  op0,
  opConst,
  idOp,
  bpOp,

  -- *** Giving gradients directly
  op1,
  op2,
  op3,

  -- *** From Isomorphisms
  opCoerce,
  opTup,
  opIso,
  opIsoN,
  opLens,

  -- *** No gradients
  noGrad1,
  noGrad,

  -- * Utility
  Reifies,
) where

import Data.Functor.Identity
import Data.Maybe
import Data.Reflection
import Data.Vinyl
import Lens.Micro
import Numeric.Backprop.Explicit (BVar, W)
import qualified Numeric.Backprop.Explicit as E
import Numeric.Backprop.Op

-- | 'Numeric.Backprop.backpropN', but with 'Num' constraints instead of
-- 'Backprop' constraints.
--
-- The @'RPureConstrained' 'Num' as@ in the constraint says that every
-- value in the type-level list @as@ must have a 'Num' instance.  This
-- means you can use, say, @'[Double, Float, Int]@, but not @'[Double,
-- Bool, String]@.
--
-- If you stick to /concerete/, monomorphic usage of this (with specific
-- types, typed into source code, known at compile-time), then
-- @'AllPureConstrained' 'Num' as@ should be fulfilled automatically.
backpropN ::
  (RPureConstrained Num as, Num b) =>
  (forall s. Reifies s W => Rec (BVar s) as -> BVar s b) ->
  Rec Identity as ->
  (b, Rec Identity as)
backpropN :: forall (as :: [*]) b.
(RPureConstrained Num as, Num b) =>
(forall s. Reifies s W => Rec (BVar s) as -> BVar s b)
-> Rec Identity as -> (b, Rec Identity as)
backpropN = Rec ZeroFunc as
-> OneFunc b
-> (forall s. Reifies s W => Rec (BVar s) as -> BVar s b)
-> Rec Identity as
-> (b, Rec Identity as)
forall (as :: [*]) b.
Rec ZeroFunc as
-> OneFunc b
-> (forall s. Reifies s W => Rec (BVar s) as -> BVar s b)
-> Rec Identity as
-> (b, Rec Identity as)
E.backpropN Rec ZeroFunc as
forall (as :: [*]). RPureConstrained Num as => Rec ZeroFunc as
E.zfNums OneFunc b
forall a. Num a => OneFunc a
E.ofNum
{-# INLINE backpropN #-}

-- | 'Numeric.Backprop.backpropWithN', but with 'Num' constraints instead
-- of 'Backprop' constraints.
--
-- See 'backpropN' for information on the 'AllConstrained' constraint.
--
-- Note that argument order changed in v0.2.4.
--
-- @since 0.2.0.0
backpropWithN ::
  RPureConstrained Num as =>
  (forall s. Reifies s W => Rec (BVar s) as -> BVar s b) ->
  Rec Identity as ->
  (b, b -> Rec Identity as)
backpropWithN :: forall (as :: [*]) b.
RPureConstrained Num as =>
(forall s. Reifies s W => Rec (BVar s) as -> BVar s b)
-> Rec Identity as -> (b, b -> Rec Identity as)
backpropWithN = Rec ZeroFunc as
-> (forall s. Reifies s W => Rec (BVar s) as -> BVar s b)
-> Rec Identity as
-> (b, b -> Rec Identity as)
forall (as :: [*]) b.
Rec ZeroFunc as
-> (forall s. Reifies s W => Rec (BVar s) as -> BVar s b)
-> Rec Identity as
-> (b, b -> Rec Identity as)
E.backpropWithN Rec ZeroFunc as
forall (as :: [*]). RPureConstrained Num as => Rec ZeroFunc as
E.zfNums
{-# INLINE backpropWithN #-}

-- | 'Numeric.Backprop.backprop', but with 'Num' constraints instead of
-- 'Backprop' constraints.
--
-- See module documentation for "Numeric.Backprop.Num" for information on
-- using this with tuples.
backprop ::
  (Num a, Num b) =>
  (forall s. Reifies s W => BVar s a -> BVar s b) ->
  a ->
  (b, a)
backprop :: forall a b.
(Num a, Num b) =>
(forall s. Reifies s W => BVar s a -> BVar s b) -> a -> (b, a)
backprop = ZeroFunc a
-> OneFunc b
-> (forall s. Reifies s W => BVar s a -> BVar s b)
-> a
-> (b, a)
forall a b.
ZeroFunc a
-> OneFunc b
-> (forall s. Reifies s W => BVar s a -> BVar s b)
-> a
-> (b, a)
E.backprop ZeroFunc a
forall a. Num a => ZeroFunc a
E.zfNum OneFunc b
forall a. Num a => OneFunc a
E.ofNum
{-# INLINE backprop #-}

-- | 'Numeric.Backprop.backpropWith', but with 'Num' constraints instead of
-- 'Backprop' constraints.
--
-- See module documentation for "Numeric.Backprop.Num" for information on
-- using this with tuples.
--
-- Note that argument order changed in v0.2.4.
--
-- @since 0.2.0.0
backpropWith ::
  Num a =>
  (forall s. Reifies s W => BVar s a -> BVar s b) ->
  a ->
  (b, b -> a)
backpropWith :: forall a b.
Num a =>
(forall s. Reifies s W => BVar s a -> BVar s b) -> a -> (b, b -> a)
backpropWith = ZeroFunc a
-> (forall s. Reifies s W => BVar s a -> BVar s b)
-> a
-> (b, b -> a)
forall a b.
ZeroFunc a
-> (forall s. Reifies s W => BVar s a -> BVar s b)
-> a
-> (b, b -> a)
E.backpropWith ZeroFunc a
forall a. Num a => ZeroFunc a
E.zfNum
{-# INLINE backpropWith #-}

-- | 'Numeric.Backprop.gradBP', but with 'Num' constraints instead of
-- 'Backprop' constraints.
gradBP ::
  (Num a, Num b) =>
  (forall s. Reifies s W => BVar s a -> BVar s b) ->
  a ->
  a
gradBP :: forall a b.
(Num a, Num b) =>
(forall s. Reifies s W => BVar s a -> BVar s b) -> a -> a
gradBP = ZeroFunc a
-> OneFunc b
-> (forall s. Reifies s W => BVar s a -> BVar s b)
-> a
-> a
forall a b.
ZeroFunc a
-> OneFunc b
-> (forall s. Reifies s W => BVar s a -> BVar s b)
-> a
-> a
E.gradBP ZeroFunc a
forall a. Num a => ZeroFunc a
E.zfNum OneFunc b
forall a. Num a => OneFunc a
E.ofNum
{-# INLINE gradBP #-}

-- | 'Numeric.Backprop.gradBPN', but with 'Num' constraints instead of
-- 'Backprop' constraints.
gradBPN ::
  (RPureConstrained Num as, Num b) =>
  (forall s. Reifies s W => Rec (BVar s) as -> BVar s b) ->
  Rec Identity as ->
  Rec Identity as
gradBPN :: forall (as :: [*]) b.
(RPureConstrained Num as, Num b) =>
(forall s. Reifies s W => Rec (BVar s) as -> BVar s b)
-> Rec Identity as -> Rec Identity as
gradBPN = Rec ZeroFunc as
-> OneFunc b
-> (forall s. Reifies s W => Rec (BVar s) as -> BVar s b)
-> Rec Identity as
-> Rec Identity as
forall (as :: [*]) b.
Rec ZeroFunc as
-> OneFunc b
-> (forall s. Reifies s W => Rec (BVar s) as -> BVar s b)
-> Rec Identity as
-> Rec Identity as
E.gradBPN Rec ZeroFunc as
forall (as :: [*]). RPureConstrained Num as => Rec ZeroFunc as
E.zfNums OneFunc b
forall a. Num a => OneFunc a
E.ofNum
{-# INLINE gradBPN #-}

-- | 'Numeric.Backprop.backprop2', but with 'Num' constraints instead of
-- 'Backprop' constraints.
backprop2 ::
  (Num a, Num b, Num c) =>
  (forall s. Reifies s W => BVar s a -> BVar s b -> BVar s c) ->
  a ->
  b ->
  (c, (a, b))
backprop2 :: forall a b c.
(Num a, Num b, Num c) =>
(forall s. Reifies s W => BVar s a -> BVar s b -> BVar s c)
-> a -> b -> (c, (a, b))
backprop2 = ZeroFunc a
-> ZeroFunc b
-> OneFunc c
-> (forall s. Reifies s W => BVar s a -> BVar s b -> BVar s c)
-> a
-> b
-> (c, (a, b))
forall a b c.
ZeroFunc a
-> ZeroFunc b
-> OneFunc c
-> (forall s. Reifies s W => BVar s a -> BVar s b -> BVar s c)
-> a
-> b
-> (c, (a, b))
E.backprop2 ZeroFunc a
forall a. Num a => ZeroFunc a
E.zfNum ZeroFunc b
forall a. Num a => ZeroFunc a
E.zfNum OneFunc c
forall a. Num a => OneFunc a
E.ofNum
{-# INLINE backprop2 #-}

-- | 'Numeric.Backprop.backpropWith2', but with 'Num' constraints instead of
-- 'Backprop' constraints.
--
-- Note that argument order changed in v0.2.4.
--
-- @since 0.2.0.0
backpropWith2 ::
  (Num a, Num b) =>
  (forall s. Reifies s W => BVar s a -> BVar s b -> BVar s c) ->
  a ->
  b ->
  -- | Takes function giving gradient of final result given the output of function
  (c, c -> (a, b))
backpropWith2 :: forall a b c.
(Num a, Num b) =>
(forall s. Reifies s W => BVar s a -> BVar s b -> BVar s c)
-> a -> b -> (c, c -> (a, b))
backpropWith2 = ZeroFunc a
-> ZeroFunc b
-> (forall s. Reifies s W => BVar s a -> BVar s b -> BVar s c)
-> a
-> b
-> (c, c -> (a, b))
forall a b c.
ZeroFunc a
-> ZeroFunc b
-> (forall s. Reifies s W => BVar s a -> BVar s b -> BVar s c)
-> a
-> b
-> (c, c -> (a, b))
E.backpropWith2 ZeroFunc a
forall a. Num a => ZeroFunc a
E.zfNum ZeroFunc b
forall a. Num a => ZeroFunc a
E.zfNum
{-# INLINE backpropWith2 #-}

-- | 'Numeric.Backprop.gradBP2', but with 'Num' constraints instead of
-- 'Backprop' constraints.
gradBP2 ::
  (Num a, Num b, Num c) =>
  (forall s. Reifies s W => BVar s a -> BVar s b -> BVar s c) ->
  a ->
  b ->
  (a, b)
gradBP2 :: forall a b c.
(Num a, Num b, Num c) =>
(forall s. Reifies s W => BVar s a -> BVar s b -> BVar s c)
-> a -> b -> (a, b)
gradBP2 = ZeroFunc a
-> ZeroFunc b
-> OneFunc c
-> (forall s. Reifies s W => BVar s a -> BVar s b -> BVar s c)
-> a
-> b
-> (a, b)
forall a b c.
ZeroFunc a
-> ZeroFunc b
-> OneFunc c
-> (forall s. Reifies s W => BVar s a -> BVar s b -> BVar s c)
-> a
-> b
-> (a, b)
E.gradBP2 ZeroFunc a
forall a. Num a => ZeroFunc a
E.zfNum ZeroFunc b
forall a. Num a => ZeroFunc a
E.zfNum OneFunc c
forall a. Num a => OneFunc a
E.ofNum
{-# INLINE gradBP2 #-}

-- | 'Numeric.Backprop.bpOp', but with 'Num' constraints instead of
-- 'Backprop' constraints.
bpOp ::
  RPureConstrained Num as =>
  (forall s. Reifies s W => Rec (BVar s) as -> BVar s b) ->
  Op as b
bpOp :: forall (as :: [*]) b.
RPureConstrained Num as =>
(forall s. Reifies s W => Rec (BVar s) as -> BVar s b) -> Op as b
bpOp = Rec ZeroFunc as
-> (forall s. Reifies s W => Rec (BVar s) as -> BVar s b)
-> Op as b
forall (as :: [*]) b.
Rec ZeroFunc as
-> (forall s. Reifies s W => Rec (BVar s) as -> BVar s b)
-> Op as b
E.bpOp Rec ZeroFunc as
forall (as :: [*]). RPureConstrained Num as => Rec ZeroFunc as
E.zfNums
{-# INLINE bpOp #-}

-- | 'Numeric.Backprop.^^.', but with 'Num' constraints instead of
-- 'Backprop' constraints.
(^^.) ::
  forall b a s.
  (Num a, Num b, Reifies s W) =>
  BVar s b ->
  Lens' b a ->
  BVar s a
BVar s b
x ^^. :: forall b a s.
(Num a, Num b, Reifies s W) =>
BVar s b -> Lens' b a -> BVar s a
^^. Lens' b a
l = Lens' b a -> BVar s b -> BVar s a
forall b a s.
(Num a, Num b, Reifies s W) =>
Lens' b a -> BVar s b -> BVar s a
viewVar (a -> f a) -> b -> f b
Lens' b a
l BVar s b
x

infixl 8 ^^.
{-# INLINE (^^.) #-}

-- | 'Numeric.Backprop.viewVar', but with 'Num' constraints instead of
-- 'Backprop' constraints.
viewVar ::
  forall b a s.
  (Num a, Num b, Reifies s W) =>
  Lens' b a ->
  BVar s b ->
  BVar s a
viewVar :: forall b a s.
(Num a, Num b, Reifies s W) =>
Lens' b a -> BVar s b -> BVar s a
viewVar = AddFunc a -> ZeroFunc b -> Lens' b a -> BVar s b -> BVar s a
forall a b s.
Reifies s W =>
AddFunc a -> ZeroFunc b -> Lens' b a -> BVar s b -> BVar s a
E.viewVar AddFunc a
forall a. Num a => AddFunc a
E.afNum ZeroFunc b
forall a. Num a => ZeroFunc a
E.zfNum
{-# INLINE viewVar #-}

-- | 'Numeric.Backprop..~~', but with 'Num' constraints instead of
-- 'Backprop' constraints.
(.~~) ::
  (Num a, Num b, Reifies s W) =>
  Lens' b a ->
  BVar s a ->
  BVar s b ->
  BVar s b
Lens' b a
l .~~ :: forall a b s.
(Num a, Num b, Reifies s W) =>
Lens' b a -> BVar s a -> BVar s b -> BVar s b
.~~ BVar s a
x = Lens' b a -> BVar s a -> BVar s b -> BVar s b
forall a b s.
(Num a, Num b, Reifies s W) =>
Lens' b a -> BVar s a -> BVar s b -> BVar s b
setVar (a -> f a) -> b -> f b
Lens' b a
l BVar s a
x

infixl 8 .~~
{-# INLINE (.~~) #-}

-- | 'Numeric.Backprop.setVar', but with 'Num' constraints instead of
-- 'Backprop' constraints.
setVar ::
  forall a b s.
  (Num a, Num b, Reifies s W) =>
  Lens' b a ->
  BVar s a ->
  BVar s b ->
  BVar s b
setVar :: forall a b s.
(Num a, Num b, Reifies s W) =>
Lens' b a -> BVar s a -> BVar s b -> BVar s b
setVar = AddFunc a
-> AddFunc b
-> ZeroFunc a
-> Lens' b a
-> BVar s a
-> BVar s b
-> BVar s b
forall a b s.
Reifies s W =>
AddFunc a
-> AddFunc b
-> ZeroFunc a
-> Lens' b a
-> BVar s a
-> BVar s b
-> BVar s b
E.setVar AddFunc a
forall a. Num a => AddFunc a
E.afNum AddFunc b
forall a. Num a => AddFunc a
E.afNum ZeroFunc a
forall a. Num a => ZeroFunc a
E.zfNum
{-# INLINE setVar #-}

-- | 'Numeric.Backprop.%~~', but with 'Num' constraints instead of
-- 'Backprop' constraints.
--
-- @since 0.2.4.0
(%~~) ::
  (Num a, Num b, Reifies s W) =>
  Lens' b a ->
  (BVar s a -> BVar s a) ->
  BVar s b ->
  BVar s b
Lens' b a
l %~~ :: forall a b s.
(Num a, Num b, Reifies s W) =>
Lens' b a -> (BVar s a -> BVar s a) -> BVar s b -> BVar s b
%~~ BVar s a -> BVar s a
f = Lens' b a -> (BVar s a -> BVar s a) -> BVar s b -> BVar s b
forall a b s.
(Num a, Num b, Reifies s W) =>
Lens' b a -> (BVar s a -> BVar s a) -> BVar s b -> BVar s b
overVar (a -> f a) -> b -> f b
Lens' b a
l BVar s a -> BVar s a
f

infixr 4 %~~
{-# INLINE (%~~) #-}

-- | 'Numeric.Backprop.overVar', but with 'Num' constraints instead of
-- 'Backprop' constraints.
--
-- @since 0.2.4.0
overVar ::
  (Num a, Num b, Reifies s W) =>
  Lens' b a ->
  (BVar s a -> BVar s a) ->
  BVar s b ->
  BVar s b
overVar :: forall a b s.
(Num a, Num b, Reifies s W) =>
Lens' b a -> (BVar s a -> BVar s a) -> BVar s b -> BVar s b
overVar = AddFunc a
-> AddFunc b
-> ZeroFunc a
-> ZeroFunc b
-> Lens' b a
-> (BVar s a -> BVar s a)
-> BVar s b
-> BVar s b
forall s a b.
Reifies s W =>
AddFunc a
-> AddFunc b
-> ZeroFunc a
-> ZeroFunc b
-> Lens' b a
-> (BVar s a -> BVar s a)
-> BVar s b
-> BVar s b
E.overVar AddFunc a
forall a. Num a => AddFunc a
E.afNum AddFunc b
forall a. Num a => AddFunc a
E.afNum ZeroFunc a
forall a. Num a => ZeroFunc a
E.zfNum ZeroFunc b
forall a. Num a => ZeroFunc a
E.zfNum
{-# INLINE overVar #-}

-- | 'Numeric.Backprop.^^?', but with 'Num' constraints instead of
-- 'Backprop' constraints.
--
-- Note that many automatically-generated prisms by the /lens/ package use
-- tuples, which cannot work this this by default (because tuples do not
-- have a 'Num' instance).
--
-- If you are writing an application or don't have to worry about orphan
-- instances, you can pull in the orphan instances from
-- <https://hackage.haskell.org/package/NumInstances NumInstances>.
-- Alternatively, you can chain those prisms with conversions to the
-- anonymous canonical strict tuple types in "Numeric.Backprop.Tuple",
-- which do have 'Num' instances.
--
-- @
-- myPrism                   :: 'Prism'' c (a, b)
-- myPrism . 'iso' 'tupT2' 't2Tup' :: 'Prism'' c ('T2' a b)
-- @
(^^?) ::
  forall b a s.
  (Num b, Num a, Reifies s W) =>
  BVar s b ->
  Traversal' b a ->
  Maybe (BVar s a)
BVar s b
v ^^? :: forall b a s.
(Num b, Num a, Reifies s W) =>
BVar s b -> Traversal' b a -> Maybe (BVar s a)
^^? Traversal' b a
t = Traversal' b a -> BVar s b -> Maybe (BVar s a)
forall b a s.
(Num b, Num a, Reifies s W) =>
Traversal' b a -> BVar s b -> Maybe (BVar s a)
previewVar (a -> f a) -> b -> f b
Traversal' b a
t BVar s b
v

infixl 8 ^^?
{-# INLINE (^^?) #-}

-- | 'Numeric.Backprop.^^?!', but with 'Num' constraints instead of
-- 'Backprop' constraints.
--
-- Like 'Numeric.Backprop.^^?!', is *UNSAFE*.
--
-- @since 0.2.1.0
(^^?!) ::
  forall b a s.
  (Num b, Num a, Reifies s W) =>
  BVar s b ->
  Traversal' b a ->
  BVar s a
BVar s b
v ^^?! :: forall b a s.
(Num b, Num a, Reifies s W) =>
BVar s b -> Traversal' b a -> BVar s a
^^?! Traversal' b a
t = BVar s a -> Maybe (BVar s a) -> BVar s a
forall a. a -> Maybe a -> a
fromMaybe ([Char] -> BVar s a
forall a. HasCallStack => [Char] -> a
error [Char]
e) (Traversal' b a -> BVar s b -> Maybe (BVar s a)
forall b a s.
(Num b, Num a, Reifies s W) =>
Traversal' b a -> BVar s b -> Maybe (BVar s a)
previewVar (a -> f a) -> b -> f b
Traversal' b a
t BVar s b
v)
  where
    e :: [Char]
e = [Char]
"Numeric.Backprop.Num.^^?!: Empty traversal"

infixl 8 ^^?!
{-# INLINE (^^?!) #-}

-- | 'Numeric.Backprop.previewVar', but with 'Num' constraints instead of
-- 'Backprop' constraints.
--
-- See documentation for '^^?' for more information and important notes.
previewVar ::
  forall b a s.
  (Num b, Num a, Reifies s W) =>
  Traversal' b a ->
  BVar s b ->
  Maybe (BVar s a)
previewVar :: forall b a s.
(Num b, Num a, Reifies s W) =>
Traversal' b a -> BVar s b -> Maybe (BVar s a)
previewVar = AddFunc a
-> ZeroFunc b -> Traversal' b a -> BVar s b -> Maybe (BVar s a)
forall b a s.
Reifies s W =>
AddFunc a
-> ZeroFunc b -> Traversal' b a -> BVar s b -> Maybe (BVar s a)
E.previewVar AddFunc a
forall a. Num a => AddFunc a
E.afNum ZeroFunc b
forall a. Num a => ZeroFunc a
E.zfNum
{-# INLINE previewVar #-}

-- | 'Numeric.Backprop.^^..', but with 'Num' constraints instead of
-- 'Backprop' constraints.
(^^..) ::
  forall b a s.
  (Num b, Num a, Reifies s W) =>
  BVar s b ->
  Traversal' b a ->
  [BVar s a]
BVar s b
v ^^.. :: forall b a s.
(Num b, Num a, Reifies s W) =>
BVar s b -> Traversal' b a -> [BVar s a]
^^.. Traversal' b a
t = Traversal' b a -> BVar s b -> [BVar s a]
forall b a s.
(Num b, Num a, Reifies s W) =>
Traversal' b a -> BVar s b -> [BVar s a]
toListOfVar (a -> f a) -> b -> f b
Traversal' b a
t BVar s b
v
{-# INLINE (^^..) #-}

-- | 'Numeric.Backprop.toListOfVar', but with 'Num' constraints instead of
-- 'Backprop' constraints.
toListOfVar ::
  forall b a s.
  (Num b, Num a, Reifies s W) =>
  Traversal' b a ->
  BVar s b ->
  [BVar s a]
toListOfVar :: forall b a s.
(Num b, Num a, Reifies s W) =>
Traversal' b a -> BVar s b -> [BVar s a]
toListOfVar = AddFunc a -> ZeroFunc b -> Traversal' b a -> BVar s b -> [BVar s a]
forall b a s.
Reifies s W =>
AddFunc a -> ZeroFunc b -> Traversal' b a -> BVar s b -> [BVar s a]
E.toListOfVar AddFunc a
forall a. Num a => AddFunc a
E.afNum ZeroFunc b
forall a. Num a => ZeroFunc a
E.zfNum
{-# INLINE toListOfVar #-}

-- | 'Numeric.Backprop.sequenceVar', but with 'Num' constraints instead of
-- 'Backprop' constraints.
--
-- Since v0.2.4, requires a 'Num' constraint on @t a@.
sequenceVar ::
  (Traversable t, Num a, Reifies s W) =>
  BVar s (t a) ->
  t (BVar s a)
sequenceVar :: forall (t :: * -> *) a s.
(Traversable t, Num a, Reifies s W) =>
BVar s (t a) -> t (BVar s a)
sequenceVar = AddFunc a -> ZeroFunc a -> BVar s (t a) -> t (BVar s a)
forall (t :: * -> *) a s.
(Reifies s W, Traversable t) =>
AddFunc a -> ZeroFunc a -> BVar s (t a) -> t (BVar s a)
E.sequenceVar AddFunc a
forall a. Num a => AddFunc a
E.afNum ZeroFunc a
forall a. Num a => ZeroFunc a
E.zfNum
{-# INLINE sequenceVar #-}

-- | 'Numeric.Backprop.collectVar', but with 'Num' constraints instead of
-- 'Backprop' constraints.
--
-- Prior to v0.2.3, required a 'Num' constraint on @t a@.
collectVar ::
  (Foldable t, Functor t, Num a, Reifies s W) =>
  t (BVar s a) ->
  BVar s (t a)
collectVar :: forall (t :: * -> *) a s.
(Foldable t, Functor t, Num a, Reifies s W) =>
t (BVar s a) -> BVar s (t a)
collectVar = AddFunc a -> ZeroFunc a -> t (BVar s a) -> BVar s (t a)
forall (t :: * -> *) a s.
(Reifies s W, Foldable t, Functor t) =>
AddFunc a -> ZeroFunc a -> t (BVar s a) -> BVar s (t a)
E.collectVar AddFunc a
forall a. Num a => AddFunc a
E.afNum ZeroFunc a
forall a. Num a => ZeroFunc a
E.zfNum
{-# INLINE collectVar #-}

-- | 'Numeric.Backprop.liftOp', but with 'Num' constraints instead of
-- 'Backprop' constraints.
liftOp ::
  (RPureConstrained Num as, Reifies s W) =>
  Op as b ->
  Rec (BVar s) as ->
  BVar s b
liftOp :: forall (as :: [*]) s b.
(RPureConstrained Num as, Reifies s W) =>
Op as b -> Rec (BVar s) as -> BVar s b
liftOp = Rec AddFunc as -> Op as b -> Rec (BVar s) as -> BVar s b
forall (as :: [*]) b s.
Reifies s W =>
Rec AddFunc as -> Op as b -> Rec (BVar s) as -> BVar s b
E.liftOp Rec AddFunc as
forall (as :: [*]). RPureConstrained Num as => Rec AddFunc as
E.afNums
{-# INLINE liftOp #-}

-- | 'Numeric.Backprop.liftOp1', but with 'Num' constraints instead of
-- 'Backprop' constraints.
liftOp1 ::
  (Num a, Reifies s W) =>
  Op '[a] b ->
  BVar s a ->
  BVar s b
liftOp1 :: forall a s b.
(Num a, Reifies s W) =>
Op '[a] b -> BVar s a -> BVar s b
liftOp1 = AddFunc a -> Op '[a] b -> BVar s a -> BVar s b
forall a b s.
Reifies s W =>
AddFunc a -> Op '[a] b -> BVar s a -> BVar s b
E.liftOp1 AddFunc a
forall a. Num a => AddFunc a
E.afNum
{-# INLINE liftOp1 #-}

-- | 'Numeric.Backprop.liftOp2', but with 'Num' constraints instead of
-- 'Backprop' constraints.
liftOp2 ::
  (Num a, Num b, Reifies s W) =>
  Op '[a, b] c ->
  BVar s a ->
  BVar s b ->
  BVar s c
liftOp2 :: forall a b s c.
(Num a, Num b, Reifies s W) =>
Op '[a, b] c -> BVar s a -> BVar s b -> BVar s c
liftOp2 = AddFunc a
-> AddFunc b -> Op '[a, b] c -> BVar s a -> BVar s b -> BVar s c
forall a b c s.
Reifies s W =>
AddFunc a
-> AddFunc b -> Op '[a, b] c -> BVar s a -> BVar s b -> BVar s c
E.liftOp2 AddFunc a
forall a. Num a => AddFunc a
E.afNum AddFunc b
forall a. Num a => AddFunc a
E.afNum
{-# INLINE liftOp2 #-}

-- | 'Numeric.Backprop.liftOp3', but with 'Num' constraints instead of
-- 'Backprop' constraints.
liftOp3 ::
  (Num a, Num b, Num c, Reifies s W) =>
  Op '[a, b, c] d ->
  BVar s a ->
  BVar s b ->
  BVar s c ->
  BVar s d
liftOp3 :: forall a b c s d.
(Num a, Num b, Num c, Reifies s W) =>
Op '[a, b, c] d -> BVar s a -> BVar s b -> BVar s c -> BVar s d
liftOp3 = AddFunc a
-> AddFunc b
-> AddFunc c
-> Op '[a, b, c] d
-> BVar s a
-> BVar s b
-> BVar s c
-> BVar s d
forall a b c d s.
Reifies s W =>
AddFunc a
-> AddFunc b
-> AddFunc c
-> Op '[a, b, c] d
-> BVar s a
-> BVar s b
-> BVar s c
-> BVar s d
E.liftOp3 AddFunc a
forall a. Num a => AddFunc a
E.afNum AddFunc b
forall a. Num a => AddFunc a
E.afNum AddFunc c
forall a. Num a => AddFunc a
E.afNum
{-# INLINE liftOp3 #-}

-- | 'Numeric.Backprop.isoVar', but with 'Num' constraints instead of
-- 'Backprop' constraints.
isoVar ::
  (Num a, Reifies s W) =>
  (a -> b) ->
  (b -> a) ->
  BVar s a ->
  BVar s b
isoVar :: forall a s b.
(Num a, Reifies s W) =>
(a -> b) -> (b -> a) -> BVar s a -> BVar s b
isoVar = AddFunc a -> (a -> b) -> (b -> a) -> BVar s a -> BVar s b
forall s a b.
Reifies s W =>
AddFunc a -> (a -> b) -> (b -> a) -> BVar s a -> BVar s b
E.isoVar AddFunc a
forall a. Num a => AddFunc a
E.afNum
{-# INLINE isoVar #-}

-- | 'Numeric.Backprop.isoVar', but with 'Num' constraints instead of
-- 'Backprop' constraints.
isoVar2 ::
  (Num a, Num b, Reifies s W) =>
  (a -> b -> c) ->
  (c -> (a, b)) ->
  BVar s a ->
  BVar s b ->
  BVar s c
isoVar2 :: forall a b s c.
(Num a, Num b, Reifies s W) =>
(a -> b -> c) -> (c -> (a, b)) -> BVar s a -> BVar s b -> BVar s c
isoVar2 = AddFunc a
-> AddFunc b
-> (a -> b -> c)
-> (c -> (a, b))
-> BVar s a
-> BVar s b
-> BVar s c
forall s a b c.
Reifies s W =>
AddFunc a
-> AddFunc b
-> (a -> b -> c)
-> (c -> (a, b))
-> BVar s a
-> BVar s b
-> BVar s c
E.isoVar2 AddFunc a
forall a. Num a => AddFunc a
E.afNum AddFunc b
forall a. Num a => AddFunc a
E.afNum
{-# INLINE isoVar2 #-}

-- | 'Numeric.Backprop.isoVar3', but with 'Num' constraints instead of
-- 'Backprop' constraints.
isoVar3 ::
  (Num a, Num b, Num c, Reifies s W) =>
  (a -> b -> c -> d) ->
  (d -> (a, b, c)) ->
  BVar s a ->
  BVar s b ->
  BVar s c ->
  BVar s d
isoVar3 :: forall a b c s d.
(Num a, Num b, Num c, Reifies s W) =>
(a -> b -> c -> d)
-> (d -> (a, b, c)) -> BVar s a -> BVar s b -> BVar s c -> BVar s d
isoVar3 = AddFunc a
-> AddFunc b
-> AddFunc c
-> (a -> b -> c -> d)
-> (d -> (a, b, c))
-> BVar s a
-> BVar s b
-> BVar s c
-> BVar s d
forall s a b c d.
Reifies s W =>
AddFunc a
-> AddFunc b
-> AddFunc c
-> (a -> b -> c -> d)
-> (d -> (a, b, c))
-> BVar s a
-> BVar s b
-> BVar s c
-> BVar s d
E.isoVar3 AddFunc a
forall a. Num a => AddFunc a
E.afNum AddFunc b
forall a. Num a => AddFunc a
E.afNum AddFunc c
forall a. Num a => AddFunc a
E.afNum
{-# INLINE isoVar3 #-}

-- | 'Numeric.Backprop.isoVarN', but with 'Num' constraints instead of
-- 'Backprop' constraints.
isoVarN ::
  (RPureConstrained Num as, Reifies s W) =>
  (Rec Identity as -> b) ->
  (b -> Rec Identity as) ->
  Rec (BVar s) as ->
  BVar s b
isoVarN :: forall (as :: [*]) s b.
(RPureConstrained Num as, Reifies s W) =>
(Rec Identity as -> b)
-> (b -> Rec Identity as) -> Rec (BVar s) as -> BVar s b
isoVarN = Rec AddFunc as
-> (Rec Identity as -> b)
-> (b -> Rec Identity as)
-> Rec (BVar s) as
-> BVar s b
forall s (as :: [*]) b.
Reifies s W =>
Rec AddFunc as
-> (Rec Identity as -> b)
-> (b -> Rec Identity as)
-> Rec (BVar s) as
-> BVar s b
E.isoVarN Rec AddFunc as
forall (as :: [*]). RPureConstrained Num as => Rec AddFunc as
E.afNums
{-# INLINE isoVarN #-}