numhask-array-0.11.0.1: Multi-dimensional arrays.
Safe HaskellSafe-Inferred
LanguageGHC2021

NumHask.Array.Fixed

Description

Arrays with a fixed shape (known shape at compile time).

Synopsis

Documentation

>>> :set -XDataKinds
>>> :set -XOverloadedLists
>>> :set -XTypeFamilies
>>> :set -XFlexibleContexts
>>> :set -XRebindableSyntax
>>> import NumHask.Prelude
>>> import NumHask.Array.Fixed
>>> import GHC.TypeLits (Nat)
>>> 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

>>> :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"}
[[

Constructors

Array 

Fields

Instances

Instances details
HasShape s => Representable (Array s) Source # 
Instance details

Defined in NumHask.Array.Fixed

Associated Types

type Rep (Array s) #

Methods

tabulate :: (Rep (Array s) -> a) -> Array s a #

index :: Array s a -> Rep (Array s) -> a #

Foldable (Array s) Source # 
Instance details

Defined in NumHask.Array.Fixed

Methods

fold :: Monoid m => Array s m -> m #

foldMap :: Monoid m => (a -> m) -> Array s a -> m #

foldMap' :: Monoid m => (a -> m) -> Array s a -> m #

foldr :: (a -> b -> b) -> b -> Array s a -> b #

foldr' :: (a -> b -> b) -> b -> Array s a -> b #

foldl :: (b -> a -> b) -> b -> Array s a -> b #

foldl' :: (b -> a -> b) -> b -> Array s a -> b #

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

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

toList :: Array s a -> [a] #

null :: Array s a -> Bool #

length :: Array s a -> Int #

elem :: Eq a => a -> Array s a -> Bool #

maximum :: Ord a => Array s a -> a #

minimum :: Ord a => Array s a -> a #

sum :: Num a => Array s a -> a #

product :: Num a => Array s a -> a #

Traversable (Array s) Source # 
Instance details

Defined in NumHask.Array.Fixed

Methods

traverse :: Applicative f => (a -> f b) -> Array s a -> f (Array s b) #

sequenceA :: Applicative f => Array s (f a) -> f (Array s a) #

mapM :: Monad m => (a -> m b) -> Array s a -> m (Array s b) #

sequence :: Monad m => Array s (m a) -> m (Array s a) #

Functor (Array s) Source # 
Instance details

Defined in NumHask.Array.Fixed

Methods

fmap :: (a -> b) -> Array s a -> Array s b #

(<$) :: a -> Array s b -> Array s a #

HasShape s => Distributive (Array s) Source # 
Instance details

Defined in NumHask.Array.Fixed

Methods

distribute :: Functor f => f (Array s a) -> Array s (f a) #

collect :: Functor f => (a -> Array s b) -> f a -> Array s (f b) #

distributeM :: Monad m => m (Array s a) -> Array s (m a) #

collectM :: Monad m => (a -> Array s b) -> m a -> Array s (m b) #

HasShape s => IsList (Array s a) Source # 
Instance details

Defined in NumHask.Array.Fixed

Associated Types

type Item (Array s a) #

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

Generic (Array s a) Source # 
Instance details

Defined in NumHask.Array.Fixed

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 #

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

Defined in NumHask.Array.Fixed

Methods

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

show :: Array s a -> String #

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

Eq a => Eq (Array s a) Source # 
Instance details

Defined in NumHask.Array.Fixed

Methods

(==) :: Array s a -> Array s a -> Bool #

(/=) :: Array s a -> Array s a -> Bool #

Ord a => Ord (Array s a) Source # 
Instance details

Defined in NumHask.Array.Fixed

Methods

compare :: Array s a -> Array s a -> Ordering #

(<) :: Array s a -> Array s a -> Bool #

(<=) :: Array s a -> Array s a -> Bool #

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

(>=) :: Array s a -> Array s a -> Bool #

max :: Array s a -> Array s a -> Array s a #

min :: Array s a -> Array s a -> Array s a #

Additive a => AdditiveAction (Array s a) Source # 
Instance details

Defined in NumHask.Array.Fixed

Associated Types

type AdditiveScalar (Array s a) #

Methods

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

Divisive a => DivisiveAction (Array s a) Source # 
Instance details

Defined in NumHask.Array.Fixed

Methods

(|/) :: Array s a -> Scalar (Array s a) -> Array s a #

Multiplicative a => MultiplicativeAction (Array s a) Source # 
Instance details

Defined in NumHask.Array.Fixed

Associated Types

type Scalar (Array s a) #

Methods

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

Subtractive a => SubtractiveAction (Array s a) Source # 
Instance details

Defined in NumHask.Array.Fixed

Methods

(|-) :: Array s a -> AdditiveScalar (Array s a) -> Array s a #

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

Defined in NumHask.Array.Fixed

Methods

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

zero :: Array s a #

(Subtractive a, HasShape s) => Subtractive (Array s a) Source # 
Instance details

Defined in NumHask.Array.Fixed

Methods

negate :: Array s a -> Array s a #

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

(HasShape s, JoinSemiLattice a) => JoinSemiLattice (Array s a) Source # 
Instance details

Defined in NumHask.Array.Fixed

Methods

(\/) :: Array s a -> Array s a -> Array s a #

(HasShape s, MeetSemiLattice a) => MeetSemiLattice (Array s a) Source # 
Instance details

Defined in NumHask.Array.Fixed

Methods

(/\) :: Array s a -> Array s a -> Array s a #

(HasShape s, Subtractive a, Epsilon a) => Epsilon (Array s a) Source # 
Instance details

Defined in NumHask.Array.Fixed

Methods

epsilon :: Array s a #

(Multiplicative a, Distributive a, Subtractive a, Eq a, ExpField a, KnownNat m, HasShape '[m, m]) => Divisive (Matrix m m a) Source # 
Instance details

Defined in NumHask.Array.Fixed

Methods

recip :: Matrix m m a -> Matrix m m a #

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

(Multiplicative a, Distributive a, Subtractive a, KnownNat m, HasShape '[m, m]) => Multiplicative (Matrix m m a) Source # 
Instance details

Defined in NumHask.Array.Fixed

Methods

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

one :: Matrix m m a #

type Rep (Array s) Source # 
Instance details

Defined in NumHask.Array.Fixed

type Rep (Array s) = [Int]
type Item (Array s a) Source # 
Instance details

Defined in NumHask.Array.Fixed

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

Defined in NumHask.Array.Fixed

type Rep (Array s a) = D1 ('MetaData "Array" "NumHask.Array.Fixed" "numhask-array-0.11.0.1-9YMpczlHMpNFmXfCLzzFiC" 'True) (C1 ('MetaCons "Array" 'PrefixI 'True) (S1 ('MetaSel ('Just "unArray") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 (Vector a))))
type AdditiveScalar (Array s a) Source # 
Instance details

Defined in NumHask.Array.Fixed

type AdditiveScalar (Array s a) = a
type Scalar (Array s a) Source # 
Instance details

Defined in NumHask.Array.Fixed

type Scalar (Array s a) = a

Conversion

with :: forall a r s. HasShape s => Array a -> (Array s a -> r) -> r Source #

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]

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 => Array s a -> Array a Source #

convert to a dynamic array with shape at the value level.

Operators

takes :: forall s s' a. (HasShape s, HasShape s') => Array s a -> Array s' a Source #

Takes the top-most elements according to the new dimension.

>>> takes a :: Array '[2,2,3] Int
[[[1, 2, 3],
  [5, 6, 7]],
 [[13, 14, 15],
  [17, 18, 19]]]

reshape :: forall a s s'. (Size s ~ Size s', HasShape s, HasShape s') => 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. (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

indices :: forall s. HasShape s => Array s [Int] Source #

Indices of an Array.

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

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

The identity array.

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

sequent :: forall s. HasShape s => Array s Int Source #

An array of sequential Ints

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

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

Extract the diagonal of an array.

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

undiag :: forall a s. (HasShape s, Additive a, HasShape ((++) s s)) => Array s a -> Array ((++) s s) a Source #

Expand the array to form a diagonal array

>>> undiag ([1,1] :: Array '[2] Int)
[[1, 0],
 [0, 1]]

singleton :: 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) => 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) => 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) => (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]

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) Source #

Extracts dimensions to an outer layer.

>>> let e = extracts (Proxy :: Proxy '[1,2]) a
>>> :t e
e :: Array [3, 4] (Array '[2] 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) Source #

Extracts except dimensions to an outer layer.

>>> let e = extractsExcept (Proxy :: Proxy '[1,2]) a
>>> :t e
e :: Array '[2] (Array [3, 4] Int)

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 Source #

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

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 Source #

Maps a function along specified dimensions.

>>> :t maps (transpose) (Proxy :: Proxy '[1]) a
maps (transpose) (Proxy :: Proxy '[1]) a :: Array [4, 3, 2] 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 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)) => 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)) => 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) => 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')) => (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]]

Alternatively, expand can be understood as representing the permutation of element pairs of two arrays, so like the Applicative List instance.

>>> i2 = indices :: Array '[2,2] [Int]
>>> expand (,) i2 i2
[[[[([0,0],[0,0]), ([0,0],[0,1])],
   [([0,0],[1,0]), ([0,0],[1,1])]],
  [[([0,1],[0,0]), ([0,1],[0,1])],
   [([0,1],[1,0]), ([0,1],[1,1])]]],
 [[[([1,0],[0,0]), ([1,0],[0,1])],
   [([1,0],[1,0]), ([1,0],[1,1])]],
  [[([1,1],[0,0]), ([1,1],[0,1])],
   [([1,1],[1,0]), ([1,1],[1,1])]]]]

expandr :: 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 Source #

Like expand, but permutes the first array first, rather than the second.

>>> expand (,) v (v |+ 3)
[[(1,4), (1,5), (1,6)],
 [(2,4), (2,5), (2,6)],
 [(3,4), (3,5), (3,6)]]
>>> expandr (,) v (v |+ 3)
[[(1,4), (2,4), (3,4)],
 [(1,5), (2,5), (3,5)],
 [(1,6), (2,6), (3,6)]]

apply :: forall s s' a b. (HasShape s, HasShape s', HasShape ((++) s s')) => Array s (a -> b) -> Array s' a -> Array ((++) s s') b Source #

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

Fixed Arrays can't be applicative functors 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]]

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 Source #

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

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 Source #

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]

Array elements don't have to be numbers:

>>> x1 = (show <$> [1..4]) :: Array '[2,2] String
>>> x2 = (show <$> [5..8]) :: Array '[2,2] String
>>> x1
[["1", "2"],
 ["3", "4"]]
>>> x2
[["5", "6"],
 ["7", "8"]]
>>> import Data.List (intercalate)
>>> dot (intercalate "+" . toList) (\a b -> a <> "*" <> b) x1 x2
[["1*5+2*7", "1*6+2*8"],
 ["3*5+4*7", "3*6+4*8"]]

dot allows operation on mis-shaped matrices. The algorithm ignores excess positions within the contracting dimension(s):

>>> let m23 = [1..6] :: Array '[2,3] Int
>>> let m12 = [1,2] :: Array '[1,2] Int
>>> shape $ dot sum (*) m23 m12
[2,2]

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]

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 Source #

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]

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

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

Unwrapping scalars is probably a performance bottleneck.

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

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

Convert a number to a scalar.

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

Vector

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

sequentv :: forall n. KnownNat n => Vector n Int Source #

Vector specialisation of sequent

Matrix

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

col :: forall m n 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. (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. ('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. ('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) => 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]]

chol :: (KnownNat n, ExpField a) => Array '[n, n] a -> Array '[n, n] a Source #

cholesky decomposition

Uses the Cholesky-Crout algorithm.

invtri :: forall a n. (KnownNat n, ExpField a, Eq a) => Array '[n, n] a -> Array '[n, n] a Source #