Ξυ³h$ItF1¦      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ‘’£€₯None'(-./>?ΐΑΒΙΤΦΧΩμ W numhask-arrayReflect a list of list of Nats numhask-arrayReflect a list of Nats$ numhask-array™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.' numhask-arrayNumber of dimensions( numhask-array&The shape of a list of element indexes) numhask-arrayNumber of elements* numhask-array.convert from n-dim shape index to a flat indexflatten [2,3,4] [1,1,1]17flatten [] [1,1,1]0+ numhask-array*convert from a flat index to a shape indexshapen [2,3,4] 17[1,1,1], numhask-arraycheckIndex i n checks if i& is a valid index of a list of length n- numhask-arraycheckIndexes is n check if is' are valid indexes of a list of length n. numhask-array,dimension i is the i'th dimension of a Shape/ numhask-arrayminimum value in a list0 numhask-array$drop the i'th dimension from a shapedropIndex [2, 3, 4] 1[2,4]1 numhask-arrayaddIndex s i d adds a new dimension to shape s at position iaddIndex [2,4] 1 3[2,3,4]2 numhask-array΄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. deletionsposRelative [0,1][0,0] additions%reverse (posRelative (reverse [1,0]))[0,0]3 numhask-arrayθ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]4 numhask-array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]5 numhask-array4take list of dimensions according to position lists.takeIndexes [2,3,4] [2,0][4,2]6 numhask-arrayΤturn a list of included positions for a given rank into a list of excluded positionsexclude 3 [1,2][0]7 numhask-array concatenateconcatenate' 1 [2,3,4] [2,3,4][2,6,4]8 numhask-array incAt d s increments the index at d of shape s by one.9 numhask-array decAt d s decrements the index at d of shape s by one.: numhask-array reorder' s i" reorders the dimensions of shape s" according to a list of positions ireorder' [2,3,4] [2,0,1][4,2,3]; numhask-arrayremove 1's from a list<  !"#$%&'()*+,-./0123456789:;<$%&"# '!( ).*+/,-1024356 7  :;89None./8:>?ΐΑΒΙΤΧΩ$πC numhask-array1a multidimensional array with a value-level shape1let a = fromFlatList [2,3,4] [1..24] :: Array Inta[[[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]], [[13, 14, 15, 16], [17, 18, 19, 20], [21, 22, 23, 24]]]G numhask-arrayconvert from a list!fromFlatList [2,3,4] [1..24] == aTrueH numhask-arrayextract an element at index iindex a [1,2,3]24I numhask-array,tabulate an array with a generating function.tabulate [2,3,4] ((1+) . flatten [2,3,4]) == aTrueJ numhask-array4Reshape 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]]]K numhask-array+Reverse indices eg transposes the element Aijk to Akji..index (transpose a) [1,0,0] == index a [0,0,1]TrueL numhask-arrayThe identity array. ident [3,2][[1, 0], [0, 1], [0, 0]]M numhask-array!Extract the diagonal of an array.diag (ident [3,2])[1, 1]N numhask-array+Create an array composed of a single value.singleton [3,2] one[[1, 1], [1, 1], [1, 1]]O numhask-array!Select an array along dimensions.let s = selects [0,1] [1,1] as[17, 18, 19, 20]P numhask-arraySelect an index except along specified dimensions!let s = selectsExcept [2] [1,1] as[17, 18, 19, 20]Q numhask-array Fold along specified dimensions.folds sum [1] a[68, 100, 132]R numhask-array&Extracts dimensions to an outer layer.let e = extracts [1,2] ashape <$> extracts [0] a[[3,4], [3,4]]S numhask-array&Join inner and outer dimension layers.let e = extracts [1,0] alet j = joins [1,0] ea == jTrueT numhask-array+Maps a function along specified dimensions.shape $ maps (transpose) [1] a[4,3,2]U numhask-arrayConcatenate along a dimension.shape $ concatenate 1 a a[2,6,4]V numhask-array'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]]]W numhask-array$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]]]X numhask-arraychange the order of dimensionslet r = reorder [2,0,1] ar [[[1, 5, 9], [13, 17, 21]], [[2, 6, 10], [14, 18, 22]], [[3, 7, 11], [15, 19, 23]], [[4, 8, 12], [16, 20, 24]]]Y numhask-array6Product 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]]Z numhask-arrayε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]][ numhask-array‹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 Intdot sum (*) b (transpose b) [[14, 32], [32, 77]] inner product,let v = fromFlatList [3] [1..3] :: Array Intdot sum (*) v v14ρmatrix-vector multiplication Note that an `Array Int` with shape [3] is neither a row vector nor column vector. [Ξ 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]\ numhask-arrayArray multiplication.matrix multiplication.let b = fromFlatList [2,3] [1..6] :: Array Intmult b (transpose b) [[14, 32], [32, 77]] inner product,let v = fromFlatList [3] [1..3] :: Array Intmult v v14matrix-vector multiplicationmult v b [9, 12, 15]mult b v[14, 32]] numhask-array3Select elements along positions in every dimension.#let s = slice [[0,1],[0,2],[1,2]] as [[[2, 3], [10, 11]], [[14, 15], [22, 23]]]^ numhask-arrayRemove single dimensions.6let a' = fromFlatList [2,1,3,4,1] [1..24] :: Array Intshape $ squeeze a'[2,3,4]_ numhask-array8Unwrapping scalars is probably a performance bottleneck.(let s = fromFlatList [] [3] :: Array Int fromScalar s3` numhask-arrayConvert a number to a scalar. :t toScalar 2toScalar 2 :: Num a => Array aa numhask-array Extract specialised to a matrix.row 1 m [4, 5, 6, 7]b numhask-arrayextract specialised to a matrixcol 1 m [1, 5, 9]c numhask-arraymatrix multiplication+This is dot sum (*) specialised to matrices4let a = fromFlatList [2,2] [1, 2, 3, 4] :: Array Int4let b = fromFlatList [2,2] [5, 6, 7, 8] :: Array Inta[[1, 2], [3, 4]]b[[5, 6], [7, 8]] mmult a b [[19, 22], [43, 50]]!CDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abc!CDEFGHIJKMLNOPQRSTUVWXYZ[\]^_`bacNone./5678>?ΐΑΒΙΞΤΦΧΩμE1#l numhask-array 2https://en.wikipedia.org/wiki/Matrix_(mathematics) Wiki Matrixm numhask-array >https://en.wikipedia.org/wiki/Vector_(mathematics_and_physics) Wiki Vectorn numhask-array 3https://en.wikipedia.org/wiki/Scalarr_(mathematics) 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.o numhask-array0a multidimensional array with a type-level shape%let a = [1..24] :: Array '[2,3,4] Inta[[[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"}r numhask-array!Get shape of an Array as a value.shape a[2,3,4]s numhask-array9convert to a dynamic array with shape at the value level.t numhask-array'Use a dynamic array in a fixed context.υ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]u numhask-array4Reshape 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]]]v numhask-array+Reverse indices eg transposes the element Aijk to Akji..index (transpose a) [1,0,0] == index a [0,0,1]Truew numhask-arrayThe identity array.ident :: Array '[3,2] Int[[1, 0], [0, 1], [0, 0]]x numhask-array!Extract the diagonal of an array. diag (ident :: Array '[3,2] Int)[1, 1]y numhask-array+Create an array composed of a single value.!singleton one :: Array '[3,2] Int[[1, 1], [1, 1], [1, 1]]z numhask-array!Select an array along dimensions./let s = selects (Proxy :: Proxy '[0,1]) [1,1] a:t ss :: Array '[4] Ints[17, 18, 19, 20]{ numhask-arraySelect an index except along specified dimensions.3let s = selectsExcept (Proxy :: Proxy '[2]) [1,1] a:t ss :: Array '[4] Ints[17, 18, 19, 20]| numhask-array Fold along specified dimensions.!folds sum (Proxy :: Proxy '[1]) a[68, 100, 132]} numhask-array&Extracts dimensions to an outer layer.*let e = extracts (Proxy :: Proxy '[1,2]) a:t e#e :: Array '[3, 4] (Array '[2] Int)~ numhask-array&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 jj :: Array '[2, 3, 4] Inta == jTrue numhask-array+Maps a function along specified dimensions.+:t maps (transpose) (Proxy :: Proxy '[1]) aΐmaps (transpose) (Proxy :: Proxy '[1]) a :: Array '[4, 3, 2] Int€ numhask-arrayConcatenate along a dimension.%:t concatenate (Proxy :: Proxy 1) a a:concatenate (Proxy :: Proxy 1) a a :: Array '[2, 6, 4] Int numhask-array'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]]]‚ numhask-array$Insert along a dimension at the end.:t append (Proxy :: Proxy 0) aappend (Proxy :: Proxy 0) a. :: Array '[3, 4] Int -> Array '[3, 3, 4] Intƒ numhask-arrayChange the order of dimensions.+let r = reorder (Proxy :: Proxy '[2,0,1]) a:t rr :: Array '[4, 2, 3] Int„ numhask-array6Product 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]]… numhask-arrayε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]]† numhask-array‹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] Intdot 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 '[] Intdot sum (*) v v14κ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] Intshape $ dot sum (*) m23 m12[2,2]Λthe algorithm ignores excess positions within the contracting dimension(s):m23 shape: 2 3m12 shape: 1 2res shape: 2 25FIXME: 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] Char2let v = fromList ("ab" :: [Char]) :: Vector 2 Chardot (all id) (==) cs v[True, False, False, True]‡ numhask-arrayArray multiplication.matrix multiplication"let b = [1..6] :: Array '[2,3] Intmult b (transpose b) [[14, 32], [32, 77]] inner product let v = [1..3] :: Array '[3] Int :t mult v vmult v v :: Array '[] Intmult v v14matrix-vector multiplicationmult v b [9, 12, 15]mult b v[14, 32]ˆ numhask-array3Select elements along positions in every dimension.5let s = slice (Proxy :: Proxy '[[0,1],[0,2],[1,2]]) a:t ss :: Array '[2, 2, 2] Ints [[[2, 3], [10, 11]], [[14, 15], [22, 23]]]?let s = squeeze $ slice (Proxy :: Proxy '[ '[0], '[0], '[0]]) a:t ss :: Array '[] Ints1‰ numhask-arrayRemove single dimensions.)let a = [1..24] :: Array '[2,1,3,4,1] Inta[[[[[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Š numhask-array8Unwrapping scalars is probably a performance bottleneck.'let s = [3] :: Array ('[] :: [Nat]) Int fromScalar s3‹ numhask-arrayConvert a number to a scalar. :t toScalar 2"toScalar 2 :: Num a => Array '[] aŒ numhask-array Extract specialised to a matrix.row 1 m [4, 5, 6, 7] numhask-array%Row extraction checked at type level.safeRow (Proxy :: Proxy 1) m [4, 5, 6, 7]safeRow (Proxy :: Proxy 3) m...... index outside range...Ž numhask-array Extract specialised to a matrix.col 1 m [1, 5, 9] numhask-array(Column extraction checked at type level.safeCol (Proxy :: Proxy 1) m [1, 5, 9]safeCol (Proxy :: Proxy 4) m...... index outside range... numhask-arrayMatrix 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] Inta[[1, 2], [3, 4]]b[[5, 6], [7, 8]] mmult a b [[19, 22], [43, 50]]%lmnopqrstuvwxyz{|}~€‚ƒ„…†‡ˆ‰Š‹ŒŽ%opqtrsuvxwyz{|}~€‚ƒ„…†‡ˆ‰nŠ‹mlŽŒNoneEΊα  !"#$%&'()*+,-./0123456789:;lmnopqrstuvwxyz{|}~€‚ƒ„…†‡ˆ‰Š‹ŒŽ¦      !"#$%&'())*+,-./0123456789:;<=>?@ABCDEFGGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqGGIHrsMNOPQRSTUVWXYZ[\]^_`abcdteufvwxyz{|}~€g‚klmjinhƒ*numhask-array-0.8.0-7fuy5KViyAd6VGcZjnd5MqNumHask.Array.ShapeNumHask.Array.DynamicNumHask.Array.Fixed NumHask.Array KnownNatssnatValss KnownNatsnatValsFilterSqueeze CheckReorderReorderInsert CheckInsertCheckConcatenate ConcatenateExclude!! TakeIndexes AddIndexesGo AddIndexes DropIndexes PosRelativeGo PosRelative ReverseGoReverseAddIndex DropIndex++DropTakeMinimum Dimension CheckIndexes CheckIndexSizeRanksRankHasShapetoShapeShapeshapeValrankrankssizeflattenshapen checkIndex checkIndexes dimensionminimum dropIndexaddIndex posRelative dropIndexes addIndexes takeIndexesexclude concatenate'incAtdecAtreorder'squeeze' $fHasShape: $fHasShape[] $fKnownNats: $fKnownNats[] $fKnownNatss:$fKnownNatss[] $fShowShapeArrayshapeunArray fromFlatListindextabulatereshape transposeidentdiag singletonselects selectsExceptfoldsextractsjoinsmaps concatenateinsertappendreorderexpandcontractdotmultslicesqueeze fromScalartoScalarrowcolmmult $fShowArray$fTraversableArray$fFoldableArray$fFunctorArray $fEqArray $fOrdArray $fNFDataArray$fGenericArrayMatrixVectorScalar toDynamicwithsafeRowsafeCol $fIsListArray$fEpsilonArray$fMeetSemiLatticeArray$fJoinSemiLatticeArray$fDivisiveActionArraya$fSubtractiveActionArraya$fAdditiveActionArraya$fMultiplicativeActionArraya$fSubtractiveArray$fAdditiveArray$fRepresentableArray$fDistributiveArray$fMultiplicativeArray