0 | module Data.Autodiff.Model
4 | import Data.ComMonoid
5 | import Data.Container.Additive
6 | import public Data.Para
7 | import Data.Materialise
8 | import public System.Random
23 | record Model (a, b : AddCont) where
26 | {auto pMon : ComMonoid Params}
28 | run : (a >*< Const Params @{pMon}) =%+> b
32 | (-\->) : AddCont -> AddCont -> Type
33 | a -\-> b = Model a b
36 | ParamCont : Model a b -> AddCont
37 | ParamCont m = Const m.Params @{m.pMon}
39 | namespace ParaConversion
41 | toPara : {0 a, b : AddCont} -> a -\-> b -> ParaAddLens a b
42 | toPara m = MkPara (ParamCont m) m.run
45 | fromPara : {0 a, b : AddCont} -> (f : ParaAddLens a b) ->
46 | (isConst : IsConst (Param f)) =>
47 | (init : IO (Param f).Shp) ->
49 | fromPara (MkPara _ f) {isConst = MkIsConst p @{mon}} init = MkModel p init f
54 | withInit : {0 a, b : AddCont} -> (m : a -\-> b) -> IO m.Params -> a -\-> b
55 | withInit m i = MkModel m.Params @{m.pMon} i m.run
59 | DefaultInit : Random p => Neg p => IO p
60 | DefaultInit = randomRIO (-
1, 1)
64 | trivialParam : {0 a, b : AddCont} -> a =%+> b -> a -\-> b
65 | trivialParam f = MkModel Unit (pure ()) $
67 | let (
y ** k)
= (%!+) f x
68 | in (
y ** \y' => (k y', ()))
71 | id : {a : AddCont} -> a -\-> a
72 | id = trivialParam id
76 | (>>>) : {0 a, b, c : AddCont} ->
77 | Materialise b.Shp => InterfaceOnPositions b Materialise =>
81 | (MkModel p ip f) >>> (MkModel q iq g) = MkModel (p, q) [| (ip, iq) |] $
83 | %+>> assocR {b=Const p, c=Const q}
84 | %+>> ((f %+>> materialiseCont) >*< id {c=Const q})
89 | (***) : {a, b, c, d : AddCont} ->
92 | a >*< b -\-> c >*< d
93 | (MkModel p ip f) *** (MkModel q iq g) = MkModel (p, q) [| (ip, iq) |] $
94 | (id {c=a>*<b} >*< constPair)
95 | %+>> swapMiddle {c3=Const p} {c4=Const q}
100 | (&&&) : {a : AddCont} -> {0 b, c : AddCont} ->
104 | (MkModel p ip f) &&& (MkModel q iq g) = MkModel (p, q) [| (ip, iq) |] $
106 | %+>> (copy >*< id {c=Const p >*< Const q})
107 | %+>> swapMiddle {c3=Const p} {c4=Const q}
113 | initAll : {n : Nat} -> {0 a : AddCont} -> {0 f : Fin n -> AddCont} ->
114 | (ms : (i : Fin n) -> a -\-> f i) ->
115 | IO (Product (\i => ParamCont (ms i))).Shp
116 | initAll {n = 0} _ = pure ()
117 | initAll {n = S k} ms = [| ((ms 0).init, initAll (\i => ms (FS i))) |]
123 | fanOutModel : {a : AddCont} -> {n : Nat} -> {0 f : Fin n -> AddCont} ->
124 | (ms : (i : Fin n) -> a -\-> f i) -> a -\-> Section f
125 | fanOutModel ms = MkModel
126 | (Product (\i => ParamCont (ms i))).Shp
127 | @{finiteShpMon {f = \i => ParamCont (ms i)} (\i => (ms i).pMon)}
129 | ((id >*< constFinite {ps = \i => (ms i).Params} (\i => (ms i).pMon))
130 | %+>> fanOut (\i => (id >*< projFinite {f = \i => ParamCont (ms i)} i) %+>> (ms i).run))
134 | nTimes : {a : AddCont} ->
135 | Materialise a.Shp =>
136 | InterfaceOnPositions a Materialise =>
137 | Nat -> a -\-> a -> a -\-> a
140 | nTimes (S k) m = m >>> nTimes k m
143 | postcomposeLens : {0 a, b, c : AddCont} -> a -\-> b -> b =%+> c -> a -\-> c
144 | postcomposeLens m g = MkModel m.Params @{m.pMon} m.init (m.run %+>> g)
148 | precomposeLens : {0 a, b, c : AddCont} -> a =%+> b -> b -\-> c -> a -\-> c
150 | = MkModel m.Params @{m.pMon} m.init ((g >*< id {c = ParamCont m}) %+>> m.run)
154 | prim : {0 a : AddCont} -> {b : AddCont} ->
155 | ((x : a.Shp) -> (y : b.Shp ** (b.PosSet y -> a.PosSet x))) ->
157 | prim f = trivialParam (!%+ f)
161 | customOp : {s, t : Type} -> ComMonoid s => ComMonoid t =>
162 | (fwd : s -> t) -> (vjp : s -> t -> s) ->
163 | Const s -\-> Const t
164 | customOp fwd vjp = prim (\x => (
fwd x ** vjp x)
)
168 | layer : {0 a : AddCont} -> {b : AddCont} ->
169 | (p : Type) -> ComMonoid p =>
171 | ((x : a.Shp) -> (param : p) -> (y : b.Shp ** (b.PosSet y -> (a.PosSet x, p)))) ->
173 | layer p initP f = MkModel p initP $
174 | !%+ \(x, ps) => f x ps
178 | runAt : {0 a, b : AddCont} -> (m : a -\-> b) ->
179 | (x : a.Shp) -> (p : m.Params) ->
180 | (y : b.Shp ** (b.PosSet y -> (a.PosSet x, m.Params)))
181 | runAt m x p = (%!+) m.run (x, p)
185 | (.fwd) : {0 a, b : AddCont} -> (m : a -\-> b) ->
186 | (x : a.Shp) -> (p : m.Params) -> b.Shp
187 | (.fwd) m x p = fst (runAt m x p)
191 | (.bwd) : {0 a, b : AddCont} -> (m : a -\-> b) ->
192 | (x : a.Shp) -> (p : m.Params) ->
193 | b.PosSet (m.fwd x p) -> (a.PosSet x, m.Params)
194 | (.bwd) m x p = snd (runAt m x p)