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}
112 | dfunFinite : {a : AddCont} -> {n : Nat} -> {0 f : Fin n -> AddCont} ->
113 | ((i : Fin n) -> a -\-> f i) -> a -\-> AddContDFunFinite f
114 | dfunFinite {n = 0} _ = trivialParam terminal
115 | dfunFinite {n = S k} ms = ms 0 &&& dfunFinite {f = f . FS} (\i => ms (FS i))
119 | lazyCons : {a : AddCont} ->
120 | {0 b : AddCont} -> {0 k : Nat} -> {0 bs : Vect k AddCont} ->
121 | a -\-> b -> a -\-> (Vect k >-+@ Coproduct bs) ->
122 | a -\-> (Vect (S k) >-+@ Coproduct (b :: bs))
123 | lazyCons (MkModel p @{pm} ip f) (MkModel q @{qm} iq g) = MkModel
124 | (p, q) [| (ip, iq) |] $
125 | !%+ \(x, (px, qx)) =>
126 | let hd : Lazy (t : b.Shp ** b.PosSet t -> (a >*< Const p).PosSet (x, px))
127 | hd = (%!+) f (x, px)
128 | rest = (%!+) g (x, qx)
130 | FZ => (
FZ ** fst hd)
131 | FS j => (
FS (fst (index (fst rest) j)) ** snd (index (fst rest) j))
)
132 | ** fromGenerators {y = (a >*< Const (p, q)).Pos (x, (px, qx))}
133 | (\(
i ** gr)
=> case i of
134 | FZ => let (x', p') = snd hd gr
135 | in (x', (p', (Const q).Zero qx))
136 | FS j => let (x', q') = snd rest (MkBag [(
j ** gr)
])
137 | in (x', ((Const p @{pm}).Zero px, q'))))
142 | lazyBranches : {a : AddCont} -> {n : Nat} -> {0 branches : Vect n AddCont} ->
143 | ((i : Fin n) -> a -\-> index i branches) ->
144 | a -\-> (Vect n >-+@ Coproduct branches)
145 | lazyBranches {n = 0} {branches = []} _ = trivialParam $
146 | !%+ \x => (
() <| (\i => absurd i) ** fromGenerators (\(
i ** _)
=> absurd i))
147 | lazyBranches {n = S k} {branches = b :: bs} ms
148 | = lazyCons (ms 0) (lazyBranches (\i => ms (FS i)))
152 | mapFst : {a, c : AddCont} ->
154 | a >*< c -\-> b >*< c
155 | mapFst m = MkModel m.Params @{m.pMon} m.init $
156 | assocL {c=ParamCont m}
157 | %+>> (id >*< swap {a=c} {b=ParamCont m})
158 | %+>> assocR {a} {b=ParamCont m}
159 | %+>> (m.run >*< id)
163 | nTimes : {a : AddCont} ->
164 | Materialise a.Shp =>
165 | InterfaceOnPositions a Materialise =>
166 | Nat -> a -\-> a -> a -\-> a
169 | nTimes (S k) m = m >>> nTimes k m
172 | postcomposeLens : {0 a, b, c : AddCont} -> a -\-> b -> b =%+> c -> a -\-> c
173 | postcomposeLens m g = MkModel m.Params @{m.pMon} m.init (m.run %+>> g)
177 | precomposeLens : {0 a, b, c : AddCont} -> a =%+> b -> b -\-> c -> a -\-> c
179 | = MkModel m.Params @{m.pMon} m.init ((g >*< id {c = ParamCont m}) %+>> m.run)
183 | prim : {0 a : AddCont} -> {b : AddCont} ->
184 | ((x : a.Shp) -> (y : b.Shp ** (b.PosSet y -> a.PosSet x))) ->
186 | prim f = trivialParam (!%+ f)
190 | customOp : {s, t : Type} -> ComMonoid s => ComMonoid t =>
191 | (fwd : s -> t) -> (vjp : s -> t -> s) ->
192 | Const s -\-> Const t
193 | customOp fwd vjp = prim (\x => (
fwd x ** vjp x)
)
197 | layer : {0 a : AddCont} -> {b : AddCont} ->
198 | (p : Type) -> ComMonoid p =>
200 | ((x : a.Shp) -> (param : p) -> (y : b.Shp ** (b.PosSet y -> (a.PosSet x, p)))) ->
202 | layer p initP f = MkModel p initP $
203 | !%+ \(x, ps) => f x ps
207 | runAt : {0 a, b : AddCont} -> (m : a -\-> b) ->
208 | (x : a.Shp) -> (p : m.Params) ->
209 | (y : b.Shp ** (b.PosSet y -> (a.PosSet x, m.Params)))
210 | runAt m x p = (%!+) m.run (x, p)
214 | (.fwd) : {0 a, b : AddCont} -> (m : a -\-> b) ->
215 | (x : a.Shp) -> (p : m.Params) -> b.Shp
216 | (.fwd) m x p = fst (runAt m x p)
220 | (.bwd) : {0 a, b : AddCont} -> (m : a -\-> b) ->
221 | (x : a.Shp) -> (p : m.Params) ->
222 | b.PosSet (m.fwd x p) -> (a.PosSet x, m.Params)
223 | (.bwd) m x p = snd (runAt m x p)