17 | module Spidr.Optimize
21 | import Data.List.HasLength
23 | import Spidr.Data.Nat
31 | Optimizer : (0 domain : Type) -> Type
32 | Optimizer a = (a -> Tag $
Tensor [] F64) -> Tag a
34 | stack : {ds : _} -> {dtype : _} -> Vect d (Tensor ds dtype) -> Tensor (d :: ds) dtype
35 | stack [] = tensor []
36 | stack (x :: xs) = concat 0 (expand 0 x) (stack xs)
38 | unstack : {d : _} -> Tensor (d :: ds) dtype -> Tag $
Vect d (Tensor ds dtype)
39 | unstack x = tag x <&> \x => Subset.tabulate $
\(Element i lt) => slice [at i] x
41 | vect : (xs : List a) -> {auto len : HasLength p xs} -> Vect p a
43 | vect (x :: xs) @{S len} = x :: vect xs
76 | (density : List Nat) ->
77 | {auto hl : HasLength d density} ->
78 | {auto nonEmpty : All (`GT` 1) density} ->
79 | (bound, bound' : Tensor [d] F64) ->
80 | Tag $
Vect d $
Tensor density F64
81 | meshGrid density bound bound' = do
82 | let iotas = Subset.tabulate $
\(Element dim lt) => iota {inBounds = ltLengthIsInBound lt hl} dim
83 | density' = F64.fromDouble . cast . pred <$> vect density
84 | bound <- traverse tag =<< unstack bound
85 | bound' <- traverse tag =<< unstack bound'
86 | pure [| rescale iotas density' bound bound' |]
89 | rescale : Tensor density F64 -> (dens, b, b' : Tensor [] F64) -> Tensor density F64
90 | rescale is dens b b' = broadcast (b' - b) * (is / broadcast dens) + broadcast b
92 | ltLengthIsInBound : {m : _} -> {xs : _} -> LT m n -> HasLength n xs -> InBounds m xs
93 | ltLengthIsInBound _ Z impossible
94 | ltLengthIsInBound {m = 0} {xs = _ :: _} _ _ = InFirst
95 | ltLengthIsInBound {m = S _} (LTESucc lt) (S hl) = InLater (ltLengthIsInBound lt hl)
106 | (density : List Nat) ->
107 | {auto hl : HasLength d density} ->
108 | {auto nonEmpty : All (`GT` 1) density} ->
109 | (bound, bound' : Tensor [d] F64) ->
110 | Optimizer $
Tensor [d] F64
111 | gridSearch {hl = Z} [] _ _ _ = pure (tensor [])
112 | gridSearch {hl = S _} density@(dn :: dns) bound bound' f = do
113 | grid <- meshGrid density bound bound'
114 | grid <- tag (stack $
reshape {sizesEqual = flattenable density} <$> grid).T
115 | [out] <- !(vmap {shapes = [_], dtypes = [_]} $
\x => do pure [!(f x)]) grid
116 | idx <- argminAS out $
sizeSuccIsSucc (dn :: dns)
117 | pure $
slice [at idx] grid
120 | argminAS : Tensor [s] F64 -> (0 _ : IsSucc s) -> Tag $
Tensor [] U64
121 | argminAS x ItIsSucc = argmin x
123 | 0 sizeSuccIsSucc : (xs : List Nat) -> {auto iss : All (`GT` 1) xs} -> IsSucc $
product xs
124 | sizeSuccIsSucc [] = ItIsSucc
125 | sizeSuccIsSucc (x :: xs) {iss = is :: _} = multSuccIsSucc (gtIsSucc is) (sizeSuccIsSucc xs)
140 | lbfgs : (initialPoints : Tensor [n] F64) -> Optimizer $
Tensor [n] F64