numhask-array-0.6.0: n-dimensional arrays

Safe HaskellNone
LanguageHaskell2010

NumHask.Array.HMatrix

Contents

Description

Arrays with a fixed shape, with a HMatrix representation.

Synopsis

Documentation

>>> :set -XDataKinds
>>> :set -XOverloadedLists
>>> :set -XTypeFamilies
>>> :set -XFlexibleContexts
>>> let s = [1] :: Array ('[] :: [Nat]) Int -- scalar
>>> let v = [1,2,3] :: Array '[3] Int       -- vector
>>> let m = [0..11] :: Array '[3,4] Int     -- matrix
>>> let a = [1..24] :: Array '[2,3,4] Int

newtype Array s a Source #

a multidimensional array with a type-level shape

>>> let a = [1..24] :: Array '[2,3,4] 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]]]
>>> [1,2,3] :: Array '[2,2] Int
[[*** Exception: NumHaskException {errorMessage = "shape mismatch"}

Constructors

Array 

Fields

Instances
(HasShape s, Element a) => IsList (Array s a) Source #

from flat list

Instance details

Defined in NumHask.Array.HMatrix

Associated Types

type Item (Array s a) :: Type #

Methods

fromList :: [Item (Array s a)] -> Array s a #

fromListN :: Int -> [Item (Array s a)] -> Array s a #

toList :: Array s a -> [Item (Array s a)] #

(Show a, Element a) => Show (Array s a) Source # 
Instance details

Defined in NumHask.Array.HMatrix

Methods

showsPrec :: Int -> Array s a -> ShowS #

show :: Array s a -> String #

showList :: [Array s a] -> ShowS #

Generic (Array s a) Source # 
Instance details

Defined in NumHask.Array.HMatrix

Associated Types

type Rep (Array s a) :: Type -> Type #

Methods

from :: Array s a -> Rep (Array s a) x #

to :: Rep (Array s a) x -> Array s a #

(Storable a, NFData a) => NFData (Array s a) Source # 
Instance details

Defined in NumHask.Array.HMatrix

Methods

rnf :: Array s a -> () #

(HasShape s, Multiplicative a, Container Vector a, Num a) => MultiplicativeAction (Array s a) Source # 
Instance details

Defined in NumHask.Array.HMatrix

Methods

(.*) :: Array s a -> Actor (Array s a) -> Array s a #

(*.) :: Actor (Array s a) -> Array s a -> Array s a #

(Multiplicative a, HasShape s, Container Vector a, Num (Vector a), Num a) => Multiplicative (Array s a) Source # 
Instance details

Defined in NumHask.Array.HMatrix

Methods

(*) :: Array s a -> Array s a -> Array s a #

one :: Array s a #

(Additive a, HasShape s, Container Vector a, Num a) => Additive (Array s a) Source # 
Instance details

Defined in NumHask.Array.HMatrix

Methods

(+) :: Array s a -> Array s a -> Array s a #

zero :: Array s a #

(Multiplicative a, Distributive a, Subtractive a, Numeric a, KnownNat m, HasShape (m ': (m ': ([] :: [Nat]))), Element a, Container Vector a) => Multiplicative (Matrix m m a) Source # 
Instance details

Defined in NumHask.Array.HMatrix

Methods

(*) :: Matrix m m a -> Matrix m m a -> Matrix m m a #

one :: Matrix m m a #

type Rep (Array s a) Source # 
Instance details

Defined in NumHask.Array.HMatrix

type Rep (Array s a) = D1 (MetaData "Array" "NumHask.Array.HMatrix" "numhask-array-0.6.0-5rM7df5wk8a2ZzOnTm4fcR" True) (C1 (MetaCons "Array" PrefixI True) (S1 (MetaSel (Just "unArray") NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 (Matrix a))))
type Item (Array s a) Source # 
Instance details

Defined in NumHask.Array.HMatrix

type Item (Array s a) = a
type Actor (Array s a) Source # 
Instance details

Defined in NumHask.Array.HMatrix

type Actor (Array s a) = a
type Actor (Array s a) Source # 
Instance details

Defined in NumHask.Array.HMatrix

type Actor (Array s a) = a

Representation

index :: forall s a. (HasShape s, Element a, Container Vector a) => Array s a -> [Int] -> a Source #

with no fmap, we supply the representable API

tabulate :: forall s a. (HasShape s, Element a) => ([Int] -> a) -> Array s a Source #

tabulate an array with a generating function

>>> tabulate [2,3,4] ((1+) . flatten [2,3,4]) == a
True

Conversion

shape :: forall a s. HasShape s => Array s a -> [Int] Source #

Get shape of an Array as a value.

>>> shape a
[2,3,4]

toDynamic :: (HasShape s, Element a) => Array s a -> Array a Source #

Convert to a dynamic array.

toFixed :: (HasShape s, Element a) => Array s a -> Array s a Source #

Convert to a fixed array.

fromFixed :: (HasShape s, Element a) => Array s a -> Array s a Source #

Convert from a fixed array.

Operators

reshape :: forall a s s'. (Size s ~ Size s', HasShape s, HasShape s', Container Vector a) => Array s a -> Array s' a Source #

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]]]

transpose :: forall a s. (Element a, Container Vector a, HasShape s, HasShape (Reverse s)) => Array s a -> Array (Reverse s) a Source #

Reverse indices eg transposes the element Aijk to Akji.

>>> index (transpose a) [1,0,0] == index a [0,0,1]
True

diag :: forall a s. (HasShape s, HasShape '[Minimum s], Element a, Container Vector a) => Array s a -> Array '[Minimum s] a Source #

Extract the diagonal of an array.

>>> diag (ident :: Array '[3,2] Int)
[1, 1]

ident :: forall a s. (Element a, Container Vector a, HasShape s, Additive a, Multiplicative a) => Array s a Source #

The identity array.

>>> ident :: Array '[3,2] Int
[[1, 0],
 [0, 1],
 [0, 0]]

singleton :: (Element a, Container Vector a, HasShape s) => a -> Array s a Source #

Create an array composed of a single value.

>>> singleton one :: Array '[3,2] Int
[[1, 1],
 [1, 1],
 [1, 1]]

selects :: forall ds s s' a. (HasShape s, HasShape ds, HasShape s', s' ~ DropIndexes s ds, Element a, Container Vector a) => Proxy ds -> [Int] -> Array s a -> Array s' a Source #

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]

selectsExcept :: forall ds s s' a. (HasShape s, HasShape ds, HasShape s', s' ~ TakeIndexes s ds, Element a, Container Vector a) => Proxy ds -> [Int] -> Array s a -> Array s' a Source #

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]

folds :: forall ds st si so a b. (HasShape st, HasShape ds, HasShape si, HasShape so, si ~ DropIndexes st ds, so ~ TakeIndexes st ds, Element a, Container Vector a, Element b, Container Vector b) => (Array si a -> b) -> Proxy ds -> Array st a -> Array so b Source #

Fold along specified dimensions.

>>> folds sum (Proxy :: Proxy '[1]) a
[68, 100, 132]

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, Element a, Container Vector a) => Proxy d -> Array s0 a -> Array s1 a -> Array s a Source #

Concatenate along a dimension.

>>> :t concatenate (Proxy :: Proxy 1) a a
concatenate (Proxy :: Proxy 1) a a :: Array '[2, 6, 4] Int

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), Element a, Container Vector a) => Proxy d -> Proxy i -> Array s a -> Array s' a -> Array (Insert d s) a Source #

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]]]

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), Element a, Container Vector a) => Proxy d -> Array s a -> Array s' a -> Array (Insert d s) a Source #

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

reorder :: forall a ds s. (HasShape ds, HasShape s, HasShape (Reorder s ds), CheckReorder ds s, Element a, Container Vector a) => Proxy ds -> Array s a -> Array (Reorder s ds) a Source #

Change the order of dimensions.

>>> let r = reorder (Proxy :: Proxy '[2,0,1]) a
>>> :t r
r :: Array '[4, 2, 3] Int

expand :: forall s s' a b c. (HasShape s, HasShape s', HasShape ((++) s s'), Element a, Container Vector a, Element b, Container Vector b, Element c) => (a -> b -> c) -> Array s a -> Array s' b -> Array ((++) s s') c Source #

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]]

slice :: forall (pss :: [[Nat]]) s s' a. (HasShape s, HasShape s', KnownNatss pss, KnownNat (Rank pss), s' ~ Ranks pss, Element a, Container Vector a) => Proxy pss -> Array s a -> Array s' a Source #

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

squeeze :: forall s t a. t ~ Squeeze s => Array s a -> Array t a Source #

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

Scalar

type Scalar a = Array ('[] :: [Nat]) a Source #

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.

fromScalar :: (Element a, Container Vector a, HasShape ('[] :: [Nat])) => Array ('[] :: [Nat]) a -> a Source #

Unwrapping scalars is probably a performance bottleneck.

>>> let s = [3] :: Array ('[] :: [Nat]) Int
>>> fromScalar s
3

toScalar :: (Element a, Container Vector a, HasShape ('[] :: [Nat])) => a -> Array ('[] :: [Nat]) a Source #

Convert a number to a scalar.

>>> :t toScalar 2
toScalar 2 :: Num a => Array '[] a

Vector

type Vector s a = Array '[s] a Source #

Matrix

type Matrix m n a = Array '[m, n] a Source #

col :: forall m n a. (Element a, Container Vector a, KnownNat m, KnownNat n, HasShape '[m, n]) => Int -> Matrix m n a -> Vector n a Source #

Extract specialised to a matrix.

>>> col 1 m
[1, 5, 9]

row :: forall m n a. (Element a, Container Vector a, KnownNat m, KnownNat n, HasShape '[m, n]) => Int -> Matrix m n a -> Vector n a Source #

Extract specialised to a matrix.

>>> row 1 m
[4, 5, 6, 7]

safeCol :: forall m n a j. (Element a, Container Vector a, True ~ CheckIndex j n, KnownNat j, KnownNat m, KnownNat n, HasShape '[m, n]) => Proxy j -> Matrix m n a -> Vector n a Source #

Column extraction checked at type level.

>>> safeCol (Proxy :: Proxy 1) m
[1, 5, 9]
>>> safeCol (Proxy :: Proxy 4) m
...
... index outside range
...

safeRow :: forall m n a j. (Element a, Container Vector a, True ~ CheckIndex j m, KnownNat j, KnownNat m, KnownNat n, HasShape '[m, n]) => Proxy j -> Matrix m n a -> Vector n a Source #

Row extraction checked at type level.

>>> safeRow (Proxy :: Proxy 1) m
[4, 5, 6, 7]
>>> safeRow (Proxy :: Proxy 3) m
...
... index outside range
...

mmult :: forall m n k a. (KnownNat k, KnownNat m, KnownNat n, HasShape [m, n], Ring a, Numeric a) => Array [m, k] a -> Array [k, n] a -> Array [m, n] a Source #

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]]