{-# LANGUAGE CPP #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE TupleSections #-}
{-# LANGUAGE UndecidableInstances #-}
module Circuit.Diff.Circuit
(
Diff (..),
Diff',
traceNFrom,
traceStarFrom,
traceStar,
quadD,
)
where
import Circuit.Bimonoid (Copy (..), Discard (..), Merge (..), MergeZero, Zero (..))
import Circuit.Bimonoid qualified as CB
import Circuit.Category (Category (..))
import Circuit.Channel (Channel (..), Strength (..), Traced (..))
import Circuit.Diff (Diff (..), Diff', runDiff)
import Circuit.Tensor (Action (..), Tensor (..), Unital (..))
import Data.Bifunctor
import NumHask.Algebra.Additive qualified as NHA
import NumHask.Algebra.Multiplicative qualified as NHM
import NumHask.Algebra.Ring qualified as NHR
import Prelude hiding (id, (.))
instance Category (Diff p) where
id :: forall a. Diff p a a
id = (a -> (a, a -> a)) -> Diff p a a
forall k (p :: k) a b. (a -> (b, b -> a)) -> Diff p a b
Diff (\a
a -> (a
a, a -> a
forall a. a -> a
forall k (arr :: k -> k -> *) (a :: k). Category arr => arr a a
id))
Diff b -> (c, c -> b)
f . :: forall b c a. Diff p b c -> Diff p a b -> Diff p a c
. Diff a -> (b, b -> a)
g = (a -> (c, c -> a)) -> Diff p a c
forall k (p :: k) a b. (a -> (b, b -> a)) -> Diff p a b
Diff ((a -> (c, c -> a)) -> Diff p a c)
-> (a -> (c, c -> a)) -> Diff p a c
forall a b. (a -> b) -> a -> b
$ \a
a ->
let (b
b, b -> a
gb) = a -> (b, b -> a)
g a
a
(c
c, c -> b
fc) = b -> (c, c -> b)
f b
b
in (c
c, \c
dc -> b -> a
gb (c -> b
fc c
dc))
{-# INLINE id #-}
{-# INLINE (.) #-}
instance Traced (,) (Diff p) where
trace :: forall a b c. Diff p (a, b) (a, c) -> Diff p b c
trace (Diff (a, b) -> ((a, c), (a, c) -> (a, b))
body) = (b -> (c, c -> b)) -> Diff p b c
forall k (p :: k) a b. (a -> (b, b -> a)) -> Diff p a b
Diff ((b -> (c, c -> b)) -> Diff p b c)
-> (b -> (c, c -> b)) -> Diff p b c
forall a b. (a -> b) -> a -> b
$ \b
b ->
let
~((a
a, c
c), (a, c) -> (a, b)
backward) = (a, b) -> ((a, c), (a, c) -> (a, b))
body (a
a, b
b)
pullback :: c -> b
pullback c
dc =
let bd :: (a, b)
bd = (a, c) -> (a, b)
backward ((a, b) -> a
forall a b. (a, b) -> a
fst (a, b)
bd, c
dc)
in (a, b) -> b
forall a b. (a, b) -> b
snd (a, b)
bd
in (c
c, c -> b
pullback)
instance Channel (,) (Diff p) where
assoc :: forall a b c. Diff p ((a, b), c) (a, (b, c))
assoc = (((a, b), c) -> ((a, (b, c)), (a, (b, c)) -> ((a, b), c)))
-> Diff p ((a, b), c) (a, (b, c))
forall k (p :: k) a b. (a -> (b, b -> a)) -> Diff p a b
Diff (\((a
s, b
s'), c
x) -> ((a
s, (b
s', c
x)), \(a
s'', (b
s''', c
x')) -> ((a
s'', b
s'''), c
x')))
assoc' :: forall a b c. Diff p (a, (b, c)) ((a, b), c)
assoc' = ((a, (b, c)) -> (((a, b), c), ((a, b), c) -> (a, (b, c))))
-> Diff p (a, (b, c)) ((a, b), c)
forall k (p :: k) a b. (a -> (b, b -> a)) -> Diff p a b
Diff (\(a
s, (b
s', c
x)) -> (((a
s, b
s'), c
x), \((a
s'', b
s'''), c
x') -> (a
s'', (b
s''', c
x'))))
slide :: forall a b c. Diff p (a, (b, c)) (b, (a, c))
slide = ((a, (b, c)) -> ((b, (a, c)), (b, (a, c)) -> (a, (b, c))))
-> Diff p (a, (b, c)) (b, (a, c))
forall k (p :: k) a b. (a -> (b, b -> a)) -> Diff p a b
Diff (\(a
s, (b
s', c
x)) -> ((b
s', (a
s, c
x)), \(b
s'', (a
s''', c
x')) -> (a
s''', (b
s'', c
x'))))
instance Channel Either (Diff p) where
assoc :: forall a b c.
Diff p (Either (Either a b) c) (Either a (Either b c))
assoc =
(Either (Either a b) c
-> (Either a (Either b c),
Either a (Either b c) -> Either (Either a b) c))
-> Diff p (Either (Either a b) c) (Either a (Either b c))
forall k (p :: k) a b. (a -> (b, b -> a)) -> Diff p a b
Diff
( \case
Left (Left a
a) -> (a -> Either a (Either b c)
forall a b. a -> Either a b
Left a
a, \case Left a
da -> Either a b -> Either (Either a b) c
forall a b. a -> Either a b
Left (a -> Either a b
forall a b. a -> Either a b
Left a
da); Right Either b c
_ -> [Char] -> Either (Either a b) c
forall a. HasCallStack => [Char] -> a
error [Char]
"assoc")
Left (Right b
b) -> (Either b c -> Either a (Either b c)
forall a b. b -> Either a b
Right (b -> Either b c
forall a b. a -> Either a b
Left b
b), \case Right (Left b
db) -> Either a b -> Either (Either a b) c
forall a b. a -> Either a b
Left (b -> Either a b
forall a b. b -> Either a b
Right b
db); Either a (Either b c)
_ -> [Char] -> Either (Either a b) c
forall a. HasCallStack => [Char] -> a
error [Char]
"assoc")
Right c
c -> (Either b c -> Either a (Either b c)
forall a b. b -> Either a b
Right (c -> Either b c
forall a b. b -> Either a b
Right c
c), \case Right (Right c
dc) -> c -> Either (Either a b) c
forall a b. b -> Either a b
Right c
dc; Either a (Either b c)
_ -> [Char] -> Either (Either a b) c
forall a. HasCallStack => [Char] -> a
error [Char]
"assoc")
)
assoc' :: forall a b c.
Diff p (Either a (Either b c)) (Either (Either a b) c)
assoc' =
(Either a (Either b c)
-> (Either (Either a b) c,
Either (Either a b) c -> Either a (Either b c)))
-> Diff p (Either a (Either b c)) (Either (Either a b) c)
forall k (p :: k) a b. (a -> (b, b -> a)) -> Diff p a b
Diff
( \case
Left a
a -> (Either a b -> Either (Either a b) c
forall a b. a -> Either a b
Left (a -> Either a b
forall a b. a -> Either a b
Left a
a), \case Left (Left a
da) -> a -> Either a (Either b c)
forall a b. a -> Either a b
Left a
da; Either (Either a b) c
_ -> [Char] -> Either a (Either b c)
forall a. HasCallStack => [Char] -> a
error [Char]
"assoc'")
Right (Left b
b) -> (Either a b -> Either (Either a b) c
forall a b. a -> Either a b
Left (b -> Either a b
forall a b. b -> Either a b
Right b
b), \case Left (Right b
db) -> Either b c -> Either a (Either b c)
forall a b. b -> Either a b
Right (b -> Either b c
forall a b. a -> Either a b
Left b
db); Either (Either a b) c
_ -> [Char] -> Either a (Either b c)
forall a. HasCallStack => [Char] -> a
error [Char]
"assoc'")
Right (Right c
c) -> (c -> Either (Either a b) c
forall a b. b -> Either a b
Right c
c, \case Right c
dc -> Either b c -> Either a (Either b c)
forall a b. b -> Either a b
Right (c -> Either b c
forall a b. b -> Either a b
Right c
dc); Either (Either a b) c
_ -> [Char] -> Either a (Either b c)
forall a. HasCallStack => [Char] -> a
error [Char]
"assoc'")
)
slide :: forall a b c.
Diff p (Either a (Either b c)) (Either b (Either a c))
slide =
(Either a (Either b c)
-> (Either b (Either a c),
Either b (Either a c) -> Either a (Either b c)))
-> Diff p (Either a (Either b c)) (Either b (Either a c))
forall k (p :: k) a b. (a -> (b, b -> a)) -> Diff p a b
Diff
( \case
Left a
a -> (Either a c -> Either b (Either a c)
forall a b. b -> Either a b
Right (a -> Either a c
forall a b. a -> Either a b
Left a
a), \case Right (Left a
da) -> a -> Either a (Either b c)
forall a b. a -> Either a b
Left a
da; Either b (Either a c)
_ -> [Char] -> Either a (Either b c)
forall a. HasCallStack => [Char] -> a
error [Char]
"slide")
Right (Left b
b) -> (b -> Either b (Either a c)
forall a b. a -> Either a b
Left b
b, \case Left b
db -> Either b c -> Either a (Either b c)
forall a b. b -> Either a b
Right (b -> Either b c
forall a b. a -> Either a b
Left b
db); Either b (Either a c)
_ -> [Char] -> Either a (Either b c)
forall a. HasCallStack => [Char] -> a
error [Char]
"slide")
Right (Right c
c) -> (Either a c -> Either b (Either a c)
forall a b. b -> Either a b
Right (c -> Either a c
forall a b. b -> Either a b
Right c
c), \case Right (Right c
dc) -> Either b c -> Either a (Either b c)
forall a b. b -> Either a b
Right (c -> Either b c
forall a b. b -> Either a b
Right c
dc); Either b (Either a c)
_ -> [Char] -> Either a (Either b c)
forall a. HasCallStack => [Char] -> a
error [Char]
"slide")
)
instance Strength (,) (Diff p) where
strength :: forall b c a. Diff p b c -> Diff p (a, b) (a, c)
strength (Diff b -> (c, c -> b)
f) = ((a, b) -> ((a, c), (a, c) -> (a, b))) -> Diff p (a, b) (a, c)
forall k (p :: k) a b. (a -> (b, b -> a)) -> Diff p a b
Diff (((a, b) -> ((a, c), (a, c) -> (a, b))) -> Diff p (a, b) (a, c))
-> ((a, b) -> ((a, c), (a, c) -> (a, b))) -> Diff p (a, b) (a, c)
forall a b. (a -> b) -> a -> b
$ \(a
a, b
b) ->
let (c
c, c -> b
back) = b -> (c, c -> b)
f b
b
in ((a
a, c
c), \(a
da, c
dc) -> (a
da, c -> b
back c
dc))
{-# INLINE strength #-}
instance Strength Either (Diff p) where
strength :: forall b c a. Diff p b c -> Diff p (Either a b) (Either a c)
strength (Diff b -> (c, c -> b)
f) = (Either a b -> (Either a c, Either a c -> Either a b))
-> Diff p (Either a b) (Either a c)
forall k (p :: k) a b. (a -> (b, b -> a)) -> Diff p a b
Diff ((Either a b -> (Either a c, Either a c -> Either a b))
-> Diff p (Either a b) (Either a c))
-> (Either a b -> (Either a c, Either a c -> Either a b))
-> Diff p (Either a b) (Either a c)
forall a b. (a -> b) -> a -> b
$ \case
Left a
a -> (a -> Either a c
forall a b. a -> Either a b
Left a
a, \case Left a
da -> a -> Either a b
forall a b. a -> Either a b
Left a
da; Right c
_ -> [Char] -> Either a b
forall a. HasCallStack => [Char] -> a
error [Char]
"strength: Left input, Right cotangent")
Right b
b ->
let (c
c, c -> b
back) = b -> (c, c -> b)
f b
b
in (c -> Either a c
forall a b. b -> Either a b
Right c
c, \case Right c
dc -> b -> Either a b
forall a b. b -> Either a b
Right (c -> b
back c
dc); Left a
_ -> [Char] -> Either a b
forall a. HasCallStack => [Char] -> a
error [Char]
"strength: Right input, Left cotangent")
{-# INLINE strength #-}
instance Traced Either (Diff p) where
trace :: forall a b c. Diff p (Either a b) (Either a c) -> Diff p b c
trace (Diff Either a b -> (Either a c, Either a c -> Either a b)
body) = (b -> (c, c -> b)) -> Diff p b c
forall k (p :: k) a b. (a -> (b, b -> a)) -> Diff p a b
Diff ((b -> (c, c -> b)) -> Diff p b c)
-> (b -> (c, c -> b)) -> Diff p b c
forall a b. (a -> b) -> a -> b
$ \b
b ->
let
goFwd :: Either a b -> (c, [Either a c -> Either a b])
goFwd Either a b
x =
let (Either a c
y, Either a c -> Either a b
pb) = Either a b -> (Either a c, Either a c -> Either a b)
body Either a b
x
in case Either a c
y of
Right c
c' -> (c
c', [Either a c -> Either a b
pb])
Left a
a ->
let (c
c', [Either a c -> Either a b]
pbs') = Either a b -> (c, [Either a c -> Either a b])
goFwd (a -> Either a b
forall a b. a -> Either a b
Left a
a)
in (c
c', Either a c -> Either a b
pb (Either a c -> Either a b)
-> [Either a c -> Either a b] -> [Either a c -> Either a b]
forall a. a -> [a] -> [a]
: [Either a c -> Either a b]
pbs')
(c
c, [Either a c -> Either a b]
pbs) = Either a b -> (c, [Either a c -> Either a b])
goFwd (b -> Either a b
forall a b. b -> Either a b
Right b
b)
rpbs :: [Either a c -> Either a b]
rpbs = [Either a c -> Either a b] -> [Either a c -> Either a b]
forall a. [a] -> [a]
reverse [Either a c -> Either a b]
pbs
pullback :: c -> b
pullback c
dc =
case [Either a c -> Either a b]
rpbs of
[] -> [Char] -> b
forall a. HasCallStack => [Char] -> a
error [Char]
"Circuit.Diff.Circuit.Trace Diff Either: empty loop (impossible)"
(Either a c -> Either a b
lastPb : [Either a c -> Either a b]
prevPbs) -> Either a b -> [Either a c -> Either a b] -> b
forall {a} {t} {b}. Either a t -> [Either a b -> Either a t] -> t
goBwd (Either a c -> Either a b
lastPb (c -> Either a c
forall a b. b -> Either a b
Right c
dc)) [Either a c -> Either a b]
prevPbs
where
goBwd :: Either a t -> [Either a b -> Either a t] -> t
goBwd (Right t
db) [] = t
db
goBwd (Left a
_) [] =
[Char] -> t
forall a. HasCallStack => [Char] -> a
error [Char]
"Circuit.Diff.Circuit.Trace Diff Either: final cotangent landed on Left (impossible)"
goBwd (Left a
da) (Either a b -> Either a t
pb : [Either a b -> Either a t]
pbs') = Either a t -> [Either a b -> Either a t] -> t
goBwd (Either a b -> Either a t
pb (a -> Either a b
forall a b. a -> Either a b
Left a
da)) [Either a b -> Either a t]
pbs'
goBwd (Right t
_) (Either a b -> Either a t
_ : [Either a b -> Either a t]
_) =
[Char] -> t
forall a. HasCallStack => [Char] -> a
error [Char]
"Circuit.Diff.Circuit.Trace Diff Either: Right cotangent mid-chain (tag-dishonest pullback)"
in (c
c, c -> b
pullback)
instance (Merge (->) a) => Copy (Diff p) a where
copy :: Diff p a (a, a)
copy = (a -> ((a, a), (a, a) -> a)) -> Diff p a (a, a)
forall k (p :: k) a b. (a -> (b, b -> a)) -> Diff p a b
Diff (\a
a -> ((a
a, a
a), (a, a) -> a
forall (arr :: * -> * -> *) a. Merge arr a => arr (a, a) a
CB.plus))
{-# INLINE copy #-}
instance (Zero (->) a) => Discard (Diff p) a where
discard :: Diff p a ()
discard = (a -> ((), () -> a)) -> Diff p a ()
forall k (p :: k) a b. (a -> (b, b -> a)) -> Diff p a b
Diff (((), () -> a) -> a -> ((), () -> a)
forall a b. a -> b -> a
const ((), \() -> () -> a
forall {k} (arr :: * -> k -> *) (a :: k). Zero arr a => arr () a
CB.zero ()))
{-# INLINE discard #-}
instance (Merge (->) a) => Merge (Diff p) a where
plus :: Diff p (a, a) a
plus = ((a, a) -> (a, a -> (a, a))) -> Diff p (a, a) a
forall k (p :: k) a b. (a -> (b, b -> a)) -> Diff p a b
Diff (\(a
a, a
b) -> ((a, a) -> a
forall (arr :: * -> * -> *) a. Merge arr a => arr (a, a) a
CB.plus (a
a, a
b), \a
d -> (a
d, a
d)))
{-# INLINE plus #-}
instance (Zero (->) a) => Zero (Diff p) a where
zero :: Diff p () a
zero = (() -> (a, a -> ())) -> Diff p () a
forall k (p :: k) a b. (a -> (b, b -> a)) -> Diff p a b
Diff (\() -> (() -> a
forall {k} (arr :: * -> k -> *) (a :: k). Zero arr a => arr () a
CB.zero (), () -> a -> ()
forall a b. a -> b -> a
const ()))
{-# INLINE zero #-}
instance Unital (,) (Diff p) where
unitl :: forall a. Diff p (Unit (,), a) a
unitl = (((), a) -> (a, a -> ((), a))) -> Diff p ((), a) a
forall k (p :: k) a b. (a -> (b, b -> a)) -> Diff p a b
Diff (\((), a
a) -> (a
a, ((),)))
{-# INLINE unitl #-}
unitl' :: forall a. Diff p a (Unit (,), a)
unitl' = (a -> (((), a), ((), a) -> a)) -> Diff p a ((), a)
forall k (p :: k) a b. (a -> (b, b -> a)) -> Diff p a b
Diff (\a
a -> (((), a
a), \((), a
da) -> a
da))
{-# INLINE unitl' #-}
unitr :: forall a. Diff p (a, Unit (,)) a
unitr = ((a, ()) -> (a, a -> (a, ()))) -> Diff p (a, ()) a
forall k (p :: k) a b. (a -> (b, b -> a)) -> Diff p a b
Diff (\(a
a, ()) -> (a
a, (,())))
{-# INLINE unitr #-}
unitr' :: forall a. Diff p a (a, Unit (,))
unitr' = (a -> ((a, ()), (a, ()) -> a)) -> Diff p a (a, ())
forall k (p :: k) a b. (a -> (b, b -> a)) -> Diff p a b
Diff (\a
a -> ((a
a, ()), \(a
da, ()) -> a
da))
{-# INLINE unitr' #-}
instance Tensor (,) (Diff p) where
tensor :: forall a b c d. Diff p a b -> Diff p c d -> Diff p (a, c) (b, d)
tensor (Diff a -> (b, b -> a)
f) (Diff c -> (d, d -> c)
g) = ((a, c) -> ((b, d), (b, d) -> (a, c))) -> Diff p (a, c) (b, d)
forall k (p :: k) a b. (a -> (b, b -> a)) -> Diff p a b
Diff (((a, c) -> ((b, d), (b, d) -> (a, c))) -> Diff p (a, c) (b, d))
-> ((a, c) -> ((b, d), (b, d) -> (a, c))) -> Diff p (a, c) (b, d)
forall a b. (a -> b) -> a -> b
$ \(a
a, c
c) ->
let (b
b, b -> a
fb) = a -> (b, b -> a)
f a
a; (d
d, d -> c
gd) = c -> (d, d -> c)
g c
c
in ((b
b, d
d), (b -> a) -> (d -> c) -> (b, d) -> (a, c)
forall a b c d. (a -> b) -> (c -> d) -> (a, c) -> (b, d)
forall (p :: * -> * -> *) a b c d.
Bifunctor p =>
(a -> b) -> (c -> d) -> p a c -> p b d
Data.Bifunctor.bimap b -> a
fb d -> c
gd)
{-# INLINE tensor #-}
instance Action (,) (Diff p) where
braid :: forall a b. Diff p (a, b) (b, a)
braid = ((a, b) -> ((b, a), (b, a) -> (a, b))) -> Diff p (a, b) (b, a)
forall k (p :: k) a b. (a -> (b, b -> a)) -> Diff p a b
Diff (\(a
a, b
b) -> ((b
b, a
a), \(b
db, a
da) -> (a
da, b
db)))
{-# INLINE braid #-}
traceStarFrom ::
(NHR.StarSemiring j, MergeZero (->) c) =>
j ->
Int ->
Diff p (j, b) (j, c) ->
Diff p b c
traceStarFrom :: forall {k} j c (p :: k) b.
(StarSemiring j, MergeZero (->) c) =>
j -> Int -> Diff p (j, b) (j, c) -> Diff p b c
traceStarFrom j
x0 Int
n (Diff (j, b) -> ((j, c), (j, c) -> (j, b))
body) = (b -> (c, c -> b)) -> Diff p b c
forall k (p :: k) a b. (a -> (b, b -> a)) -> Diff p a b
Diff ((b -> (c, c -> b)) -> Diff p b c)
-> (b -> (c, c -> b)) -> Diff p b c
forall a b. (a -> b) -> a -> b
$ \b
b ->
let
stepFwd :: j -> j
stepFwd j
x = let ((j
x', c
_), (j, c) -> (j, b)
_) = (j, b) -> ((j, c), (j, c) -> (j, b))
body (j
x, b
b) in j
x'
a :: j
a = (j -> j) -> j -> [j]
forall a. (a -> a) -> a -> [a]
iterate j -> j
stepFwd j
x0 [j] -> Int -> j
forall a. HasCallStack => [a] -> Int -> a
!! Int
n
((j
_, c
c), (j, c) -> (j, b)
backward) = (j, b) -> ((j, c), (j, c) -> (j, b))
body (j
a, b
b)
aStar :: j
aStar = j -> j
forall a. StarSemiring a => a -> a
NHR.star ((j, b) -> j
forall a b. (a, b) -> a
fst ((j, c) -> (j, b)
backward (j
forall a. Multiplicative a => a
NHM.one, () -> c
forall {k} (arr :: * -> k -> *) (a :: k). Zero arr a => arr () a
CB.zero ())))
pullback :: c -> b
pullback c
dc =
let cdc :: j
cdc = (j, b) -> j
forall a b. (a, b) -> a
fst ((j, c) -> (j, b)
backward (j
forall a. Additive a => a
NHA.zero, c
dc))
in (j, b) -> b
forall a b. (a, b) -> b
snd ((j, c) -> (j, b)
backward (j
aStar j -> j -> j
forall a. Multiplicative a => a -> a -> a
NHM.* j
cdc, c
dc))
in (c
c, c -> b
pullback)
traceStar :: Diff p (j, b) (j, c) -> Diff p b c
traceStar :: forall k (p :: k) a b c. Diff p (a, b) (a, c) -> Diff p b c
traceStar = Diff p (j, b) (j, c) -> Diff p b c
forall a b c. Diff p (a, b) (a, c) -> Diff p b c
forall {k} (t :: k -> k -> k) (arr :: k -> k -> *) (a :: k)
(b :: k) (c :: k).
Traced t arr =>
arr (t a b) (t a c) -> arr b c
trace
traceNFrom ::
(MergeZero (->) a) =>
a ->
Int ->
Diff p (a, b) (a, c) ->
Diff p b c
traceNFrom :: forall {k} a (p :: k) b c.
MergeZero (->) a =>
a -> Int -> Diff p (a, b) (a, c) -> Diff p b c
traceNFrom a
x0 Int
n (Diff (a, b) -> ((a, c), (a, c) -> (a, b))
body) = (b -> (c, c -> b)) -> Diff p b c
forall k (p :: k) a b. (a -> (b, b -> a)) -> Diff p a b
Diff ((b -> (c, c -> b)) -> Diff p b c)
-> (b -> (c, c -> b)) -> Diff p b c
forall a b. (a -> b) -> a -> b
$ \b
b ->
let
stepFwd :: a -> a
stepFwd a
x = let ((a
x', c
_), (a, c) -> (a, b)
_) = (a, b) -> ((a, c), (a, c) -> (a, b))
body (a
x, b
b) in a
x'
a :: a
a = (a -> a) -> a -> [a]
forall a. (a -> a) -> a -> [a]
iterate a -> a
stepFwd a
x0 [a] -> Int -> a
forall a. HasCallStack => [a] -> Int -> a
!! Int
n
((a
_, c
c), (a, c) -> (a, b)
backward) = (a, b) -> ((a, c), (a, c) -> (a, b))
body (a
a, b
b)
pullback :: c -> b
pullback c
dc =
let stepBwd :: a -> a
stepBwd a
d = (a, b) -> a
forall a b. (a, b) -> a
fst ((a, c) -> (a, b)
backward (a
d, c
dc))
da :: a
da = (a -> a) -> a -> [a]
forall a. (a -> a) -> a -> [a]
iterate a -> a
stepBwd (() -> a
forall {k} (arr :: * -> k -> *) (a :: k). Zero arr a => arr () a
CB.zero ()) [a] -> Int -> a
forall a. HasCallStack => [a] -> Int -> a
!! Int
n
in (a, b) -> b
forall a b. (a, b) -> b
snd ((a, c) -> (a, b)
backward (a
da, c
dc))
in (c
c, c -> b
pullback)
quadD :: Diff p Double Double
quadD :: forall {k} (p :: k). Diff p Double Double
quadD = Diff p (Double, Double) Double
forall (arr :: * -> * -> *) a. Merge arr a => arr (a, a) a
CB.plus Diff p (Double, Double) Double
-> Diff p (Double, Double) (Double, Double)
-> Diff p (Double, Double) Double
forall b c a. Diff p b c -> Diff p a b -> Diff p a c
forall k (arr :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category arr =>
arr b c -> arr a b -> arr a c
. Diff p Double Double
-> Diff p Double Double -> Diff p (Double, Double) (Double, Double)
forall a b c d. Diff p a b -> Diff p c d -> Diff p (a, c) (b, d)
forall {k} (t :: k -> k -> k) (arr :: k -> k -> *) (a :: k)
(b :: k) (c :: k) (d :: k).
Tensor t arr =>
arr a b -> arr c d -> arr (t a c) (t b d)
tensor Diff p Double Double
forall {k} (p :: k). Diff p Double Double
sq Diff p Double Double
forall {k} (p :: k). Diff p Double Double
lin Diff p (Double, Double) Double
-> Diff p Double (Double, Double) -> Diff p Double Double
forall b c a. Diff p b c -> Diff p a b -> Diff p a c
forall k (arr :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category arr =>
arr b c -> arr a b -> arr a c
. Diff p Double (Double, Double)
forall (arr :: * -> * -> *) a. Copy arr a => arr a (a, a)
CB.copy
where
sq :: Diff p Double Double
sq = (Double -> (Double, Double -> Double)) -> Diff p Double Double
forall k (p :: k) a b. (a -> (b, b -> a)) -> Diff p a b
Diff (\Double
x -> (Double
2 Double -> Double -> Double
forall a. Num a => a -> a -> a
* Double
x Double -> Double -> Double
forall a. Num a => a -> a -> a
* Double
x, \Double
d -> Double
4 Double -> Double -> Double
forall a. Num a => a -> a -> a
* Double
x Double -> Double -> Double
forall a. Num a => a -> a -> a
* Double
d))
lin :: Diff p Double Double
lin = (Double -> (Double, Double -> Double)) -> Diff p Double Double
forall k (p :: k) a b. (a -> (b, b -> a)) -> Diff p a b
Diff (\Double
x -> (Double
3 Double -> Double -> Double
forall a. Num a => a -> a -> a
* Double
x Double -> Double -> Double
forall a. Num a => a -> a -> a
+ Double
5, (Double
3 Double -> Double -> Double
forall a. Num a => a -> a -> a
*)))