-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Pure, type-indexed haskell vector, matrix, and tensor library. -- -- Pure, type-indexed haskell vector, matrix, and tensor library. -- Features dimensionality type-checking for all operations. Generic -- n-dimensional versions are implemented using low-level prim ops. -- Allows ad-hoc replacement with fixed low-dimensionality vectors and -- matrices without changing user interface. Please see the README on -- GitHub at https://github.com/achirkin/easytensor#readme @package easytensor @version 2.0.0.0 -- | Facilities for converting Haskell data to and from raw bytes. -- -- The main purpose of this module is to support the implementation of -- the DataFrame Backend. However, it also comes very -- useful for writing FFI. To that end, the PrimBytes class is -- similar to the Storable class: it provides means to write your -- data to and read from a raw memory area. Though, it is more flexible -- in that it can work with both, foreign pointers and primitive byte -- arrays, and it provides means to get data field offsets by their -- selector names. On top of that, a PrimBytes instance can be -- derived via the Generic machinery. -- -- A derived PrimBytes instance tries to pack the data as dense as -- possible, while respecting the alignment requirements. In all cases -- known to me, the resulting data layout coincides with a corresponding -- C struct, allowing to marshal the data without any boilerplate. -- However, this is not guaranteed, but you can write a PrimBytes -- instance manually if necessary (and report an issue plz). -- -- Note about alignment, size, and padding of the data. There are -- two basic sanity assumptions about these, which are not checked in -- this module at all: -- --
-- data MyData a b = ... -- deriving Generic -- -- instance (PrimBytes a, PrimBytes b) => PrimBytes (MyData a b) ---- -- .. or use the DeriveAnyClass extension to make it even -- shorter: -- --
-- data MyData a b = ... -- deriving (Generic, PrimBytes) ---- -- The derived instance tries to pack the data as dense as possible, but -- sometimes it is better to write the instance by hand. If a derived -- type has more than one constructor, the derived instance puts a -- Word32 tag at the beginning of the byte representation. All -- fields of a constructor are packed in a C-like fashion next to each -- other, while respecting their alignments. class PrimTagged a => PrimBytes a where { -- | List of field names. -- -- It is used to get field offsets using byteFieldOffset function. -- -- A Generic-derived instance has this list non-empty only if two obvious -- conditions are met: -- --
-- import qualified Numeric.ProductOrd.NonTransitive as NonTransitive --module Numeric.ProductOrd.NonTransitive -- | Redefine Ord instance for a type which is a cartesian product -- -- as a partial product order. -- -- Since vanilla Haskell Ord class is always about total order, -- ProductOrd instance is not particularly correct. However, it -- turns out to be very useful for comparing vector or tuple-like types. -- -- The implementation of ProductOrd in this module workarounds -- this by using a non-transitive Eq instance: <math> -- -- Another inconsistency with the Haskell Report is the min and -- max functions; these are simply element-wise minimum and -- maximum here. Thus, these instances preserve important properties like -- min a b <= a && min a b <= b, but do not -- preserve a property that min a b == a || min a b == b. -- -- All of this is really useful in geometry applications and for -- calculating things like Pareto dominance, but should be used -- with care. Remember about this if you want to put a -- ProductOrd into a Set or a Map! newtype ProductOrd a ProductOrd :: a -> ProductOrd a [getProductOrd] :: ProductOrd a -> a -- | Treat Incomparable as EQ (non-transitive equality). toOrdering :: PartialOrdering -> Ordering instance Data.Traversable.Traversable Numeric.ProductOrd.NonTransitive.ProductOrd instance Foreign.Storable.Storable a => Foreign.Storable.Storable (Numeric.ProductOrd.NonTransitive.ProductOrd a) instance GHC.Base.Monoid a => GHC.Base.Monoid (Numeric.ProductOrd.NonTransitive.ProductOrd a) instance GHC.Base.Semigroup a => GHC.Base.Semigroup (Numeric.ProductOrd.NonTransitive.ProductOrd a) instance GHC.Real.Fractional a => GHC.Real.Fractional (Numeric.ProductOrd.NonTransitive.ProductOrd a) instance GHC.Float.Floating a => GHC.Float.Floating (Numeric.ProductOrd.NonTransitive.ProductOrd a) instance GHC.Enum.Bounded a => GHC.Enum.Bounded (Numeric.ProductOrd.NonTransitive.ProductOrd a) instance GHC.Enum.Enum a => GHC.Enum.Enum (Numeric.ProductOrd.NonTransitive.ProductOrd a) instance GHC.Num.Num a => GHC.Num.Num (Numeric.ProductOrd.NonTransitive.ProductOrd a) instance GHC.Generics.Generic1 Numeric.ProductOrd.NonTransitive.ProductOrd instance GHC.Generics.Generic (Numeric.ProductOrd.NonTransitive.ProductOrd a) instance Data.Data.Data a => Data.Data.Data (Numeric.ProductOrd.NonTransitive.ProductOrd a) instance GHC.Read.Read a => GHC.Read.Read (Numeric.ProductOrd.NonTransitive.ProductOrd a) instance GHC.Show.Show a => GHC.Show.Show (Numeric.ProductOrd.NonTransitive.ProductOrd a) instance (GHC.Classes.Ord (Numeric.ProductOrd.NonTransitive.ProductOrd a), GHC.Real.Integral a) => GHC.Real.Integral (Numeric.ProductOrd.NonTransitive.ProductOrd a) instance (GHC.Classes.Ord (Numeric.ProductOrd.NonTransitive.ProductOrd a), Data.Bits.Bits a) => Data.Bits.Bits (Numeric.ProductOrd.NonTransitive.ProductOrd a) instance (GHC.Classes.Ord (Numeric.ProductOrd.NonTransitive.ProductOrd a), Data.Bits.FiniteBits a) => Data.Bits.FiniteBits (Numeric.ProductOrd.NonTransitive.ProductOrd a) instance (GHC.Classes.Ord (Numeric.ProductOrd.NonTransitive.ProductOrd a), GHC.Real.Real a) => GHC.Real.Real (Numeric.ProductOrd.NonTransitive.ProductOrd a) instance (GHC.Classes.Ord (Numeric.ProductOrd.NonTransitive.ProductOrd a), GHC.Real.RealFrac a) => GHC.Real.RealFrac (Numeric.ProductOrd.NonTransitive.ProductOrd a) instance (GHC.Classes.Ord (Numeric.ProductOrd.NonTransitive.ProductOrd a), GHC.Float.RealFloat a) => GHC.Float.RealFloat (Numeric.ProductOrd.NonTransitive.ProductOrd a) instance Data.Foldable.Foldable Numeric.ProductOrd.NonTransitive.ProductOrd instance GHC.Base.Functor Numeric.ProductOrd.NonTransitive.ProductOrd instance GHC.Base.Applicative Numeric.ProductOrd.NonTransitive.ProductOrd instance GHC.Base.Monad Numeric.ProductOrd.NonTransitive.ProductOrd instance Control.Monad.Fix.MonadFix Numeric.ProductOrd.NonTransitive.ProductOrd instance Control.Monad.Zip.MonadZip Numeric.ProductOrd.NonTransitive.ProductOrd instance GHC.Classes.Ord (Numeric.ProductOrd.NonTransitive.ProductOrd a) => GHC.Classes.Eq (Numeric.ProductOrd.NonTransitive.ProductOrd a) instance forall k (f :: k -> *) (xs :: [k]). Data.Type.List.All GHC.Classes.Ord (Data.Type.List.Map f xs) => GHC.Classes.Ord (Numeric.ProductOrd.NonTransitive.ProductOrd (Numeric.TypedList.TypedList f xs)) instance (GHC.Classes.Ord a1, GHC.Classes.Ord a2) => GHC.Classes.Ord (Numeric.ProductOrd.NonTransitive.ProductOrd (a1, a2)) instance (GHC.Classes.Ord a1, GHC.Classes.Ord a2, GHC.Classes.Ord a3) => GHC.Classes.Ord (Numeric.ProductOrd.NonTransitive.ProductOrd (a1, a2, a3)) instance (GHC.Classes.Ord a1, GHC.Classes.Ord a2, GHC.Classes.Ord a3, GHC.Classes.Ord a4) => GHC.Classes.Ord (Numeric.ProductOrd.NonTransitive.ProductOrd (a1, a2, a3, a4)) instance (GHC.Classes.Ord a1, GHC.Classes.Ord a2, GHC.Classes.Ord a3, GHC.Classes.Ord a4, GHC.Classes.Ord a5) => GHC.Classes.Ord (Numeric.ProductOrd.NonTransitive.ProductOrd (a1, a2, a3, a4, a5)) instance (GHC.Classes.Ord a1, GHC.Classes.Ord a2, GHC.Classes.Ord a3, GHC.Classes.Ord a4, GHC.Classes.Ord a5, GHC.Classes.Ord a6) => GHC.Classes.Ord (Numeric.ProductOrd.NonTransitive.ProductOrd (a1, a2, a3, a4, a5, a6)) instance (GHC.Classes.Ord a1, GHC.Classes.Ord a2, GHC.Classes.Ord a3, GHC.Classes.Ord a4, GHC.Classes.Ord a5, GHC.Classes.Ord a6, GHC.Classes.Ord a7) => GHC.Classes.Ord (Numeric.ProductOrd.NonTransitive.ProductOrd (a1, a2, a3, a4, a5, a6, a7)) instance (GHC.Classes.Ord a1, GHC.Classes.Ord a2, GHC.Classes.Ord a3, GHC.Classes.Ord a4, GHC.Classes.Ord a5, GHC.Classes.Ord a6, GHC.Classes.Ord a7, GHC.Classes.Ord a8) => GHC.Classes.Ord (Numeric.ProductOrd.NonTransitive.ProductOrd (a1, a2, a3, a4, a5, a6, a7, a8)) instance (GHC.Classes.Ord a1, GHC.Classes.Ord a2, GHC.Classes.Ord a3, GHC.Classes.Ord a4, GHC.Classes.Ord a5, GHC.Classes.Ord a6, GHC.Classes.Ord a7, GHC.Classes.Ord a8, GHC.Classes.Ord a9) => GHC.Classes.Ord (Numeric.ProductOrd.NonTransitive.ProductOrd (a1, a2, a3, a4, a5, a6, a7, a8, a9)) -- | Compare product types using partial Ord instances: -- --
-- import qualified Numeric.ProductOrd.Partial as Partial --module Numeric.ProductOrd.Partial -- | Redefine Ord instance for a type which is a cartesian product -- -- as a partial product order. -- -- Since vanilla Haskell Ord class is always about total order, -- ProductOrd instance is not particularly correct. However, it -- turns out to be very useful for comparing vector or tuple-like types. -- -- The implementation of ProductOrd in this module workarounds -- this by using a partial compare function in an Eq -- instance: <math> -- -- Another inconsistency with the Haskell Report is the min and -- max functions; these are simply element-wise minimum and -- maximum here. Thus, these instances preserve important properties like -- min a b <= a && min a b <= b, but do not -- preserve a property that min a b == a || min a b == b. -- -- All of this is really useful in geometry applications and for -- calculating things like Pareto dominance, but should be used -- with care. In particular, never use ProductOrd as a key to a -- Set or a Map! newtype ProductOrd a ProductOrd :: a -> ProductOrd a [getProductOrd] :: ProductOrd a -> a -- | Treat Incomparable as error (partial function). toOrdering :: PartialOrdering -> Ordering instance Data.Bits.FiniteBits a => Data.Bits.FiniteBits (Numeric.ProductOrd.Partial.ProductOrd a) instance Data.Bits.Bits a => Data.Bits.Bits (Numeric.ProductOrd.Partial.ProductOrd a) instance Data.Traversable.Traversable Numeric.ProductOrd.Partial.ProductOrd instance Foreign.Storable.Storable a => Foreign.Storable.Storable (Numeric.ProductOrd.Partial.ProductOrd a) instance GHC.Base.Monoid a => GHC.Base.Monoid (Numeric.ProductOrd.Partial.ProductOrd a) instance GHC.Base.Semigroup a => GHC.Base.Semigroup (Numeric.ProductOrd.Partial.ProductOrd a) instance GHC.Real.Fractional a => GHC.Real.Fractional (Numeric.ProductOrd.Partial.ProductOrd a) instance GHC.Float.Floating a => GHC.Float.Floating (Numeric.ProductOrd.Partial.ProductOrd a) instance GHC.Enum.Bounded a => GHC.Enum.Bounded (Numeric.ProductOrd.Partial.ProductOrd a) instance GHC.Enum.Enum a => GHC.Enum.Enum (Numeric.ProductOrd.Partial.ProductOrd a) instance GHC.Num.Num a => GHC.Num.Num (Numeric.ProductOrd.Partial.ProductOrd a) instance GHC.Generics.Generic1 Numeric.ProductOrd.Partial.ProductOrd instance GHC.Generics.Generic (Numeric.ProductOrd.Partial.ProductOrd a) instance Data.Data.Data a => Data.Data.Data (Numeric.ProductOrd.Partial.ProductOrd a) instance GHC.Read.Read a => GHC.Read.Read (Numeric.ProductOrd.Partial.ProductOrd a) instance GHC.Show.Show a => GHC.Show.Show (Numeric.ProductOrd.Partial.ProductOrd a) instance GHC.Classes.Eq a => GHC.Classes.Eq (Numeric.ProductOrd.Partial.ProductOrd a) instance (GHC.Classes.Ord (Numeric.ProductOrd.Partial.ProductOrd a), GHC.Real.Integral a) => GHC.Real.Integral (Numeric.ProductOrd.Partial.ProductOrd a) instance (GHC.Classes.Ord (Numeric.ProductOrd.Partial.ProductOrd a), GHC.Real.Real a) => GHC.Real.Real (Numeric.ProductOrd.Partial.ProductOrd a) instance (GHC.Classes.Ord (Numeric.ProductOrd.Partial.ProductOrd a), GHC.Real.RealFrac a) => GHC.Real.RealFrac (Numeric.ProductOrd.Partial.ProductOrd a) instance (GHC.Classes.Ord (Numeric.ProductOrd.Partial.ProductOrd a), GHC.Float.RealFloat a) => GHC.Float.RealFloat (Numeric.ProductOrd.Partial.ProductOrd a) instance Data.Foldable.Foldable Numeric.ProductOrd.Partial.ProductOrd instance GHC.Base.Functor Numeric.ProductOrd.Partial.ProductOrd instance GHC.Base.Applicative Numeric.ProductOrd.Partial.ProductOrd instance GHC.Base.Monad Numeric.ProductOrd.Partial.ProductOrd instance Control.Monad.Fix.MonadFix Numeric.ProductOrd.Partial.ProductOrd instance Control.Monad.Zip.MonadZip Numeric.ProductOrd.Partial.ProductOrd instance forall k (f :: k -> *) (xs :: [k]). Data.Type.List.All GHC.Classes.Ord (Data.Type.List.Map f xs) => GHC.Classes.Eq (Numeric.ProductOrd.Partial.ProductOrd (Numeric.TypedList.TypedList f xs)) instance forall k (f :: k -> *) (xs :: [k]). Data.Type.List.All GHC.Classes.Ord (Data.Type.List.Map f xs) => GHC.Classes.Ord (Numeric.ProductOrd.Partial.ProductOrd (Numeric.TypedList.TypedList f xs)) instance (GHC.Classes.Ord a1, GHC.Classes.Ord a2) => GHC.Classes.Ord (Numeric.ProductOrd.Partial.ProductOrd (a1, a2)) instance (GHC.Classes.Ord a1, GHC.Classes.Ord a2, GHC.Classes.Ord a3) => GHC.Classes.Ord (Numeric.ProductOrd.Partial.ProductOrd (a1, a2, a3)) instance (GHC.Classes.Ord a1, GHC.Classes.Ord a2, GHC.Classes.Ord a3, GHC.Classes.Ord a4) => GHC.Classes.Ord (Numeric.ProductOrd.Partial.ProductOrd (a1, a2, a3, a4)) instance (GHC.Classes.Ord a1, GHC.Classes.Ord a2, GHC.Classes.Ord a3, GHC.Classes.Ord a4, GHC.Classes.Ord a5) => GHC.Classes.Ord (Numeric.ProductOrd.Partial.ProductOrd (a1, a2, a3, a4, a5)) instance (GHC.Classes.Ord a1, GHC.Classes.Ord a2, GHC.Classes.Ord a3, GHC.Classes.Ord a4, GHC.Classes.Ord a5, GHC.Classes.Ord a6) => GHC.Classes.Ord (Numeric.ProductOrd.Partial.ProductOrd (a1, a2, a3, a4, a5, a6)) instance (GHC.Classes.Ord a1, GHC.Classes.Ord a2, GHC.Classes.Ord a3, GHC.Classes.Ord a4, GHC.Classes.Ord a5, GHC.Classes.Ord a6, GHC.Classes.Ord a7) => GHC.Classes.Ord (Numeric.ProductOrd.Partial.ProductOrd (a1, a2, a3, a4, a5, a6, a7)) instance (GHC.Classes.Ord a1, GHC.Classes.Ord a2, GHC.Classes.Ord a3, GHC.Classes.Ord a4, GHC.Classes.Ord a5, GHC.Classes.Ord a6, GHC.Classes.Ord a7, GHC.Classes.Ord a8) => GHC.Classes.Ord (Numeric.ProductOrd.Partial.ProductOrd (a1, a2, a3, a4, a5, a6, a7, a8)) instance (GHC.Classes.Ord a1, GHC.Classes.Ord a2, GHC.Classes.Ord a3, GHC.Classes.Ord a4, GHC.Classes.Ord a5, GHC.Classes.Ord a6, GHC.Classes.Ord a7, GHC.Classes.Ord a8, GHC.Classes.Ord a9) => GHC.Classes.Ord (Numeric.ProductOrd.Partial.ProductOrd (a1, a2, a3, a4, a5, a6, a7, a8, a9)) -- | The core easytensor types. module Numeric.DataFrame.Type -- | Data frame that has an unknown dimensionality at compile time. -- Pattern-match against its constructor to get a Nat-indexed data frame data SomeDataFrame (t :: l) SomeDataFrame :: DataFrame t ns -> SomeDataFrame -- | DataFrame with its type arguments swapped. data DataFrame' (xs :: [k]) (t :: l) -- | Keep data in a primitive data frame and maintain information about -- Dimensions in the type system data family DataFrame (t :: l) (xs :: [k]) -- | Empty MultiFrame pattern Z :: forall (xs :: [Type]) (ns :: [Nat]). () => xs ~ '[] => DataFrame xs ns -- | Constructing a MultiFrame using DataFrame columns pattern (:*:) :: forall (xs :: [Type]) (ns :: [Nat]). () => forall (y :: Type) (ys :: [Type]). xs ~ (y : ys) => DataFrame y ns -> DataFrame ys ns -> DataFrame xs ns infixr 6 :*: -- | A scalar DataFrame is just a newtype wrapper on a value. pattern S :: forall (t :: Type). t -> DataFrame t ('[] :: [Nat]) pattern DF2 :: forall (t :: Type) (ds :: [Nat]). (PrimBytes t, Dimensions (2 : ds)) => (Dimensions ds, KnownBackend t ds) => DataFrame t ds -> DataFrame t ds -> DataFrame t (2 : ds) pattern DF3 :: forall (t :: Type) (ds :: [Nat]). (PrimBytes t, Dimensions (3 : ds)) => (Dimensions ds, KnownBackend t ds) => DataFrame t ds -> DataFrame t ds -> DataFrame t ds -> DataFrame t (3 : ds) pattern DF4 :: forall (t :: Type) (ds :: [Nat]). (PrimBytes t, Dimensions (4 : ds)) => (Dimensions ds, KnownBackend t ds) => DataFrame t ds -> DataFrame t ds -> DataFrame t ds -> DataFrame t ds -> DataFrame t (4 : ds) pattern DF5 :: forall (t :: Type) (ds :: [Nat]). (PrimBytes t, Dimensions (5 : ds)) => (Dimensions ds, KnownBackend t ds) => DataFrame t ds -> DataFrame t ds -> DataFrame t ds -> DataFrame t ds -> DataFrame t ds -> DataFrame t (5 : ds) pattern DF6 :: forall (t :: Type) (ds :: [Nat]). (PrimBytes t, Dimensions (6 : ds)) => (Dimensions ds, KnownBackend t ds) => DataFrame t ds -> DataFrame t ds -> DataFrame t ds -> DataFrame t ds -> DataFrame t ds -> DataFrame t ds -> DataFrame t (6 : ds) pattern DF7 :: forall (t :: Type) (ds :: [Nat]). (PrimBytes t, Dimensions (7 : ds)) => (Dimensions ds, KnownBackend t ds) => DataFrame t ds -> DataFrame t ds -> DataFrame t ds -> DataFrame t ds -> DataFrame t ds -> DataFrame t ds -> DataFrame t ds -> DataFrame t (7 : ds) pattern DF8 :: forall (t :: Type) (ds :: [Nat]). (PrimBytes t, Dimensions (8 : ds)) => (Dimensions ds, KnownBackend t ds) => DataFrame t ds -> DataFrame t ds -> DataFrame t ds -> DataFrame t ds -> DataFrame t ds -> DataFrame t ds -> DataFrame t ds -> DataFrame t ds -> DataFrame t (8 : ds) pattern DF9 :: forall (t :: Type) (ds :: [Nat]). (PrimBytes t, Dimensions (9 : ds)) => (Dimensions ds, KnownBackend t ds) => DataFrame t ds -> DataFrame t ds -> DataFrame t ds -> DataFrame t ds -> DataFrame t ds -> DataFrame t ds -> DataFrame t ds -> DataFrame t ds -> DataFrame t ds -> DataFrame t (9 : ds) -- | Represent smart constructor functions packDF and -- unpackDF. type family PackDF (t :: Type) (ds :: [Nat]) (d :: Nat) (r :: Type) :: Type -- | Takes d arguments of type DataFrame t ds and produce -- a DataFrame t (d ': ds). -- -- NB: always use TypeApplications extension with this function -- to apply all type arguments! Otherwise, a very dumb type family -- PackDF will not infer the types for you. -- -- The following example creates a Matrix Double 12 3 filled -- with twelve 3D vectors (using fromInteger of Vector -- Double 3): -- --
-- >>> packDF @Double @12 @'[3] 1 2 3 4 5 6 7 8 9 10 11 12 ---- -- packDF and unpackDF together serve as a generic -- constructor for a DataFrame of an arbitrary (statically known) size. packDF :: forall (t :: Type) (d :: Nat) (ds :: [Nat]). (PrimBytes t, Dimensions (d : ds)) => PackDF t ds d (DataFrame t (d : ds)) -- | Takes a function (e.g. a constructor) with d+1 argument (df1, -- df2, .. dfd, Dict) and a DataFrame t (d ': ds). Feeds the -- dataframe elements into that function. For example, you can pass a -- tuple to this function, and get all dataframe elements (and some -- dictionaries -- useful evidence to work with element frames) -- -- NB: always use TypeApplications extension with this function -- to apply all type arguments! Otherwise, a very dumb type family -- PackDF will not infer the types for you. -- -- The following example unpacks a 3D vector (created using -- fromInteger of Vector Double 3) into a 4-tuple with -- three scalars and one Dict: -- --
-- >>> unpackDF @Double @3 @'[] (,,,) 2 ---- -- packDF and unpackDF together serve as a generic -- constructor for a DataFrame of an arbitrary (statically known) size. unpackDF :: forall (t :: Type) (d :: Nat) (ds :: [Nat]) (rep :: RuntimeRep) (r :: TYPE rep). (PrimBytes t, Dimensions (d : ds)) => PackDF t ds d (Dict (Dimensions ds, KnownBackend t ds) -> r) -> DataFrame t (d : ds) -> r -- | Append one DataFrame to another, sum up the first dimension. -- -- If you want to deconstruct a DataFrame, use index or -- slice instead. appendDF :: forall (n :: Nat) (m :: Nat) (ds :: [Nat]) (t :: Type). (PrimBytes t, Dimensions ds, KnownDim n, KnownDim m) => DataFrame t (n :+ ds) -> DataFrame t (m :+ ds) -> DataFrame t ((n + m) :+ ds) -- | Append a small DataFrame to a big DataFrame on the left. -- -- If you want to deconstruct a DataFrame, use index or -- slice instead. consDF :: forall (n :: Nat) (ds :: [Nat]) (t :: Type). (PrimBytes t, Dimensions ds, KnownDim n) => DataFrame t ds -> DataFrame t (n :+ ds) -> DataFrame t ((n + 1) :+ ds) -- | Append a small DataFrame to a big DataFrame on the right. -- -- If you want to deconstruct a DataFrame, use index or -- slice instead. snocDF :: forall (n :: Nat) (ds :: [Nat]) (t :: Type). (PrimBytes t, Dimensions ds, KnownDim n) => DataFrame t (n :+ ds) -> DataFrame t ds -> DataFrame t ((n + 1) :+ ds) -- | Construct a DataFrame from a flat list. -- -- The values are filled according to the DataFrame layout: row-by-row -- and further from the last dimension (least significant) to the first -- dimension (most significant). -- -- If the argument list is shorter than totalDim, then the rest -- of the frame is padded with a default value (second argument). -- -- If the argument list is longer than totalDim, then unused -- values are dropped. If you want, you can pass an infinite list as an -- argument, i.e. the following is a valid use: -- --
-- >>> fromFlatList (dims :: Dims '[2,5]) 0 [6,8..] --fromFlatList :: forall (t :: Type) (ds :: [Nat]). PrimArray t (DataFrame t ds) => Dims ds -> t -> [t] -> DataFrame t ds -- | Construct a DataFrame from a list of smaller DataFrames. -- -- If the argument list is shorter than d, then the rest of the -- frame is padded with a default value (first argument). -- -- If the argument list is longer than d, then unused values are -- dropped. If you want, you can pass an infinite list as an argument. fromListWithDefault :: forall (t :: Type) (d :: Nat) (ds :: [Nat]). (PrimBytes t, Dimensions (d : ds)) => DataFrame t ds -> [DataFrame t ds] -> DataFrame t (d : ds) -- | Construct a dynamic DataFrame from a list of smaller DataFrames. -- Pattern-match against the resulting XFrame to find out its -- dimensionality. -- -- You must not provide an infinite list as an argument. fromList :: forall (t :: Type) (ds :: [Nat]). (PrimBytes t, Dimensions ds) => [DataFrame t ds] -> DataFrame t (XN 0 : AsXDims ds) -- | Try to convert between XNat-indexed DataFrames. -- -- This is useful for imposing restrictions on unknown DataFrames, e.g. -- increasing the minimum number of elements. constrainDF :: forall (ds :: [XNat]) (ys :: [XNat]) (l :: Type) (ts :: l). (BoundedDims ds, All KnownXNatType ds) => DataFrame ts ys -> Maybe (DataFrame ts ds) type KnownBackend t (ds :: [Nat]) = KnownBackend t ds BackendFamily t ds type DFBackend t (ds :: [Nat]) = Backend I t ds BackendFamily t ds -- | I use this kind-polymorphic constraint to generalize XFrame -- and SomeDataFrame over SingleFrame and -- MultiFrame. type family KnownBackends (ts :: l) (ns :: [Nat]) :: Constraint -- | Allow inferring KnownBackends if you know the dimensions and -- the element types. class InferKnownBackend (t :: k) ds inferKnownBackend :: InferKnownBackend t ds => Dict (KnownBackends t ds) -- | Evidence that the elements of the DataFrame are PrimBytes. inferPrimElem :: forall (t :: Type) (d :: Nat) (ds :: [Nat]). KnownBackend t (d : ds) => DataFrame t (d : ds) -> Dict (PrimBytes t) -- | Singleton type to store type-level dimension value. -- -- On the one hand, it can be used to let type-inference system know -- relations between type-level naturals. On the other hand, this is just -- a newtype wrapper on the Word type. -- -- Usually, the type parameter of Dim is either Nat or -- XNat. If dimensionality of your data is known in advance, use -- Nat; if you know the size of some dimensions, but do not know -- the size of others, use XNats to represent them. data Dim (x :: k) :: forall k. () => k -> Type -- | Match against this pattern to bring KnownDim instance into -- scope. pattern D :: forall (n :: Nat). () => KnownDim n => Dim n -- | Match Dim n against a concrete Nat pattern D1 :: forall (n :: Nat). () => n ~ 1 => Dim n -- | Match Dim n against a concrete Nat pattern D25 :: forall (n :: Nat). () => n ~ 25 => Dim n -- | Match Dim n against a concrete Nat pattern D24 :: forall (n :: Nat). () => n ~ 24 => Dim n -- | Match Dim n against a concrete Nat pattern D23 :: forall (n :: Nat). () => n ~ 23 => Dim n -- | Match Dim n against a concrete Nat pattern D22 :: forall (n :: Nat). () => n ~ 22 => Dim n -- | Match Dim n against a concrete Nat pattern D21 :: forall (n :: Nat). () => n ~ 21 => Dim n -- | Match Dim n against a concrete Nat pattern D20 :: forall (n :: Nat). () => n ~ 20 => Dim n -- | Match Dim n against a concrete Nat pattern D19 :: forall (n :: Nat). () => n ~ 19 => Dim n -- | Match Dim n against a concrete Nat pattern D18 :: forall (n :: Nat). () => n ~ 18 => Dim n -- | Match Dim n against a concrete Nat pattern D17 :: forall (n :: Nat). () => n ~ 17 => Dim n -- | Match Dim n against a concrete Nat pattern D16 :: forall (n :: Nat). () => n ~ 16 => Dim n -- | Match Dim n against a concrete Nat pattern D15 :: forall (n :: Nat). () => n ~ 15 => Dim n -- | Match Dim n against a concrete Nat pattern D14 :: forall (n :: Nat). () => n ~ 14 => Dim n -- | Match Dim n against a concrete Nat pattern D13 :: forall (n :: Nat). () => n ~ 13 => Dim n -- | Match Dim n against a concrete Nat pattern D12 :: forall (n :: Nat). () => n ~ 12 => Dim n -- | Match Dim n against a concrete Nat pattern D11 :: forall (n :: Nat). () => n ~ 11 => Dim n -- | Match Dim n against a concrete Nat pattern D10 :: forall (n :: Nat). () => n ~ 10 => Dim n -- | Match Dim n against a concrete Nat pattern D9 :: forall (n :: Nat). () => n ~ 9 => Dim n -- | Match Dim n against a concrete Nat pattern D8 :: forall (n :: Nat). () => n ~ 8 => Dim n -- | Match Dim n against a concrete Nat pattern D7 :: forall (n :: Nat). () => n ~ 7 => Dim n -- | Match Dim n against a concrete Nat pattern D6 :: forall (n :: Nat). () => n ~ 6 => Dim n -- | Match Dim n against a concrete Nat pattern D5 :: forall (n :: Nat). () => n ~ 5 => Dim n -- | Match Dim n against a concrete Nat pattern D4 :: forall (n :: Nat). () => n ~ 4 => Dim n -- | Match Dim n against a concrete Nat pattern D3 :: forall (n :: Nat). () => n ~ 3 => Dim n -- | Match Dim n against a concrete Nat pattern D2 :: forall (n :: Nat). () => n ~ 2 => Dim n -- | Match Dim n against a concrete Nat pattern D0 :: forall (n :: Nat). () => n ~ 0 => Dim n -- | XNat that is unknown at compile time. Same as SomeNat, -- but for a dimension: Hide dimension size inside, but allow specifying -- its minimum possible value. pattern Dx :: forall (xn :: XNat). KnownXNatType xn => forall (n :: Nat) (m :: Nat). (KnownDim n, m <= n, xn ~ XN m) => Dim n -> Dim xn -- | Statically known XNat pattern Dn :: forall (xn :: XNat). KnownXNatType xn => forall (n :: Nat). (KnownDim n, xn ~ N n) => Dim n -> Dim xn -- | This type is used to index a single dimension; the range of indices is -- from 0 to n-1. data Idx (n :: k) :: forall k. () => k -> Type -- | Either known or unknown at compile-time natural number data XNat XN :: Nat -> XNat N :: Nat -> XNat -- | Known natural number type N (n :: Nat) = N n -- | Unknown natural number, known to be not smaller than the given Nat type XN (n :: Nat) = XN n -- | Type-level dimensionality. type Dims (xs :: [k]) = TypedList (Dim :: k -> Type) xs -- | Type-level dimensional indexing with arbitrary Word values inside. -- Most of the operations on it require Dimensions constraint, -- because the Idxs itself does not store info about dimension -- bounds. type Idxs (xs :: [k]) = TypedList (Idx :: k -> Type) xs -- | Type-indexed list data TypedList (f :: k -> Type) (xs :: [k]) :: forall k. () => k -> Type -> [k] -> Type -- | Zero-length type list; synonym to U. pattern Empty :: forall k (f :: k -> Type) (xs :: [k]). () => xs ~ ([] :: [k]) => TypedList f xs -- | Constructing a type-indexed list from the other end pattern Snoc :: forall k (f :: k -> Type) (xs :: [k]). () => forall (sy :: [k]) (y :: k). xs ~ (sy +: y) => TypedList f sy -> f y -> TypedList f xs -- | Reverse a typed list pattern Reverse :: forall k (f :: k -> Type) (xs :: [k]). () => forall (sx :: [k]). (xs ~ Reverse sx, sx ~ Reverse xs) => TypedList f sx -> TypedList f xs -- | Constructing a type-indexed list in the canonical way pattern Cons :: forall k (f :: k -> Type) (xs :: [k]). () => forall (y :: k) (ys :: [k]). xs ~ (y : ys) => f y -> TypedList f ys -> TypedList f xs -- | Pattern matching against this causes RepresentableList instance -- come into scope. Also it allows constructing a term-level list out of -- a constraint. pattern TypeList :: forall k (xs :: [k]). () => RepresentableList xs => TypeList xs -- | Constructing a type-indexed list pattern (:*) :: forall k (f :: k -> Type) (xs :: [k]). () => forall (y :: k) (ys :: [k]). xs ~ (y : ys) => f y -> TypedList f ys -> TypedList f xs -- | Zero-length type list pattern U :: forall k (f :: k -> Type) (xs :: [k]). () => xs ~ ([] :: [k]) => TypedList f xs -- | An easy way to convert Nat-indexed dims into XNat-indexed dims. pattern AsXDims :: forall (ns :: [Nat]). () => (KnownXNatTypes (AsXDims ns), RepresentableList (AsXDims ns)) => Dims (AsXDims ns) -> Dims ns -- | O(1) Pattern-matching against this constructor brings a -- Dimensions instance into the scope. Thus, you can do arbitrary -- operations on your dims and use this pattern at any time to -- reconstruct the class instance at runtime. pattern Dims :: forall (ds :: [Nat]). () => Dimensions ds => Dims ds -- | Pattern-matching against this constructor reveals Nat-kinded list of -- dims, pretending the dimensionality is known at compile time within -- the scope of the pattern match. This is the main recommended way to -- get Dims at runtime; for example, reading a list of dimensions -- from a file. -- -- In order to use this pattern, one must know XNat type -- constructors in each dimension at compile time. pattern XDims :: forall (xns :: [XNat]). KnownXNatTypes xns => forall (ns :: [Nat]). (FixedDims xns ns, Dimensions ns) => Dims ns -> Dims xns -- | O(Length ds) A heavy weapon against all sorts of type errors pattern KnownDims :: forall (ds :: [Nat]). () => (All KnownDim ds, All (BoundedDim :: Nat -> Constraint) ds, RepresentableList ds, Dimensions ds) => Dims ds infixr 5 :* -- | Defines how to read and write your data to and from Haskell unboxed -- byte arrays and plain pointers. -- -- Similarly to Storable, this class provides functions to get the -- size and alignment of a data via phantom arguments. Thus, the size and -- alignment of the data must not depend on the data content (they depend -- only on the type of the data). In particular, this means that -- dynamically sized structures like Haskell lists or maps are not -- allowed. -- -- This module provides default implementations for all methods of this -- class via Generic. Hence, to make your data an instance of -- PrimBytes, it is sufficient to write the instance head: -- --
-- data MyData a b = ... -- deriving Generic -- -- instance (PrimBytes a, PrimBytes b) => PrimBytes (MyData a b) ---- -- .. or use the DeriveAnyClass extension to make it even -- shorter: -- --
-- data MyData a b = ... -- deriving (Generic, PrimBytes) ---- -- The derived instance tries to pack the data as dense as possible, but -- sometimes it is better to write the instance by hand. If a derived -- type has more than one constructor, the derived instance puts a -- Word32 tag at the beginning of the byte representation. All -- fields of a constructor are packed in a C-like fashion next to each -- other, while respecting their alignments. class PrimTagged a => PrimBytes a -- | A wrapper on byteSize bSizeOf :: (PrimBytes a, Num b) => a -> b -- | A wrapper on byteAlign bAlignOf :: (PrimBytes a, Num b) => a -> b -- | A wrapper on byteFieldOffset. bFieldOffsetOf :: forall (name :: Symbol) (a :: Type) (b :: Type). (PrimBytes a, Elem name (PrimFields a), KnownSymbol name, Num b) => a -> b class PrimBytes t => PrimArray t a | a -> t -- | Index array by an integer offset (starting from 0). ixOff :: PrimArray t a => Int -> a -> t instance forall k l (t :: l) (xs :: [k]). (Data.Data.Data (Numeric.DataFrame.Type.DataFrame t xs), Data.Typeable.Internal.Typeable t, Data.Typeable.Internal.Typeable xs, Data.Typeable.Internal.Typeable k, Data.Typeable.Internal.Typeable l) => Data.Data.Data (Numeric.DataFrame.Type.DataFrame' xs t) instance GHC.Classes.Eq (Numeric.DataFrame.Internal.Backend.DFBackend t ds) => GHC.Classes.Eq (Numeric.DataFrame.Type.DataFrame t ds) instance GHC.Classes.Ord (Numeric.DataFrame.Internal.Backend.DFBackend t ds) => GHC.Classes.Ord (Numeric.DataFrame.Type.DataFrame t ds) instance Numeric.ProductOrd.ProductOrder (Numeric.DataFrame.Internal.Backend.DFBackend t ds) => Numeric.ProductOrd.ProductOrder (Numeric.DataFrame.Type.DataFrame t ds) instance GHC.Enum.Bounded (Numeric.DataFrame.Internal.Backend.DFBackend t ds) => GHC.Enum.Bounded (Numeric.DataFrame.Type.DataFrame t ds) instance GHC.Enum.Enum (Numeric.DataFrame.Internal.Backend.DFBackend t ds) => GHC.Enum.Enum (Numeric.DataFrame.Type.DataFrame t ds) instance GHC.Real.Integral (Numeric.DataFrame.Internal.Backend.DFBackend t ds) => GHC.Real.Integral (Numeric.DataFrame.Type.DataFrame t ds) instance GHC.Num.Num (Numeric.DataFrame.Internal.Backend.DFBackend t ds) => GHC.Num.Num (Numeric.DataFrame.Type.DataFrame t ds) instance GHC.Real.Fractional (Numeric.DataFrame.Internal.Backend.DFBackend t ds) => GHC.Real.Fractional (Numeric.DataFrame.Type.DataFrame t ds) instance GHC.Float.Floating (Numeric.DataFrame.Internal.Backend.DFBackend t ds) => GHC.Float.Floating (Numeric.DataFrame.Type.DataFrame t ds) instance GHC.Real.Real (Numeric.DataFrame.Internal.Backend.DFBackend t ds) => GHC.Real.Real (Numeric.DataFrame.Type.DataFrame t ds) instance GHC.Real.RealFrac (Numeric.DataFrame.Internal.Backend.DFBackend t ds) => GHC.Real.RealFrac (Numeric.DataFrame.Type.DataFrame t ds) instance GHC.Float.RealFloat (Numeric.DataFrame.Internal.Backend.DFBackend t ds) => GHC.Float.RealFloat (Numeric.DataFrame.Type.DataFrame t ds) instance Numeric.PrimBytes.PrimBytes (Numeric.DataFrame.Internal.Backend.DFBackend t ds) => Numeric.PrimBytes.PrimBytes (Numeric.DataFrame.Type.DataFrame t ds) instance (Numeric.DataFrame.Internal.PrimArray.PrimArray t (Numeric.DataFrame.Internal.Backend.DFBackend t ds), Numeric.PrimBytes.PrimBytes t) => Numeric.DataFrame.Internal.PrimArray.PrimArray t (Numeric.DataFrame.Type.DataFrame t ds) instance GHC.Generics.Generic (Numeric.DataFrame.Type.DataFrame ts ds) instance (Numeric.PrimBytes.PrimBytes t, Numeric.Dimensions.Dim.Dimensions ds) => GHC.Generics.Generic (Numeric.DataFrame.Type.DataFrame t ds) instance (Data.Data.Data t, Numeric.PrimBytes.PrimBytes t, Data.Typeable.Internal.Typeable ds) => Data.Data.Data (Numeric.DataFrame.Type.DataFrame t ds) instance Numeric.DataFrame.Type.AllFrames GHC.Classes.Eq ts ds => GHC.Classes.Eq (Numeric.DataFrame.Type.DataFrame ts ds) instance (Numeric.DataFrame.Type.AllFrames Data.Data.Data ts ds, Data.Typeable.Internal.Typeable ts, Data.Typeable.Internal.Typeable ds) => Data.Data.Data (Numeric.DataFrame.Type.DataFrame ts ds) instance (Numeric.PrimBytes.PrimBytes t, Numeric.Dimensions.Dim.Dimensions ds) => Numeric.DataFrame.Type.InferKnownBackend t ds instance (Numeric.TypedList.RepresentableList ts, Data.Type.List.All Numeric.PrimBytes.PrimBytes ts, Numeric.Dimensions.Dim.Dimensions ds) => Numeric.DataFrame.Type.InferKnownBackend ts ds instance GHC.Classes.Eq t => GHC.Classes.Eq (Numeric.DataFrame.Type.SomeDataFrame t) instance Data.Type.List.All GHC.Classes.Eq ts => GHC.Classes.Eq (Numeric.DataFrame.Type.SomeDataFrame ts) instance (GHC.Show.Show t, Numeric.PrimBytes.PrimBytes t) => GHC.Show.Show (Numeric.DataFrame.Type.SomeDataFrame t) instance (Data.Type.List.All GHC.Show.Show ts, Data.Type.List.All Numeric.PrimBytes.PrimBytes ts) => GHC.Show.Show (Numeric.DataFrame.Type.SomeDataFrame ts) instance (GHC.Read.Read t, Numeric.PrimBytes.PrimBytes t) => GHC.Read.Read (Numeric.DataFrame.Type.SomeDataFrame t) instance (Data.Type.List.All GHC.Read.Read ts, Data.Type.List.All Numeric.PrimBytes.PrimBytes ts, Numeric.TypedList.RepresentableList ts) => GHC.Read.Read (Numeric.DataFrame.Type.SomeDataFrame ts) instance GHC.Classes.Ord (Numeric.ProductOrd.NonTransitive.ProductOrd (Numeric.DataFrame.Internal.Backend.DFBackend t ds)) => GHC.Classes.Ord (Numeric.ProductOrd.NonTransitive.ProductOrd (Numeric.DataFrame.Type.DataFrame t ds)) instance (GHC.Classes.Ord (Numeric.ProductOrd.Partial.ProductOrd (Numeric.DataFrame.Internal.Backend.DFBackend t ds)), GHC.Classes.Eq (Numeric.DataFrame.Internal.Backend.DFBackend t ds)) => GHC.Classes.Ord (Numeric.ProductOrd.Partial.ProductOrd (Numeric.DataFrame.Type.DataFrame t ds)) instance forall k l (t :: l) (ds :: [k]). Numeric.PrimBytes.PrimBytes (Numeric.DataFrame.Type.DataFrame t ds) => Foreign.Storable.Storable (Numeric.DataFrame.Type.DataFrame t ds) instance GHC.Classes.Eq t => GHC.Classes.Eq (Numeric.DataFrame.Type.DataFrame t ds) instance Data.Type.List.All GHC.Classes.Eq ts => GHC.Classes.Eq (Numeric.DataFrame.Type.DataFrame ts ds) instance (GHC.Show.Show t, Numeric.PrimBytes.PrimBytes t, Numeric.Dimensions.Dim.Dimensions ds) => GHC.Show.Show (Numeric.DataFrame.Type.DataFrame t ds) instance (Data.Type.List.All GHC.Show.Show ts, Data.Type.List.All Numeric.PrimBytes.PrimBytes ts, Numeric.Dimensions.Dim.Dimensions ds) => GHC.Show.Show (Numeric.DataFrame.Type.DataFrame ts ds) instance (GHC.Show.Show t, Numeric.PrimBytes.PrimBytes t) => GHC.Show.Show (Numeric.DataFrame.Type.DataFrame t xns) instance (Data.Type.List.All GHC.Show.Show ts, Data.Type.List.All Numeric.PrimBytes.PrimBytes ts) => GHC.Show.Show (Numeric.DataFrame.Type.DataFrame ts xns) instance (GHC.Read.Read t, Numeric.PrimBytes.PrimBytes t, Numeric.Dimensions.Dim.Dimensions ds) => GHC.Read.Read (Numeric.DataFrame.Type.DataFrame t ds) instance (Data.Type.List.All GHC.Read.Read ts, Data.Type.List.All Numeric.PrimBytes.PrimBytes ts, Numeric.TypedList.RepresentableList ts, Numeric.Dimensions.Dim.Dimensions ds) => GHC.Read.Read (Numeric.DataFrame.Type.DataFrame ts ds) instance (GHC.Read.Read t, Numeric.PrimBytes.PrimBytes t, Numeric.Dimensions.Dim.BoundedDims ds, Data.Type.List.All Numeric.Dimensions.Dim.KnownXNatType ds) => GHC.Read.Read (Numeric.DataFrame.Type.DataFrame t ds) instance (Data.Type.List.All GHC.Read.Read ts, Data.Type.List.All Numeric.PrimBytes.PrimBytes ts, Numeric.TypedList.RepresentableList ts, Numeric.Dimensions.Dim.BoundedDims ds, Data.Type.List.All Numeric.Dimensions.Dim.KnownXNatType ds) => GHC.Read.Read (Numeric.DataFrame.Type.DataFrame ts ds) module Numeric.DataFrame.SubSpace -- | Operations on DataFrames -- -- as is an indexing dimensionality -- -- bs is an element dimensionality -- -- t is an underlying data type (i.e. Float, Int, Double) class (ConcatList as bs asbs, Dimensions as, Dimensions bs, Dimensions asbs, PrimArray t (DataFrame t bs), PrimArray t (DataFrame t asbs), PrimBytes (DataFrame t bs), PrimBytes (DataFrame t asbs)) => SubSpace (t :: Type) (as :: [Nat]) (bs :: [Nat]) (asbs :: [Nat]) | asbs as -> bs, asbs bs -> as, as bs -> asbs -- | Unsafely get a sub-dataframe by its primitive element offset. The -- offset is not checked to be aligned to the space structure or for -- bounds. Arguments are zero-based primitive element offset and subset -- ("bs" element) size (aka totalDim of sub dataframe) -- -- Normal indexing can be expressed in terms of indexOffset#: -- --
-- index i = case (# dimVal (dim @bs), fromEnum i #) of (# I# n, I# j #) -> indexOffset# (n *# j) --indexOffset# :: SubSpace t as bs asbs => Int# -> DataFrame t asbs -> DataFrame t bs -- | Unsafely update a sub-dataframe by its primitive element offset. The -- offset is not checked to be aligned to the space structure or for -- bounds. Arguments are zero-based primitive element offset and subset -- ("bs" element) size (aka totalDim of sub dataframe) -- -- Normal updating can be expressed in terms of indexOffset#: -- --
-- update i = case (# dimVal (dim @bs), fromEnum i #) of (# I# n, I# j #) -> updateOffset# (n *# j) --updateOffset# :: SubSpace t as bs asbs => Int# -> DataFrame t bs -> DataFrame t asbs -> DataFrame t asbs -- | Get an element by its index in the dataframe index :: SubSpace t as bs asbs => Idxs as -> DataFrame t asbs -> DataFrame t bs -- | Get a few contiguous elements. -- -- In a sense, this is just a more complicated version of index. slice :: forall (bi :: Nat) (bd :: Nat) (b' :: Nat) (bs' :: [Nat]). (SubSpace t as bs asbs, b' ~ ((bi + bd) - 1), bs ~ (b' :+ bs'), KnownDim bd) => Idxs (as +: bi) -> DataFrame t asbs -> DataFrame t (bd :+ bs') -- | Set a new value to an element update :: SubSpace t as bs asbs => Idxs as -> DataFrame t bs -> DataFrame t asbs -> DataFrame t asbs -- | Update a few contiguous elements -- -- In a sense, this is just a more complicated version of update. updateSlice :: forall (bi :: Nat) (bd :: Nat) (b' :: Nat) (bs' :: [Nat]). (SubSpace t as bs asbs, b' ~ ((bi + bd) - 1), bs ~ (b' :+ bs'), KnownDim bd) => Idxs (as +: bi) -> DataFrame t (bd :+ bs') -> DataFrame t asbs -> DataFrame t asbs -- | Map a function over each element of DataFrame ewmap :: forall s (bs' :: [Nat]) (asbs' :: [Nat]). (SubSpace t as bs asbs, SubSpace s as bs' asbs') => (DataFrame s bs' -> DataFrame t bs) -> DataFrame s asbs' -> DataFrame t asbs -- | Map a function over each element with its index of DataFrame iwmap :: forall s (bs' :: [Nat]) (asbs' :: [Nat]). (SubSpace t as bs asbs, SubSpace s as bs' asbs') => (Idxs as -> DataFrame s bs' -> DataFrame t bs) -> DataFrame s asbs' -> DataFrame t asbs -- | Generate a DataFrame by repeating an element ewgen :: SubSpace t as bs asbs => DataFrame t bs -> DataFrame t asbs -- | Generate a DataFrame by iterating a function (index -> element) iwgen :: SubSpace t as bs asbs => (Idxs as -> DataFrame t bs) -> DataFrame t asbs -- | Left-associative fold of a DataFrame. The fold is strict, so -- accumulater is evaluated to WHNF; but you'd better make sure that the -- function is strict enough to not produce memory leaks deeply inside -- the result data type. ewfoldl :: SubSpace t as bs asbs => (b -> DataFrame t bs -> b) -> b -> DataFrame t asbs -> b -- | Left-associative fold of a DataFrame with an index The fold is strict, -- so accumulater is evaluated to WHNF; but you'd better make sure that -- the function is strict enough to not produce memory leaks deeply -- inside the result data type. iwfoldl :: SubSpace t as bs asbs => (Idxs as -> b -> DataFrame t bs -> b) -> b -> DataFrame t asbs -> b -- | Right-associative fold of a DataFrame The fold is strict, so -- accumulater is evaluated to WHNF; but you'd better make sure that the -- function is strict enough to not produce memory leaks deeply inside -- the result data type. ewfoldr :: SubSpace t as bs asbs => (DataFrame t bs -> b -> b) -> b -> DataFrame t asbs -> b -- | Right-associative fold of a DataFrame with an index The fold is -- strict, so accumulater is evaluated to WHNF; but you'd better make -- sure that the function is strict enough to not produce memory leaks -- deeply inside the result data type. iwfoldr :: SubSpace t as bs asbs => (Idxs as -> DataFrame t bs -> b -> b) -> b -> DataFrame t asbs -> b -- | Apply an applicative functor on each element (Lens-like traversal) elementWise :: forall (s :: Type) (bs' :: [Nat]) (asbs' :: [Nat]) (f :: Type -> Type). (SubSpace t as bs asbs, Applicative f, SubSpace s as bs' asbs') => (DataFrame s bs' -> f (DataFrame t bs)) -> DataFrame s asbs' -> f (DataFrame t asbs) -- | Apply an applicative functor on each element with its index (Lens-like -- indexed traversal) indexWise :: forall (s :: Type) (bs' :: [Nat]) (asbs' :: [Nat]) (f :: Type -> Type). (SubSpace t as bs asbs, Applicative f, SubSpace s as bs' asbs') => (Idxs as -> DataFrame s bs' -> f (DataFrame t bs)) -> DataFrame s asbs' -> f (DataFrame t asbs) -- | Index an element (reverse arguments of index) (!) :: SubSpace t (as :: [Nat]) (bs :: [Nat]) (asbs :: [Nat]) => DataFrame t asbs -> Idxs as -> DataFrame t bs infixl 4 ! -- | Apply a functor over a single element (simple lens) element :: forall t (as :: [Nat]) (bs :: [Nat]) (asbs :: [Nat]) f. (SubSpace t as bs asbs, Applicative f) => Idxs as -> (DataFrame t bs -> f (DataFrame t bs)) -> DataFrame t asbs -> f (DataFrame t asbs) ewfoldMap :: forall t (as :: [Nat]) (bs :: [Nat]) (asbs :: [Nat]) m. (Monoid m, SubSpace t as bs asbs) => (DataFrame t bs -> m) -> DataFrame t asbs -> m iwfoldMap :: forall t (as :: [Nat]) (bs :: [Nat]) (asbs :: [Nat]) m. (Monoid m, SubSpace t as bs asbs) => (Idxs as -> DataFrame t bs -> m) -> DataFrame t asbs -> m -- | Zip two spaces on a specified subspace element-wise (without index) ewzip :: forall t (as :: [Nat]) (bs :: [Nat]) (asbs :: [Nat]) s (bs' :: [Nat]) (asbs' :: [Nat]) r (bs'' :: [Nat]) (asbs'' :: [Nat]). (SubSpace t as bs asbs, SubSpace s as bs' asbs', SubSpace r as bs'' asbs'') => (DataFrame t bs -> DataFrame s bs' -> DataFrame r bs'') -> DataFrame t asbs -> DataFrame s asbs' -> DataFrame r asbs'' -- | Zip two spaces on a specified subspace index-wise (with index) iwzip :: forall t (as :: [Nat]) (bs :: [Nat]) (asbs :: [Nat]) s (bs' :: [Nat]) (asbs' :: [Nat]) r (bs'' :: [Nat]) (asbs'' :: [Nat]). (SubSpace t as bs asbs, SubSpace s as bs' asbs', SubSpace r as bs'' asbs'') => (Idxs as -> DataFrame t bs -> DataFrame s bs' -> DataFrame r bs'') -> DataFrame t asbs -> DataFrame s asbs' -> DataFrame r asbs'' -- | Apply an applicative functor on each element with its index (Lens-like -- indexed traversal) indexWise_ :: forall t as bs asbs f b. (SubSpace t as bs asbs, Applicative f) => (Idxs as -> DataFrame t bs -> f b) -> DataFrame t asbs -> f () -- | Apply an applicative functor on each element (Lens-like traversal) elementWise_ :: forall t as bs asbs f b. (SubSpace t as bs asbs, Applicative f) => (DataFrame t bs -> f b) -> DataFrame t asbs -> f () instance (Data.Type.List.ConcatList as bs asbs, Numeric.Dimensions.Dim.Dimensions as, Numeric.Dimensions.Dim.Dimensions bs, Numeric.Dimensions.Dim.Dimensions asbs, Numeric.DataFrame.Internal.PrimArray.PrimArray t (Numeric.DataFrame.Type.DataFrame t bs), Numeric.DataFrame.Internal.PrimArray.PrimArray t (Numeric.DataFrame.Type.DataFrame t asbs), Numeric.PrimBytes.PrimBytes (Numeric.DataFrame.Type.DataFrame t bs), Numeric.PrimBytes.PrimBytes (Numeric.DataFrame.Type.DataFrame t asbs)) => Numeric.DataFrame.SubSpace.SubSpace t as bs asbs -- | Interfrace to perform primitive stateful operations on mutable frames. module Numeric.DataFrame.Internal.Mutable -- | Mutable DataFrame type. Keeps element offset, number of elements, and -- a mutable byte storage data MDataFrame s t (ns :: [Nat]) -- | Create a new mutable DataFrame. newDataFrame# :: forall t (ns :: [Nat]) s. (PrimBytes t, Dimensions ns) => State# s -> (# State# s, MDataFrame s t ns #) -- | Create a new mutable DataFrame. newPinnedDataFrame# :: forall t (ns :: [Nat]) s. (PrimBytes t, Dimensions ns) => State# s -> (# State# s, MDataFrame s t ns #) -- | Copy one DataFrame into another mutable DataFrame at specified -- position. -- -- In contrast to copyDataFrame', this function allows to copy -- over a range of contiguous indices over a single dimension. For -- example, you can write a 3x4 matrix into a 7x4 matrix, starting at -- indices 0..3. copyDataFrame# :: forall (t :: Type) (b :: Nat) (bi :: Nat) (bd :: Nat) (as :: [Nat]) (bs :: [Nat]) (asbs :: [Nat]) s. (b ~ ((bi + bd) - 1), PrimBytes t, PrimBytes (DataFrame t (bd :+ bs)), ConcatList as (b :+ bs) asbs) => Idxs (as +: bi) -> DataFrame t (bd :+ bs) -> MDataFrame s t asbs -> State# s -> (# State# s, () #) -- | Copy one mutable DataFrame into another mutable DataFrame at specified -- position. -- -- In contrast to copyMDataFrame', this function allows to copy -- over a range of contiguous indices over a single dimension. For -- example, you can write a 3x4 matrix into a 7x4 matrix, starting at -- indices 0..3. copyMDataFrame# :: forall (t :: Type) (b :: Nat) (bi :: Nat) (bd :: Nat) (as :: [Nat]) (bs :: [Nat]) (asbs :: [Nat]) s. (b ~ ((bi + bd) - 1), PrimBytes t, ConcatList as (b :+ bs) asbs) => Idxs (as +: bi) -> MDataFrame s t (bd :+ bs) -> MDataFrame s t asbs -> State# s -> (# State# s, () #) -- | Copy one DataFrame into another mutable DataFrame at specified -- position. -- -- This is a simpler version of copyDataFrame that allows to -- copy over one index at a time. copyDataFrame'# :: forall (t :: Type) (as :: [Nat]) (bs :: [Nat]) (asbs :: [Nat]) s. (PrimBytes t, PrimBytes (DataFrame t bs), ConcatList as bs asbs) => Idxs as -> DataFrame t bs -> MDataFrame s t asbs -> State# s -> (# State# s, () #) -- | Copy one mutable DataFrame into another mutable DataFrame at specified -- position. -- -- This is a simpler version of copyMDataFrame that allows to -- copy over one index at a time. copyMDataFrame'# :: forall (t :: Type) (as :: [Nat]) (bs :: [Nat]) (asbs :: [Nat]) s. (PrimBytes t, ConcatList as bs asbs) => Idxs as -> MDataFrame s t bs -> MDataFrame s t asbs -> State# s -> (# State# s, () #) -- | Copy content of a mutable DataFrame into a new immutable DataFrame. freezeDataFrame# :: forall (t :: Type) (ns :: [Nat]) s. PrimArray t (DataFrame t ns) => MDataFrame s t ns -> State# s -> (# State# s, DataFrame t ns #) -- | Make a mutable DataFrame immutable, without copying. unsafeFreezeDataFrame# :: forall (t :: Type) (ns :: [Nat]) s. PrimArray t (DataFrame t ns) => MDataFrame s t ns -> State# s -> (# State# s, DataFrame t ns #) -- | Create a new mutable DataFrame and copy content of immutable one in -- there. thawDataFrame# :: forall (t :: Type) (ns :: [Nat]) s. (Dimensions ns, PrimBytes (DataFrame t ns)) => DataFrame t ns -> State# s -> (# State# s, MDataFrame s t ns #) -- | Create a new mutable DataFrame and copy content of immutable one in -- there. The result array is pinned and aligned. thawPinDataFrame# :: forall (t :: Type) (ns :: [Nat]) s. (Dimensions ns, PrimBytes (DataFrame t ns)) => DataFrame t ns -> State# s -> (# State# s, MDataFrame s t ns #) -- | UnsafeCoerces an underlying byte array. unsafeThawDataFrame# :: forall (t :: Type) (ns :: [Nat]) s. (Dimensions ns, PrimBytes (DataFrame t ns), PrimBytes t) => DataFrame t ns -> State# s -> (# State# s, MDataFrame s t ns #) -- | Write a single element at the specified index writeDataFrame# :: forall (t :: Type) (ns :: [Nat]) s. PrimBytes t => MDataFrame s t ns -> Idxs ns -> t -> State# s -> (# State# s, () #) -- | Write a single element at the specified element offset writeDataFrameOff# :: forall (t :: Type) (ns :: [Nat]) s. PrimBytes t => MDataFrame s t ns -> Int# -> t -> State# s -> (# State# s, () #) -- | Read a single element at the specified index readDataFrame# :: forall (t :: Type) (ns :: [Nat]) s. PrimBytes t => MDataFrame s t ns -> Idxs ns -> State# s -> (# State# s, t #) -- | Read a single element at the specified element offset readDataFrameOff# :: forall (t :: Type) (ns :: [Nat]) s. PrimBytes t => MDataFrame s t ns -> Int# -> State# s -> (# State# s, t #) -- | Allow arbitrary operations on a pointer to the beginning of the data. -- Only possible with RealWord state (thus, in IO) due -- to semantics of touch# operation that keeps the data from -- being garbage collected. withDataFramePtr# :: forall (t :: Type) (ns :: [Nat]) (r :: Type). PrimBytes t => MDataFrame RealWorld t ns -> (Addr# -> State# RealWorld -> (# State# RealWorld, r #)) -> State# RealWorld -> (# State# RealWorld, r #) -- | Check if the byte array wrapped by this DataFrame is pinned, which -- means cannot be relocated by GC. isDataFramePinned# :: forall (t :: Type) (ns :: [Nat]) s. MDataFrame s t ns -> Bool -- | Mutable DataFrames living in ST. module Numeric.DataFrame.ST -- | Mutable DataFrame that lives in ST. Internal representation is always -- a MutableByteArray. data family STDataFrame s (t :: Type) (ns :: [k]) -- | Mutable DataFrame of unknown dimensionality data SomeSTDataFrame s (t :: Type) SomeSTDataFrame :: STDataFrame s t ns -> SomeSTDataFrame s -- | Create a new mutable DataFrame. newDataFrame :: forall t (ns :: [Nat]) s. (PrimBytes t, Dimensions ns) => ST s (STDataFrame s t ns) -- | Create a new mutable DataFrame. newPinnedDataFrame :: forall t (ns :: [Nat]) s. (PrimBytes t, Dimensions ns) => ST s (STDataFrame s t ns) -- | Copy one DataFrame into another mutable DataFrame at specified -- position. -- -- In contrast to copyMDataFrame', this function allows to copy -- over a range of contiguous indices over a single dimension. For -- example, you can write a 3x4 matrix into a 7x4 matrix, starting at -- indices 0..3. copyDataFrame :: forall (t :: Type) (b :: Nat) (bi :: Nat) (bd :: Nat) (as :: [Nat]) (bs :: [Nat]) (asbs :: [Nat]) s. (b ~ ((bi + bd) - 1), PrimBytes t, PrimBytes (DataFrame t (bd :+ bs)), ConcatList as (b :+ bs) asbs) => Idxs (as +: bi) -> DataFrame t (bd :+ bs) -> STDataFrame s t asbs -> ST s () -- | Copy one mutable DataFrame into another mutable DataFrame at specified -- position. -- -- In contrast to copyMDataFrame', this function allows to copy -- over a range of contiguous indices over a single dimension. For -- example, you can write a 3x4 matrix into a 7x4 matrix, starting at -- indices 0..3. copyMutableDataFrame :: forall (t :: Type) (b :: Nat) (bi :: Nat) (bd :: Nat) (as :: [Nat]) (bs :: [Nat]) (asbs :: [Nat]) s. (b ~ ((bi + bd) - 1), PrimBytes t, ConcatList as (b :+ bs) asbs) => Idxs (as +: bi) -> STDataFrame s t (bd :+ bs) -> STDataFrame s t asbs -> ST s () -- | Copy one DataFrame into another mutable DataFrame at specified -- position. -- -- This is a simpler version of copyDataFrame that allows to -- copy over one index at a time. copyDataFrame' :: forall (t :: Type) (as :: [Nat]) (bs :: [Nat]) (asbs :: [Nat]) s. (PrimBytes t, PrimBytes (DataFrame t bs), ConcatList as bs asbs) => Idxs as -> DataFrame t bs -> STDataFrame s t asbs -> ST s () -- | Copy one mutable DataFrame into another mutable DataFrame at specified -- position. -- -- This is a simpler version of copyDataFrame that allows to -- copy over one index at a time. copyMutableDataFrame' :: forall (t :: Type) (as :: [Nat]) (bs :: [Nat]) (asbs :: [Nat]) s. (PrimBytes t, ConcatList as bs asbs) => Idxs as -> STDataFrame s t bs -> STDataFrame s t asbs -> ST s () -- | Copy content of a mutable DataFrame into a new immutable DataFrame. freezeDataFrame :: forall (t :: Type) (ns :: [Nat]) s. PrimArray t (DataFrame t ns) => STDataFrame s t ns -> ST s (DataFrame t ns) -- | Make a mutable DataFrame immutable, without copying. unsafeFreezeDataFrame :: forall (t :: Type) (ns :: [Nat]) s. PrimArray t (DataFrame t ns) => STDataFrame s t ns -> ST s (DataFrame t ns) -- | Create a new mutable DataFrame and copy content of immutable one in -- there. thawDataFrame :: forall (t :: Type) (ns :: [Nat]) s. (Dimensions ns, PrimBytes (DataFrame t ns)) => DataFrame t ns -> ST s (STDataFrame s t ns) -- | Create a new mutable DataFrame and copy content of immutable one in -- there. The result array is pinned and aligned. thawPinDataFrame :: forall (t :: Type) (ns :: [Nat]) s. (Dimensions ns, PrimBytes (DataFrame t ns)) => DataFrame t ns -> ST s (STDataFrame s t ns) -- | UnsafeCoerces an underlying byte array. unsafeThawDataFrame :: forall (t :: Type) (ns :: [Nat]) s. (Dimensions ns, PrimBytes (DataFrame t ns), PrimBytes t) => DataFrame t ns -> ST s (STDataFrame s t ns) -- | Write a single element at the specified index writeDataFrame :: forall t (ns :: [Nat]) s. PrimBytes t => STDataFrame s t ns -> Idxs ns -> DataFrame t ('[] :: [Nat]) -> ST s () -- | Write a single element at the specified element offset writeDataFrameOff :: forall (t :: Type) (ns :: [Nat]) s. PrimBytes t => STDataFrame s t ns -> Int -> DataFrame t ('[] :: [Nat]) -> ST s () -- | Read a single element at the specified index readDataFrame :: forall (t :: Type) (ns :: [Nat]) s. PrimBytes t => STDataFrame s t ns -> Idxs ns -> ST s (DataFrame t ('[] :: [Nat])) -- | Read a single element at the specified element offset readDataFrameOff :: forall (t :: Type) (ns :: [Nat]) s. PrimBytes t => STDataFrame s t ns -> Int -> ST s (DataFrame t ('[] :: [Nat])) -- | Check if the byte array wrapped by this DataFrame is pinned, which -- means cannot be relocated by GC. isDataFramePinned :: forall (k :: Type) (t :: Type) (ns :: [k]) s. KnownDimKind k => STDataFrame s t ns -> Bool -- | Mutable DataFrames living in IO. module Numeric.DataFrame.IO -- | Mutable DataFrame that lives in IO. Internal representation is always -- a MutableByteArray. data family IODataFrame (t :: Type) (ns :: [k]) -- | Mutable DataFrame of unknown dimensionality data SomeIODataFrame (t :: Type) SomeIODataFrame :: IODataFrame t ns -> SomeIODataFrame -- | Create a new mutable DataFrame. newDataFrame :: forall t (ns :: [Nat]). (PrimBytes t, Dimensions ns) => IO (IODataFrame t ns) -- | Create a new mutable DataFrame. newPinnedDataFrame :: forall t (ns :: [Nat]). (PrimBytes t, Dimensions ns) => IO (IODataFrame t ns) -- | Copy one DataFrame into another mutable DataFrame at specified -- position. -- -- In contrast to copyMDataFrame', this function allows to copy -- over a range of contiguous indices over a single dimension. For -- example, you can write a 3x4 matrix into a 7x4 matrix, starting at -- indices 0..3. copyDataFrame :: forall (t :: Type) (b :: Nat) (bi :: Nat) (bd :: Nat) (as :: [Nat]) (bs :: [Nat]) (asbs :: [Nat]). (b ~ ((bi + bd) - 1), PrimBytes t, PrimBytes (DataFrame t (bd :+ bs)), ConcatList as (b :+ bs) asbs) => Idxs (as +: bi) -> DataFrame t (bd :+ bs) -> IODataFrame t asbs -> IO () -- | Copy one mutable DataFrame into another mutable DataFrame at specified -- position. -- -- In contrast to copyMDataFrame', this function allows to copy -- over a range of contiguous indices over a single dimension. For -- example, you can write a 3x4 matrix into a 7x4 matrix, starting at -- indices 0..3. copyMutableDataFrame :: forall (t :: Type) (b :: Nat) (bi :: Nat) (bd :: Nat) (as :: [Nat]) (bs :: [Nat]) (asbs :: [Nat]). (b ~ ((bi + bd) - 1), PrimBytes t, ConcatList as (b :+ bs) asbs) => Idxs (as +: bi) -> IODataFrame t (bd :+ bs) -> IODataFrame t asbs -> IO () -- | Copy one DataFrame into another mutable DataFrame at specified -- position. -- -- This is a simpler version of copyDataFrame that allows to -- copy over one index at a time. copyDataFrame' :: forall (t :: Type) (as :: [Nat]) (bs :: [Nat]) (asbs :: [Nat]). (PrimBytes t, PrimBytes (DataFrame t bs), ConcatList as bs asbs) => Idxs as -> DataFrame t bs -> IODataFrame t asbs -> IO () -- | Copy one mutable DataFrame into another mutable DataFrame at specified -- position. -- -- This is a simpler version of copyDataFrame that allows to -- copy over one index at a time. copyMutableDataFrame' :: forall (t :: Type) (as :: [Nat]) (bs :: [Nat]) (asbs :: [Nat]). (PrimBytes t, ConcatList as bs asbs) => Idxs as -> IODataFrame t bs -> IODataFrame t asbs -> IO () -- | Copy content of a mutable DataFrame into a new immutable DataFrame. freezeDataFrame :: forall (t :: Type) (ns :: [Nat]). PrimArray t (DataFrame t ns) => IODataFrame t ns -> IO (DataFrame t ns) -- | Make a mutable DataFrame immutable, without copying. unsafeFreezeDataFrame :: forall (t :: Type) (ns :: [Nat]). PrimArray t (DataFrame t ns) => IODataFrame t ns -> IO (DataFrame t ns) -- | Create a new mutable DataFrame and copy content of immutable one in -- there. thawDataFrame :: forall (t :: Type) (ns :: [Nat]). (Dimensions ns, PrimBytes (DataFrame t ns)) => DataFrame t ns -> IO (IODataFrame t ns) -- | Create a new mutable DataFrame and copy content of immutable one in -- there. The result array is pinned and aligned. thawPinDataFrame :: forall (t :: Type) (ns :: [Nat]). (Dimensions ns, PrimBytes (DataFrame t ns)) => DataFrame t ns -> IO (IODataFrame t ns) -- | UnsafeCoerces an underlying byte array. unsafeThawDataFrame :: forall (t :: Type) (ns :: [Nat]). (Dimensions ns, PrimBytes (DataFrame t ns), PrimBytes t) => DataFrame t ns -> IO (IODataFrame t ns) -- | Write a single element at the specified index writeDataFrame :: forall t (ns :: [Nat]). PrimBytes t => IODataFrame t ns -> Idxs ns -> DataFrame t ('[] :: [Nat]) -> IO () -- | Write a single element at the specified element offset writeDataFrameOff :: forall (t :: Type) (ns :: [Nat]). PrimBytes t => IODataFrame t ns -> Int -> DataFrame t ('[] :: [Nat]) -> IO () -- | Read a single element at the specified index readDataFrame :: forall (t :: Type) (ns :: [Nat]). PrimBytes t => IODataFrame t ns -> Idxs ns -> IO (DataFrame t ('[] :: [Nat])) -- | Read a single element at the specified element offset readDataFrameOff :: forall (t :: Type) (ns :: [Nat]). PrimBytes t => IODataFrame t ns -> Int -> IO (DataFrame t ('[] :: [Nat])) -- | Allow arbitrary IO operations on a pointer to the beginning of the -- data keeping the data from garbage collecting until the arg function -- returns. -- -- Warning: do not let Ptr t leave the scope of the arg -- function, the data may be garbage-collected by then. -- -- Warning: use this function on a pinned DataFrame only; otherwise, the -- data may be relocated before the arg fun finishes. withDataFramePtr :: forall (k :: Type) (t :: Type) (ns :: [k]) (r :: Type). (PrimBytes t, KnownDimKind k) => IODataFrame t ns -> (Ptr t -> IO r) -> IO r -- | Check if the byte array wrapped by this DataFrame is pinned, which -- means cannot be relocated by GC. isDataFramePinned :: forall (k :: Type) (t :: Type) (ns :: [k]). KnownDimKind k => IODataFrame t ns -> Bool -- | This modules provides generalization of a matrix product: tensor-like -- contraction. For matrices and vectors this is a normal matrix*matrix -- or vector*matrix or matrix*vector product, for larger dimensions it -- calculates the scalar product of "adjacent" dimesnions of a tensor. module Numeric.DataFrame.Contraction class ConcatList as bs asbs => Contraction (t :: Type) (as :: [Nat]) (bs :: [Nat]) (asbs :: [Nat]) | asbs as -> bs, asbs bs -> as, as bs -> asbs -- | Generalization of a matrix product: take scalar product over one -- dimension and, thus, concatenate other dimesnions contract :: (Contraction t as bs asbs, KnownDim m, PrimArray t (DataFrame t (as +: m)), PrimArray t (DataFrame t (m :+ bs)), PrimArray t (DataFrame t asbs)) => DataFrame t (as +: m) -> DataFrame t (m :+ bs) -> DataFrame t asbs -- | Tensor contraction. In particular: 1. matrix-matrix product 2. -- matrix-vector or vector-matrix product 3. dot product of two vectors. (%*) :: (Contraction t as bs asbs, KnownDim m, PrimArray t (DataFrame t (as +: m)), PrimArray t (DataFrame t (m :+ bs)), PrimArray t (DataFrame t asbs)) => DataFrame t (as +: m) -> DataFrame t (m :+ bs) -> DataFrame t asbs infixl 7 %* instance (Data.Type.List.ConcatList as bs asbs, Numeric.Dimensions.Dim.Dimensions as, Numeric.Dimensions.Dim.Dimensions bs, GHC.Num.Num t) => Numeric.DataFrame.Contraction.Contraction t as bs asbs module Numeric.DataFrame.Internal.Backend -- | Implementation behind the DataFrame type DFBackend (t :: Type) (ds :: [Nat]) = Backend I t ds (BackendFamily t ds) -- | A newtype wrapper for all DataFrame implementations. I need two layers -- of wrappers to provide default overlappable instances to all type -- classes using KnownBackend mechanics. Type arguments are redundant -- here; nevertheless, they improve readability of error messages. newtype Backend (i :: Type) (t :: Type) (ds :: [Nat]) (backend :: Type) Backend :: backend -> Backend [_getBackend] :: Backend -> backend -- | This type family aggregates all types used for arrays with different -- dimensioinality. The family is injective; thus, it is possible to get -- type family instance given the data constructor (and vice versa). If -- GHC knows the dimensionality of a backend at compile time, it chooses -- a more efficient specialized instance of BackendFamily, e.g. -- Scalar newtype wrapper. Otherwise, it falls back to the generic -- ArrayBase implementation. -- -- Data family would not work here, because it would give overlapping -- instances. type family BackendFamily (t :: Type) (ds :: [Nat]) = (v :: Type) | v -> t ds -- | Backend resolver: Use this constraint to find any class instances -- defined for all DataFrame implementations, e.g. Num, -- PrimBytes, etc. type KnownBackend (t :: Type) (ds :: [Nat]) = KnownBackend t ds (BackendFamily t ds) inferKnownBackend :: forall (t :: Type) (ds :: [Nat]). (PrimBytes t, Dimensions ds) => Dict (KnownBackend t ds) inferPrimElem :: forall (t :: Type) (d :: Nat) (ds :: [Nat]). KnownBackend t (d : ds) => DFBackend t (d : ds) -> Dict (PrimBytes t) inferEq :: forall (t :: Type) (ds :: [Nat]) (b :: Type). (Eq t, KnownBackend t ds b) => Dict (Eq (Backend I t ds b)) inferOrd :: forall (t :: Type) (ds :: [Nat]) (b :: Type). (Ord t, KnownBackend t ds b) => Dict (Ord (Backend I t ds b)) inferProductOrder :: forall (t :: Type) (ds :: [Nat]) (b :: Type). (Ord t, KnownBackend t ds b) => Dict (ProductOrder (Backend I t ds b)) inferPONonTransitive :: forall (t :: Type) (ds :: [Nat]) (b :: Type). (Ord t, KnownBackend t ds b) => Dict (Ord (ProductOrd (Backend I t ds b))) inferPOPartial :: forall (t :: Type) (ds :: [Nat]) (b :: Type). (Ord t, KnownBackend t ds b) => Dict (Ord (ProductOrd (Backend I t ds b))) inferBounded :: forall (t :: Type) (ds :: [Nat]) (b :: Type). (Bounded t, KnownBackend t ds b) => Dict (Bounded (Backend I t ds b)) inferNum :: forall (t :: Type) (ds :: [Nat]) (b :: Type). (Num t, KnownBackend t ds b) => Dict (Num (Backend I t ds b)) inferFractional :: forall (t :: Type) (ds :: [Nat]) (b :: Type). (Fractional t, KnownBackend t ds b) => Dict (Fractional (Backend I t ds b)) inferFloating :: forall (t :: Type) (ds :: [Nat]) (b :: Type). (Floating t, KnownBackend t ds b) => Dict (Floating (Backend I t ds b)) inferPrimBytes :: forall (t :: Type) (ds :: [Nat]) (b :: Type). (PrimBytes t, Dimensions ds, KnownBackend t ds b) => Dict (PrimBytes (Backend I t ds b)) inferPrimArray :: forall (t :: Type) (ds :: [Nat]) (b :: Type). (PrimBytes t, KnownBackend t ds b) => Dict (PrimArray t (Backend I t ds b)) -- | Scalar is an alias to zero-dimensional DataFrame module Numeric.Scalar -- | Alias for zero-dimensional DataFrame type Scalar t = DataFrame t ('[] :: [Nat]) -- | Convert scalar back to ordinary type unScalar :: Scalar t -> t -- | Convert any type to scalar wrapper scalar :: t -> Scalar t -- | Broadcast scalar value onto a whole data frame fromScalar :: SubSpace t ds '[] ds => Scalar t -> DataFrame t ds type Scf = Scalar Float type Scd = Scalar Double type Sci = Scalar Int type Scw = Scalar Word -- | Vector is an alias to a DataFrame with order 1. module Numeric.Vector type Vector (t :: l) (n :: k) = DataFrame t '[n] type Vec2f = Vector Float 2 type Vec3f = Vector Float 3 type Vec4f = Vector Float 4 type Vec2d = Vector Double 2 type Vec3d = Vector Double 3 type Vec4d = Vector Double 4 type Vec2i = Vector Int 2 type Vec3i = Vector Int 3 type Vec4i = Vector Int 4 type Vec2w = Vector Word 2 type Vec3w = Vector Word 3 type Vec4w = Vector Word 4 -- | Packing and unpacking 2D vectors class Vector2 t -- | Compose a 2D vector vec2 :: Vector2 t => t -> t -> Vector t 2 -- | Unpack 2D vector elements unpackV2# :: Vector2 t => Vector t 2 -> (# t, t #) -- | Packing and unpacking 3D vectors class Vector3 t -- | Compose a 3D vector vec3 :: Vector3 t => t -> t -> t -> Vector t 3 -- | Unpack 3D vector elements unpackV3# :: Vector3 t => Vector t 3 -> (# t, t, t #) -- | Packing and unpacking 4D vectors class Vector4 t -- | Compose a 4D vector vec4 :: Vector4 t => t -> t -> t -> t -> Vector t 4 -- | Unpack 4D vector elements unpackV4# :: Vector4 t => Vector t 4 -> (# t, t, t, t #) -- | Keep data in a primitive data frame and maintain information about -- Dimensions in the type system data family DataFrame (t :: l) (xs :: [k]) pattern Vec2 :: Vector2 t => t -> t -> Vector t 2 pattern Vec3 :: Vector3 t => t -> t -> t -> Vector t 3 pattern Vec4 :: Vector4 t => t -> t -> t -> t -> Vector t 4 -- | Scalar product -- sum of Vecs' components products, propagated into -- whole Vec (.*.) :: (Num t, Num (Vector t n), SubSpace t '[n] '[] '[n]) => Vector t n -> Vector t n -> Vector t n infixl 7 .*. -- | Scalar product -- sum of Vecs' components products -- a scalar dot :: (Num t, Num (Vector t n), SubSpace t '[n] '[] '[n]) => Vector t n -> Vector t n -> Scalar t -- | Dot product of two vectors (·) :: (Num t, Num (Vector t n), SubSpace t '[n] '[] '[n]) => Vector t n -> Vector t n -> Scalar t infixl 7 · -- | Sum of absolute values normL1 :: (Num t, SubSpace t '[n] '[] '[n]) => Vector t n -> Scalar t -- | hypot function (square root of squares) normL2 :: (Floating t, SubSpace t '[n] '[] '[n]) => Vector t n -> Scalar t -- | Maximum of absolute values normLPInf :: (Ord t, Num t, SubSpace t '[n] '[] '[n]) => Vector t n -> Scalar t -- | Minimum of absolute values normLNInf :: (Ord t, Num t, SubSpace t '[n] '[] '[n]) => Vector t n -> Scalar t -- | Norm in Lp space normLP :: (Floating t, SubSpace t '[n] '[] '[n]) => Int -> Vector t n -> Scalar t -- | Normalize vector w.r.t. Euclidean metric (L2). normalized :: (Floating t, Fractional (Vector t n), SubSpace t '[n] '[] '[n]) => Vector t n -> Vector t n -- | Take a determinant of a matrix composed from two 2D vectors. Like a -- cross product in 2D. det2 :: (Num t, SubSpace t '[2] '[] '[2]) => Vector t 2 -> Vector t 2 -> Scalar t -- | Cross product cross :: (Num t, SubSpace t '[3] '[] '[3]) => Vector t 3 -> Vector t 3 -> Vector t 3 -- | Cross product for two vectors in 3D (×) :: (Num t, SubSpace t '[3] '[] '[3]) => Vector t 3 -> Vector t 3 -> Vector t 3 infixl 7 × -- | Quaternion operations implemented for Floats and Doubles. -- -- The types QDouble and QFloat have the same -- representation as corresponding Vector t 4. This means, you -- can do a cheap conversion between the types. -- -- However, arithmetic instances, such as Num and Floating are -- implemented in substentially different ways. For example, fromInteger -- fills a vector fully but sets only real part to a quaternion: -- --
-- >>> 1 = vec4 1 1 1 1 -- -- >>> 1 = packQ 0 0 0 1 ---- -- All other numeric operations for vectors are element-wise, but for -- quaternions I have implemented the actual quaternion math. In most of -- the cases, you can think of these as being operations on complex -- numbers, where the role of imaginary i is played by a 3D -- vector. Some of the operations are ambiguous for quaternions; for -- example <math>, but also <math>, and <math>, and any -- other unit quaterion with zero real part. In cases like this, I stick -- to the i-th axis: <math> module Numeric.Quaternion -- | Quaternion operations class Quaternion t where { -- | Quaternion data type. The ordering of coordinates is -- (x,y,z,w), where w is the argument, and x y -- z are the components of a 3D vector data family Quater t; } -- | Set the quaternion in format (x,y,z,w) packQ :: Quaternion t => t -> t -> t -> t -> Quater t -- | Get the values of the quaternion in format (x,y,z,w) unpackQ# :: Quaternion t => Quater t -> (# t, t, t, t #) -- | Set the quaternion from 3D axis vector and argument fromVecNum :: Quaternion t => Vector t 3 -> t -> Quater t -- | Set the quaternion from 4D vector in format (x,y,z,w) fromVec4 :: Quaternion t => Vector t 4 -> Quater t -- | Transform the quaternion to 4D vector in format (x,y,z,w) toVec4 :: Quaternion t => Quater t -> Vector t 4 -- | Get scalar square of the quaternion. -- --
-- >>> realToFrac (square q) == q * conjugate q --square :: Quaternion t => Quater t -> t -- | Imaginary part of the quaternion (orientation vector) im :: Quaternion t => Quater t -> Quater t -- | Real part of the quaternion re :: Quaternion t => Quater t -> Quater t -- | Imaginary part of the quaternion as a 3D vector imVec :: Quaternion t => Quater t -> Vector t 3 -- | Real part of the quaternion as a scalar taker :: Quaternion t => Quater t -> t -- | i-th component takei :: Quaternion t => Quater t -> t -- | j-th component takej :: Quaternion t => Quater t -> t -- | k-th component takek :: Quaternion t => Quater t -> t -- | Conjugate quaternion (negate imaginary part) conjugate :: Quaternion t => Quater t -> Quater t -- | Rotates and scales vector in 3D using quaternion. Let <math> , -- <math>, <math>; then the rotation angle is <math>, -- and the axis of rotation is <math>. Scaling is proportional to -- <math>. -- --
-- >>> rotScale q x == q * x * (conjugate q) --rotScale :: Quaternion t => Quater t -> Vector t 3 -> Vector t 3 -- | Creates a quaternion q from two vectors a and -- b, such that rotScale q a == b. getRotScale :: Quaternion t => Vector t 3 -> Vector t 3 -> Quater t -- | Creates a rotation versor from an axis vector and an angle in radians. -- Result is always a unit quaternion (versor). If the argument vector is -- zero, then result is a real unit quaternion. axisRotation :: Quaternion t => Vector t 3 -> t -> Quater t -- | Quaternion rotation angle <math> (where <math> , -- <math>, <math>). -- --
-- >>> q /= 0 ==> axisRotation (imVec q) (qArg q) == signum q --qArg :: Quaternion t => Quater t -> t -- | Create a quaternion from a rotation matrix. Note, that rotations of -- <math> and <math> are equivalent, there result of this -- function may be ambiguious. Assume the sign of the result to be chosen -- arbitrarily. fromMatrix33 :: Quaternion t => Matrix t 3 3 -> Quater t -- | Create a quaternion from a homogenious coordinates trasform matrix. -- Ignores matrix translation transform. Note, that rotations of -- <math> and <math> are equivalent, there result of this -- function may be ambiguious. Assume the sign of the result to be chosen -- arbitrarily. fromMatrix44 :: Quaternion t => Matrix t 4 4 -> Quater t -- | Create a rotation matrix from a quaternion. Note, that rotations of -- <math> and <math> are equivalent, so the following -- property holds: -- --
-- >>> toMatrix33 q == toMatrix33 (-q) --toMatrix33 :: Quaternion t => Quater t -> Matrix t 3 3 -- | Create a homogenious coordinates trasform matrix from a quaternion. -- Translation of the output matrix is zero. Note, that rotations of -- <math> and <math> are equivalent, so the following -- property holds: -- --
-- >>> toMatrix44 q == toMatrix44 (-q) --toMatrix44 :: Quaternion t => Quater t -> Matrix t 4 4 type QDouble = Quater Double type QFloat = Quater Float module Numeric.Matrix class MatrixTranspose t (n :: k) (m :: k) -- | Transpose Mat transpose :: MatrixTranspose t n m => Matrix t n m -> Matrix t m n class SquareMatrix t (n :: Nat) -- | Mat with 1 on diagonal and 0 elsewhere eye :: SquareMatrix t n => Matrix t n n -- | Put the same value on the Mat diagonal, 0 otherwise diag :: SquareMatrix t n => Scalar t -> Matrix t n n -- | Sum of diagonal elements trace :: SquareMatrix t n => Matrix t n n -> Scalar t class MatrixDeterminant t (n :: Nat) -- | Determinant of Mat det :: MatrixDeterminant t n => Matrix t n n -> Scalar t class MatrixInverse t (n :: Nat) -- | Matrix inverse inverse :: MatrixInverse t n => Matrix t n n -> Matrix t n n class MatrixLU t (n :: Nat) -- | Compute LU factorization with Partial Pivoting lu :: MatrixLU t n => Matrix t n n -> LUFact t n -- | Result of LU factorization with Partial Pivoting PA = LU . data LUFact t n LUFact :: Matrix t n n -> Matrix t n n -> Matrix t n n -> Scalar t -> LUFact t n -- | Lower triangular matrix L. All elements on the diagonal of -- L equal 1. [luLower] :: LUFact t n -> Matrix t n n -- | Upper triangular matrix U [luUpper] :: LUFact t n -> Matrix t n n -- | Row permutation matrix P [luPerm] :: LUFact t n -> Matrix t n n -- | Sign of permutation luPermSign == det . luPerm [luPermSign] :: LUFact t n -> Scalar t -- | Alias for DataFrames of rank 2 type Matrix (t :: l) (n :: k) (m :: k) = DataFrame t '[n, m] -- | Operations on 4x4 transformation matrices and vectors in homogeneous -- coordinates. All angles are specified in radians. -- -- Note: since version 2 of easytensor, DataFrames and matrices -- are row-major. A good SIMD implementation may drastically improve -- performance of 4D vector-matrix products of the form v %* m, -- but not so much for products of the form m %* v (due to -- memory layout). Thus, all operations here assume the former form to -- benefit more from SIMD in future. class HomTransform4 t -- | Create a translation matrix from a vector. The 4th coordinate is -- ignored. -- -- If p ! 3 == 1 and v ! 3 == 0, then -- --
-- p %* translate4 v == p + v --translate4 :: HomTransform4 t => Vector t 4 -> Matrix t 4 4 -- | Create a translation matrix from a vector. -- -- If p ! 3 == 1, then -- --
-- p %* translate3 v == p + toHomVector v --translate3 :: HomTransform4 t => Vector t 3 -> Matrix t 4 4 -- | Rotation matrix for a rotation around the X axis, angle is given in -- radians. e.g. p %* rotateX (pi/2) rotates point p -- around Ox by 90 degrees. rotateX :: HomTransform4 t => t -> Matrix t 4 4 -- | Rotation matrix for a rotation around the Y axis, angle is given in -- radians. e.g. p %* rotateY (pi/2) rotates point p -- around Oy by 90 degrees. rotateY :: HomTransform4 t => t -> Matrix t 4 4 -- | Rotation matrix for a rotation around the Z axis, angle is given in -- radians. e.g. p %* rotateZ (pi/2) rotates point p -- around Oz by 90 degrees. rotateZ :: HomTransform4 t => t -> Matrix t 4 4 -- | Rotation matrix for a rotation around an arbitrary normalized vector -- e.g. p %* rotate (pi/2) v rotates point p around -- v by 90 degrees. rotate :: HomTransform4 t => Vector t 3 -> t -> Matrix t 4 4 -- | Rotation matrix from the Euler angles roll (axis Z), yaw -- (axis Y'), and pitch (axis X''). This order is known -- as Tait-Bryan angles (Z-Y'-X'' intrinsic rotations), or -- nautical angles, or Cardan angles. -- --
-- rotateEuler pitch yaw roll == rotateZ roll %* rotateY yaw %* rotateX pitch ---- -- https://en.wikipedia.org/wiki/Euler_angles#Conventions_2 rotateEuler :: HomTransform4 t => t -> t -> t -> Matrix t 4 4 -- | Create a transform matrix using up direction, camera position and a -- point to look at. Just the same as GluLookAt. lookAt :: HomTransform4 t => Vector t 3 -> Vector t 3 -> Vector t 3 -> Matrix t 4 4 -- | A perspective symmetric projection matrix. Right-handed coordinate -- system. (x - right, y - top) -- http://en.wikibooks.org/wiki/GLSL_Programming/Vertex_Transformations perspective :: HomTransform4 t => t -> t -> t -> t -> Matrix t 4 4 -- | An orthogonal symmetric projection matrix. Right-handed coordinate -- system. (x - right, y - top) -- http://en.wikibooks.org/wiki/GLSL_Programming/Vertex_Transformations orthogonal :: HomTransform4 t => t -> t -> t -> t -> Matrix t 4 4 -- | Add one more dimension and set it to 1. toHomPoint :: HomTransform4 t => Vector t 3 -> Vector t 4 -- | Add one more dimension and set it to 0. toHomVector :: HomTransform4 t => Vector t 3 -> Vector t 4 -- | Transform a homogenous vector or point into a normal 3D vector. If the -- last coordinate is not zero, divide the rest by it. fromHom :: HomTransform4 t => Vector t 4 -> Vector t 3 type Mat22f = Matrix Float 2 2 type Mat23f = Matrix Float 2 3 type Mat24f = Matrix Float 2 4 type Mat32f = Matrix Float 3 2 type Mat33f = Matrix Float 3 3 type Mat34f = Matrix Float 3 4 type Mat42f = Matrix Float 4 2 type Mat43f = Matrix Float 4 3 type Mat44f = Matrix Float 4 4 type Mat22d = Matrix Double 2 2 type Mat23d = Matrix Double 2 3 type Mat24d = Matrix Double 2 4 type Mat32d = Matrix Double 3 2 type Mat33d = Matrix Double 3 3 type Mat34d = Matrix Double 3 4 type Mat42d = Matrix Double 4 2 type Mat43d = Matrix Double 4 3 type Mat44d = Matrix Double 4 4 -- | Compose a 2x2D matrix mat22 :: PrimBytes (t :: Type) => Vector t 2 -> Vector t 2 -> Matrix t 2 2 -- | Compose a 3x3D matrix mat33 :: PrimBytes (t :: Type) => Vector t 3 -> Vector t 3 -> Vector t 3 -> Matrix t 3 3 -- | Compose a 4x4D matrix mat44 :: PrimBytes (t :: Type) => Vector t 4 -> Vector t 4 -> Vector t 4 -> Vector t 4 -> Matrix t 4 4 -- | Tensor contraction. In particular: 1. matrix-matrix product 2. -- matrix-vector or vector-matrix product 3. dot product of two vectors. (%*) :: (Contraction t as bs asbs, KnownDim m, PrimArray t (DataFrame t (as +: m)), PrimArray t (DataFrame t (m :+ bs)), PrimArray t (DataFrame t asbs)) => DataFrame t (as +: m) -> DataFrame t (m :+ bs) -> DataFrame t asbs infixl 7 %* -- | Permute rows that the largest magnitude elements in columns are on -- diagonals. -- -- Invariants of result matrix: * forall j >= i: |M[i,i]| >= M[j,i] -- * if M[i,i] == 0 then forall j >= i: |M[i+1,i+1]| >= M[j,i+1] pivotMat :: forall (t :: Type) (n :: Nat). (KnownDim n, PrimArray t (Matrix t n n), Ord t, Num t) => Matrix t n n -> (Matrix t n n, Matrix t n n, Scalar t) -- | Solve Ax = b problem given LU decomposition of A. luSolve :: forall (t :: Type) (n :: Nat). (KnownDim n, Fractional t, PrimArray t (Matrix t n n), PrimArray t (Vector t n)) => LUFact t n -> Vector t n -> Vector t n module Numeric.DataFrame