-- 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.1.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: -- -- -- -- Generated instances of PrimBytes meet these assumptions if all -- components of a data meet these assumptions too. You are strongly -- advised to provide all byte offset arguments to the PrimBytes -- functions respecting the alignment of the data; otherwise, the data -- may be written or read incorrectly. module Numeric.PrimBytes -- | 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 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: -- --
    --
  1. The data has only one constructor.
  2. --
  3. The data uses record syntax to define its fields.
  4. --
type family PrimFields a :: [Symbol]; type PrimFields a = GPrimFields (Rep a); } -- | Store content of a data type in a primitive byte array (should be used -- together with byteOffset function). -- -- Note, the default implementation of this function returns a not pinned -- array, which is aligned to 8. Thus, it ignores the alignment -- of the underlying data type if it is larger. However, alignment -- calculation still makes sense for data types that are smaller than -- 8 bytes: they are packed more densely. getBytes :: PrimBytes a => a -> ByteArray# -- | Store content of a data type in a primitive byte array (should be used -- together with byteOffset function). -- -- In contrast to getBytes, this function returns a pinned byte -- array, aligned to the byteAlign bytes of this data. -- -- Note, GC guarantees not to move the created array. While this is very -- useful sometimes, it incurs a certain performance penalty. getBytesPinned :: PrimBytes a => a -> ByteArray# -- | Load content of a data type from a primitive byte array given an -- offset in bytes. fromBytes :: PrimBytes a => Int# -> ByteArray# -> a -- | Read data from a mutable byte array given an offset in bytes. readBytes :: PrimBytes a => MutableByteArray# s -> Int# -> State# s -> (# State# s, a #) -- | Write data into a mutable byte array at a given position (offset in -- bytes). writeBytes :: PrimBytes a => MutableByteArray# s -> Int# -> a -> State# s -> State# s -- | Read data from a specified address. readAddr :: PrimBytes a => Addr# -> State# s -> (# State# s, a #) -- | Write data to a specified address. writeAddr :: PrimBytes a => a -> Addr# -> State# s -> State# s -- | Size of a data type in bytes. It should be a multiple of -- byteAlign for indexing functions to operate correctly. -- -- Implementation of this function must not inspect the argument value; a -- caller may provide undefined in place of the argument. byteSize :: PrimBytes a => a -> Int# -- | Alignment of a data type in bytes. byteOffset should be -- multiple of this value. -- -- Implementation of this function must not inspect the argument value; a -- caller may provide undefined in place of the argument. byteAlign :: PrimBytes a => a -> Int# -- | Offset of the data in a byte array used to store the data, measured in -- bytes. Should be used together with getBytes function. Unless -- in case of special data types represented by ByteArrays, it is equal -- to zero. -- -- Implementation of this function may inspect the argument value; a -- caller must not provide undefined in place of the argument. byteOffset :: PrimBytes a => a -> Int# -- | Offset of a data record within the data type in bytes. -- -- Implementation of this function must not inspect the argument value; a -- caller may provide undefined in place of the argument. -- -- The default (generic) implementation of this fucntion looks for the -- leftmost occurrence of a given field name (in case of multiple -- constructors). If a field with the given name is not found, it returns -- -1, but this is not possible thanks to Elem name -- (PrimFields a) constraint. byteFieldOffset :: (PrimBytes a, Elem name (PrimFields a), KnownSymbol name) => Proxy# name -> a -> Int# -- | Index array given an element offset (which is byteSize a and -- should be a multiple of byteAlign a). indexArray :: PrimBytes a => ByteArray# -> Int# -> a -- | Read a mutable array given an element offset (which is byteSize -- a and should be a multiple of byteAlign a). readArray :: PrimBytes a => MutableByteArray# s -> Int# -> State# s -> (# State# s, a #) -- | Write a mutable array given an element offset (which is byteSize -- a and should be a multiple of byteAlign a). writeArray :: PrimBytes a => MutableByteArray# s -> Int# -> a -> State# s -> State# s -- | Load content of a data type from a primitive byte array given an -- offset in bytes. fromBytes :: (PrimBytes a, Generic a, GPrimBytes (Rep a)) => Int# -> ByteArray# -> a -- | Read data from a mutable byte array given an offset in bytes. readBytes :: (PrimBytes a, Generic a, GPrimBytes (Rep a)) => MutableByteArray# s -> Int# -> State# s -> (# State# s, a #) -- | Write data into a mutable byte array at a given position (offset in -- bytes). writeBytes :: (PrimBytes a, Generic a, GPrimBytes (Rep a)) => MutableByteArray# s -> Int# -> a -> State# s -> State# s -- | Read data from a specified address. readAddr :: (PrimBytes a, Generic a, GPrimBytes (Rep a)) => Addr# -> State# s -> (# State# s, a #) -- | Write data to a specified address. writeAddr :: (PrimBytes a, Generic a, GPrimBytes (Rep a)) => a -> Addr# -> State# s -> State# s -- | Size of a data type in bytes. It should be a multiple of -- byteAlign for indexing functions to operate correctly. -- -- Implementation of this function must not inspect the argument value; a -- caller may provide undefined in place of the argument. byteSize :: (PrimBytes a, Generic a, GPrimBytes (Rep a)) => a -> Int# -- | Alignment of a data type in bytes. byteOffset should be -- multiple of this value. -- -- Implementation of this function must not inspect the argument value; a -- caller may provide undefined in place of the argument. byteAlign :: (PrimBytes a, Generic a, GPrimBytes (Rep a)) => a -> Int# -- | Offset of a data record within the data type in bytes. -- -- Implementation of this function must not inspect the argument value; a -- caller may provide undefined in place of the argument. -- -- The default (generic) implementation of this fucntion looks for the -- leftmost occurrence of a given field name (in case of multiple -- constructors). If a field with the given name is not found, it returns -- -1, but this is not possible thanks to Elem name -- (PrimFields a) constraint. byteFieldOffset :: (PrimBytes a, Generic a, GPrimBytes (Rep a), KnownSymbol name) => Proxy# name -> a -> Int# -- | 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 -- | Same as peekElemOff: peek an element a by the offset -- measured in byteSize a. -- -- Note: the size of the element must be a multiple of its alignment for -- a correct operation of this function. bPeekElemOff :: forall (a :: Type). PrimBytes a => Ptr a -> Int -> IO a -- | Same as pokeElemOff: poke an element a by the offset -- measured in byteSize a. -- -- Note: the size of the element must be a multiple of its alignment for -- a correct operation of this function. bPokeElemOff :: forall (a :: Type). PrimBytes a => Ptr a -> Int -> a -> IO () -- | Same as peekByteOff: peek an element a by the offset -- measured in bytes. -- -- Note: you'd better be sure the address is a multiple of the data -- alignment (peek). bPeekByteOff :: forall (a :: Type) (b :: Type). PrimBytes a => Ptr b -> Int -> IO a -- | Same as pokeByteOff: poke an element a by the offset -- measured in bytes. -- -- Note: you'd better be sure the address is a multiple of the data -- alignment (peek). bPokeByteOff :: forall (a :: Type) (b :: Type). PrimBytes a => Ptr b -> Int -> a -> IO () -- | Same as peek: read a data from a pointer. -- -- Note: you'd better be sure the address is a multiple of the data -- alignment (peek). bPeek :: forall (a :: Type). PrimBytes a => Ptr a -> IO a -- | Same as poke: write a data to a pointer. -- -- Note: you'd better be sure the address is a multiple of the data -- alignment (peek). bPoke :: forall (a :: Type). PrimBytes a => Ptr a -> a -> IO () -- | Find out which basic GHC type it is at runtime. It is used for -- DataFrame backend specialization: by matching a PrimTag -- a against its constructors, you can figure out a specific -- implementation of Backend a ds (e.g. whether this is a -- specialized float array, or a generic polymorphic array). For -- non-basic types it defaults to PTagOther. data PrimTag a [PTagFloat] :: PrimTag Float [PTagDouble] :: PrimTag Double [PTagInt] :: PrimTag Int [PTagInt8] :: PrimTag Int8 [PTagInt16] :: PrimTag Int16 [PTagInt32] :: PrimTag Int32 [PTagInt64] :: PrimTag Int64 [PTagWord] :: PrimTag Word [PTagWord8] :: PrimTag Word8 [PTagWord16] :: PrimTag Word16 [PTagWord32] :: PrimTag Word32 [PTagWord64] :: PrimTag Word64 [PTagChar] :: PrimTag Char [PTagPtr] :: PrimTag (Ptr a) [PTagOther] :: PrimTag a -- | This function allows to find out a type by comparing its tag. This is -- needed for backend specialization, to infer array instances. For -- non-basic types it defaults to PTagOther. primTag :: PrimBytes a => a -> PrimTag a instance GHC.Show.Show (Numeric.PrimBytes.PrimTag a) instance Numeric.PrimBytes.PrimBytes a => Numeric.PrimBytes.GPrimBytes (GHC.Generics.K1 i a) instance Numeric.PrimBytes.PrimBytes GHC.Types.Word instance Numeric.PrimBytes.PrimBytes GHC.Types.Int instance Numeric.PrimBytes.PrimBytes GHC.Types.Float instance Numeric.PrimBytes.PrimBytes GHC.Types.Double instance Numeric.PrimBytes.PrimBytes (GHC.Ptr.Ptr a) instance Numeric.PrimBytes.PrimBytes GHC.Int.Int8 instance Numeric.PrimBytes.PrimBytes GHC.Int.Int16 instance Numeric.PrimBytes.PrimBytes GHC.Int.Int32 instance Numeric.PrimBytes.PrimBytes GHC.Int.Int64 instance Numeric.PrimBytes.PrimBytes GHC.Word.Word8 instance Numeric.PrimBytes.PrimBytes GHC.Word.Word16 instance Numeric.PrimBytes.PrimBytes GHC.Word.Word32 instance Numeric.PrimBytes.PrimBytes GHC.Word.Word64 instance Numeric.PrimBytes.PrimBytes GHC.Types.Char instance forall k (x :: k). Numeric.PrimBytes.PrimBytes (Numeric.Dimensions.Idx.Idx x) instance forall k (xs :: [k]). Numeric.TypedList.RepresentableList xs => Numeric.PrimBytes.PrimBytes (Numeric.Dimensions.Idx.Idxs xs) instance (Numeric.TypedList.RepresentableList xs, Data.Type.List.All Numeric.PrimBytes.PrimBytes xs) => Numeric.PrimBytes.PrimBytes (Numeric.Tuple.Lazy.Tuple xs) instance (Numeric.TypedList.RepresentableList xs, Data.Type.List.All Numeric.PrimBytes.PrimBytes xs) => Numeric.PrimBytes.PrimBytes (Numeric.Tuple.Strict.Tuple xs) instance Numeric.PrimBytes.PrimBytes () instance Numeric.PrimBytes.PrimBytes a => Numeric.PrimBytes.PrimBytes (GHC.Maybe.Maybe a) instance (Numeric.PrimBytes.PrimBytes a, Numeric.PrimBytes.PrimBytes b) => Numeric.PrimBytes.PrimBytes (Data.Either.Either a b) instance (Numeric.PrimBytes.PrimBytes a, Numeric.PrimBytes.PrimBytes b) => Numeric.PrimBytes.PrimBytes (a, b) instance (Numeric.PrimBytes.PrimBytes a, Numeric.PrimBytes.PrimBytes b, Numeric.PrimBytes.PrimBytes c) => Numeric.PrimBytes.PrimBytes (a, b, c) instance (Numeric.PrimBytes.PrimBytes a, Numeric.PrimBytes.PrimBytes b, Numeric.PrimBytes.PrimBytes c, Numeric.PrimBytes.PrimBytes d) => Numeric.PrimBytes.PrimBytes (a, b, c, d) instance (Numeric.PrimBytes.PrimBytes a, Numeric.PrimBytes.PrimBytes b, Numeric.PrimBytes.PrimBytes c, Numeric.PrimBytes.PrimBytes d, Numeric.PrimBytes.PrimBytes e) => Numeric.PrimBytes.PrimBytes (a, b, c, d, e) instance (Numeric.PrimBytes.PrimBytes a, Numeric.PrimBytes.PrimBytes b, Numeric.PrimBytes.PrimBytes c, Numeric.PrimBytes.PrimBytes d, Numeric.PrimBytes.PrimBytes e, Numeric.PrimBytes.PrimBytes f) => Numeric.PrimBytes.PrimBytes (a, b, c, d, e, f) instance (Numeric.PrimBytes.PrimBytes a, Numeric.PrimBytes.PrimBytes b, Numeric.PrimBytes.PrimBytes c, Numeric.PrimBytes.PrimBytes d, Numeric.PrimBytes.PrimBytes e, Numeric.PrimBytes.PrimBytes f, Numeric.PrimBytes.PrimBytes g) => Numeric.PrimBytes.PrimBytes (a, b, c, d, e, f, g) instance Numeric.PrimBytes.PrimTagged a instance Numeric.PrimBytes.PrimTagged GHC.Types.Float instance Numeric.PrimBytes.PrimTagged GHC.Types.Double instance Numeric.PrimBytes.PrimTagged GHC.Types.Int instance Numeric.PrimBytes.PrimTagged GHC.Int.Int8 instance Numeric.PrimBytes.PrimTagged GHC.Int.Int16 instance Numeric.PrimBytes.PrimTagged GHC.Int.Int32 instance Numeric.PrimBytes.PrimTagged GHC.Int.Int64 instance Numeric.PrimBytes.PrimTagged GHC.Types.Word instance Numeric.PrimBytes.PrimTagged GHC.Word.Word8 instance Numeric.PrimBytes.PrimTagged GHC.Word.Word16 instance Numeric.PrimBytes.PrimTagged GHC.Word.Word32 instance Numeric.PrimBytes.PrimTagged GHC.Word.Word64 instance Numeric.PrimBytes.PrimTagged GHC.Types.Char instance Numeric.PrimBytes.PrimTagged (GHC.Ptr.Ptr a) instance Numeric.PrimBytes.GPrimBytes GHC.Generics.V1 instance Numeric.PrimBytes.GPrimBytes GHC.Generics.U1 instance forall k (f :: k -> *) (sn :: GHC.Types.Symbol) (a :: GHC.Generics.SourceUnpackedness) (b :: GHC.Generics.SourceStrictness) (c :: GHC.Generics.DecidedStrictness). (Numeric.PrimBytes.GPrimBytes f, GHC.TypeLits.KnownSymbol sn) => Numeric.PrimBytes.GPrimBytes (GHC.Generics.M1 GHC.Generics.S ('GHC.Generics.MetaSel ('GHC.Maybe.Just sn) a b c) f) instance forall k (f :: k -> *) i (c :: GHC.Generics.Meta). Numeric.PrimBytes.GPrimBytes f => Numeric.PrimBytes.GPrimBytes (GHC.Generics.M1 i c f) instance forall k (f :: k -> *) (g :: k -> *). (Numeric.PrimBytes.GPrimBytes f, Numeric.PrimBytes.GPrimBytes g) => Numeric.PrimBytes.GPrimBytes (f GHC.Generics.:*: g) instance forall k (f :: k -> *) (g :: k -> *). (Numeric.PrimBytes.GPrimBytes f, Numeric.PrimBytes.GPrimBytes g) => Numeric.PrimBytes.GPrimBytes (f GHC.Generics.:+: g) instance Numeric.PrimBytes.GPrimBytes (GHC.Generics.URec GHC.Types.Word) instance Numeric.PrimBytes.GPrimBytes (GHC.Generics.URec GHC.Types.Int) instance Numeric.PrimBytes.GPrimBytes (GHC.Generics.URec GHC.Types.Float) instance Numeric.PrimBytes.GPrimBytes (GHC.Generics.URec GHC.Types.Double) instance Numeric.PrimBytes.GPrimBytes (GHC.Generics.URec GHC.Types.Char) instance Numeric.PrimBytes.GPrimBytes (GHC.Generics.URec (GHC.Ptr.Ptr ())) module Numeric.DataFrame.Internal.PrimArray class PrimBytes t => PrimArray t a | a -> t -- | Broadcast element into array broadcast :: PrimArray t a => t -> a -- | Index an array given an offset ix# :: PrimArray t a => Int# -> a -> t -- | Generate an array using an accumulator funtion gen# :: PrimArray t a => CumulDims -> (s -> (# s, t #)) -> s -> (# s, a #) -- | update a single element in an array given an offset upd# :: PrimArray t a => CumulDims -> Int# -> t -> a -> a -- | If the array represented as a single broadcasted value, return this -- value. Otherwise, return full array content: CumulDims, array -- offset (elements), byte array with the content. arrayContent# :: PrimArray t a => a -> (# t | (# CumulDims, Int#, ByteArray# #) #) -- | Offset of an array as a number of elements offsetElems :: PrimArray t a => a -> Int# -- | Normally, this returns a cumulative totalDims. However, if a -- particular implementation does not have the dimensionality -- information, it cannot return CumulDims; In this case, it is -- a sign that all elements of an array are same. Thus, it is possible to -- return the single element value instead. -- -- Note, this function returns the only unique element only if it is a -- such by construction (there is no equality checks involved). uniqueOrCumulDims :: PrimArray t a => a -> Either t CumulDims -- | Get array by its offset and cumulative dims in a ByteArray. Both -- offset and dims are given in element number (not in bytes). -- -- It is better to use this function instead of fromBytes to -- avoid recalculating CumulDims for implementations that -- require it. fromElems :: PrimArray t a => CumulDims -> Int# -> ByteArray# -> a -- | Given Dims ns, CumulativeDims is a list of length -- Length ns + 1; which cumulative totalDim accumulated -- on the right. In particular, its first element is totalDim -- ds, its last element is always is always 1. newtype CumulDims CumulDims :: [Word] -> CumulDims [unCumulDims] :: CumulDims -> [Word] -- | Calculate cumulative dims cumulDims :: Dims (ns :: [k]) -> CumulDims -- | Get the total number of elements cdTotalDim :: CumulDims -> Word cdTotalDim# :: CumulDims -> Int# -- | Calculate offset of an Idxs -- -- Note, you can take offset of subspace with CumulDims of larger space - -- very convenient! cdIx :: CumulDims -> Idxs ns -> Int -- | Index array by an integer offset (starting from 0). ixOff :: PrimArray t a => Int -> a -> t -- | Construct an array from a flat list and Dims; Be careful! -- ns depends on a, but this is not reflected in types -- and is not checked at runtime. unsafeFromFlatList :: PrimArray t a => Dims ns -> t -> [t] -> a -- | Try to get CumulDims from an array, and create it using -- Dims if failed. getSteps :: PrimArray t a => Dims (ns :: [k]) -> a -> CumulDims -- | Get Dims by "de-accumulating" CumulDims. fromSteps :: CumulDims -> SomeDims instance GHC.Base.Semigroup Numeric.DataFrame.Internal.PrimArray.CumulDims instance GHC.Base.Monoid Numeric.DataFrame.Internal.PrimArray.CumulDims -- | Compare product types -- partial order. module Numeric.ProductOrd -- | Partial order for comparing product types -- product order. class ProductOrder a -- | Same as compare, but may return Incomparable. cmp :: ProductOrder a => a -> a -> PartialOrdering -- | Similar to Ordering, but may be Incomparable. data PartialOrdering PLT :: PartialOrdering PEQ :: PartialOrdering PGT :: PartialOrdering Incomparable :: PartialOrdering -- | Extend Ordering with Incomparable option. fromOrdering :: Ordering -> PartialOrdering instance GHC.Enum.Bounded Numeric.ProductOrd.PartialOrdering instance GHC.Enum.Enum Numeric.ProductOrd.PartialOrdering instance GHC.Generics.Generic Numeric.ProductOrd.PartialOrdering instance Data.Data.Data Numeric.ProductOrd.PartialOrdering instance GHC.Read.Read Numeric.ProductOrd.PartialOrdering instance GHC.Show.Show Numeric.ProductOrd.PartialOrdering instance GHC.Classes.Ord Numeric.ProductOrd.PartialOrdering instance GHC.Classes.Eq Numeric.ProductOrd.PartialOrdering instance forall k (f :: k -> *) (xs :: [k]). Data.Type.List.All GHC.Classes.Ord (Data.Type.List.Map f xs) => Numeric.ProductOrd.ProductOrder (Numeric.TypedList.TypedList f xs) instance (GHC.Classes.Ord a1, GHC.Classes.Ord a2) => Numeric.ProductOrd.ProductOrder (a1, a2) instance (GHC.Classes.Ord a1, GHC.Classes.Ord a2, GHC.Classes.Ord a3) => Numeric.ProductOrd.ProductOrder (a1, a2, a3) instance (GHC.Classes.Ord a1, GHC.Classes.Ord a2, GHC.Classes.Ord a3, GHC.Classes.Ord a4) => Numeric.ProductOrd.ProductOrder (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) => Numeric.ProductOrd.ProductOrder (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) => Numeric.ProductOrd.ProductOrder (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) => Numeric.ProductOrd.ProductOrder (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) => Numeric.ProductOrd.ProductOrder (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) => Numeric.ProductOrd.ProductOrder (a1, a2, a3, a4, a5, a6, a7, a8, a9) instance GHC.Base.Semigroup Numeric.ProductOrd.PartialOrdering instance GHC.Base.Monoid Numeric.ProductOrd.PartialOrdering -- | Compare product types using non-transitive Ord instances: -- -- -- -- To remind yourself that ProductOrd is not fully faithful, you -- may import it qualified, e.g. -- --
--   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: -- -- -- -- To remind yourself that ProductOrd is partial, you may import -- it qualified, e.g. -- --
--   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