packages feed

numhask-array 0.10.2 → 0.11.0.0

raw patch · 8 files changed

+325/−186 lines, 8 filesdep −QuickCheckdep ~basedep ~numhasksetup-changed

Dependencies removed: QuickCheck

Dependency ranges changed: base, numhask

Files

ChangeLog.md view
@@ -1,3 +1,10 @@+0.11.0.0+===++* new operators: indices, sequent, takes, undiag+* Divisive instance for Array+* inverse machinery: chol, invtri+ 0.9.2 == * fixes for numhask-0.9
− Setup.hs
@@ -1,3 +0,0 @@-import Distribution.Simple--main = defaultMain
numhask-array.cabal view
@@ -1,6 +1,6 @@-cabal-version:      2.4+cabal-version:      3.0 name:               numhask-array-version:            0.10.2+version:            0.11.0.0 synopsis:           Multi-dimensional arrays. description:   This package provides an interface into the [numhask](https://hackage.haskell.org/package/numhask) API, and both type- and value-level shape manipulation routines.@@ -25,41 +25,93 @@ copyright:          Tony Day license:            BSD-3-Clause license-file:       LICENSE-tested-with:        GHC ==8.8.4 || ==8.10.7 || ==9.2.5 || ==9.4.4+tested-with:        GHC == 8.10.7 || ==9.2.8 || ==9.4.5 || ==9.6.2 build-type:         Simple-extra-source-files: ChangeLog.md+extra-doc-files: ChangeLog.md  source-repository head   type:     git   location: https://github.com/tonyday567/numhask-array -library-  hs-source-dirs:     src-  default-extensions:+common ghc2021-stanza+  if impl(ghc >=9.2)+    default-language:+      GHC2021+  if impl(ghc <9.2)+    default-language:+      Haskell2010+    default-extensions:+      BangPatterns+      BinaryLiterals+      ConstrainedClassMethods+      ConstraintKinds+      DeriveDataTypeable+      DeriveFoldable+      DeriveFunctor+      DeriveGeneric+      DeriveLift+      DeriveTraversable+      DoAndIfThenElse+      EmptyCase+      EmptyDataDecls+      EmptyDataDeriving+      ExistentialQuantification+      ExplicitForAll+      FlexibleContexts+      FlexibleInstances+      ForeignFunctionInterface+      GADTSyntax+      GeneralisedNewtypeDeriving+      HexFloatLiterals+      ImplicitPrelude+      InstanceSigs+      KindSignatures+      MonomorphismRestriction+      MultiParamTypeClasses+      NamedFieldPuns+      NamedWildCards+      NumericUnderscores+      PatternGuards+      PolyKinds+      PostfixOperators+      RankNTypes+      RelaxedPolyRec+      ScopedTypeVariables+      StandaloneDeriving+      StarIsType+      TraditionalRecordSyntax+      TupleSections+      TypeApplications+      TypeOperators+      TypeSynonymInstances+  if impl(ghc <9.2) && impl(ghc >=8.10)+    default-extensions:+      ImportQualifiedPost+      StandaloneKindSignatures++common ghc-options-stanza   ghc-options:-    -Wall -Wcompat -Wincomplete-record-updates-    -Wincomplete-uni-patterns -Wredundant-constraints+    -Wall+    -Wcompat+    -Wincomplete-record-updates+    -Wincomplete-uni-patterns+    -Wredundant-constraints+    -Widentities+    -Wpartial-fields +library+  import: ghc2021-stanza+  import: ghc-options-stanza+  hs-source-dirs:     src   build-depends:-    , adjunctions   >=4.0   && <5-    , base          >=4.11  && <5-    , distributive  >=0.4   && <0.7-    , numhask       ^>=0.10-    , vector        >=0.10  && <0.14+    , adjunctions   >=4.0 && <5+    , base          >=4.11 && <5+    , distributive  >=0.4 && <0.7+    , numhask       >=0.11 && < 0.12+    , vector        >=0.10 && <0.14    exposed-modules:     NumHask.Array     NumHask.Array.Dynamic     NumHask.Array.Fixed     NumHask.Array.Shape--  default-language:   Haskell2010--test-suite doctests-  type:             exitcode-stdio-1.0-  main-is:          doctests.hs-  hs-source-dirs:   test-  default-language: Haskell2010-  build-depends:-    , base-    , QuickCheck
src/NumHask/Array.hs view
@@ -1,6 +1,4 @@-{-# OPTIONS_GHC -Wall #-}---- | Multi-dimensional arrays for numhask.+-- | Multi-dimensional arrays module NumHask.Array   ( -- * Imports     -- $imports@@ -38,19 +36,3 @@ -- - provides operators at value and type level to help manipulate shapes. -- -- - provides fixed and dynamic arrays with the same API.------ === API of an array language------ See <http://hiperfit.dk/pdf/array14_final.pdf> for context and a sketch of an intermediate typed array language effort.------ The operators that result from using the 'Representable' type - separation of size tracking at compile level, from computational at runtime - ends up looking like [APL](https://en.wikipedia.org/wiki/APL_(programming_language\)).------ Matrix multiplication in APL is @+.x@ and in numhask-array is @dot sum (*)@.  There is a slight increase in abstraction by explicitly exposing the fold in the algorithm, but the expressions are both very neat and abstracted away from the specialisation of multiplying matrices.------ References:------ <https://blog.plover.com/prog/apl-matrix-product.html>------ <https://en.wikipedia.org/wiki/Tensor_contraction>------ <https://en.wikipedia.org/wiki/Tensor_(intrinsic_definition)#Definition:_Tensor_Product_of_Vector_Spaces>
src/NumHask/Array/Dynamic.hs view
@@ -1,20 +1,11 @@ {-# LANGUAGE DataKinds #-}-{-# LANGUAGE DeriveGeneric #-}-{-# LANGUAGE FlexibleContexts #-}-{-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE MultiParamTypeClasses #-}-{-# LANGUAGE PolyKinds #-}-{-# LANGUAGE RankNTypes #-} {-# LANGUAGE RebindableSyntax #-}-{-# LANGUAGE ScopedTypeVariables #-}-{-# LANGUAGE StrictData #-} {-# LANGUAGE TypeFamilies #-}-{-# LANGUAGE NoStarIsType #-} {-# OPTIONS_GHC -Wno-redundant-constraints #-} {-# OPTIONS_GHC -fno-warn-incomplete-patterns #-} {-# OPTIONS_GHC -fno-warn-incomplete-uni-patterns #-} --- | Arrays with a dynamic shape.+-- | Arrays with a dynamic shape (shape only known at runtime). module NumHask.Array.Dynamic   ( -- $usage     Array (..),@@ -28,10 +19,14 @@     tabulate,      -- * Operators+    takes,     reshape,     transpose,-    diag,+    indices,     ident,+    sequent,+    diag,+    undiag,     singleton,     selects,     selectsExcept,@@ -45,6 +40,7 @@     append,     reorder,     expand,+    expandr,     apply,     contract,     dot,@@ -70,7 +66,7 @@ where  import Data.List (intercalate)-import qualified Data.Vector as V+import Data.Vector qualified as V import GHC.Show (Show (..)) import NumHask.Array.Shape import NumHask.Prelude as P hiding (product)@@ -170,6 +166,19 @@ tabulate :: () => [Int] -> ([Int] -> a) -> Array a tabulate ds f = Array ds . V.generate (size ds) $ (f . shapen ds) +-- | Takes the top-most elements according to the new dimension.+--+-- >>> takes [2,2,3] a+-- [[[1, 2, 3],+--   [5, 6, 7]],+--  [[13, 14, 15],+--   [17, 18, 19]]]+takes ::+  [Int] ->+  Array a ->+  Array a+takes ds a = tabulate ds $ \s -> index a s+ -- | Reshape an array (with the same number of elements). -- -- >>> reshape [4,3,2] a@@ -198,6 +207,15 @@ transpose :: Array a -> Array a transpose a = tabulate (reverse $ shape a) (index a . reverse) +-- | Indices of an Array.+--+-- >>> indices [3,3]+-- [[[0,0], [0,1], [0,2]],+--  [[1,0], [1,1], [1,2]],+--  [[2,0], [2,1], [2,2]]]+indices :: [Int] -> Array [Int]+indices ds = tabulate ds id+ -- | The identity array. -- -- >>> ident [3,2]@@ -212,6 +230,22 @@     isDiag [x, y] = x == y     isDiag (x : y : xs) = x == y && isDiag (y : xs) +-- | An array of sequential Ints+--+-- >>> sequent [3]+-- [0, 1, 2]+--+-- >>> sequent [3,3]+-- [[0, 0, 0],+--  [0, 1, 0],+--  [0, 0, 2]]+sequent :: [Int] -> Array Int+sequent ds = tabulate ds go+  where+    go [] = zero+    go [i] = i+    go (i : js) = bool zero i (all (i ==) js)+ -- | Extract the diagonal of an array. -- -- >>> diag (ident [3,2])@@ -224,6 +258,21 @@     go [] = throw (NumHaskException "Rank Underflow")     go (s' : _) = index a (replicate (rank (shape a)) s') +-- | Expand the array to form a diagonal array+--+-- >>> undiag 2 (fromFlatList [2] [1,1])+-- [[1, 0],+--  [0, 1]]+undiag ::+  (Additive a) =>+  Int ->+  Array a ->+  Array a+undiag r a = tabulate (replicate r (head (shape a))) go+  where+    go [] = throw (NumHaskException "Rank Underflow")+    go xs@(x : xs') = bool zero (index a xs) (all (x ==) xs')+ -- | Create an array composed of a single value. -- -- >>> singleton [3,2] one@@ -420,6 +469,19 @@ -- [[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 [2,2]+-- >>> 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])]]]] expand ::   (a -> b -> c) ->   Array a ->@@ -429,9 +491,29 @@   where     r = rank (shape a) +-- | Like expand, but permutes the first array first, rather than the second.+--+-- >>> expand (,) v (fmap (+3) v)+-- [[(1,4), (1,5), (1,6)],+--  [(2,4), (2,5), (2,6)],+--  [(3,4), (3,5), (3,6)]]+--+-- >>> expandr (,) v (fmap (+3) v)+-- [[(1,4), (2,4), (3,4)],+--  [(1,5), (2,5), (3,5)],+--  [(1,6), (2,6), (3,6)]]+expandr ::+  (a -> b -> c) ->+  Array a ->+  Array b ->+  Array c+expandr f a b = tabulate ((++) (shape a) (shape b)) (\i -> f (index a (drop r i)) (index b (take r i)))+  where+    r = rank (shape a)+ -- | Apply an array of functions to each array of values. ----- This is in the spirit of the applicative functor operation (<*>).+-- This is in the spirit of the applicative functor operation (\<*\>). -- -- > expand f a b == apply (fmap f a) b --@@ -439,6 +521,8 @@ -- [[1, 2, 3], --  [2, 4, 6], --  [3, 6, 9]]+--+-- Dynamic arrays can't be Applicatives because there is no 'pure' (Shape is not known at compile-time). -- -- >>> let b = fromFlatList [2,3] [1..6] :: Array Int -- >>> contract sum [1,2] (apply (fmap (*) b) (transpose b))
src/NumHask/Array/Fixed.hs view
@@ -1,26 +1,13 @@ {-# LANGUAGE DataKinds #-}-{-# LANGUAGE DeriveGeneric #-}-{-# LANGUAGE DeriveTraversable #-}-{-# LANGUAGE FlexibleContexts #-}-{-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE GeneralizedNewtypeDeriving #-}-{-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE OverloadedLists #-}-{-# LANGUAGE PolyKinds #-}-{-# LANGUAGE RankNTypes #-} {-# LANGUAGE RebindableSyntax #-}-{-# LANGUAGE ScopedTypeVariables #-}-{-# LANGUAGE StrictData #-}-{-# LANGUAGE TypeApplications #-} {-# LANGUAGE TypeFamilies #-}-{-# LANGUAGE TypeOperators #-}-{-# LANGUAGE NoStarIsType #-} {-# OPTIONS_GHC -Wno-incomplete-uni-patterns #-} {-# OPTIONS_GHC -Wno-redundant-constraints #-} {-# OPTIONS_GHC -fno-warn-incomplete-patterns #-} {-# OPTIONS_GHC -fno-warn-unused-imports #-} --- | Arrays with a fixed shape.+-- | Arrays with a fixed shape (known shape at compile time). module NumHask.Array.Fixed   ( -- $usage     Array (..),@@ -34,10 +21,11 @@     takes,     reshape,     transpose,-    diag,-    undiag,+    indices,     ident,     sequent,+    diag,+    undiag,     singleton,     selects,     selectsExcept,@@ -51,7 +39,7 @@     append,     reorder,     expand,-    expand',+    expandr,     apply,     contract,     dot,@@ -63,7 +51,6 @@      --     -- Scalar specialisations-    Scalar,     fromScalar,     toScalar, @@ -85,7 +72,6 @@     safeRow,     mmult,     chol,-    inv,     invtri,   ) where@@ -94,11 +80,11 @@ import Data.Functor.Rep import Data.List ((!!)) import Data.Proxy-import qualified Data.Vector as V+import Data.Vector qualified as V import GHC.Exts (IsList (..)) import GHC.Show (Show (..)) import GHC.TypeLits-import qualified NumHask.Array.Dynamic as D+import NumHask.Array.Dynamic qualified as D import NumHask.Array.Shape import NumHask.Prelude as P hiding (sequence, toList) @@ -115,6 +101,7 @@ -- >>> import Data.Functor.Rep -- >>> let s = [1] :: Array ('[] :: [Nat]) Int -- scalar -- >>> let v = [1,2,3] :: Array '[3] Int       -- vector+-- >>> let t = [0..3] :: Array '[2,2] Int     -- square matrix -- >>> let m = [0..11] :: Array '[3,4] Int     -- matrix -- >>> let a = [1..24] :: Array '[2,3,4] Int @@ -146,6 +133,7 @@ -- -- >>> [1,2,3] :: Array '[2,2] Int -- *** Exception: NumHaskException {errorMessage = "shape mismatch"}+-- [[ newtype Array s a = Array {unArray :: V.Vector a} deriving (Eq, Ord, Functor, Foldable, Generic, Traversable)  instance (HasShape s, Show a) => Show (Array s a) where@@ -199,32 +187,27 @@   negate = fmapRep negate  instance-  (HasShape s, Multiplicative a) =>-  MultiplicativeAction (Array s a) a+  (Multiplicative a) =>+  MultiplicativeAction (Array s a)   where-  (.*) s r = fmap (s *) r-  {-# INLINE (.*) #-}+  type Scalar (Array s a) = a+  (|*) r s = fmap (s *) r -instance-  (HasShape s, Additive a) =>-  AdditiveAction (Array s a) a-  where-  (.+) s r = fmap (s +) r-  {-# INLINE (.+) #-}+instance (Additive a) => AdditiveAction (Array s a) where+  type AdditiveScalar (Array s a) = a+  (|+) r s = fmap (s +) r  instance-  (HasShape s, Subtractive a) =>-  SubtractiveAction (Array s a) a+  (Subtractive a) =>+  SubtractiveAction (Array s a)   where-  (.-) s r = fmap (s -) r-  {-# INLINE (.-) #-}+  (|-) r s = fmap (\x -> x - s) r  instance-  (HasShape s, Divisive a) =>-  DivisiveAction (Array s a) a+  (Divisive a) =>+  DivisiveAction (Array s a)   where-  (./) s r = fmap (s /) r-  {-# INLINE (./) #-}+  (|/) r s = fmap (/ s) r  instance (HasShape s, JoinSemiLattice a) => JoinSemiLattice (Array s a) where   (\/) = liftR2 (\/)@@ -232,7 +215,7 @@ instance (HasShape s, MeetSemiLattice a) => MeetSemiLattice (Array s a) where   (/\) = liftR2 (/\) -instance (HasShape s, Subtractive a, Epsilon a, Ord a) => Epsilon (Array s a) where+instance (HasShape s, Subtractive a, Epsilon a) => Epsilon (Array s a) where   epsilon = singleton epsilon  instance@@ -277,6 +260,22 @@   r with (D.Array _ v) f = f (Array v) +-- | 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]]]+takes ::+  forall s s' a.+  ( HasShape s,+    HasShape s'+  ) =>+  Array s a ->+  Array s' a+takes a = tabulate $ \s -> index a s+ -- | Reshape an array (with the same number of elements). -- -- >>> reshape a :: Array '[4,3,2] Int@@ -312,6 +311,15 @@ transpose :: forall a s. (HasShape s, HasShape (Reverse s)) => Array s a -> Array (Reverse s) a transpose a = tabulate (index a . reverse) +-- | 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]]]+indices :: forall s. (HasShape s) => Array s [Int]+indices = tabulate id+ -- | The identity array. -- -- >>> ident :: Array '[3,2] Int@@ -326,16 +334,21 @@     isDiag [x, y] = x == y     isDiag (x : y : xs) = x == y && isDiag (y : xs) --- | A sequential array of Ints+-- | 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]] sequent :: forall s. (HasShape s) => Array s Int sequent = tabulate go   where     go [] = zero     go [i] = i-    go (i : j : _) = bool zero i (i == j)+    go (i : js) = bool zero i (all (i ==) js)  -- | Extract the diagonal of an array. --@@ -354,6 +367,24 @@     go (s' : _) = index a (replicate (length ds) s')     ds = shapeVal (toShape @s) +-- | Expand the array to form a diagonal array+--+-- >>> undiag ([1,1] :: Array '[2] Int)+-- [[1, 0],+--  [0, 1]]+undiag ::+  forall a s.+  ( HasShape s,+    Additive a,+    HasShape ((++) s s)+  ) =>+  Array s a ->+  Array ((++) s s) a+undiag a = tabulate go+  where+    go [] = throw (NumHaskException "Rank Underflow")+    go xs@(x : xs') = bool zero (index a xs) (all (x ==) xs')+ -- | Create an array composed of a single value. -- -- >>> singleton one :: Array '[3,2] Int@@ -436,7 +467,7 @@ -- -- >>> let e = extracts (Proxy :: Proxy '[1,2]) a -- >>> :t e--- e :: Array '[3, 4] (Array '[2] Int)+-- e :: Array [3, 4] (Array '[2] Int) extracts ::   forall ds st si so a.   ( HasShape st,@@ -457,7 +488,7 @@ -- -- >>> let e = extractsExcept (Proxy :: Proxy '[1,2]) a -- >>> :t e--- e :: Array '[2] (Array '[3, 4] Int)+-- e :: Array '[2] (Array [3, 4] Int) extractsExcept ::   forall ds st si so a.   ( HasShape st,@@ -479,12 +510,12 @@ -- >>> let e = extracts (Proxy :: Proxy '[1,0]) a -- -- >>> :t e--- e :: Array '[3, 2] (Array '[4] Int)+-- e :: Array [3, 2] (Array '[4] Int) -- -- >>> let j = joins (Proxy :: Proxy '[1,0]) e -- -- >>> :t j--- j :: Array '[2, 3, 4] Int+-- j :: Array [2, 3, 4] Int -- -- >>> a == j -- True@@ -507,7 +538,7 @@ -- | 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 (transpose) (Proxy :: Proxy '[1]) a :: Array [4, 3, 2] Int maps ::   forall ds st st' si si' so a b.   ( HasShape st,@@ -530,7 +561,7 @@ -- | Concatenate along a dimension. -- -- >>> :t concatenate (Proxy :: Proxy 1) a a--- concatenate (Proxy :: Proxy 1) a a :: Array '[2, 6, 4] Int+-- concatenate (Proxy :: Proxy 1) a a :: Array [2, 6, 4] Int concatenate ::   forall a s0 s1 d s.   ( CheckConcatenate d s0 s1 s,@@ -598,7 +629,7 @@ -- -- >>>  :t append (Proxy :: Proxy 0) a -- append (Proxy :: Proxy 0) a---   :: Array '[3, 4] Int -> Array '[3, 3, 4] Int+--   :: Array [3, 4] Int -> Array [3, 3, 4] Int append ::   forall a d s s'.   ( DropIndex s d ~ s',@@ -619,7 +650,7 @@ -- -- >>> let r = reorder (Proxy :: Proxy '[2,0,1]) a -- >>> :t r--- r :: Array '[4, 2, 3] Int+-- r :: Array [4, 2, 3] Int reorder ::   forall a ds s.   ( HasShape ds,@@ -640,7 +671,7 @@ -- 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+-- < 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: --@@ -650,6 +681,19 @@ -- [[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])]]]] expand ::   forall s s' a b c.   ( HasShape s,@@ -664,7 +708,18 @@   where     r = rank (shape a) -expand' ::+-- | 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)]]+expandr ::   forall s s' a b c.   ( HasShape s,     HasShape s',@@ -674,13 +729,13 @@   Array s a ->   Array s' b ->   Array ((++) s s') c-expand' f a b = tabulate (\i -> f (index a (drop r i)) (index b (take r i)))+expandr f a b = tabulate (\i -> f (index a (drop r i)) (index b (take r i)))   where     r = rank (shape a)  -- | Apply an array of functions to each array of values. ----- This is in the spirit of the applicative functor operation (<*>).+-- This is in the spirit of the applicative functor operation (\<*\>). -- -- > expand f a b == apply (fmap f a) b --@@ -689,14 +744,14 @@ --  [2, 4, 6], --  [3, 6, 9]] ----- Arrays can't be applicative functors in haskell because the changes in shape are reflected in the types.+-- 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+-- > 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+-- > (<*>) :: 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))@@ -767,24 +822,31 @@ -- >>> 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]+-- Array elements don't have to be numbers: ----- the algorithm ignores excess positions within the contracting dimension(s):+-- >>> x1 = (show <$> [1..4]) :: Array '[2,2] String+-- >>> x2 = (show <$> [5..8]) :: Array '[2,2] String+-- >>> x1+-- [["1", "2"],+--  ["3", "4"]] ----- m23 shape: 2 3+-- >>> x2+-- [["5", "6"],+--  ["7", "8"]] ----- m12 shape: 1 2+-- >>> 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"]] ----- res shape: 2 2+-- 'dot' allows operation on mis-shaped matrices. The algorithm ignores excess positions within the contracting dimension(s): ----- FIXME: work out whether this is a feature or a bug...+-- >>> 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+-- 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@@ -863,7 +925,7 @@ -- -- >>> let s = slice (Proxy :: Proxy '[[0,1],[0,2],[1,2]]) a -- >>> :t s--- s :: Array '[2, 2, 2] Int+-- s :: Array [2, 2, 2] Int -- -- >>> s -- [[[2, 3],@@ -893,15 +955,6 @@     go s = index a (zipWith (!!) pss' s)     pss' = natValss pss -takes ::-  forall s s' a.-  ( HasShape s,-    HasShape s'-  ) =>-  Array s a ->-  Array s' a-takes a = tabulate $ \s -> index a s- -- | Remove single dimensions. -- -- >>> let a = [1..24] :: Array '[2,1,3,4,1] Int@@ -950,11 +1003,6 @@ -- $scalar -- Scalar specialisations --- | <https://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.-type Scalar a = Array ('[] :: [Nat]) a- -- | Unwrapping scalars is probably a performance bottleneck. -- -- >>> let s = [3] :: Array ('[] :: [Nat]) Int@@ -973,6 +1021,7 @@ -- | <https://en.wikipedia.org/wiki/Vector_(mathematics_and_physics) Wiki Vector> type Vector s a = Array '[s] a +-- | Vector specialisation of 'sequent' sequentv :: forall n. (KnownNat n) => Vector n Int sequentv = sequent @@ -1005,7 +1054,7 @@   where   recip a = invtri (transpose (chol a)) * invtri (chol a) --- | inverse of a triangular matrix+-- | <https://math.stackexchange.com/questions/1003801/inverse-of-an-invertible-upper-triangular-matrix-of-order-3 Inverse of a triangular> matrix. invtri :: forall a n. (KnownNat n, ExpField a, Eq a) => Array '[n, n] a -> Array '[n, n] a invtri a = sum (fmap (l ^) (sequentv :: Vector n Int)) * ti   where@@ -1013,25 +1062,9 @@     tl = a - undiag (diag a)     l = negate (ti * tl) --- | Expand the array to form a diagonal array------ >>> undiag ([1,1] :: Array '[2] Int)--- [[1, 0],---  [0, 1]]-undiag ::-  forall a s.-  ( HasShape s,-    Additive a,-    HasShape ((++) s s)-  ) =>-  Array s a ->-  Array ((++) s s) a-undiag a = tabulate go-  where-    go [] = throw (NumHaskException "Rank Underflow")-    go xs@(x : xs') = bool zero (index a xs) (all (x ==) xs')- -- | cholesky decomposition+--+-- Uses the <https://en.wikipedia.org/wiki/Cholesky_decomposition#The_Cholesky_algorithm Cholesky-Crout> algorithm. chol :: (KnownNat n, ExpField a) => Array '[n, n] a -> Array '[n, n] a chol a =   let l =
src/NumHask/Array/Shape.hs view
@@ -1,19 +1,7 @@-{-# LANGUAGE ConstraintKinds #-}-{-# LANGUAGE FlexibleContexts #-}-{-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE GADTs #-}-{-# LANGUAGE MultiParamTypeClasses #-}-{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE DataKinds #-} {-# LANGUAGE RebindableSyntax #-}-{-# LANGUAGE ScopedTypeVariables #-}-{-# LANGUAGE StrictData #-}-{-# LANGUAGE TypeApplications #-} {-# LANGUAGE TypeFamilies #-}-{-# LANGUAGE TypeInType #-}-{-# LANGUAGE TypeOperators #-} {-# LANGUAGE UndecidableInstances #-}-{-# LANGUAGE NoStarIsType #-}-{-# OPTIONS_GHC -Wall #-} {-# OPTIONS_GHC -fno-warn-incomplete-patterns #-} {-# OPTIONS_GHC -fno-warn-unused-top-binds #-} @@ -51,15 +39,19 @@     posRelative,     PosRelative,     PosRelativeGo,+    DecMap,     addIndexes,     AddIndexes,     AddIndexesGo,     dropIndexes,     DropIndexes,+    DropIndexesGo,     takeIndexes,     TakeIndexes,     exclude,     Exclude,+    Enumerate,+    EnumerateGo,     concatenate',     Concatenate,     CheckConcatenate,
− test/doctests.hs
@@ -1,8 +0,0 @@-module Main where--main :: IO ()-main = do-  putStrLn "This test-suite exists only to add dependencies"-  putStrLn "To run doctests: "-  putStrLn "    cabal build all --enable-tests"-  putStrLn "    cabal-docspec"