!      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~None&',-.=>?@ADHSUVXbk)h numhask-arrayReflect a list of list of Nats numhask-arrayReflect a list of Nats7 numhask-arraySThe Shape type holds a [Nat] at type level and the equivalent [Int] at value level.: 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 nA numhask-array,dimension i is the i'th dimension of a ShapeB numhask-arrayminimum value in a listC numhask-array$drop the i'th dimension from a shapedropIndex [2, 3, 4] 1[2,4]D numhask-arrayaddIndex s i d adds a new dimension to shape s at position iaddIndex [2,4] 1 3[2,3,4]E numhask-arrayconvert 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]F numhask-arrayhdrop dimensions of a shape according to a list of positions (where position refers to the initial shape)dropIndexes [2, 3, 4] [1, 0][4]G numhask-arrayinsert 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]H numhask-array4take list of dimensions according to position lists.takeIndexes [2,3,4] [2,0][4,2]I numhask-arrayTturn a list of included positions for a given rank into a list of excluded positionsexclude 3 [1,2][0]K numhask-array incAt d s increments the index at d of shape s by one.L numhask-array decAt d s decrements the index at d of shape s by one.O  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNO78956:4;3<2=>?1@0A/B.-,+*)('C&D%$#E"! FGHIJKLMN None&'-.7=>?@ADHMSUVXbk.hY numhask-array&explicit rather than via RepresentableZ numhask-arrayfast[ numhask-arrayfrom flat listVWXYZVWXYZNone&'-.79=>?@ADHSUVXbc numhask-array1a multidimensional array with a value-level shapea[[[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] == aTrue numhask-arrayconvert to a flat list.toFlatList a == [1..24]True numhask-arrayextract an element at index iindex a [1,2,3]24 numhask-array,tabulate an array with a generating function.tabulate [2,3,4] ((1+) . flatten [2,3,4]) == aTrueh numhask-array3reshape 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]]]i numhask-array*reverse indices eg transposes the element Aijk to Akji.index (transpose a) [1,0,0] == index a [0,0,1]Truej numhask-array ident [3,2][[1, 0], [0, 1], [0, 0]]k numhask-arrayextract the diagonaldiag (ident [3,2])[1, 1]l numhask-arraysingleton [3,2] one[[1, 1], [1, 1], [1, 1]]m numhask-arrayselects ds ps a select from a, elements along ds dimensions at positions pslet s = selects [0,1] [1,1] as[17, 18, 19, 20]n numhask-arrayselect an index except along dimensions!let s = selectsExcept [2] [1,1] as[17, 18, 19, 20]o numhask-arrayfold along specified dimensionsfolds sum [1] a[68, 100, 132]p numhask-array%extracts dimensions to an outer layerlet e = extracts [1,2] ashape <$> extracts [0] a[[3,4], [3,4]] numhask-array extracts except dimensions to an outer layerlet e = extractsExcept [1,2] ashape <$> extracts [0] a[[3,4], [3,4]]q numhask-array%join inner and outer dimension layerslet e = extracts [1,0] alet j = joins [1,0] ea == jTruer numhask-arraymaps along specified dimensionsshape $ maps (transpose) [1] a[4,3,2]s numhask-arrayconcatenate along a dimensionshape $ concatenate 1 a a[2,6,4]t numhask-array insert d i insert along the dimension d at position i,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]]]u 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]]]v 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]]]w numhask-arrayproduct two arrays using the supplied binary function 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_productGThe 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]]x numhask-arrayecontract 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 another binary other than addition.let b = fromFlatList [2,3] [1..6] :: Array Int/contract sum [1,2] (expand (*) b (transpose b)) [[14, 32], [32, 77]]y numhask-arraya generalisation of a dot operation, which is a multiplicative expansion of two arrays and sum contraction along the middle two dimensions.=dot sum (*) on two matrices is known as matrix multiplication.let b = fromFlatList [2,3] [1..6] :: Array Intdot sum (*) b (transpose b) [[14, 32], [32, 77]]8dot sum (*) on two vectors is known as the inner product,let v = fromFlatList [3] [1..3] :: Array Intdot sum (*) v v14dot sum (*) m v on a matrix and a vector is matrix-vector multiplication Note that an `Array Int` with shape [3] is neither a row vector nor column vector. yN 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]z numhask-array%select elements along every dimension#let s = slice [[0,1],[0,2],[1,2]] as [[[2, 3], [10, 11]], [[14, 15], [22, 23]]]{ numhask-arrayremove singleton dimensions6let a' = fromFlatList [2,1,3,4,1] [1..24] :: Array Intshape $ squeeze a'[2,3,4]| numhask-array 3https://en.wikipedia.org/wiki/Scalarr_(mathematics) Wiki ScalarAn ArrayZ with shape [] despite being a Scalar is nevertheless a one-element vector under the hood.7unwrapping 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 a~ numhask-arrayextract specialised to a matrixrow 1 m [4, 5, 6, 7] numhask-arrayextract specialised to a matrixcol 1 m [1, 5, 9] 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{|}~cdefghikmnopqrstuvwxyz{lj|}~None&'-.4567=>?@ADHMSUVXbk$ numhask-array 2https://en.wikipedia.org/wiki/Matrix_(mathematics) Wiki Matrix numhask-array >https://en.wikipedia.org/wiki/Vector_(mathematics_and_physics) Wiki Vector numhask-array 3https://en.wikipedia.org/wiki/Scalarr_(mathematics) Wiki ScalarAn  Array '[] a{ despite being a Scalar is never-the-less a one-element vector under the hood. Unification of representation is unexplored. numhask-array0a multidimensional array with a type-level shapea[[[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] IntC[[*** Exception: NumHaskException {errorMessage = "shape mismatch"} numhask-array get shape of an Array as a valueshape a[2,3,4] numhask-array9convert to a dynamic array with shape at the value level. numhask-array&use a dynamic array in a fixed contextuwith (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] numhask-array3reshape 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]]] numhask-array*reverse indices eg transposes the element Aijk to Akji.index (transpose a) [1,0,0] == index a [0,0,1]True numhask-arrayident :: Array '[3,2] Int[[1, 0], [0, 1], [0, 0]] numhask-array diag (ident :: Array '[3,2] Int)[1, 1] numhask-array!singleton one :: Array '[3,2] Int[[1, 1], [1, 1], [1, 1]] numhask-arrayselects ds ps a select from a elements ds dimensions at positions ps/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 dimensions3let s = selectsExcept (Proxy :: Proxy '[2]) [1,1] a:t ss :: Array '[4] Ints[17, 18, 19, 20] numhask-arrayfold 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 extracts except dimensions to an outer layer0let e = extractsExcept (Proxy :: Proxy '[1,2]) a:t e#e :: Array '[2] (Array '[3, 4] 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-arraymaps 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 (Proxy :: Proxy d) (Proxy :: Proxy i) insert along the dimension d at position i;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-arrayproduct two arrays using the supplied binary function 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_productGThe 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-arrayecontract 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 another binary other than addition"let b = [1..6] :: Array '[2,3] IntAcontract sum (Proxy :: Proxy '[1,2]) (expand (*) b (transpose b)) [[14, 32], [32, 77]] numhask-arraya generalisation of a dot operation, which is a multiplicative expansion of two arrays and sum contraction along the middle two dimensions.=dot sum (*) on two matrices is known as matrix multiplication"let b = [1..6] :: Array '[2,3] Intdot sum (*) b (transpose b) [[14, 32], [32, 77]]8dot sum (*) on two vectors is known as the inner product let v = [1..3] :: Array '[3] Int:t dot sum (*) v v dot sum (*) v v :: Array '[] Intdot sum (*) v v14dot sum (*) m v on a matrix and a vector is matrix-vector multiplication Note that an `Array '[3] Int` is neither a row vector nor column vector. N 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-array%select elements along every dimension5let 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 singleton 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-array7unwrapping 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-arrayextract specialised to a matrixrow 1 m [4, 5, 6, 7] numhask-array$row extraction checked at type levelsafeRow (Proxy :: Proxy 1) m [4, 5, 6, 7]safeRow (Proxy :: Proxy 3) m...... index outside range... numhask-arrayextract specialised to a matrixcol 1 m [1, 5, 9] numhask-array'column extraction checked at type levelsafeCol (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]] numhask-arrayfrom flat list$$NoneDbs  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMN      !"#$%&'()*+,-./0123456789:;<==>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[[\]^_`abcdef[[g\hijklmnopqrstuvwxyz{|}~^def[[\gijklmnopqrstuvwxyz{|}~^_`cdbef]+numhask-array-0.4.0.0-LdEWQ1A9tQ8CbmYBdHSCANumHask.Array.ShapeNumHask.Array.HMatrixNumHask.Array.DynamicNumHask.Array.Fixed NumHask.Array KnownNatssnatValss KnownNatsnatValsFMapSndFstZipWithZipSFilterCmpFlagFMinFMaxSortFilterSqueeze CheckReorderReorderInsert CheckInsertCheckConcatenate ConcatenateExclude EnumerateGo Enumerate!! TakeIndexes AddIndexesGo AddIndexes DropIndexesGo DropIndexesDecMap PosRelativeGo PosRelative ReverseGoReverseAddIndex DropIndex++LastHeadInitTailDropTakeMinimum Dimension CheckIndexes CheckIndexSizeRanksRankHasShapetoShapeShapeshapeValrankrankssizeflattenshapen checkIndex checkIndexes dimensionminimum dropIndexaddIndex posRelative dropIndexes addIndexes takeIndexesexclude concatenate'incAtdecAtreorder'squeeze' $fHasShape: $fHasShape[] $fKnownNats: $fKnownNats[] $fKnownNatss:$fKnownNatss[] $fShowShapeArrayunArrayindexmmult $fIsListArray$fMultiplicativeActionArray$fHilbertArray$fMultiplicativeArray$fAdditiveArray $fShowArray $fNFDataArray$fGenericArrayshape fromFlatListreshape transposeidentdiag singletonselects selectsExceptfoldsextractsjoinsmaps concatenateinsertappendreorderexpandcontractdotslicesqueeze fromScalartoScalarrowcol$fTraversableArray$fFoldableArray$fFunctorArray $fEqArray $fOrdArrayMatrixVectorScalar toDynamicwithsafeRowsafeCol$fEpsilonArray$fMeetSemiLatticeArray$fJoinSemiLatticeArray$fHadamardDivisionArraya$fHadamardMultiplicationArraya$fSubtractiveArray$fRepresentableArray$fDistributiveArray toFlatListtabulateextractsExcept