-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Multi-dimensional arrays. -- -- This package provides an interface into the numhask API, and -- both type- and value-level shape manipulation routines. -- --
-- >>> {-# LANGUAGE RebindableSyntax #-}
--
-- >>> import NumHask.Prelude
--
-- >>> import NumHask.Array
--
--
-- In situations where shape is only known at runtime, a clear module
-- configuration is:
--
-- -- >>> import NumHask.Array.Shape -- -- >>> import qualified NumHask.Array.Fixed as F -- -- >>> import qualified NumHask.Array.Dynamic as D --@package numhask-array @version 0.9.2 -- | Functions for manipulating shape. The module tends to supply -- equivalent functionality at type-level and value-level with functions -- of the same name (except for capitalization). module NumHask.Array.Shape -- | The Shape type holds a [Nat] at type level and the equivalent [Int] at -- value level. Using [Int] as the index for an array nicely represents -- the practical interests and constraints downstream of this high-level -- API: densely-packed numbers (reals or integrals), indexed and layered. newtype Shape (s :: [Nat]) Shape :: [Int] -> Shape (s :: [Nat]) [shapeVal] :: Shape (s :: [Nat]) -> [Int] class HasShape s toShape :: HasShape s => Shape s type family (a :: [k]) ++ (b :: [k]) :: [k] type family (a :: [k]) !! (b :: Nat) :: k type family Take (n :: Nat) (a :: [k]) :: [k] type family Drop (n :: Nat) (a :: [k]) :: [k] type Reverse (a :: [k]) = ReverseGo a '[] type family ReverseGo (a :: [k]) (b :: [k]) :: [k] type family Filter (r :: [Nat]) (xs :: [Nat]) (i :: Nat) -- | Number of dimensions rank :: [a] -> Int type family Rank (s :: [a]) :: Nat -- | The shape of a list of element indexes ranks :: [[a]] -> [Int] type family Ranks (s :: [[a]]) :: [Nat] -- | Number of elements size :: [Int] -> Int type family Size (s :: [Nat]) :: Nat -- | dimension i is the i'th dimension of a Shape dimension :: [Int] -> Int -> Int type family Dimension (s :: [Nat]) (i :: Nat) :: Nat -- | convert from n-dim shape index to a flat index -- --
-- >>> flatten [2,3,4] [1,1,1] -- 17 ---- --
-- >>> flatten [] [1,1,1] -- 0 --flatten :: [Int] -> [Int] -> Int -- | convert from a flat index to a shape index -- --
-- >>> shapen [2,3,4] 17 -- [1,1,1] --shapen :: [Int] -> Int -> [Int] -- | minimum value in a list minimum :: [Int] -> Int type family Minimum (s :: [Nat]) :: Nat -- | checkIndex i n checks if i is a valid index of a list of -- length n checkIndex :: Int -> Int -> Bool type family CheckIndex (i :: Nat) (n :: Nat) :: Bool -- | checkIndexes is n check if is are valid indexes of a -- list of length n checkIndexes :: [Int] -> Int -> Bool type family CheckIndexes (i :: [Nat]) (n :: Nat) :: Bool -- | addIndex s i d adds a new dimension to shape s at -- position i -- --
-- >>> addIndex [2,4] 1 3 -- [2,3,4] --addIndex :: [Int] -> Int -> Int -> [Int] type AddIndex s i d = Take i s ++ (d : Drop i s) -- | drop the i'th dimension from a shape -- --
-- >>> dropIndex [2, 3, 4] 1 -- [2,4] --dropIndex :: [Int] -> Int -> [Int] type DropIndex s i = Take i s ++ Drop (i + 1) s -- | convert a list of position that references a final shape to one that -- references positions relative to an accumulator. Deletions are from -- the left and additions are from the right. -- -- deletions -- --
-- >>> posRelative [0,1] -- [0,0] ---- -- additions -- --
-- >>> reverse (posRelative (reverse [1,0])) -- [0,0] --posRelative :: [Int] -> [Int] type family PosRelative (s :: [Nat]) type family PosRelativeGo (r :: [Nat]) (s :: [Nat]) -- | insert a list of dimensions according to position and dimension lists. -- Note that the list of positions references the final shape and not the -- initial shape. -- --
-- >>> addIndexes [4] [1,0] [3,2] -- [2,3,4] --addIndexes :: () => [Int] -> [Int] -> [Int] -> [Int] type family AddIndexes (as :: [Nat]) (xs :: [Nat]) (ys :: [Nat]) type family AddIndexesGo (as :: [Nat]) (xs :: [Nat]) (ys :: [Nat]) -- | drop dimensions of a shape according to a list of positions (where -- position refers to the initial shape) -- --
-- >>> dropIndexes [2, 3, 4] [1, 0] -- [4] --dropIndexes :: [Int] -> [Int] -> [Int] type family DropIndexes (s :: [Nat]) (i :: [Nat]) -- | take list of dimensions according to position lists. -- --
-- >>> takeIndexes [2,3,4] [2,0] -- [4,2] --takeIndexes :: [Int] -> [Int] -> [Int] type family TakeIndexes (s :: [Nat]) (i :: [Nat]) -- | turn a list of included positions for a given rank into a list of -- excluded positions -- --
-- >>> exclude 3 [1,2] -- [0] --exclude :: Int -> [Int] -> [Int] type family Exclude (r :: Nat) (i :: [Nat]) -- | concatenate -- --
-- >>> concatenate' 1 [2,3,4] [2,3,4] -- [2,6,4] --concatenate' :: Int -> [Int] -> [Int] -> [Int] type Concatenate i s0 s1 = Take i s0 ++ (Dimension s0 i + Dimension s1 i : Drop (i + 1) s0) type CheckConcatenate i s0 s1 s = (CheckIndex i (Rank s0) && DropIndex s0 i == DropIndex s1 i && Rank s0 == Rank s1) ~ 'True type Insert d s = Take d s ++ (Dimension s d + 1 : Drop (d + 1) s) type CheckInsert d i s = (CheckIndex d (Rank s) && CheckIndex i (Dimension s d)) ~ 'True -- | reorder' s i reorders the dimensions of shape s -- according to a list of positions i -- --
-- >>> reorder' [2,3,4] [2,0,1] -- [4,2,3] --reorder' :: [Int] -> [Int] -> [Int] type family Reorder (s :: [Nat]) (ds :: [Nat]) :: [Nat] type family CheckReorder (ds :: [Nat]) (s :: [Nat]) -- | remove 1's from a list squeeze' :: (Eq a, Multiplicative a) => [a] -> [a] type family Squeeze (a :: [Nat]) -- | incAt d s increments the index at d of shape s by -- one. incAt :: Int -> [Int] -> [Int] -- | decAt d s decrements the index at d of shape s by -- one. decAt :: Int -> [Int] -> [Int] -- | Reflect a list of Nats class KnownNats (ns :: [Nat]) natVals :: KnownNats ns => Proxy ns -> [Int] -- | Reflect a list of list of Nats class KnownNatss (ns :: [[Nat]]) natValss :: KnownNatss ns => Proxy ns -> [[Int]] instance GHC.Show.Show (NumHask.Array.Shape.Shape s) instance NumHask.Array.Shape.KnownNatss '[] instance (NumHask.Array.Shape.KnownNats n, NumHask.Array.Shape.KnownNatss ns) => NumHask.Array.Shape.KnownNatss (n : ns) instance NumHask.Array.Shape.KnownNats '[] instance (GHC.TypeNats.KnownNat n, NumHask.Array.Shape.KnownNats ns) => NumHask.Array.Shape.KnownNats (n : ns) instance NumHask.Array.Shape.HasShape '[] instance (GHC.TypeNats.KnownNat n, NumHask.Array.Shape.HasShape s) => NumHask.Array.Shape.HasShape (n : s) -- | Arrays with a dynamic shape. module NumHask.Array.Dynamic -- | a multidimensional array with a value-level shape -- --
-- >>> let a = fromFlatList [2,3,4] [1..24] :: Array Int -- -- >>> a -- [[[1, 2, 3, 4], -- [5, 6, 7, 8], -- [9, 10, 11, 12]], -- [[13, 14, 15, 16], -- [17, 18, 19, 20], -- [21, 22, 23, 24]]] --data Array a Array :: [Int] -> Vector a -> Array a [shape] :: Array a -> [Int] [unArray] :: Array a -> Vector a -- | convert from a list -- --
-- >>> fromFlatList [2,3,4] [1..24] == a -- True --fromFlatList :: [Int] -> [a] -> Array a -- | convert to a flat list. -- --
-- >>> toFlatList a == [1..24] -- True --toFlatList :: Array a -> [a] -- | extract an element at index i -- --
-- >>> index a [1,2,3] -- 24 --index :: () => Array a -> [Int] -> a -- | tabulate an array with a generating function -- --
-- >>> tabulate [2,3,4] ((1+) . flatten [2,3,4]) == a -- True --tabulate :: () => [Int] -> ([Int] -> a) -> Array a -- | Reshape an array (with the same number of elements). -- --
-- >>> reshape [4,3,2] a -- [[[1, 2], -- [3, 4], -- [5, 6]], -- [[7, 8], -- [9, 10], -- [11, 12]], -- [[13, 14], -- [15, 16], -- [17, 18]], -- [[19, 20], -- [21, 22], -- [23, 24]]] --reshape :: [Int] -> Array a -> Array a -- | Reverse indices eg transposes the element Aijk to Akji. -- --
-- >>> index (transpose a) [1,0,0] == index a [0,0,1] -- True --transpose :: Array a -> Array a -- | Extract the diagonal of an array. -- --
-- >>> diag (ident [3,2]) -- [1, 1] --diag :: Array a -> Array a -- | The identity array. -- --
-- >>> ident [3,2] -- [[1, 0], -- [0, 1], -- [0, 0]] --ident :: (Additive a, Multiplicative a) => [Int] -> Array a -- | Create an array composed of a single value. -- --
-- >>> singleton [3,2] one -- [[1, 1], -- [1, 1], -- [1, 1]] --singleton :: [Int] -> a -> Array a -- | Select an array along dimensions. -- --
-- >>> let s = selects [0,1] [1,1] a -- -- >>> s -- [17, 18, 19, 20] --selects :: [Int] -> [Int] -> Array a -> Array a -- | Select an index except along specified dimensions -- --
-- >>> let s = selectsExcept [2] [1,1] a -- -- >>> s -- [17, 18, 19, 20] --selectsExcept :: [Int] -> [Int] -> Array a -> Array a -- | Fold along specified dimensions. -- --
-- >>> folds sum [1] a -- [68, 100, 132] --folds :: (Array a -> b) -> [Int] -> Array a -> Array b -- | Extracts dimensions to an outer layer. -- --
-- >>> let e = extracts [1,2] a -- -- >>> shape <$> extracts [0] a -- [[3,4], [3,4]] --extracts :: [Int] -> Array a -> Array (Array a) -- | Extracts except dimensions to an outer layer. -- --
-- >>> let e = extractsExcept [1,2] a -- -- >>> shape <$> extracts [0] a -- [[3,4], [3,4]] --extractsExcept :: [Int] -> Array a -> Array (Array a) -- | Join inner and outer dimension layers. -- --
-- >>> let e = extracts [1,0] a -- -- >>> let j = joins [1,0] e -- -- >>> a == j -- True --joins :: [Int] -> Array (Array a) -> Array a -- | Maps a function along specified dimensions. -- --
-- >>> shape $ maps (transpose) [1] a -- [4,3,2] --maps :: (Array a -> Array b) -> [Int] -> Array a -> Array b -- | Concatenate along a dimension. -- --
-- >>> shape $ concatenate 1 a a -- [2,6,4] --concatenate :: Int -> Array a -> Array a -> Array a -- | Insert along a dimension at a position. -- --
-- >>> insert 2 0 a (fromFlatList [2,3] [100..105]) -- [[[100, 1, 2, 3, 4], -- [101, 5, 6, 7, 8], -- [102, 9, 10, 11, 12]], -- [[103, 13, 14, 15, 16], -- [104, 17, 18, 19, 20], -- [105, 21, 22, 23, 24]]] --insert :: Int -> Int -> Array a -> Array a -> Array a -- | Insert along a dimension at the end. -- --
-- >>> append 2 a (fromFlatList [2,3] [100..105]) -- [[[1, 2, 3, 4, 100], -- [5, 6, 7, 8, 101], -- [9, 10, 11, 12, 102]], -- [[13, 14, 15, 16, 103], -- [17, 18, 19, 20, 104], -- [21, 22, 23, 24, 105]]] --append :: Int -> Array a -> Array a -> Array a -- | change the order of dimensions -- --
-- >>> let r = reorder [2,0,1] a -- -- >>> r -- [[[1, 5, 9], -- [13, 17, 21]], -- [[2, 6, 10], -- [14, 18, 22]], -- [[3, 7, 11], -- [15, 19, 23]], -- [[4, 8, 12], -- [16, 20, 24]]] --reorder :: [Int] -> Array a -> Array a -- | Product two arrays using the supplied binary function. -- -- For context, if the function is multiply, and the arrays are tensors, -- then this can be interpreted as a tensor product. -- -- https://en.wikipedia.org/wiki/Tensor_product -- -- The concept of a tensor product is a dense crossroad, and a complete -- treatment is elsewhere. To quote: ... the tensor product can be -- extended to other categories of mathematical objects in addition to -- vector spaces, such as to matrices, tensors, algebras, topological -- vector spaces, and modules. In each such case the tensor product is -- characterized by a similar universal property: it is the freest -- bilinear operation. The general concept of a "tensor product" is -- captured by monoidal categories; that is, the class of all things that -- have a tensor product is a monoidal category. -- --
-- >>> expand (*) v v -- [[1, 2, 3], -- [2, 4, 6], -- [3, 6, 9]] --expand :: (a -> b -> c) -> Array a -> Array b -> Array c -- | Apply an array of functions to each array of values. -- -- This is in the spirit of the applicative functor operation (*). -- --
-- expand f a b == apply (fmap f a) b ---- --
-- >>> apply ((*) <$> v) v -- [[1, 2, 3], -- [2, 4, 6], -- [3, 6, 9]] ---- --
-- >>> let b = fromFlatList [2,3] [1..6] :: Array Int -- -- >>> contract sum [1,2] (apply (fmap (*) b) (transpose b)) -- [[14, 32], -- [32, 77]] --apply :: Array (a -> b) -> Array a -> Array b -- | Contract an array by applying the supplied (folding) function on -- diagonal elements of the dimensions. -- -- This generalises a tensor contraction by allowing the number of -- contracting diagonals to be other than 2, and allowing a binary -- operator other than multiplication. -- --
-- >>> let b = fromFlatList [2,3] [1..6] :: Array Int -- -- >>> contract sum [1,2] (expand (*) b (transpose b)) -- [[14, 32], -- [32, 77]] --contract :: (Array a -> b) -> [Int] -> Array a -> Array b -- | A generalisation of a dot operation, which is a multiplicative -- expansion of two arrays and sum contraction along the middle two -- dimensions. -- -- matrix multiplication -- --
-- >>> let b = fromFlatList [2,3] [1..6] :: Array Int -- -- >>> dot sum (*) b (transpose b) -- [[14, 32], -- [32, 77]] ---- -- inner product -- --
-- >>> let v = fromFlatList [3] [1..3] :: Array Int -- -- >>> dot sum (*) v v -- 14 ---- -- matrix-vector multiplication Note that an `Array Int` with shape [3] -- is neither a row vector nor column vector. dot is not turning -- the vector into a matrix and then using matrix multiplication. -- --
-- >>> dot sum (*) v b -- [9, 12, 15] ---- --
-- >>> dot sum (*) b v -- [14, 32] --dot :: (Array c -> d) -> (a -> b -> c) -> Array a -> Array b -> Array d -- | Array multiplication. -- -- matrix multiplication -- --
-- >>> let b = fromFlatList [2,3] [1..6] :: Array Int -- -- >>> mult b (transpose b) -- [[14, 32], -- [32, 77]] ---- -- inner product -- --
-- >>> let v = fromFlatList [3] [1..3] :: Array Int -- -- >>> mult v v -- 14 ---- -- matrix-vector multiplication -- --
-- >>> mult v b -- [9, 12, 15] ---- --
-- >>> mult b v -- [14, 32] --mult :: (Additive a, Multiplicative a) => Array a -> Array a -> Array a -- | Select elements along positions in every dimension. -- --
-- >>> let s = slice [[0,1],[0,2],[1,2]] a -- -- >>> s -- [[[2, 3], -- [10, 11]], -- [[14, 15], -- [22, 23]]] --slice :: [[Int]] -> Array a -> Array a -- | Remove single dimensions. -- --
-- >>> let a' = fromFlatList [2,1,3,4,1] [1..24] :: Array Int -- -- >>> shape $ squeeze a' -- [2,3,4] --squeeze :: Array a -> Array a -- | Unwrapping scalars is probably a performance bottleneck. -- --
-- >>> let s = fromFlatList [] [3] :: Array Int -- -- >>> fromScalar s -- 3 --fromScalar :: Array a -> a -- | Convert a number to a scalar. -- --
-- >>> :t toScalar 2 -- toScalar 2 :: FromInteger a => Array a --toScalar :: a -> Array a -- | extract specialised to a matrix -- --
-- >>> col 1 m -- [1, 5, 9] --col :: Int -> Array a -> Array a -- | Extract specialised to a matrix. -- --
-- >>> row 1 m -- [4, 5, 6, 7] --row :: Int -> Array a -> Array a -- | matrix multiplication -- -- This is dot sum (*) specialised to matrices -- --
-- >>> let a = fromFlatList [2,2] [1, 2, 3, 4] :: Array Int -- -- >>> let b = fromFlatList [2,2] [5, 6, 7, 8] :: Array Int -- -- >>> a -- [[1, 2], -- [3, 4]] ---- --
-- >>> b -- [[5, 6], -- [7, 8]] ---- --
-- >>> mmult a b -- [[19, 22], -- [43, 50]] --mmult :: Ring a => Array a -> Array a -> Array a instance GHC.Generics.Generic (NumHask.Array.Dynamic.Array a) instance GHC.Classes.Ord a => GHC.Classes.Ord (NumHask.Array.Dynamic.Array a) instance GHC.Classes.Eq a => GHC.Classes.Eq (NumHask.Array.Dynamic.Array a) instance GHC.Base.Functor NumHask.Array.Dynamic.Array instance Data.Foldable.Foldable NumHask.Array.Dynamic.Array instance Data.Traversable.Traversable NumHask.Array.Dynamic.Array instance GHC.Show.Show a => GHC.Show.Show (NumHask.Array.Dynamic.Array a) -- | Arrays with a fixed shape. module NumHask.Array.Fixed -- | a multidimensional array with a type-level shape -- --
-- >>> :set -XDataKinds -- -- >>> [1..24] :: Array '[2,3,4] Int -- [[[1, 2, 3, 4], -- [5, 6, 7, 8], -- [9, 10, 11, 12]], -- [[13, 14, 15, 16], -- [17, 18, 19, 20], -- [21, 22, 23, 24]]] ---- --
-- >>> [1,2,3] :: Array '[2,2] Int
-- *** Exception: NumHaskException {errorMessage = "shape mismatch"}
--
newtype Array s a
Array :: Vector a -> Array s a
[unArray] :: Array s a -> Vector a
-- | Use a dynamic array in a fixed context.
--
-- -- >>> import qualified NumHask.Array.Dynamic as D -- -- >>> with (D.fromFlatList [2,3,4] [1..24]) (selects (Proxy :: Proxy '[0,1]) [1,1] :: Array '[2,3,4] Int -> Array '[4] Int) -- [17, 18, 19, 20] --with :: forall a r s. HasShape s => Array a -> (Array s a -> r) -> r -- | Get shape of an Array as a value. -- --
-- >>> shape a -- [2,3,4] --shape :: forall a s. HasShape s => Array s a -> [Int] -- | convert to a dynamic array with shape at the value level. toDynamic :: HasShape s => Array s a -> Array a -- | Reshape an array (with the same number of elements). -- --
-- >>> reshape a :: Array '[4,3,2] Int -- [[[1, 2], -- [3, 4], -- [5, 6]], -- [[7, 8], -- [9, 10], -- [11, 12]], -- [[13, 14], -- [15, 16], -- [17, 18]], -- [[19, 20], -- [21, 22], -- [23, 24]]] --reshape :: forall a s s'. (Size s ~ Size s', HasShape s, HasShape s') => Array s a -> Array s' a -- | Reverse indices eg transposes the element Aijk to Akji. -- --
-- >>> index (transpose a) [1,0,0] == index a [0,0,1] -- True --transpose :: forall a s. (HasShape s, HasShape (Reverse s)) => Array s a -> Array (Reverse s) a -- | Extract the diagonal of an array. -- --
-- >>> diag (ident :: Array '[3,2] Int) -- [1, 1] --diag :: forall a s. (HasShape s, HasShape '[Minimum s]) => Array s a -> Array '[Minimum s] a -- | The identity array. -- --
-- >>> ident :: Array '[3,2] Int -- [[1, 0], -- [0, 1], -- [0, 0]] --ident :: forall a s. (HasShape s, Additive a, Multiplicative a) => Array s a -- | Create an array composed of a single value. -- --
-- >>> singleton one :: Array '[3,2] Int -- [[1, 1], -- [1, 1], -- [1, 1]] --singleton :: HasShape s => a -> Array s a -- | Select an array along dimensions. -- --
-- >>> let s = selects (Proxy :: Proxy '[0,1]) [1,1] a -- -- >>> :t s -- s :: Array '[4] Int ---- --
-- >>> s -- [17, 18, 19, 20] --selects :: forall ds s s' a. (HasShape s, HasShape ds, HasShape s', s' ~ DropIndexes s ds) => Proxy ds -> [Int] -> Array s a -> Array s' a -- | Select an index except along specified dimensions. -- --
-- >>> let s = selectsExcept (Proxy :: Proxy '[2]) [1,1] a -- -- >>> :t s -- s :: Array '[4] Int ---- --
-- >>> s -- [17, 18, 19, 20] --selectsExcept :: forall ds s s' a. (HasShape s, HasShape ds, HasShape s', s' ~ TakeIndexes s ds) => Proxy ds -> [Int] -> Array s a -> Array s' a -- | Fold along specified dimensions. -- --
-- >>> folds sum (Proxy :: Proxy '[1]) a -- [68, 100, 132] --folds :: forall ds st si so a b. (HasShape st, HasShape ds, HasShape si, HasShape so, si ~ DropIndexes st ds, so ~ TakeIndexes st ds) => (Array si a -> b) -> Proxy ds -> Array st a -> Array so b -- | Extracts dimensions to an outer layer. -- --
-- >>> let e = extracts (Proxy :: Proxy '[1,2]) a -- -- >>> :t e -- e :: Array '[3, 4] (Array '[2] Int) --extracts :: forall ds st si so a. (HasShape st, HasShape ds, HasShape si, HasShape so, si ~ DropIndexes st ds, so ~ TakeIndexes st ds) => Proxy ds -> Array st a -> Array so (Array si a) -- | Extracts except dimensions to an outer layer. -- --
-- >>> let e = extractsExcept (Proxy :: Proxy '[1,2]) a -- -- >>> :t e -- e :: Array '[2] (Array '[3, 4] Int) --extractsExcept :: forall ds st si so a. (HasShape st, HasShape ds, HasShape si, HasShape so, so ~ DropIndexes st ds, si ~ TakeIndexes st ds) => Proxy ds -> Array st a -> Array so (Array si a) -- | Join inner and outer dimension layers. -- --
-- >>> let e = extracts (Proxy :: Proxy '[1,0]) a ---- --
-- >>> :t e -- e :: Array '[3, 2] (Array '[4] Int) ---- --
-- >>> let j = joins (Proxy :: Proxy '[1,0]) e ---- --
-- >>> :t j -- j :: Array '[2, 3, 4] Int ---- --
-- >>> a == j -- True --joins :: forall ds si st so a. (HasShape st, HasShape ds, st ~ AddIndexes si ds so, HasShape si, HasShape so) => Proxy ds -> Array so (Array si a) -> Array st a -- | Maps a function along specified dimensions. -- --
-- >>> :t maps (transpose) (Proxy :: Proxy '[1]) a -- maps (transpose) (Proxy :: Proxy '[1]) a :: Array '[4, 3, 2] Int --maps :: forall ds st st' si si' so a b. (HasShape st, HasShape st', HasShape ds, HasShape si, HasShape si', HasShape so, si ~ DropIndexes st ds, so ~ TakeIndexes st ds, st' ~ AddIndexes si' ds so, st ~ AddIndexes si ds so) => (Array si a -> Array si' b) -> Proxy ds -> Array st a -> Array st' b -- | Concatenate along a dimension. -- --
-- >>> :t concatenate (Proxy :: Proxy 1) a a -- concatenate (Proxy :: Proxy 1) a a :: Array '[2, 6, 4] Int --concatenate :: forall a s0 s1 d s. (CheckConcatenate d s0 s1 s, Concatenate d s0 s1 ~ s, HasShape s0, HasShape s1, HasShape s, KnownNat d) => Proxy d -> Array s0 a -> Array s1 a -> Array s a -- | Insert along a dimension at a position. -- --
-- >>> insert (Proxy :: Proxy 2) (Proxy :: Proxy 0) a ([100..105]) -- [[[100, 1, 2, 3, 4], -- [101, 5, 6, 7, 8], -- [102, 9, 10, 11, 12]], -- [[103, 13, 14, 15, 16], -- [104, 17, 18, 19, 20], -- [105, 21, 22, 23, 24]]] --insert :: forall a s s' d i. (DropIndex s d ~ s', CheckInsert d i s, KnownNat i, KnownNat d, HasShape s, HasShape s', HasShape (Insert d s)) => Proxy d -> Proxy i -> Array s a -> Array s' a -> Array (Insert d s) a -- | Insert along a dimension at the end. -- --
-- >>> :t append (Proxy :: Proxy 0) a -- append (Proxy :: Proxy 0) a -- :: Array '[3, 4] Int -> Array '[3, 3, 4] Int --append :: forall a d s s'. (DropIndex s d ~ s', CheckInsert d (Dimension s d - 1) s, KnownNat (Dimension s d - 1), KnownNat d, HasShape s, HasShape s', HasShape (Insert d s)) => Proxy d -> Array s a -> Array s' a -> Array (Insert d s) a -- | Change the order of dimensions. -- --
-- >>> let r = reorder (Proxy :: Proxy '[2,0,1]) a -- -- >>> :t r -- r :: Array '[4, 2, 3] Int --reorder :: forall a ds s. (HasShape ds, HasShape s, HasShape (Reorder s ds), CheckReorder ds s) => Proxy ds -> Array s a -> Array (Reorder s ds) a -- | Product two arrays using the supplied binary function. -- -- For context, if the function is multiply, and the arrays are tensors, -- then this can be interpreted as a tensor product. -- -- https://en.wikipedia.org/wiki/Tensor_product -- -- The concept of a tensor product is a dense crossroad, and a complete -- treatment is elsewhere. To quote: -- -- ... the tensor product can be extended to other categories of -- mathematical objects in addition to vector spaces, such as to -- matrices, tensors, algebras, topological vector spaces, and modules. -- In each such case the tensor product is characterized by a similar -- universal property: it is the freest bilinear operation. The general -- concept of a "tensor product" is captured by monoidal categories; that -- is, the class of all things that have a tensor product is a monoidal -- category. -- --
-- >>> expand (*) v v -- [[1, 2, 3], -- [2, 4, 6], -- [3, 6, 9]] --expand :: forall s s' a b c. (HasShape s, HasShape s', HasShape ((++) s s')) => (a -> b -> c) -> Array s a -> Array s' b -> Array ((++) s s') c -- | Apply an array of functions to each array of values. -- -- This is in the spirit of the applicative functor operation (*). -- --
-- expand f a b == apply (fmap f a) b ---- --
-- >>> apply ((*) <$> v) v -- [[1, 2, 3], -- [2, 4, 6], -- [3, 6, 9]] ---- -- Arrays can't be applicative functors in haskell because the changes in -- shape are reflected in the types. -- --
-- :t apply ---- -- apply :: (HasShape s, HasShape s', HasShape (s ++ s')) => Array s -- (a -> b) -> Array s' a -> Array (s ++ s') b > :t -- (*) (*) :: Applicative f => f (a -> b) -> f a -- -> f b -- --
-- >>> let b = [1..6] :: Array '[2,3] Int -- -- >>> contract sum (Proxy :: Proxy '[1,2]) (apply (fmap (*) b) (transpose b)) -- [[14, 32], -- [32, 77]] --apply :: forall s s' a b. (HasShape s, HasShape s', HasShape ((++) s s')) => Array s (a -> b) -> Array s' a -> Array ((++) s s') b -- | Contract an array by applying the supplied (folding) function on -- diagonal elements of the dimensions. -- -- This generalises a tensor contraction by allowing the number of -- contracting diagonals to be other than 2, and allowing a binary -- operator other than multiplication. -- --
-- >>> let b = [1..6] :: Array '[2,3] Int -- -- >>> contract sum (Proxy :: Proxy '[1,2]) (expand (*) b (transpose b)) -- [[14, 32], -- [32, 77]] --contract :: forall a b s ss s' ds. (KnownNat (Minimum (TakeIndexes s ds)), HasShape (TakeIndexes s ds), HasShape s, HasShape ds, HasShape ss, HasShape s', s' ~ DropIndexes s ds, ss ~ '[Minimum (TakeIndexes s ds)]) => (Array ss a -> b) -> Proxy ds -> Array s a -> Array s' b -- | A generalisation of a dot operation, which is a multiplicative -- expansion of two arrays and sum contraction along the middle two -- dimensions. -- -- matrix multiplication -- --
-- >>> let b = [1..6] :: Array '[2,3] Int -- -- >>> dot sum (*) b (transpose b) -- [[14, 32], -- [32, 77]] ---- -- inner product -- --
-- >>> let v = [1..3] :: Array '[3] Int -- -- >>> :t dot sum (*) v v -- dot sum (*) v v :: Array '[] Int ---- --
-- >>> dot sum (*) v v -- 14 ---- -- matrix-vector multiplication (Note how the vector doesn't need to be -- converted to a row or column vector) -- --
-- >>> dot sum (*) v b -- [9, 12, 15] ---- --
-- >>> dot sum (*) b v -- [14, 32] ---- -- dot allows operation on mis-shaped matrices: -- --
-- >>> let m23 = [1..6] :: Array '[2,3] Int -- -- >>> let m12 = [1,2] :: Array '[1,2] Int -- -- >>> shape $ dot sum (*) m23 m12 -- [2,2] ---- -- the algorithm ignores excess positions within the contracting -- dimension(s): -- -- m23 shape: 2 3 -- -- m12 shape: 1 2 -- -- res shape: 2 2 -- -- FIXME: work out whether this is a feature or a bug... -- -- find instances of a vector in a matrix -- --
-- >>> let cs = fromList ("abacbaab" :: [Char]) :: Array '[4,2] Char
--
-- >>> let v = fromList ("ab" :: [Char]) :: Vector 2 Char
--
-- >>> dot (all id) (==) cs v
-- [True, False, False, True]
--
dot :: forall a b c d sa sb s' ss se. (HasShape sa, HasShape sb, HasShape (sa ++ sb), se ~ TakeIndexes (sa ++ sb) '[Rank sa - 1, Rank sa], HasShape se, KnownNat (Minimum se), KnownNat (Rank sa - 1), KnownNat (Rank sa), ss ~ '[Minimum se], HasShape ss, s' ~ DropIndexes (sa ++ sb) '[Rank sa - 1, Rank sa], HasShape s') => (Array ss c -> d) -> (a -> b -> c) -> Array sa a -> Array sb b -> Array s' d
-- | Array multiplication.
--
-- matrix multiplication
--
-- -- >>> let b = [1..6] :: Array '[2,3] Int -- -- >>> mult b (transpose b) -- [[14, 32], -- [32, 77]] ---- -- inner product -- --
-- >>> let v = [1..3] :: Array '[3] Int -- -- >>> :t mult v v -- mult v v :: Array '[] Int ---- --
-- >>> mult v v -- 14 ---- -- matrix-vector multiplication -- --
-- >>> mult v b -- [9, 12, 15] ---- --
-- >>> mult b v -- [14, 32] --mult :: forall a sa sb s' ss se. (Additive a, Multiplicative a, HasShape sa, HasShape sb, HasShape (sa ++ sb), se ~ TakeIndexes (sa ++ sb) '[Rank sa - 1, Rank sa], HasShape se, KnownNat (Minimum se), KnownNat (Rank sa - 1), KnownNat (Rank sa), ss ~ '[Minimum se], HasShape ss, s' ~ DropIndexes (sa ++ sb) '[Rank sa - 1, Rank sa], HasShape s') => Array sa a -> Array sb a -> Array s' a -- | Select elements along positions in every dimension. -- --
-- >>> let s = slice (Proxy :: Proxy '[[0,1],[0,2],[1,2]]) a -- -- >>> :t s -- s :: Array '[2, 2, 2] Int ---- --
-- >>> s -- [[[2, 3], -- [10, 11]], -- [[14, 15], -- [22, 23]]] ---- --
-- >>> let s = squeeze $ slice (Proxy :: Proxy '[ '[0], '[0], '[0]]) a -- -- >>> :t s -- s :: Array '[] Int ---- --
-- >>> s -- 1 --slice :: forall (pss :: [[Nat]]) s s' a. (HasShape s, HasShape s', KnownNatss pss, KnownNat (Rank pss), s' ~ Ranks pss) => Proxy pss -> Array s a -> Array s' a -- | Remove single dimensions. -- --
-- >>> let a = [1..24] :: Array '[2,1,3,4,1] Int -- -- >>> a -- [[[[[1], -- [2], -- [3], -- [4]], -- [[5], -- [6], -- [7], -- [8]], -- [[9], -- [10], -- [11], -- [12]]]], -- [[[[13], -- [14], -- [15], -- [16]], -- [[17], -- [18], -- [19], -- [20]], -- [[21], -- [22], -- [23], -- [24]]]]] -- -- >>> squeeze a -- [[[1, 2, 3, 4], -- [5, 6, 7, 8], -- [9, 10, 11, 12]], -- [[13, 14, 15, 16], -- [17, 18, 19, 20], -- [21, 22, 23, 24]]] ---- --
-- >>> squeeze ([1] :: Array '[1,1] Double) -- 1.0 --squeeze :: forall s t a. t ~ Squeeze s => Array s a -> Array t a -- | Wiki Scalar -- -- An Array '[] a despite being a Scalar is never-the-less a one-element -- vector under the hood. Unification of representation is unexplored. type Scalar a = Array ('[] :: [Nat]) a -- | Unwrapping scalars is probably a performance bottleneck. -- --
-- >>> let s = [3] :: Array ('[] :: [Nat]) Int
--
-- >>> fromScalar s
-- 3
--
fromScalar :: HasShape ('[] :: [Nat]) => Array ('[] :: [Nat]) a -> a
-- | Convert a number to a scalar.
--
-- -- >>> :t toScalar 2 -- toScalar 2 :: FromInteger a => Array '[] a --toScalar :: HasShape ('[] :: [Nat]) => a -> Array ('[] :: [Nat]) a -- | Wiki Vector type Vector s a = Array '[s] a -- | Wiki Matrix type Matrix m n a = Array '[m, n] a -- | Extract specialised to a matrix. -- --
-- >>> col 1 m -- [1, 5, 9] --col :: forall m n a. (KnownNat m, KnownNat n, HasShape '[m, n]) => Int -> Matrix m n a -> Vector n a -- | Extract specialised to a matrix. -- --
-- >>> row 1 m -- [4, 5, 6, 7] --row :: forall m n a. (KnownNat m, KnownNat n, HasShape '[m, n]) => Int -> Matrix m n a -> Vector n a -- | Column extraction checked at type level. -- --
-- >>> safeCol (Proxy :: Proxy 1) m -- [1, 5, 9] ---- --
-- >>> safeCol (Proxy :: Proxy 4) m -- ... -- ... index outside range -- ... --safeCol :: forall m n a j. ('True ~ CheckIndex j n, KnownNat j, KnownNat m, KnownNat n, HasShape '[m, n]) => Proxy j -> Matrix m n a -> Vector n a -- | Row extraction checked at type level. -- --
-- >>> safeRow (Proxy :: Proxy 1) m -- [4, 5, 6, 7] ---- --
-- >>> safeRow (Proxy :: Proxy 3) m -- ... -- ... index outside range -- ... --safeRow :: forall m n a j. ('True ~ CheckIndex j m, KnownNat j, KnownNat m, KnownNat n, HasShape '[m, n]) => Proxy j -> Matrix m n a -> Vector n a -- | Matrix multiplication. -- -- This is dot sum (*) specialised to matrices -- --
-- >>> let a = [1, 2, 3, 4] :: Array '[2, 2] Int -- -- >>> let b = [5, 6, 7, 8] :: Array '[2, 2] Int -- -- >>> a -- [[1, 2], -- [3, 4]] ---- --
-- >>> b -- [[5, 6], -- [7, 8]] ---- --
-- >>> mmult a b -- [[19, 22], -- [43, 50]] --mmult :: forall m n k a. (KnownNat k, KnownNat m, KnownNat n, HasShape [m, n], Ring a) => Array [m, k] a -> Array [k, n] a -> Array [m, n] a instance forall k (s :: k). Data.Traversable.Traversable (NumHask.Array.Fixed.Array s) instance forall k (s :: k) a. GHC.Generics.Generic (NumHask.Array.Fixed.Array s a) instance forall k (s :: k). Data.Foldable.Foldable (NumHask.Array.Fixed.Array s) instance forall k (s :: k). GHC.Base.Functor (NumHask.Array.Fixed.Array s) instance forall k (s :: k) a. GHC.Classes.Ord a => GHC.Classes.Ord (NumHask.Array.Fixed.Array s a) instance forall k (s :: k) a. GHC.Classes.Eq a => GHC.Classes.Eq (NumHask.Array.Fixed.Array s a) instance (NumHask.Algebra.Multiplicative.Multiplicative a, NumHask.Algebra.Ring.Distributive a, NumHask.Algebra.Additive.Subtractive a, GHC.TypeNats.KnownNat m, NumHask.Array.Shape.HasShape '[m, m]) => NumHask.Algebra.Multiplicative.Multiplicative (NumHask.Array.Fixed.Matrix m m a) instance (NumHask.Array.Shape.HasShape s, GHC.Show.Show a) => GHC.Show.Show (NumHask.Array.Fixed.Array s a) instance NumHask.Array.Shape.HasShape s => Data.Distributive.Distributive (NumHask.Array.Fixed.Array s) instance NumHask.Array.Shape.HasShape s => Data.Functor.Rep.Representable (NumHask.Array.Fixed.Array s) instance (NumHask.Algebra.Additive.Additive a, NumHask.Array.Shape.HasShape s) => NumHask.Algebra.Additive.Additive (NumHask.Array.Fixed.Array s a) instance (NumHask.Algebra.Additive.Subtractive a, NumHask.Array.Shape.HasShape s) => NumHask.Algebra.Additive.Subtractive (NumHask.Array.Fixed.Array s a) instance (NumHask.Array.Shape.HasShape s, NumHask.Algebra.Multiplicative.Multiplicative a) => NumHask.Algebra.Module.MultiplicativeAction (NumHask.Array.Fixed.Array s a) a instance (NumHask.Array.Shape.HasShape s, NumHask.Algebra.Additive.Additive a) => NumHask.Algebra.Module.AdditiveAction (NumHask.Array.Fixed.Array s a) a instance (NumHask.Array.Shape.HasShape s, NumHask.Algebra.Additive.Subtractive a) => NumHask.Algebra.Module.SubtractiveAction (NumHask.Array.Fixed.Array s a) a instance (NumHask.Array.Shape.HasShape s, NumHask.Algebra.Multiplicative.Divisive a) => NumHask.Algebra.Module.DivisiveAction (NumHask.Array.Fixed.Array s a) a instance (NumHask.Array.Shape.HasShape s, NumHask.Algebra.Lattice.JoinSemiLattice a) => NumHask.Algebra.Lattice.JoinSemiLattice (NumHask.Array.Fixed.Array s a) instance (NumHask.Array.Shape.HasShape s, NumHask.Algebra.Lattice.MeetSemiLattice a) => NumHask.Algebra.Lattice.MeetSemiLattice (NumHask.Array.Fixed.Array s a) instance (NumHask.Array.Shape.HasShape s, NumHask.Algebra.Additive.Subtractive a, NumHask.Algebra.Metric.Epsilon a) => NumHask.Algebra.Metric.Epsilon (NumHask.Array.Fixed.Array s a) instance NumHask.Array.Shape.HasShape s => GHC.Exts.IsList (NumHask.Array.Fixed.Array s a) -- | Multi-dimensional arrays for numhask. module NumHask.Array