0 | module Data.Tensor.Utils
6 | import Data.Tensor.Tensor
7 | import Data.Container.Additive
8 | import Data.Container.SubTerm
29 | namespace CommonNames
31 | Scalar : (a : Type) -> Type
32 | Scalar a = Tensor [] a
35 | Vector : (c : Axis) -> (a : Type) -> Type
36 | Vector c a = Tensor [c] a
39 | Matrix : (row, col : Axis) -> ConsistentWith row [col] =>
41 | Matrix row col a = Tensor [row, col] a
43 | namespace FillZerosOnes
45 | fill : Num a => {shape : TensorShape rank} ->
46 | AllC TensorMonoid shape =>
48 | fill x = tensorReplicate x
51 | zeros : Num a => {shape : TensorShape rank} ->
52 | AllC TensorMonoid shape =>
54 | zeros = fill (fromInteger 0)
57 | ones : Num a => {shape : TensorShape rank} ->
58 | AllC TensorMonoid shape =>
60 | ones = fill (fromInteger 1)
64 | identityBool : {0 c : Axis} -> IsCubical c =>
66 | identityBool @{MkIsCubical _ n}
67 | = outerWith (==) (positions {sh=()}) (positions {sh=()})
72 | identity : {0 c : Axis} -> IsCubical c =>
73 | Num a => Tensor [c, c] a
74 | identity @{MkIsCubical _ n} = fromBool <$> identityBool
89 | arange : {0 stop : Axis} -> IsCubical stop =>
90 | Cast Nat a => Tensor [stop] a
91 | arange @{MkIsCubical _ n} = cast . finToNat <$> positions {sh=()}
96 | arangeFromTo : {default (TTInternalName ~~> 0) start : Axis} ->
98 | (cStart : IsCubical start) => (cStop : IsCubical stop) =>
99 | Cast Nat a => Tensor [stop.name ~~> minus (dim stop) (dim start)] a
100 | arangeFromTo {cStart=(MkIsCubical _ n)} {cStop=(MkIsCubical _ m)}
101 | = cast . (+n) . finToNat <$> positions {sh=()}
106 | flip : {shape : TensorShape rank} ->
107 | (axis : Fin rank) ->
108 | IsCubical (index axis (toVect shape)) =>
109 | Tensor shape a -> Tensor shape a
112 | namespace Concatenate
116 | concat : {shape : TensorShape rank} -> {l : AxisName} ->
117 | {x, y : Axis} -> IsCubical x => IsCubical y =>
118 | ConsistentWith (l ~~> dim x + dim y) shape =>
119 | ConsistentWith x shape =>
120 | ConsistentWith y shape =>
121 | Tensor (x :: shape) a ->
122 | Tensor (y :: shape) a ->
123 | Tensor ((l ~~> dim x + dim y) :: shape) a
124 | concat @{MkIsCubical _ n} @{MkIsCubical _ m} t t'
125 | = embedTopExt $
extractTopExt t ++ extractTopExt t'
134 | size : {shape : TensorShape rank} ->
135 | Tensor shape a -> Nat
140 | size : {shape : TensorShape rank} ->
141 | All IsCubical (toVect shape) =>
142 | (0 _ : Tensor shape a) -> Nat
143 | size {shape} _ = size (toVect shape)
150 | flatten : {0 shape : TensorShape rank} ->
151 | Foldable (Tensor shape) =>
152 | Tensor shape a -> List a
159 | flatten : {shape : TensorShape rank} ->
160 | All IsCubical (conts shape) =>
161 | Tensor shape a -> Vect (size shape) a
162 | flatten = toVect . extMap (flattenCubical DefaultLayoutOrder) . GetT
168 | max : {0 shape : TensorShape rank} ->
169 | Foldable (Tensor shape) => Ord a =>
170 | Tensor shape a -> Maybe a
171 | max = max . flatten
173 | namespace ArgMinMax
177 | argmax : {name : AxisName} -> {n : Nat} -> IsSucc n => Ord a =>
178 | Tensor [name ~~> n] a -> Fin n
179 | argmax = Vect.argmax . (#>)
184 | argmin : {name : AxisName} -> {n : Nat} -> IsSucc n => Ord a =>
185 | Tensor [name ~~> n] a -> Fin n
186 | argmin = Vect.argmin . (#>)
192 | isClose : {default 1.0e-8 atol : Double} -> {default 1.0e-5 rtol : Double} ->
193 | Double -> Double -> Bool
194 | isClose x y = abs (x - y) <= atol + rtol * abs y
198 | allClose : {0 shape : TensorShape rank} ->
199 | Applicative (Tensor shape) => Foldable (Tensor shape) =>
200 | {default 1.0e-8 atol : Double} -> {default 1.0e-5 rtol : Double} ->
201 | Tensor shape Double -> Tensor shape Double -> Bool
202 | allClose t t' = all id [| isClose {atol} {rtol} t t' |]
206 | oneHot : {0 c : Axis} -> IsCubical c =>
207 | (i : Fin (dim c)) ->
208 | Num a => Tensor [c] a
209 | oneHot @{MkIsCubical _ n} i = set zeros [i] 1
211 | namespace Triangular
214 | cTriBool : {c : Axis} ->
215 | (ip : InterfaceOnPositions c.cont MOrd) =>
216 | TensorMonoid c.cont =>
217 | (sh : c.cont.Shp) -> Tensor [c, c] Bool
218 | cTriBool {ip = MkI p} sh
219 | = let cPositions = positions {sh=sh}
220 | pp : MOrd (c.cont.Pos sh) := p sh
221 | in outerWith (flip isSubTerm) cPositions cPositions
224 | triBool : {0 c : Axis} -> IsCubical c =>
226 | triBool @{MkIsCubical _ n} = cTriBool ()
232 | tri : {0 c : Axis} -> IsCubical c =>
233 | Num a => Tensor [c, c] a
234 | tri @{MkIsCubical _ n} = fromBool <$> triBool
239 | lowerTriangular : {0 c : Axis} -> IsCubical c =>
240 | Num a => Tensor [c, c] a -> Tensor [c, c] a
241 | lowerTriangular @{MkIsCubical _ n} = (* tri)
246 | upperTriangular : {0 c : Axis} -> IsCubical c =>
247 | Num a => Tensor [c, c] a -> Tensor [c, c] a
248 | upperTriangular @{MkIsCubical _ n} = (* ((fromBool . not) <$> triBool))
252 | maskedFill : {shape : TensorShape rank} ->
253 | Num a => AllC TensorMonoid shape =>
254 | (t : Tensor shape a) ->
255 | (mask : Tensor shape Bool) ->
258 | maskedFill t mask fill = liftA2Tensor mask t <&>
259 | (\(maskVal, tVal) => if maskVal then fill else tVal)
263 | sum : {shape : TensorShape rank} ->
264 | Algebra (Tensor shape) a =>
265 | Tensor shape a -> a
269 | mean : {shape : TensorShape rank} ->
270 | All IsCubical (toVect shape) =>
273 | Algebra (Tensor shape) a =>
274 | Tensor shape a -> a
275 | mean t = sum t / cast (Cubical.size t)
278 | variance : {c : Axis} -> IsCubical c =>
279 | Neg a => Fractional a => Cast Nat a =>
281 | variance @{MkIsCubical _ n} t =
282 | let inputMinusMean = t - pure (mean t)
283 | in mean (inputMinusMean * inputMinusMean)
286 | cumulativeSum : {c : Axis} -> Num a =>
287 | (isCubical : IsCubical c) =>
288 | Tensor [c] a -> Tensor [c] a
289 | cumulativeSum {isCubical=(MkIsCubical _ n)} t
290 | = (#>#) (scanl1 (+)) t
300 | namespace TensorComMonoid
304 | tensorComMonoid : {shape : TensorShape rank} -> AllC TensorMonoid shape =>
305 | ComMonoid a -> ComMonoid (Tensor shape a)
306 | tensorComMonoid (MkComMonoid p z) = MkComMonoid
307 | (\t, t' => [| p t t' |])
310 | namespace Traversals
312 | inorder : Tensor [b ~> BinTreeNode] a -> Tensor [l ~> List] a
313 | inorder = extToVector . extMap BinTreeNode.inorder . vectorToExt
319 | {shape : TensorShape rank} ->
321 | AllC TensorMonoid shape =>
322 | Traversable (Tensor shape) =>
323 | Random (Tensor shape a) where
324 | randomIO = sequence (pure randomIO)
325 | randomRIO (lo, hi) = traverse randomRIO [| MkPair lo hi |]
328 | tta : Applicative (Tensor ["a" ~~> 1])
331 | ttt : Traversable (Tensor ["b" ~~> 1])
334 | ttd : Random Double
337 | randTensorShape : Random (Tensor ["a" ~~> 2, "b" ~~> 3] Double)
338 | randTensorShape = %search
342 | random : Num a => Random a => HasIO io =>
343 | (shape : TensorShape rank) ->
344 | All IsCubical (toVect shape) =>
345 | Applicative (Tensor shape) =>
346 | Traversable (Tensor shape) =>
347 | io (Tensor shape a)
348 | random shape = sequence $
pure $
randomRIO (0, 1)