packages feed

easytensor 1.0.1.0 → 2.0.0.0

raw patch · 73 files changed

+12413/−8879 lines, 73 filesdep +constraints-derivingdep +template-haskelldep ~basedep ~dimensionsPVP ok

version bump matches the API change (PVP)

Dependencies added: constraints-deriving, template-haskell

Dependency ranges changed: base, dimensions

API changes (from Hackage documentation)

- Numeric.DataFrame.Contraction: instance (Numeric.Type.List.ConcatList as bs asbs, Numeric.Dimensions.Dims.Dimensions as, Numeric.Dimensions.Dims.Dimensions bs, GHC.Num.Num t) => Numeric.DataFrame.Contraction.Contraction t as bs asbs
- Numeric.DataFrame.Family: data family DataFrame (t :: l) (xs :: [k])
- Numeric.DataFrame.Internal.Array.Class: broadcast :: PrimArray t a => t -> a
- Numeric.DataFrame.Internal.Array.Class: class PrimBytes t => PrimArray t a | a -> t
- Numeric.DataFrame.Internal.Array.Class: elemOffset :: PrimArray t a => a -> Int#
- Numeric.DataFrame.Internal.Array.Class: elemSize0 :: PrimArray t a => a -> Int#
- Numeric.DataFrame.Internal.Array.Class: fromElems :: PrimArray t a => Int# -> Int# -> ByteArray# -> a
- Numeric.DataFrame.Internal.Array.Class: gen# :: PrimArray t a => Int# -> (s -> (# s, t #)) -> s -> (# s, a #)
- Numeric.DataFrame.Internal.Array.Class: ix# :: PrimArray t a => Int# -> a -> t
- Numeric.DataFrame.Internal.Array.Class: ixOff :: PrimArray t a => Int -> a -> t
- Numeric.DataFrame.Internal.Array.Class: unsafeFromFlatList :: PrimArray t a => Int -> [t] -> a
- Numeric.DataFrame.Internal.Array.Class: upd# :: PrimArray t a => Int# -> Int# -> t -> a -> a
- Numeric.DataFrame.Internal.Array.Family: ArrayBase :: (# t | (# Int#, Int#, ByteArray#, Evidence (PrimBytes t) #) #) -> ArrayBase
- Numeric.DataFrame.Internal.Array.Family: ScalarBase :: t -> ScalarBase t
- Numeric.DataFrame.Internal.Array.Family: [ABase] :: (Array t ds ~ ArrayBase t ds, PrimBytes t) => ArraySing t ds
- Numeric.DataFrame.Internal.Array.Family: [AD2] :: Array t ds ~ DoubleX2 => ArraySing Double '[2]
- Numeric.DataFrame.Internal.Array.Family: [AD3] :: Array t ds ~ DoubleX3 => ArraySing Double '[3]
- Numeric.DataFrame.Internal.Array.Family: [AD4] :: Array t ds ~ DoubleX4 => ArraySing Double '[4]
- Numeric.DataFrame.Internal.Array.Family: [AF2] :: Array t ds ~ FloatX2 => ArraySing Float '[2]
- Numeric.DataFrame.Internal.Array.Family: [AF3] :: Array t ds ~ FloatX3 => ArraySing Float '[3]
- Numeric.DataFrame.Internal.Array.Family: [AF4] :: Array t ds ~ FloatX4 => ArraySing Float '[4]
- Numeric.DataFrame.Internal.Array.Family: [AScalar] :: Array t ds ~ ScalarBase t => ArraySing t '[]
- Numeric.DataFrame.Internal.Array.Family: [_unScalarBase] :: ScalarBase t -> t
- Numeric.DataFrame.Internal.Array.Family: aSing :: ArraySingleton t ds => ArraySing t ds
- Numeric.DataFrame.Internal.Array.Family: aSingEv :: ArraySing t ds -> Evidence (ArraySingleton t ds)
- Numeric.DataFrame.Internal.Array.Family: class ArraySingleton (t :: Type) (ds :: [Nat])
- Numeric.DataFrame.Internal.Array.Family: data ArrayBase (t :: Type) (ds :: [Nat])
- Numeric.DataFrame.Internal.Array.Family: data ArraySing t (ds :: [Nat])
- Numeric.DataFrame.Internal.Array.Family: inferASing :: forall t ds. (PrimBytes t, Dimensions ds) => Evidence (ArraySingleton t ds)
- Numeric.DataFrame.Internal.Array.Family: inferEq :: forall t ds. (Eq t, ArraySingleton t ds) => Evidence (Eq (Array t ds))
- Numeric.DataFrame.Internal.Array.Family: inferFloating :: forall t ds. (Floating t, ArraySingleton t ds) => Evidence (Floating (Array t ds))
- Numeric.DataFrame.Internal.Array.Family: inferFractional :: forall t ds. (Fractional t, ArraySingleton t ds) => Evidence (Fractional (Array t ds))
- Numeric.DataFrame.Internal.Array.Family: inferNum :: forall t ds. (Num t, ArraySingleton t ds) => Evidence (Num (Array t ds))
- Numeric.DataFrame.Internal.Array.Family: inferOrd :: forall t ds. (Ord t, ArraySingleton t ds) => Evidence (Ord (Array t ds))
- Numeric.DataFrame.Internal.Array.Family: inferPrim :: forall t ds. (PrimBytes t, ArraySingleton t ds, Dimensions ds) => Evidence (PrimBytes (Array t ds), PrimArray t (Array t ds))
- Numeric.DataFrame.Internal.Array.Family: inferPrimElem :: forall t d ds. ArraySingleton t (d : ds) => Evidence (PrimBytes t)
- Numeric.DataFrame.Internal.Array.Family: inferShow :: forall t ds. (Show t, Dimensions ds, ArraySingleton t ds) => Evidence (Show (Array t ds))
- Numeric.DataFrame.Internal.Array.Family: instance (Numeric.DataFrame.Internal.Array.Family.Array t ds Data.Type.Equality.~ Numeric.DataFrame.Internal.Array.Family.ArrayBase.ArrayBase t ds, Numeric.PrimBytes.PrimBytes t) => Numeric.DataFrame.Internal.Array.Family.ArraySingleton t ds
- Numeric.DataFrame.Internal.Array.Family: instance GHC.Classes.Eq (Numeric.DataFrame.Internal.Array.Family.ArraySing t ds)
- Numeric.DataFrame.Internal.Array.Family: instance GHC.Classes.Ord (Numeric.DataFrame.Internal.Array.Family.ArraySing t ds)
- Numeric.DataFrame.Internal.Array.Family: instance GHC.Show.Show (Numeric.DataFrame.Internal.Array.Family.ArraySing t ds)
- Numeric.DataFrame.Internal.Array.Family: instance Numeric.DataFrame.Internal.Array.Family.ArraySingleton GHC.Types.Double '[2]
- Numeric.DataFrame.Internal.Array.Family: instance Numeric.DataFrame.Internal.Array.Family.ArraySingleton GHC.Types.Double '[3]
- Numeric.DataFrame.Internal.Array.Family: instance Numeric.DataFrame.Internal.Array.Family.ArraySingleton GHC.Types.Double '[4]
- Numeric.DataFrame.Internal.Array.Family: instance Numeric.DataFrame.Internal.Array.Family.ArraySingleton GHC.Types.Float '[2]
- Numeric.DataFrame.Internal.Array.Family: instance Numeric.DataFrame.Internal.Array.Family.ArraySingleton GHC.Types.Float '[3]
- Numeric.DataFrame.Internal.Array.Family: instance Numeric.DataFrame.Internal.Array.Family.ArraySingleton GHC.Types.Float '[4]
- Numeric.DataFrame.Internal.Array.Family: instance Numeric.DataFrame.Internal.Array.Family.ArraySingleton t '[]
- Numeric.DataFrame.Internal.Array.Family: newtype ScalarBase t
- Numeric.DataFrame.Internal.Array.Family: type family Array (t :: Type) (ds :: [Nat]) = (v :: Type) | v -> t ds
- Numeric.DataFrame.Internal.Array.Family.ArrayBase: ArrayBase :: (# t | (# Int#, Int#, ByteArray#, Evidence (PrimBytes t) #) #) -> ArrayBase
- Numeric.DataFrame.Internal.Array.Family.ArrayBase: data ArrayBase (t :: Type) (ds :: [Nat])
- Numeric.DataFrame.Internal.Array.Family.ArrayBase: instance (Numeric.Dimensions.Dims.Dimensions ds, GHC.Show.Show t) => GHC.Show.Show (Numeric.DataFrame.Internal.Array.Family.ArrayBase.ArrayBase t ds)
- Numeric.DataFrame.Internal.Array.Family.ArrayBase: instance (Numeric.PrimBytes.PrimBytes t, Numeric.Dimensions.Dims.Dimensions ds) => Numeric.PrimBytes.PrimBytes (Numeric.DataFrame.Internal.Array.Family.ArrayBase.ArrayBase t ds)
- Numeric.DataFrame.Internal.Array.Family.ArrayBase: instance GHC.Classes.Eq t => GHC.Classes.Eq (Numeric.DataFrame.Internal.Array.Family.ArrayBase.ArrayBase t ds)
- Numeric.DataFrame.Internal.Array.Family.ArrayBase: instance GHC.Classes.Ord t => GHC.Classes.Ord (Numeric.DataFrame.Internal.Array.Family.ArrayBase.ArrayBase t ds)
- Numeric.DataFrame.Internal.Array.Family.ArrayBase: instance GHC.Enum.Bounded (Numeric.DataFrame.Internal.Array.Family.ArrayBase.ArrayBase GHC.Types.Double ds)
- Numeric.DataFrame.Internal.Array.Family.ArrayBase: instance GHC.Enum.Bounded (Numeric.DataFrame.Internal.Array.Family.ArrayBase.ArrayBase GHC.Types.Float ds)
- Numeric.DataFrame.Internal.Array.Family.ArrayBase: instance GHC.Enum.Bounded t => GHC.Enum.Bounded (Numeric.DataFrame.Internal.Array.Family.ArrayBase.ArrayBase t ds)
- Numeric.DataFrame.Internal.Array.Family.ArrayBase: instance GHC.Float.Floating t => GHC.Float.Floating (Numeric.DataFrame.Internal.Array.Family.ArrayBase.ArrayBase t ds)
- Numeric.DataFrame.Internal.Array.Family.ArrayBase: instance GHC.Num.Num t => GHC.Num.Num (Numeric.DataFrame.Internal.Array.Family.ArrayBase.ArrayBase t ds)
- Numeric.DataFrame.Internal.Array.Family.ArrayBase: instance GHC.Real.Fractional t => GHC.Real.Fractional (Numeric.DataFrame.Internal.Array.Family.ArrayBase.ArrayBase t ds)
- Numeric.DataFrame.Internal.Array.Family.ArrayBase: instance Numeric.PrimBytes.PrimBytes t => Numeric.DataFrame.Internal.Array.Class.PrimArray t (Numeric.DataFrame.Internal.Array.Family.ArrayBase.ArrayBase t ds)
- Numeric.DataFrame.Internal.Array.Family.DoubleX2: DoubleX2# :: Double# -> Double# -> DoubleX2
- Numeric.DataFrame.Internal.Array.Family.DoubleX2: data DoubleX2
- Numeric.DataFrame.Internal.Array.Family.DoubleX2: instance GHC.Classes.Eq Numeric.DataFrame.Internal.Array.Family.DoubleX2.DoubleX2
- Numeric.DataFrame.Internal.Array.Family.DoubleX2: instance GHC.Classes.Ord Numeric.DataFrame.Internal.Array.Family.DoubleX2.DoubleX2
- Numeric.DataFrame.Internal.Array.Family.DoubleX2: instance GHC.Enum.Bounded Numeric.DataFrame.Internal.Array.Family.DoubleX2.DoubleX2
- Numeric.DataFrame.Internal.Array.Family.DoubleX2: instance GHC.Float.Floating Numeric.DataFrame.Internal.Array.Family.DoubleX2.DoubleX2
- Numeric.DataFrame.Internal.Array.Family.DoubleX2: instance GHC.Num.Num Numeric.DataFrame.Internal.Array.Family.DoubleX2.DoubleX2
- Numeric.DataFrame.Internal.Array.Family.DoubleX2: instance GHC.Real.Fractional Numeric.DataFrame.Internal.Array.Family.DoubleX2.DoubleX2
- Numeric.DataFrame.Internal.Array.Family.DoubleX2: instance GHC.Show.Show Numeric.DataFrame.Internal.Array.Family.DoubleX2.DoubleX2
- Numeric.DataFrame.Internal.Array.Family.DoubleX2: instance Numeric.DataFrame.Internal.Array.Class.PrimArray GHC.Types.Double Numeric.DataFrame.Internal.Array.Family.DoubleX2.DoubleX2
- Numeric.DataFrame.Internal.Array.Family.DoubleX2: instance Numeric.PrimBytes.PrimBytes Numeric.DataFrame.Internal.Array.Family.DoubleX2.DoubleX2
- Numeric.DataFrame.Internal.Array.Family.DoubleX3: DoubleX3# :: Double# -> Double# -> Double# -> DoubleX3
- Numeric.DataFrame.Internal.Array.Family.DoubleX3: data DoubleX3
- Numeric.DataFrame.Internal.Array.Family.DoubleX3: instance GHC.Classes.Eq Numeric.DataFrame.Internal.Array.Family.DoubleX3.DoubleX3
- Numeric.DataFrame.Internal.Array.Family.DoubleX3: instance GHC.Classes.Ord Numeric.DataFrame.Internal.Array.Family.DoubleX3.DoubleX3
- Numeric.DataFrame.Internal.Array.Family.DoubleX3: instance GHC.Enum.Bounded Numeric.DataFrame.Internal.Array.Family.DoubleX3.DoubleX3
- Numeric.DataFrame.Internal.Array.Family.DoubleX3: instance GHC.Float.Floating Numeric.DataFrame.Internal.Array.Family.DoubleX3.DoubleX3
- Numeric.DataFrame.Internal.Array.Family.DoubleX3: instance GHC.Num.Num Numeric.DataFrame.Internal.Array.Family.DoubleX3.DoubleX3
- Numeric.DataFrame.Internal.Array.Family.DoubleX3: instance GHC.Real.Fractional Numeric.DataFrame.Internal.Array.Family.DoubleX3.DoubleX3
- Numeric.DataFrame.Internal.Array.Family.DoubleX3: instance GHC.Show.Show Numeric.DataFrame.Internal.Array.Family.DoubleX3.DoubleX3
- Numeric.DataFrame.Internal.Array.Family.DoubleX3: instance Numeric.DataFrame.Internal.Array.Class.PrimArray GHC.Types.Double Numeric.DataFrame.Internal.Array.Family.DoubleX3.DoubleX3
- Numeric.DataFrame.Internal.Array.Family.DoubleX3: instance Numeric.PrimBytes.PrimBytes Numeric.DataFrame.Internal.Array.Family.DoubleX3.DoubleX3
- Numeric.DataFrame.Internal.Array.Family.DoubleX4: DoubleX4# :: Double# -> Double# -> Double# -> Double# -> DoubleX4
- Numeric.DataFrame.Internal.Array.Family.DoubleX4: data DoubleX4
- Numeric.DataFrame.Internal.Array.Family.DoubleX4: instance GHC.Classes.Eq Numeric.DataFrame.Internal.Array.Family.DoubleX4.DoubleX4
- Numeric.DataFrame.Internal.Array.Family.DoubleX4: instance GHC.Classes.Ord Numeric.DataFrame.Internal.Array.Family.DoubleX4.DoubleX4
- Numeric.DataFrame.Internal.Array.Family.DoubleX4: instance GHC.Enum.Bounded Numeric.DataFrame.Internal.Array.Family.DoubleX4.DoubleX4
- Numeric.DataFrame.Internal.Array.Family.DoubleX4: instance GHC.Float.Floating Numeric.DataFrame.Internal.Array.Family.DoubleX4.DoubleX4
- Numeric.DataFrame.Internal.Array.Family.DoubleX4: instance GHC.Num.Num Numeric.DataFrame.Internal.Array.Family.DoubleX4.DoubleX4
- Numeric.DataFrame.Internal.Array.Family.DoubleX4: instance GHC.Real.Fractional Numeric.DataFrame.Internal.Array.Family.DoubleX4.DoubleX4
- Numeric.DataFrame.Internal.Array.Family.DoubleX4: instance GHC.Show.Show Numeric.DataFrame.Internal.Array.Family.DoubleX4.DoubleX4
- Numeric.DataFrame.Internal.Array.Family.DoubleX4: instance Numeric.DataFrame.Internal.Array.Class.PrimArray GHC.Types.Double Numeric.DataFrame.Internal.Array.Family.DoubleX4.DoubleX4
- Numeric.DataFrame.Internal.Array.Family.DoubleX4: instance Numeric.PrimBytes.PrimBytes Numeric.DataFrame.Internal.Array.Family.DoubleX4.DoubleX4
- Numeric.DataFrame.Internal.Array.Family.FloatX2: FloatX2# :: Float# -> Float# -> FloatX2
- Numeric.DataFrame.Internal.Array.Family.FloatX2: data FloatX2
- Numeric.DataFrame.Internal.Array.Family.FloatX2: instance GHC.Classes.Eq Numeric.DataFrame.Internal.Array.Family.FloatX2.FloatX2
- Numeric.DataFrame.Internal.Array.Family.FloatX2: instance GHC.Classes.Ord Numeric.DataFrame.Internal.Array.Family.FloatX2.FloatX2
- Numeric.DataFrame.Internal.Array.Family.FloatX2: instance GHC.Enum.Bounded Numeric.DataFrame.Internal.Array.Family.FloatX2.FloatX2
- Numeric.DataFrame.Internal.Array.Family.FloatX2: instance GHC.Float.Floating Numeric.DataFrame.Internal.Array.Family.FloatX2.FloatX2
- Numeric.DataFrame.Internal.Array.Family.FloatX2: instance GHC.Num.Num Numeric.DataFrame.Internal.Array.Family.FloatX2.FloatX2
- Numeric.DataFrame.Internal.Array.Family.FloatX2: instance GHC.Real.Fractional Numeric.DataFrame.Internal.Array.Family.FloatX2.FloatX2
- Numeric.DataFrame.Internal.Array.Family.FloatX2: instance GHC.Show.Show Numeric.DataFrame.Internal.Array.Family.FloatX2.FloatX2
- Numeric.DataFrame.Internal.Array.Family.FloatX2: instance Numeric.DataFrame.Internal.Array.Class.PrimArray GHC.Types.Float Numeric.DataFrame.Internal.Array.Family.FloatX2.FloatX2
- Numeric.DataFrame.Internal.Array.Family.FloatX2: instance Numeric.PrimBytes.PrimBytes Numeric.DataFrame.Internal.Array.Family.FloatX2.FloatX2
- Numeric.DataFrame.Internal.Array.Family.FloatX3: FloatX3# :: Float# -> Float# -> Float# -> FloatX3
- Numeric.DataFrame.Internal.Array.Family.FloatX3: data FloatX3
- Numeric.DataFrame.Internal.Array.Family.FloatX3: instance GHC.Classes.Eq Numeric.DataFrame.Internal.Array.Family.FloatX3.FloatX3
- Numeric.DataFrame.Internal.Array.Family.FloatX3: instance GHC.Classes.Ord Numeric.DataFrame.Internal.Array.Family.FloatX3.FloatX3
- Numeric.DataFrame.Internal.Array.Family.FloatX3: instance GHC.Enum.Bounded Numeric.DataFrame.Internal.Array.Family.FloatX3.FloatX3
- Numeric.DataFrame.Internal.Array.Family.FloatX3: instance GHC.Float.Floating Numeric.DataFrame.Internal.Array.Family.FloatX3.FloatX3
- Numeric.DataFrame.Internal.Array.Family.FloatX3: instance GHC.Num.Num Numeric.DataFrame.Internal.Array.Family.FloatX3.FloatX3
- Numeric.DataFrame.Internal.Array.Family.FloatX3: instance GHC.Real.Fractional Numeric.DataFrame.Internal.Array.Family.FloatX3.FloatX3
- Numeric.DataFrame.Internal.Array.Family.FloatX3: instance GHC.Show.Show Numeric.DataFrame.Internal.Array.Family.FloatX3.FloatX3
- Numeric.DataFrame.Internal.Array.Family.FloatX3: instance Numeric.DataFrame.Internal.Array.Class.PrimArray GHC.Types.Float Numeric.DataFrame.Internal.Array.Family.FloatX3.FloatX3
- Numeric.DataFrame.Internal.Array.Family.FloatX3: instance Numeric.PrimBytes.PrimBytes Numeric.DataFrame.Internal.Array.Family.FloatX3.FloatX3
- Numeric.DataFrame.Internal.Array.Family.FloatX4: FloatX4# :: Float# -> Float# -> Float# -> Float# -> FloatX4
- Numeric.DataFrame.Internal.Array.Family.FloatX4: data FloatX4
- Numeric.DataFrame.Internal.Array.Family.FloatX4: instance GHC.Classes.Eq Numeric.DataFrame.Internal.Array.Family.FloatX4.FloatX4
- Numeric.DataFrame.Internal.Array.Family.FloatX4: instance GHC.Classes.Ord Numeric.DataFrame.Internal.Array.Family.FloatX4.FloatX4
- Numeric.DataFrame.Internal.Array.Family.FloatX4: instance GHC.Enum.Bounded Numeric.DataFrame.Internal.Array.Family.FloatX4.FloatX4
- Numeric.DataFrame.Internal.Array.Family.FloatX4: instance GHC.Float.Floating Numeric.DataFrame.Internal.Array.Family.FloatX4.FloatX4
- Numeric.DataFrame.Internal.Array.Family.FloatX4: instance GHC.Num.Num Numeric.DataFrame.Internal.Array.Family.FloatX4.FloatX4
- Numeric.DataFrame.Internal.Array.Family.FloatX4: instance GHC.Real.Fractional Numeric.DataFrame.Internal.Array.Family.FloatX4.FloatX4
- Numeric.DataFrame.Internal.Array.Family.FloatX4: instance GHC.Show.Show Numeric.DataFrame.Internal.Array.Family.FloatX4.FloatX4
- Numeric.DataFrame.Internal.Array.Family.FloatX4: instance Numeric.DataFrame.Internal.Array.Class.PrimArray GHC.Types.Float Numeric.DataFrame.Internal.Array.Family.FloatX4.FloatX4
- Numeric.DataFrame.Internal.Array.Family.FloatX4: instance Numeric.PrimBytes.PrimBytes Numeric.DataFrame.Internal.Array.Family.FloatX4.FloatX4
- Numeric.DataFrame.Internal.Array.Family.ScalarBase: ScalarBase :: t -> ScalarBase t
- Numeric.DataFrame.Internal.Array.Family.ScalarBase: [_unScalarBase] :: ScalarBase t -> t
- Numeric.DataFrame.Internal.Array.Family.ScalarBase: instance GHC.Classes.Eq t => GHC.Classes.Eq (Numeric.DataFrame.Internal.Array.Family.ScalarBase.ScalarBase t)
- Numeric.DataFrame.Internal.Array.Family.ScalarBase: instance GHC.Classes.Ord t => GHC.Classes.Ord (Numeric.DataFrame.Internal.Array.Family.ScalarBase.ScalarBase t)
- Numeric.DataFrame.Internal.Array.Family.ScalarBase: instance GHC.Enum.Bounded (Numeric.DataFrame.Internal.Array.Family.ScalarBase.ScalarBase GHC.Types.Double)
- Numeric.DataFrame.Internal.Array.Family.ScalarBase: instance GHC.Enum.Bounded (Numeric.DataFrame.Internal.Array.Family.ScalarBase.ScalarBase GHC.Types.Float)
- Numeric.DataFrame.Internal.Array.Family.ScalarBase: instance GHC.Enum.Bounded t => GHC.Enum.Bounded (Numeric.DataFrame.Internal.Array.Family.ScalarBase.ScalarBase t)
- Numeric.DataFrame.Internal.Array.Family.ScalarBase: instance GHC.Enum.Enum t => GHC.Enum.Enum (Numeric.DataFrame.Internal.Array.Family.ScalarBase.ScalarBase t)
- Numeric.DataFrame.Internal.Array.Family.ScalarBase: instance GHC.Float.Floating t => GHC.Float.Floating (Numeric.DataFrame.Internal.Array.Family.ScalarBase.ScalarBase t)
- Numeric.DataFrame.Internal.Array.Family.ScalarBase: instance GHC.Float.RealFloat t => GHC.Float.RealFloat (Numeric.DataFrame.Internal.Array.Family.ScalarBase.ScalarBase t)
- Numeric.DataFrame.Internal.Array.Family.ScalarBase: instance GHC.Num.Num t => GHC.Num.Num (Numeric.DataFrame.Internal.Array.Family.ScalarBase.ScalarBase t)
- Numeric.DataFrame.Internal.Array.Family.ScalarBase: instance GHC.Read.Read t => GHC.Read.Read (Numeric.DataFrame.Internal.Array.Family.ScalarBase.ScalarBase t)
- Numeric.DataFrame.Internal.Array.Family.ScalarBase: instance GHC.Real.Fractional t => GHC.Real.Fractional (Numeric.DataFrame.Internal.Array.Family.ScalarBase.ScalarBase t)
- Numeric.DataFrame.Internal.Array.Family.ScalarBase: instance GHC.Real.Integral t => GHC.Real.Integral (Numeric.DataFrame.Internal.Array.Family.ScalarBase.ScalarBase t)
- Numeric.DataFrame.Internal.Array.Family.ScalarBase: instance GHC.Real.Real t => GHC.Real.Real (Numeric.DataFrame.Internal.Array.Family.ScalarBase.ScalarBase t)
- Numeric.DataFrame.Internal.Array.Family.ScalarBase: instance GHC.Real.RealFrac t => GHC.Real.RealFrac (Numeric.DataFrame.Internal.Array.Family.ScalarBase.ScalarBase t)
- Numeric.DataFrame.Internal.Array.Family.ScalarBase: instance GHC.Show.Show t => GHC.Show.Show (Numeric.DataFrame.Internal.Array.Family.ScalarBase.ScalarBase t)
- Numeric.DataFrame.Internal.Array.Family.ScalarBase: instance Numeric.PrimBytes.PrimBytes t => Numeric.DataFrame.Internal.Array.Class.PrimArray t (Numeric.DataFrame.Internal.Array.Family.ScalarBase.ScalarBase t)
- Numeric.DataFrame.Internal.Array.Family.ScalarBase: instance Numeric.PrimBytes.PrimBytes t => Numeric.PrimBytes.PrimBytes (Numeric.DataFrame.Internal.Array.Family.ScalarBase.ScalarBase t)
- Numeric.DataFrame.Internal.Array.Family.ScalarBase: newtype ScalarBase t
- Numeric.DataFrame.Internal.Array.PrimOps: inftyD :: Double
- Numeric.DataFrame.Internal.Array.PrimOps: inftyF :: Float
- Numeric.DataFrame.Internal.Array.PrimOps: loop# :: Int# -> Int# -> Int# -> (Int# -> State# s -> State# s) -> State# s -> State# s
- Numeric.DataFrame.Internal.Array.PrimOps: loop1# :: Int# -> (Int# -> State# s -> State# s) -> State# s -> State# s
- Numeric.DataFrame.Internal.Array.PrimOps: loop1a# :: Int# -> (Int# -> a -> a) -> a -> a
- Numeric.DataFrame.Internal.Array.PrimOps: loopWithI# :: Int# -> Int# -> Int# -> (Int# -> Int# -> State# s -> State# s) -> State# s -> State# s
- Numeric.DataFrame.Internal.Array.PrimOps: minInt# :: Int# -> Int# -> Int#
- Numeric.DataFrame.Internal.Array.PrimOps: overDim_# :: Dims (ds :: [k]) -> (Idxs ds -> Int# -> State# s -> State# s) -> Int# -> Int# -> State# s -> State# s
- Numeric.DataFrame.Internal.Array.PrimOps: overDim_'# :: Dims (ds :: [k]) -> (Idxs ds -> Int# -> State# s -> (# State# s, Int# #)) -> Int# -> State# s -> (# State# s, Int# #)
- Numeric.DataFrame.Shape: (<+:>) :: forall (ds :: [Nat]) (n :: Nat) (m :: Nat) (t :: Type). (PrimBytes (DataFrame t (ds +: n)), PrimBytes (DataFrame t ds), PrimBytes (DataFrame t (ds +: m)), m ~ (n + 1)) => DataFrame t (ds +: n) -> DataFrame t ds -> DataFrame t (ds +: m)
- Numeric.DataFrame.Shape: (<::>) :: forall (ds :: [Nat]) (t :: Type). (PrimBytes (DataFrame t ds), PrimBytes (DataFrame t ds), PrimBytes (DataFrame t (ds +: 2 :: [Nat]))) => DataFrame t ds -> DataFrame t ds -> DataFrame t (ds +: 2 :: [Nat])
- Numeric.DataFrame.Shape: (<:>) :: forall (n :: Nat) (m :: Nat) (npm :: Nat) (ds :: [Nat]) (t :: Type). (PrimBytes (DataFrame t (ds +: n)), PrimBytes (DataFrame t (ds +: m)), PrimBytes (DataFrame t (ds +: npm)), npm ~ (n + m), n ~ (npm - m), m ~ (npm - n)) => DataFrame t (ds +: n) -> DataFrame t (ds +: m) -> DataFrame t (ds +: npm)
- Numeric.DataFrame.Shape: class DataFrameToList (t :: Type) (ds :: [k]) (z :: k)
- Numeric.DataFrame.Shape: fromList :: forall m ns t. (Dimensions ns, PrimBytes t) => Dim m -> [DataFrame t ns] -> Maybe (DataFrame t (AsXDims ns +: XN m))
- Numeric.DataFrame.Shape: fromListN :: forall (m :: Nat) (ns :: [Nat]) (t :: Type). (Dimensions ns, PrimBytes t) => Dim m -> Int -> [DataFrame t ns] -> Maybe (DataFrame t (AsXDims ns +: XN m))
- Numeric.DataFrame.Shape: fromScalar :: SubSpace t '[] ds ds => Scalar t -> DataFrame t ds
- Numeric.DataFrame.Shape: infixl 5 <+:>
- Numeric.DataFrame.Shape: instance (Numeric.Dimensions.Dims.Dimensions (ns Numeric.Type.List.+: z), Numeric.PrimBytes.PrimBytes t) => Numeric.DataFrame.Shape.DataFrameToList t ns z
- Numeric.DataFrame.Shape: instance Numeric.DataFrame.Shape.DataFrameToList t xns xz
- Numeric.DataFrame.Shape: toList :: DataFrameToList t ds z => DataFrame t (ds +: z) -> [DataFrame t ds]
- Numeric.DataFrame.SubSpace: (!.) :: forall t as bs asbs. SubSpace t as bs asbs => Idxs bs -> DataFrame t asbs -> DataFrame t as
- Numeric.DataFrame.SubSpace: infixr 4 !.
- Numeric.DataFrame.SubSpace: instance (Numeric.Type.List.ConcatList as bs asbs, Numeric.Dimensions.Dims.Dimensions as, Numeric.Dimensions.Dims.Dimensions bs, Numeric.Dimensions.Dims.Dimensions asbs, Numeric.DataFrame.Internal.Array.Class.PrimArray t (Numeric.DataFrame.Family.DataFrame t as), Numeric.DataFrame.Internal.Array.Class.PrimArray t (Numeric.DataFrame.Family.DataFrame t asbs), Numeric.PrimBytes.PrimBytes (Numeric.DataFrame.Family.DataFrame t as), Numeric.PrimBytes.PrimBytes (Numeric.DataFrame.Family.DataFrame t asbs)) => Numeric.DataFrame.SubSpace.SubSpace t as bs asbs
- Numeric.DataFrame.Type: Idx :: Word -> Idx
- Numeric.DataFrame.Type: [unIdx] :: Idx -> Word
- Numeric.DataFrame.Type: class DataFrameInference (t :: l)
- Numeric.DataFrame.Type: class Dim1 (t :: [k] -> Type) (ds :: [k])
- Numeric.DataFrame.Type: class Dim2 (t :: [k] -> Type) (ds :: [k])
- Numeric.DataFrame.Type: class Dim3 (t :: [k] -> Type) (ds :: [k])
- Numeric.DataFrame.Type: dim1 :: Dim1 t ds => t ds -> Dim (Head ds)
- Numeric.DataFrame.Type: dim2 :: Dim2 t ds => t ds -> Dim (Head (Tail ds))
- Numeric.DataFrame.Type: dim3 :: Dim3 t ds => t ds -> Dim (Head (Tail (Tail ds)))
- Numeric.DataFrame.Type: dimSize1 :: Dim1 t ds => t ds -> Word
- Numeric.DataFrame.Type: dimSize2 :: Dim2 t ds => t ds -> Word
- Numeric.DataFrame.Type: dimSize3 :: Dim3 t ds => t ds -> Word
- Numeric.DataFrame.Type: inferASing :: (DataFrameInference t, AllTypes PrimBytes t, Dimensions ds) => DataFrame t ds -> Evidence (ArraySingletons t ds)
- Numeric.DataFrame.Type: inferASing' :: forall t ds. (DataFrameInference t, AllTypes PrimBytes t, Dimensions ds) => Evidence (ArraySingletons t ds)
- Numeric.DataFrame.Type: inferEq :: (DataFrameInference t, AllTypes Eq t, ArraySingletons t ds) => DataFrame t ds -> Evidence (Eq (DataFrame t ds))
- Numeric.DataFrame.Type: inferEq' :: forall t ds. (DataFrameInference t, AllTypes Eq t, ArraySingletons t ds) => Evidence (Eq (DataFrame t ds))
- Numeric.DataFrame.Type: inferFloating :: forall t ds. (Floating t, ArraySingleton t ds) => DataFrame t ds -> Evidence (Floating (DataFrame t ds))
- Numeric.DataFrame.Type: inferFloating' :: forall t ds. (Floating t, ArraySingleton t ds) => Evidence (Floating (DataFrame t ds))
- Numeric.DataFrame.Type: inferFractional :: forall t ds. (Fractional t, ArraySingleton t ds) => DataFrame t ds -> Evidence (Fractional (DataFrame t ds))
- Numeric.DataFrame.Type: inferFractional' :: forall t ds. (Fractional t, ArraySingleton t ds) => Evidence (Fractional (DataFrame t ds))
- Numeric.DataFrame.Type: inferNum :: forall t ds. (Num t, ArraySingletons t ds) => DataFrame t ds -> Evidence (Num (DataFrame t ds))
- Numeric.DataFrame.Type: inferNum' :: forall t ds. (Num t, ArraySingletons t ds) => Evidence (Num (DataFrame t ds))
- Numeric.DataFrame.Type: inferOrd :: forall t ds. (Ord t, ArraySingleton t ds) => DataFrame t ds -> Evidence (Ord (DataFrame t ds))
- Numeric.DataFrame.Type: inferOrd' :: forall t ds. (Ord t, ArraySingleton t ds) => Evidence (Ord (DataFrame t ds))
- Numeric.DataFrame.Type: inferPrim :: (DataFrameInference t, AllTypes PrimBytes t, ArraySingletons t ds, Dimensions ds) => DataFrame t ds -> Evidence (PrimFrames t ds)
- Numeric.DataFrame.Type: inferPrim' :: forall t ds. (DataFrameInference t, AllTypes PrimBytes t, ArraySingletons t ds, Dimensions ds) => Evidence (PrimFrames t ds)
- Numeric.DataFrame.Type: inferPrimElem' :: forall t ds. (DataFrameInference t, ArraySingletons t ds, ds ~ (Head ds : Tail ds)) => Evidence (AllTypes PrimBytes t)
- Numeric.DataFrame.Type: inferShow :: (DataFrameInference t, AllTypes Show t, ArraySingletons t ds, Dimensions ds) => DataFrame t ds -> Evidence (Show (DataFrame t ds))
- Numeric.DataFrame.Type: inferShow' :: forall t ds. (DataFrameInference t, AllTypes Show t, ArraySingletons t ds, Dimensions ds) => Evidence (Show (DataFrame t ds))
- Numeric.DataFrame.Type: instance (GHC.Read.Read (Numeric.DataFrame.Internal.Array.Family.Array t ds), Numeric.Dimensions.Dims.Dimensions ds) => GHC.Read.Read (Numeric.DataFrame.Family.DataFrame t ds)
- Numeric.DataFrame.Type: instance (GHC.Show.Show (Numeric.DataFrame.Internal.Array.Family.Array t ds), Numeric.Dimensions.Dims.Dimensions ds) => GHC.Show.Show (Numeric.DataFrame.Family.DataFrame t ds)
- Numeric.DataFrame.Type: instance (Numeric.DataFrame.Internal.Array.Class.PrimArray t (Numeric.DataFrame.Internal.Array.Family.Array t ds), Numeric.PrimBytes.PrimBytes t) => Numeric.DataFrame.Internal.Array.Class.PrimArray t (Numeric.DataFrame.Family.DataFrame t ds)
- Numeric.DataFrame.Type: instance (Numeric.Dimensions.Dims.Dimensions ds, Numeric.DataFrame.Type.ImplAllows GHC.Show.Show ts ds) => GHC.Show.Show (Numeric.DataFrame.Family.DataFrame ts ds)
- Numeric.DataFrame.Type: instance GHC.Classes.Eq (Numeric.DataFrame.Internal.Array.Family.Array t ds) => GHC.Classes.Eq (Numeric.DataFrame.Family.DataFrame t ds)
- Numeric.DataFrame.Type: instance GHC.Classes.Ord (Numeric.DataFrame.Internal.Array.Family.Array t ds) => GHC.Classes.Ord (Numeric.DataFrame.Family.DataFrame t ds)
- Numeric.DataFrame.Type: instance GHC.Enum.Bounded (Numeric.DataFrame.Internal.Array.Family.Array t ds) => GHC.Enum.Bounded (Numeric.DataFrame.Family.DataFrame t ds)
- Numeric.DataFrame.Type: instance GHC.Enum.Enum (Numeric.DataFrame.Internal.Array.Family.Array t ds) => GHC.Enum.Enum (Numeric.DataFrame.Family.DataFrame t ds)
- Numeric.DataFrame.Type: instance GHC.Float.Floating (Numeric.DataFrame.Internal.Array.Family.Array t ds) => GHC.Float.Floating (Numeric.DataFrame.Family.DataFrame t ds)
- Numeric.DataFrame.Type: instance GHC.Float.RealFloat (Numeric.DataFrame.Internal.Array.Family.Array t ds) => GHC.Float.RealFloat (Numeric.DataFrame.Family.DataFrame t ds)
- Numeric.DataFrame.Type: instance GHC.Num.Num (Numeric.DataFrame.Internal.Array.Family.Array t ds) => GHC.Num.Num (Numeric.DataFrame.Family.DataFrame t ds)
- Numeric.DataFrame.Type: instance GHC.Real.Fractional (Numeric.DataFrame.Internal.Array.Family.Array t ds) => GHC.Real.Fractional (Numeric.DataFrame.Family.DataFrame t ds)
- Numeric.DataFrame.Type: instance GHC.Real.Integral (Numeric.DataFrame.Internal.Array.Family.Array t ds) => GHC.Real.Integral (Numeric.DataFrame.Family.DataFrame t ds)
- Numeric.DataFrame.Type: instance GHC.Real.Real (Numeric.DataFrame.Internal.Array.Family.Array t ds) => GHC.Real.Real (Numeric.DataFrame.Family.DataFrame t ds)
- Numeric.DataFrame.Type: instance GHC.Real.RealFrac (Numeric.DataFrame.Internal.Array.Family.Array t ds) => GHC.Real.RealFrac (Numeric.DataFrame.Family.DataFrame t ds)
- Numeric.DataFrame.Type: instance Numeric.DataFrame.Type.DataFrameInference t
- Numeric.DataFrame.Type: instance Numeric.DataFrame.Type.ImplAllows GHC.Classes.Eq ts ds => GHC.Classes.Eq (Numeric.DataFrame.Family.DataFrame ts ds)
- Numeric.DataFrame.Type: instance Numeric.PrimBytes.PrimBytes (Numeric.DataFrame.Internal.Array.Family.Array t ds) => Numeric.PrimBytes.PrimBytes (Numeric.DataFrame.Family.DataFrame t ds)
- Numeric.DataFrame.Type: instance Numeric.TypedList.RepresentableList ts => Numeric.DataFrame.Type.DataFrameInference ts
- Numeric.DataFrame.Type: instance forall k (d :: k) (ds :: [k]) (t :: [k] -> Type). Numeric.Dimensions.Dims.Dimensions (d : ds) => Numeric.DataFrame.Type.Dim1 t (d : ds)
- Numeric.DataFrame.Type: instance forall k (d :: k) (ds :: [k]). Numeric.DataFrame.Type.Dim1 (Numeric.TypedList.TypedList Numeric.Dim.Dim) (d : ds)
- Numeric.DataFrame.Type: instance forall k (d1 :: k) (d2 :: k) (d3 :: k) (ds :: [k]) (t :: [k] -> Type). Numeric.Dimensions.Dims.Dimensions (d1 : d2 : d3 : ds) => Numeric.DataFrame.Type.Dim3 t (d1 : d2 : d3 : ds)
- Numeric.DataFrame.Type: instance forall k (d1 :: k) (d2 :: k) (d3 :: k) (ds :: [k]). Numeric.DataFrame.Type.Dim3 (Numeric.TypedList.TypedList Numeric.Dim.Dim) (d1 : d2 : d3 : ds)
- Numeric.DataFrame.Type: instance forall k (d1 :: k) (d2 :: k) (ds :: [k]) (t :: [k] -> Type). Numeric.Dimensions.Dims.Dimensions (d1 : d2 : ds) => Numeric.DataFrame.Type.Dim2 t (d1 : d2 : ds)
- Numeric.DataFrame.Type: instance forall k (d1 :: k) (d2 :: k) (ds :: [k]). Numeric.DataFrame.Type.Dim2 (Numeric.TypedList.TypedList Numeric.Dim.Dim) (d1 : d2 : ds)
- Numeric.DataFrame.Type: instance forall k l (t :: l) (ds :: [k]). Numeric.PrimBytes.PrimBytes (Numeric.DataFrame.Family.DataFrame t ds) => Foreign.Storable.Storable (Numeric.DataFrame.Family.DataFrame t ds)
- Numeric.DataFrame.Type: instance forall l (t :: l) (ds :: [Numeric.Dim.XNat]). (Numeric.DataFrame.Type.AllTypes GHC.Classes.Eq t, Numeric.DataFrame.Type.DataFrameInference t) => GHC.Classes.Eq (Numeric.DataFrame.Family.DataFrame t ds)
- Numeric.DataFrame.Type: instance forall l (t :: l) (xns :: [Numeric.Dim.XNat]). (Numeric.DataFrame.Type.AllTypes GHC.Show.Show t, Numeric.DataFrame.Type.DataFrameInference t) => GHC.Show.Show (Numeric.DataFrame.Family.DataFrame t xns)
- Numeric.DataFrame.Type: instance forall l (t :: l). (Numeric.DataFrame.Type.AllTypes GHC.Classes.Eq t, Numeric.DataFrame.Type.DataFrameInference t) => GHC.Classes.Eq (Numeric.DataFrame.Type.SomeDataFrame t)
- Numeric.DataFrame.Type: instance forall l (t :: l). (Numeric.DataFrame.Type.AllTypes GHC.Show.Show t, Numeric.DataFrame.Type.DataFrameInference t) => GHC.Show.Show (Numeric.DataFrame.Type.SomeDataFrame t)
- Numeric.DataFrame.Type: instance forall l1 (l2 :: l1) (d :: Numeric.Dim.XNat) (ds :: [Numeric.Dim.XNat]). Numeric.DataFrame.Type.Dim1 (Numeric.DataFrame.Family.DataFrame l2) (d : ds)
- Numeric.DataFrame.Type: instance forall l1 (l2 :: l1) (d1 :: Numeric.Dim.XNat) (d2 :: Numeric.Dim.XNat) (d3 :: Numeric.Dim.XNat) (ds :: [Numeric.Dim.XNat]). Numeric.DataFrame.Type.Dim3 (Numeric.DataFrame.Family.DataFrame l2) (d1 : d2 : d3 : ds)
- Numeric.DataFrame.Type: instance forall l1 (l2 :: l1) (d1 :: Numeric.Dim.XNat) (d2 :: Numeric.Dim.XNat) (ds :: [Numeric.Dim.XNat]). Numeric.DataFrame.Type.Dim2 (Numeric.DataFrame.Family.DataFrame l2) (d1 : d2 : ds)
- Numeric.DataFrame.Type: newtype Idx (n :: k) :: forall k. () => k -> Type
- Numeric.DataFrame.Type: unsafeFromFlatList :: PrimArray t a => Int -> [t] -> a
- Numeric.Matrix: instance (Numeric.Dim.KnownDim n, GHC.Classes.Ord t, GHC.Real.Fractional t, Numeric.PrimBytes.PrimBytes t, Numeric.DataFrame.Internal.Array.Class.PrimArray t (Numeric.Matrix.Class.Matrix t n n)) => Numeric.Matrix.Class.MatrixDeterminant t n
- Numeric.Matrix: instance (Numeric.Dim.KnownDim n, GHC.Classes.Ord t, GHC.Real.Fractional t, Numeric.PrimBytes.PrimBytes t, Numeric.DataFrame.Internal.Array.Class.PrimArray t (Numeric.Matrix.Class.Matrix t n n)) => Numeric.Matrix.Class.MatrixLU t n
- Numeric.Matrix: instance (Numeric.Dim.KnownDim n, GHC.Classes.Ord t, GHC.Real.Fractional t, Numeric.PrimBytes.PrimBytes t, Numeric.DataFrame.Internal.Array.Class.PrimArray t (Numeric.Matrix.Class.Matrix t n n), Numeric.DataFrame.Internal.Array.Class.PrimArray t (Numeric.Vector.Vector t n), Numeric.PrimBytes.PrimBytes (Numeric.Vector.Vector t n), Numeric.PrimBytes.PrimBytes (Numeric.Matrix.Class.Matrix t n n)) => Numeric.Matrix.Class.MatrixInverse t n
- Numeric.Matrix: instance (Numeric.Dim.KnownDim n, Numeric.DataFrame.Internal.Array.Class.PrimArray t (Numeric.Matrix.Class.Matrix t n n), GHC.Num.Num t) => Numeric.Matrix.Class.SquareMatrix t n
- Numeric.Matrix: instance (Numeric.Dim.KnownDim n, Numeric.Dim.KnownDim m, Numeric.DataFrame.Internal.Array.Class.PrimArray t (Numeric.Matrix.Class.Matrix t n m), Numeric.DataFrame.Internal.Array.Class.PrimArray t (Numeric.Matrix.Class.Matrix t m n)) => Numeric.Matrix.Class.MatrixTranspose t n m
- Numeric.Matrix: instance Numeric.Matrix.Class.MatrixTranspose t xn xm
- Numeric.Matrix.Class: LUFact :: Matrix t n n -> Matrix t n n -> Matrix t n n -> Scalar t -> LUFact t n
- Numeric.Matrix.Class: [luLower] :: LUFact t n -> Matrix t n n
- Numeric.Matrix.Class: [luPermSign] :: LUFact t n -> Scalar t
- Numeric.Matrix.Class: [luPerm] :: LUFact t n -> Matrix t n n
- Numeric.Matrix.Class: [luUpper] :: LUFact t n -> Matrix t n n
- Numeric.Matrix.Class: class HomTransform4 t
- Numeric.Matrix.Class: class MatrixDeterminant t (n :: Nat)
- Numeric.Matrix.Class: class MatrixInverse t (n :: Nat)
- Numeric.Matrix.Class: class MatrixLU t (n :: Nat)
- Numeric.Matrix.Class: class MatrixTranspose t (n :: k) (m :: k)
- Numeric.Matrix.Class: class SquareMatrix t (n :: Nat)
- Numeric.Matrix.Class: data LUFact t n
- Numeric.Matrix.Class: det :: MatrixDeterminant t n => Matrix t n n -> Scalar t
- Numeric.Matrix.Class: diag :: SquareMatrix t n => Scalar t -> Matrix t n n
- Numeric.Matrix.Class: eye :: SquareMatrix t n => Matrix t n n
- Numeric.Matrix.Class: fromHom :: HomTransform4 t => Vector t 4 -> Vector t 3
- Numeric.Matrix.Class: instance forall k t (n :: k). (GHC.Classes.Eq (Numeric.Matrix.Class.Matrix t n n), GHC.Classes.Eq t) => GHC.Classes.Eq (Numeric.Matrix.Class.LUFact t n)
- Numeric.Matrix.Class: instance forall k t (n :: k). (GHC.Show.Show (Numeric.Matrix.Class.Matrix t n n), GHC.Show.Show t) => GHC.Show.Show (Numeric.Matrix.Class.LUFact t n)
- Numeric.Matrix.Class: inverse :: MatrixInverse t n => Matrix t n n -> Matrix t n n
- Numeric.Matrix.Class: lookAt :: HomTransform4 t => Vector t 3 -> Vector t 3 -> Vector t 3 -> Matrix t 4 4
- Numeric.Matrix.Class: lu :: MatrixLU t n => Matrix t n n -> LUFact t n
- Numeric.Matrix.Class: orthogonal :: HomTransform4 t => t -> t -> t -> t -> Matrix t 4 4
- Numeric.Matrix.Class: perspective :: HomTransform4 t => t -> t -> t -> t -> Matrix t 4 4
- Numeric.Matrix.Class: rotate :: HomTransform4 t => Vector t 3 -> t -> Matrix t 4 4
- Numeric.Matrix.Class: rotateEuler :: HomTransform4 t => t -> t -> t -> Matrix t 4 4
- Numeric.Matrix.Class: rotateX :: HomTransform4 t => t -> Matrix t 4 4
- Numeric.Matrix.Class: rotateY :: HomTransform4 t => t -> Matrix t 4 4
- Numeric.Matrix.Class: rotateZ :: HomTransform4 t => t -> Matrix t 4 4
- Numeric.Matrix.Class: toHomPoint :: HomTransform4 t => Vector t 3 -> Vector t 4
- Numeric.Matrix.Class: toHomVector :: HomTransform4 t => Vector t 3 -> Vector t 4
- Numeric.Matrix.Class: trace :: SquareMatrix t n => Matrix t n n -> Scalar t
- Numeric.Matrix.Class: translate3 :: HomTransform4 t => Vector t 3 -> Matrix t 4 4
- Numeric.Matrix.Class: translate4 :: HomTransform4 t => Vector t 4 -> Matrix t 4 4
- Numeric.Matrix.Class: transpose :: MatrixTranspose t n m => Matrix t n m -> Matrix t m n
- Numeric.Matrix.Class: type Mat22d = Matrix Double 2 2
- Numeric.Matrix.Class: type Mat22f = Matrix Float 2 2
- Numeric.Matrix.Class: type Mat23d = Matrix Double 2 3
- Numeric.Matrix.Class: type Mat23f = Matrix Float 2 3
- Numeric.Matrix.Class: type Mat24d = Matrix Double 2 4
- Numeric.Matrix.Class: type Mat24f = Matrix Float 2 4
- Numeric.Matrix.Class: type Mat32d = Matrix Double 3 2
- Numeric.Matrix.Class: type Mat32f = Matrix Float 3 2
- Numeric.Matrix.Class: type Mat33d = Matrix Double 3 3
- Numeric.Matrix.Class: type Mat33f = Matrix Float 3 3
- Numeric.Matrix.Class: type Mat34d = Matrix Double 3 4
- Numeric.Matrix.Class: type Mat34f = Matrix Float 3 4
- Numeric.Matrix.Class: type Mat42d = Matrix Double 4 2
- Numeric.Matrix.Class: type Mat42f = Matrix Float 4 2
- Numeric.Matrix.Class: type Mat43d = Matrix Double 4 3
- Numeric.Matrix.Class: type Mat43f = Matrix Float 4 3
- Numeric.Matrix.Class: type Mat44d = Matrix Double 4 4
- Numeric.Matrix.Class: type Mat44f = Matrix Float 4 4
- Numeric.Matrix.Class: type Matrix (t :: l) (n :: k) (m :: k) = DataFrame t '[n, m]
- Numeric.PrimBytes: instance (Numeric.PrimBytes.GPrimBytes f, Numeric.PrimBytes.GPrimBytes g) => Numeric.PrimBytes.GPrimBytes (f GHC.Generics.:*: g)
- Numeric.PrimBytes: instance (Numeric.PrimBytes.GPrimBytes f, Numeric.PrimBytes.GPrimBytes g) => Numeric.PrimBytes.GPrimBytes (f GHC.Generics.:+: g)
- Numeric.PrimBytes: instance (Numeric.TypedList.RepresentableList xs, Numeric.Type.List.All Numeric.PrimBytes.PrimBytes xs) => Numeric.PrimBytes.PrimBytes (Numeric.Tuple.Lazy.Tuple xs)
- Numeric.PrimBytes: instance (Numeric.TypedList.RepresentableList xs, Numeric.Type.List.All Numeric.PrimBytes.PrimBytes xs) => Numeric.PrimBytes.PrimBytes (Numeric.Tuple.Strict.Tuple xs)
- Numeric.PrimBytes: instance Numeric.PrimBytes.GPrimBytes f => Numeric.PrimBytes.GPrimBytes (GHC.Generics.M1 i c f)
- Numeric.PrimBytes: instance Numeric.PrimBytes.PrimBytes (Numeric.Dimensions.Idxs.Idx x)
- Numeric.PrimBytes: instance Numeric.PrimBytes.PrimBytes a => Numeric.PrimBytes.PrimBytes [a]
- Numeric.PrimBytes: instance Numeric.TypedList.RepresentableList xs => Numeric.PrimBytes.PrimBytes (Numeric.Dimensions.Idxs.Idxs xs)
- Numeric.Quaternion: -- a 3D vector
- Numeric.Quaternion: -- where <tt>w</tt> is an argument, and <tt>x y z</tt> are components of
- Numeric.Quaternion: unpackQ :: Quaternion t => Quater t -> (t, t, t, t)
- Numeric.Semigroup: (<>) :: Semigroup a => a -> a -> a
- Numeric.Semigroup: All :: Bool -> All
- Numeric.Semigroup: Any :: Bool -> Any
- Numeric.Semigroup: Arg :: a -> b -> Arg a b
- Numeric.Semigroup: Dual :: a -> Dual a
- Numeric.Semigroup: Endo :: (a -> a) -> Endo a
- Numeric.Semigroup: First :: a -> First a
- Numeric.Semigroup: Last :: a -> Last a
- Numeric.Semigroup: Max :: a -> Max a
- Numeric.Semigroup: Min :: a -> Min a
- Numeric.Semigroup: MinMax :: a -> a -> MinMax a
- Numeric.Semigroup: Option :: Maybe a -> Option a
- Numeric.Semigroup: Product :: a -> Product a
- Numeric.Semigroup: Sum :: a -> Sum a
- Numeric.Semigroup: WrapMonoid :: m -> WrappedMonoid m
- Numeric.Semigroup: [appEndo] :: Endo a -> a -> a
- Numeric.Semigroup: [getAll] :: All -> Bool
- Numeric.Semigroup: [getAny] :: Any -> Bool
- Numeric.Semigroup: [getDual] :: Dual a -> a
- Numeric.Semigroup: [getFirst] :: First a -> a
- Numeric.Semigroup: [getLast] :: Last a -> a
- Numeric.Semigroup: [getMax] :: Max a -> a
- Numeric.Semigroup: [getMin] :: Min a -> a
- Numeric.Semigroup: [getOption] :: Option a -> Maybe a
- Numeric.Semigroup: [getProduct] :: Product a -> a
- Numeric.Semigroup: [getSum] :: Sum a -> a
- Numeric.Semigroup: [unwrapMonoid] :: WrappedMonoid m -> m
- Numeric.Semigroup: class Semigroup a => Monoid a
- Numeric.Semigroup: class Semigroup a
- Numeric.Semigroup: cycle1 :: Semigroup m => m -> m
- Numeric.Semigroup: data Arg a b
- Numeric.Semigroup: data MinMax a
- Numeric.Semigroup: diff :: Semigroup m => m -> Endo m
- Numeric.Semigroup: foldMap' :: (Foldable t, Monoid m) => (a -> m) -> t a -> m
- Numeric.Semigroup: fromOption :: a -> Option a -> a
- Numeric.Semigroup: infixr 6 <>
- Numeric.Semigroup: instance (GHC.Classes.Ord a, GHC.Enum.Bounded a) => GHC.Base.Monoid (Numeric.Semigroup.MinMax a)
- Numeric.Semigroup: instance (GHC.Num.Num a, GHC.Classes.Ord a) => GHC.Num.Num (Numeric.Semigroup.MinMax a)
- Numeric.Semigroup: instance Control.Monad.Fix.MonadFix Numeric.Semigroup.MinMax
- Numeric.Semigroup: instance Control.Monad.Fix.MonadFix Numeric.Semigroup.Option
- Numeric.Semigroup: instance Data.Data.Data a => Data.Data.Data (Numeric.Semigroup.MinMax a)
- Numeric.Semigroup: instance Data.Data.Data a => Data.Data.Data (Numeric.Semigroup.Option a)
- Numeric.Semigroup: instance Data.Foldable.Foldable Numeric.Semigroup.Option
- Numeric.Semigroup: instance Data.Traversable.Traversable Numeric.Semigroup.Option
- Numeric.Semigroup: instance GHC.Base.Alternative Numeric.Semigroup.Option
- Numeric.Semigroup: instance GHC.Base.Applicative Numeric.Semigroup.MinMax
- Numeric.Semigroup: instance GHC.Base.Applicative Numeric.Semigroup.Option
- Numeric.Semigroup: instance GHC.Base.Functor Numeric.Semigroup.MinMax
- Numeric.Semigroup: instance GHC.Base.Functor Numeric.Semigroup.Option
- Numeric.Semigroup: instance GHC.Base.Monad Numeric.Semigroup.MinMax
- Numeric.Semigroup: instance GHC.Base.Monad Numeric.Semigroup.Option
- Numeric.Semigroup: instance GHC.Base.Semigroup a => GHC.Base.Monoid (Numeric.Semigroup.Option a)
- Numeric.Semigroup: instance GHC.Base.Semigroup a => GHC.Base.Semigroup (Numeric.Semigroup.Option a)
- Numeric.Semigroup: instance GHC.Classes.Eq a => GHC.Classes.Eq (Numeric.Semigroup.MinMax a)
- Numeric.Semigroup: instance GHC.Classes.Eq a => GHC.Classes.Eq (Numeric.Semigroup.Option a)
- Numeric.Semigroup: instance GHC.Classes.Ord a => GHC.Base.Semigroup (Numeric.Semigroup.MinMax a)
- Numeric.Semigroup: instance GHC.Classes.Ord a => GHC.Classes.Ord (Numeric.Semigroup.MinMax a)
- Numeric.Semigroup: instance GHC.Classes.Ord a => GHC.Classes.Ord (Numeric.Semigroup.Option a)
- Numeric.Semigroup: instance GHC.Enum.Bounded a => GHC.Enum.Bounded (Numeric.Semigroup.MinMax a)
- Numeric.Semigroup: instance GHC.Generics.Generic (Numeric.Semigroup.MinMax a)
- Numeric.Semigroup: instance GHC.Generics.Generic (Numeric.Semigroup.Option a)
- Numeric.Semigroup: instance GHC.Generics.Generic1 Numeric.Semigroup.MinMax
- Numeric.Semigroup: instance GHC.Generics.Generic1 Numeric.Semigroup.Option
- Numeric.Semigroup: instance GHC.Read.Read a => GHC.Read.Read (Numeric.Semigroup.MinMax a)
- Numeric.Semigroup: instance GHC.Read.Read a => GHC.Read.Read (Numeric.Semigroup.Option a)
- Numeric.Semigroup: instance GHC.Show.Show a => GHC.Show.Show (Numeric.Semigroup.MinMax a)
- Numeric.Semigroup: instance GHC.Show.Show a => GHC.Show.Show (Numeric.Semigroup.Option a)
- Numeric.Semigroup: mappend :: Monoid a => a -> a -> a
- Numeric.Semigroup: mconcat :: Monoid a => [a] -> a
- Numeric.Semigroup: mempty :: Monoid a => a
- Numeric.Semigroup: minMax :: a -> MinMax a
- Numeric.Semigroup: mmAvg :: Fractional a => MinMax a -> a
- Numeric.Semigroup: mmDiff :: Num a => MinMax a -> a
- Numeric.Semigroup: mtimesDefault :: (Integral b, Monoid a) => b -> a -> a
- Numeric.Semigroup: newtype All
- Numeric.Semigroup: newtype Any
- Numeric.Semigroup: newtype Dual a
- Numeric.Semigroup: newtype Endo a
- Numeric.Semigroup: newtype First a
- Numeric.Semigroup: newtype Last a
- Numeric.Semigroup: newtype Max a
- Numeric.Semigroup: newtype Min a
- Numeric.Semigroup: newtype Option a
- Numeric.Semigroup: newtype Product a
- Numeric.Semigroup: newtype Sum a
- Numeric.Semigroup: newtype WrappedMonoid m
- Numeric.Semigroup: option :: b -> (a -> b) -> Option a -> b
- Numeric.Semigroup: sconcat :: Semigroup a => NonEmpty a -> a
- Numeric.Semigroup: stimes :: (Semigroup a, Integral b) => b -> a -> a
- Numeric.Semigroup: stimesIdempotent :: Integral b => b -> a -> a
- Numeric.Semigroup: stimesIdempotentMonoid :: (Integral b, Monoid a) => b -> a -> a
- Numeric.Semigroup: stimesMonoid :: (Integral b, Monoid a) => b -> a -> a
- Numeric.Semigroup: toOption :: a -> Option a
- Numeric.Semigroup: type ArgMax a b = Max Arg a b
- Numeric.Semigroup: type ArgMin a b = Min Arg a b
- Numeric.Vector: unpackV2 :: SubSpace t '[] '[2] '[2] => Vector t 2 -> (t, t)
- Numeric.Vector: unpackV3 :: SubSpace t '[] '[3] '[3] => Vector t 3 -> (t, t, t)
- Numeric.Vector: unpackV4 :: SubSpace t '[] '[4] '[4] => Vector t 4 -> (t, t, t, t)
+ Numeric.DataFrame.Contraction: 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
+ Numeric.DataFrame.IO: 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 ()
+ Numeric.DataFrame.IO: 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 ()
+ Numeric.DataFrame.Internal.Backend: Backend :: backend -> Backend
+ Numeric.DataFrame.Internal.Backend: [_getBackend] :: Backend -> backend
+ Numeric.DataFrame.Internal.Backend: inferBounded :: forall (t :: Type) (ds :: [Nat]) (b :: Type). (Bounded t, KnownBackend t ds b) => Dict (Bounded (Backend I t ds b))
+ Numeric.DataFrame.Internal.Backend: inferEq :: forall (t :: Type) (ds :: [Nat]) (b :: Type). (Eq t, KnownBackend t ds b) => Dict (Eq (Backend I t ds b))
+ Numeric.DataFrame.Internal.Backend: inferFloating :: forall (t :: Type) (ds :: [Nat]) (b :: Type). (Floating t, KnownBackend t ds b) => Dict (Floating (Backend I t ds b))
+ Numeric.DataFrame.Internal.Backend: inferFractional :: forall (t :: Type) (ds :: [Nat]) (b :: Type). (Fractional t, KnownBackend t ds b) => Dict (Fractional (Backend I t ds b))
+ Numeric.DataFrame.Internal.Backend: inferKnownBackend :: forall (t :: Type) (ds :: [Nat]). (PrimBytes t, Dimensions ds) => Dict (KnownBackend t ds)
+ Numeric.DataFrame.Internal.Backend: inferNum :: forall (t :: Type) (ds :: [Nat]) (b :: Type). (Num t, KnownBackend t ds b) => Dict (Num (Backend I t ds b))
+ Numeric.DataFrame.Internal.Backend: inferOrd :: forall (t :: Type) (ds :: [Nat]) (b :: Type). (Ord t, KnownBackend t ds b) => Dict (Ord (Backend I t ds b))
+ Numeric.DataFrame.Internal.Backend: inferPONonTransitive :: forall (t :: Type) (ds :: [Nat]) (b :: Type). (Ord t, KnownBackend t ds b) => Dict (Ord (ProductOrd (Backend I t ds b)))
+ Numeric.DataFrame.Internal.Backend: inferPOPartial :: forall (t :: Type) (ds :: [Nat]) (b :: Type). (Ord t, KnownBackend t ds b) => Dict (Ord (ProductOrd (Backend I t ds b)))
+ Numeric.DataFrame.Internal.Backend: inferPrimArray :: forall (t :: Type) (ds :: [Nat]) (b :: Type). (PrimBytes t, KnownBackend t ds b) => Dict (PrimArray t (Backend I t ds b))
+ Numeric.DataFrame.Internal.Backend: inferPrimBytes :: forall (t :: Type) (ds :: [Nat]) (b :: Type). (PrimBytes t, Dimensions ds, KnownBackend t ds b) => Dict (PrimBytes (Backend I t ds b))
+ Numeric.DataFrame.Internal.Backend: inferPrimElem :: forall (t :: Type) (d :: Nat) (ds :: [Nat]). KnownBackend t (d : ds) => DFBackend t (d : ds) -> Dict (PrimBytes t)
+ Numeric.DataFrame.Internal.Backend: inferProductOrder :: forall (t :: Type) (ds :: [Nat]) (b :: Type). (Ord t, KnownBackend t ds b) => Dict (ProductOrder (Backend I t ds b))
+ Numeric.DataFrame.Internal.Backend: newtype Backend (i :: Type) (t :: Type) (ds :: [Nat]) (backend :: Type)
+ Numeric.DataFrame.Internal.Backend: type DFBackend (t :: Type) (ds :: [Nat]) = Backend I t ds (BackendFamily t ds)
+ Numeric.DataFrame.Internal.Backend: type KnownBackend (t :: Type) (ds :: [Nat]) = KnownBackend t ds (BackendFamily t ds)
+ Numeric.DataFrame.Internal.Backend: type family BackendFamily (t :: Type) (ds :: [Nat]) = (v :: Type) | v -> t ds
+ Numeric.DataFrame.Internal.Mutable: 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, () #)
+ Numeric.DataFrame.Internal.Mutable: 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, () #)
+ Numeric.DataFrame.Internal.PrimArray: CumulDims :: [Word] -> CumulDims
+ Numeric.DataFrame.Internal.PrimArray: [unCumulDims] :: CumulDims -> [Word]
+ Numeric.DataFrame.Internal.PrimArray: arrayContent# :: PrimArray t a => a -> (# t | (# CumulDims, Int#, ByteArray# #) #)
+ Numeric.DataFrame.Internal.PrimArray: broadcast :: PrimArray t a => t -> a
+ Numeric.DataFrame.Internal.PrimArray: cdIx :: CumulDims -> Idxs ns -> Int
+ Numeric.DataFrame.Internal.PrimArray: cdTotalDim :: CumulDims -> Word
+ Numeric.DataFrame.Internal.PrimArray: cdTotalDim# :: CumulDims -> Int#
+ Numeric.DataFrame.Internal.PrimArray: class PrimBytes t => PrimArray t a | a -> t
+ Numeric.DataFrame.Internal.PrimArray: cumulDims :: Dims (ns :: [k]) -> CumulDims
+ Numeric.DataFrame.Internal.PrimArray: fromElems :: PrimArray t a => CumulDims -> Int# -> ByteArray# -> a
+ Numeric.DataFrame.Internal.PrimArray: fromSteps :: CumulDims -> SomeDims
+ Numeric.DataFrame.Internal.PrimArray: gen# :: PrimArray t a => CumulDims -> (s -> (# s, t #)) -> s -> (# s, a #)
+ Numeric.DataFrame.Internal.PrimArray: getSteps :: PrimArray t a => Dims (ns :: [k]) -> a -> CumulDims
+ Numeric.DataFrame.Internal.PrimArray: instance GHC.Base.Monoid Numeric.DataFrame.Internal.PrimArray.CumulDims
+ Numeric.DataFrame.Internal.PrimArray: instance GHC.Base.Semigroup Numeric.DataFrame.Internal.PrimArray.CumulDims
+ Numeric.DataFrame.Internal.PrimArray: ix# :: PrimArray t a => Int# -> a -> t
+ Numeric.DataFrame.Internal.PrimArray: ixOff :: PrimArray t a => Int -> a -> t
+ Numeric.DataFrame.Internal.PrimArray: newtype CumulDims
+ Numeric.DataFrame.Internal.PrimArray: offsetElems :: PrimArray t a => a -> Int#
+ Numeric.DataFrame.Internal.PrimArray: uniqueOrCumulDims :: PrimArray t a => a -> Either t CumulDims
+ Numeric.DataFrame.Internal.PrimArray: unsafeFromFlatList :: PrimArray t a => Dims ns -> t -> [t] -> a
+ Numeric.DataFrame.Internal.PrimArray: upd# :: PrimArray t a => CumulDims -> Int# -> t -> a -> a
+ Numeric.DataFrame.ST: 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 ()
+ Numeric.DataFrame.ST: 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 ()
+ Numeric.DataFrame.SubSpace: index :: SubSpace t as bs asbs => Idxs as -> DataFrame t asbs -> DataFrame t bs
+ Numeric.DataFrame.SubSpace: 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
+ Numeric.DataFrame.SubSpace: 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')
+ Numeric.DataFrame.SubSpace: updateOffset# :: SubSpace t as bs asbs => Int# -> DataFrame t bs -> DataFrame t asbs -> DataFrame t asbs
+ Numeric.DataFrame.SubSpace: 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
+ Numeric.DataFrame.Type: 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)
+ Numeric.DataFrame.Type: bFieldOffsetOf :: forall (name :: Symbol) (a :: Type) (b :: Type). (PrimBytes a, Elem name (PrimFields a), KnownSymbol name, Num b) => a -> b
+ Numeric.DataFrame.Type: class InferKnownBackend (t :: k) ds
+ Numeric.DataFrame.Type: class PrimBytes t => PrimArray t a | a -> t
+ Numeric.DataFrame.Type: class PrimTagged a => PrimBytes a
+ Numeric.DataFrame.Type: 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)
+ Numeric.DataFrame.Type: constrainDF :: forall (ds :: [XNat]) (ys :: [XNat]) (l :: Type) (ts :: l). (BoundedDims ds, All KnownXNatType ds) => DataFrame ts ys -> Maybe (DataFrame ts ds)
+ Numeric.DataFrame.Type: fromFlatList :: forall (t :: Type) (ds :: [Nat]). PrimArray t (DataFrame t ds) => Dims ds -> t -> [t] -> DataFrame t ds
+ Numeric.DataFrame.Type: fromList :: forall (t :: Type) (ds :: [Nat]). (PrimBytes t, Dimensions ds) => [DataFrame t ds] -> DataFrame t (XN 0 : AsXDims ds)
+ Numeric.DataFrame.Type: fromListWithDefault :: forall (t :: Type) (d :: Nat) (ds :: [Nat]). (PrimBytes t, Dimensions (d : ds)) => DataFrame t ds -> [DataFrame t ds] -> DataFrame t (d : ds)
+ Numeric.DataFrame.Type: inferKnownBackend :: InferKnownBackend t ds => Dict (KnownBackends t ds)
+ Numeric.DataFrame.Type: instance (Data.Data.Data t, Numeric.PrimBytes.PrimBytes t, Data.Typeable.Internal.Typeable ds) => Data.Data.Data (Numeric.DataFrame.Type.DataFrame t ds)
+ Numeric.DataFrame.Type: 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)
+ Numeric.DataFrame.Type: 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)
+ Numeric.DataFrame.Type: 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)
+ Numeric.DataFrame.Type: 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)
+ Numeric.DataFrame.Type: 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)
+ Numeric.DataFrame.Type: 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)
+ Numeric.DataFrame.Type: 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))
+ Numeric.DataFrame.Type: instance (GHC.Read.Read t, Numeric.PrimBytes.PrimBytes t) => GHC.Read.Read (Numeric.DataFrame.Type.SomeDataFrame t)
+ Numeric.DataFrame.Type: 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)
+ Numeric.DataFrame.Type: instance (GHC.Read.Read t, Numeric.PrimBytes.PrimBytes t, Numeric.Dimensions.Dim.Dimensions ds) => GHC.Read.Read (Numeric.DataFrame.Type.DataFrame t ds)
+ Numeric.DataFrame.Type: instance (GHC.Show.Show t, Numeric.PrimBytes.PrimBytes t) => GHC.Show.Show (Numeric.DataFrame.Type.DataFrame t xns)
+ Numeric.DataFrame.Type: instance (GHC.Show.Show t, Numeric.PrimBytes.PrimBytes t) => GHC.Show.Show (Numeric.DataFrame.Type.SomeDataFrame t)
+ Numeric.DataFrame.Type: instance (GHC.Show.Show t, Numeric.PrimBytes.PrimBytes t, Numeric.Dimensions.Dim.Dimensions ds) => GHC.Show.Show (Numeric.DataFrame.Type.DataFrame t ds)
+ Numeric.DataFrame.Type: 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)
+ Numeric.DataFrame.Type: 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)
+ Numeric.DataFrame.Type: instance (Numeric.PrimBytes.PrimBytes t, Numeric.Dimensions.Dim.Dimensions ds) => GHC.Generics.Generic (Numeric.DataFrame.Type.DataFrame t ds)
+ Numeric.DataFrame.Type: instance (Numeric.PrimBytes.PrimBytes t, Numeric.Dimensions.Dim.Dimensions ds) => Numeric.DataFrame.Type.InferKnownBackend t ds
+ Numeric.DataFrame.Type: instance (Numeric.TypedList.RepresentableList ts, Data.Type.List.All Numeric.PrimBytes.PrimBytes ts, Numeric.Dimensions.Dim.Dimensions ds) => Numeric.DataFrame.Type.InferKnownBackend ts ds
+ Numeric.DataFrame.Type: instance Data.Type.List.All GHC.Classes.Eq ts => GHC.Classes.Eq (Numeric.DataFrame.Type.DataFrame ts ds)
+ Numeric.DataFrame.Type: instance Data.Type.List.All GHC.Classes.Eq ts => GHC.Classes.Eq (Numeric.DataFrame.Type.SomeDataFrame ts)
+ Numeric.DataFrame.Type: instance GHC.Classes.Eq (Numeric.DataFrame.Internal.Backend.DFBackend t ds) => GHC.Classes.Eq (Numeric.DataFrame.Type.DataFrame t ds)
+ Numeric.DataFrame.Type: instance GHC.Classes.Eq t => GHC.Classes.Eq (Numeric.DataFrame.Type.DataFrame t ds)
+ Numeric.DataFrame.Type: instance GHC.Classes.Eq t => GHC.Classes.Eq (Numeric.DataFrame.Type.SomeDataFrame t)
+ Numeric.DataFrame.Type: instance GHC.Classes.Ord (Numeric.DataFrame.Internal.Backend.DFBackend t ds) => GHC.Classes.Ord (Numeric.DataFrame.Type.DataFrame t ds)
+ Numeric.DataFrame.Type: 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))
+ Numeric.DataFrame.Type: instance GHC.Enum.Bounded (Numeric.DataFrame.Internal.Backend.DFBackend t ds) => GHC.Enum.Bounded (Numeric.DataFrame.Type.DataFrame t ds)
+ Numeric.DataFrame.Type: instance GHC.Enum.Enum (Numeric.DataFrame.Internal.Backend.DFBackend t ds) => GHC.Enum.Enum (Numeric.DataFrame.Type.DataFrame t ds)
+ Numeric.DataFrame.Type: instance GHC.Float.Floating (Numeric.DataFrame.Internal.Backend.DFBackend t ds) => GHC.Float.Floating (Numeric.DataFrame.Type.DataFrame t ds)
+ Numeric.DataFrame.Type: instance GHC.Float.RealFloat (Numeric.DataFrame.Internal.Backend.DFBackend t ds) => GHC.Float.RealFloat (Numeric.DataFrame.Type.DataFrame t ds)
+ Numeric.DataFrame.Type: instance GHC.Generics.Generic (Numeric.DataFrame.Type.DataFrame ts ds)
+ Numeric.DataFrame.Type: instance GHC.Num.Num (Numeric.DataFrame.Internal.Backend.DFBackend t ds) => GHC.Num.Num (Numeric.DataFrame.Type.DataFrame t ds)
+ Numeric.DataFrame.Type: instance GHC.Real.Fractional (Numeric.DataFrame.Internal.Backend.DFBackend t ds) => GHC.Real.Fractional (Numeric.DataFrame.Type.DataFrame t ds)
+ Numeric.DataFrame.Type: instance GHC.Real.Integral (Numeric.DataFrame.Internal.Backend.DFBackend t ds) => GHC.Real.Integral (Numeric.DataFrame.Type.DataFrame t ds)
+ Numeric.DataFrame.Type: instance GHC.Real.Real (Numeric.DataFrame.Internal.Backend.DFBackend t ds) => GHC.Real.Real (Numeric.DataFrame.Type.DataFrame t ds)
+ Numeric.DataFrame.Type: instance GHC.Real.RealFrac (Numeric.DataFrame.Internal.Backend.DFBackend t ds) => GHC.Real.RealFrac (Numeric.DataFrame.Type.DataFrame t ds)
+ Numeric.DataFrame.Type: instance Numeric.DataFrame.Type.AllFrames GHC.Classes.Eq ts ds => GHC.Classes.Eq (Numeric.DataFrame.Type.DataFrame ts ds)
+ Numeric.DataFrame.Type: instance Numeric.PrimBytes.PrimBytes (Numeric.DataFrame.Internal.Backend.DFBackend t ds) => Numeric.PrimBytes.PrimBytes (Numeric.DataFrame.Type.DataFrame t ds)
+ Numeric.DataFrame.Type: instance Numeric.ProductOrd.ProductOrder (Numeric.DataFrame.Internal.Backend.DFBackend t ds) => Numeric.ProductOrd.ProductOrder (Numeric.DataFrame.Type.DataFrame t ds)
+ Numeric.DataFrame.Type: 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)
+ Numeric.DataFrame.Type: 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)
+ Numeric.DataFrame.Type: packDF :: forall (t :: Type) (d :: Nat) (ds :: [Nat]). (PrimBytes t, Dimensions (d : ds)) => PackDF t ds d (DataFrame t (d : ds))
+ Numeric.DataFrame.Type: pattern S :: forall (t :: Type). t -> DataFrame t ('[] :: [Nat])
+ Numeric.DataFrame.Type: 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)
+ Numeric.DataFrame.Type: type DFBackend t (ds :: [Nat]) = Backend I t ds BackendFamily t ds
+ Numeric.DataFrame.Type: type KnownBackend t (ds :: [Nat]) = KnownBackend t ds BackendFamily t ds
+ Numeric.DataFrame.Type: type N (n :: Nat) = N n
+ Numeric.DataFrame.Type: type XN (n :: Nat) = XN n
+ Numeric.DataFrame.Type: 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
+ Numeric.PrimBytes: --
+ Numeric.PrimBytes: -- </ol>
+ Numeric.PrimBytes: -- <li>The data uses record syntax to define its fields.</li>
+ Numeric.PrimBytes: -- <ol>
+ Numeric.PrimBytes: -- A Generic-derived instance has this list non-empty only if two obvious
+ Numeric.PrimBytes: -- It is used to get field offsets using <a>byteFieldOffset</a> function.
+ Numeric.PrimBytes: -- conditions are met:
+ Numeric.PrimBytes: -- | List of field names.
+ Numeric.PrimBytes: [PTagChar] :: PrimTag Char
+ Numeric.PrimBytes: bAlignOf :: (PrimBytes a, Num b) => a -> b
+ Numeric.PrimBytes: bFieldOffsetOf :: forall (name :: Symbol) (a :: Type) (b :: Type). (PrimBytes a, Elem name (PrimFields a), KnownSymbol name, Num b) => a -> b
+ Numeric.PrimBytes: bPeek :: forall (a :: Type). PrimBytes a => Ptr a -> IO a
+ Numeric.PrimBytes: bPeekByteOff :: forall (a :: Type) (b :: Type). PrimBytes a => Ptr b -> Int -> IO a
+ Numeric.PrimBytes: bPeekElemOff :: forall (a :: Type). PrimBytes a => Ptr a -> Int -> IO a
+ Numeric.PrimBytes: bPoke :: forall (a :: Type). PrimBytes a => Ptr a -> a -> IO ()
+ Numeric.PrimBytes: bPokeByteOff :: forall (a :: Type) (b :: Type). PrimBytes a => Ptr b -> Int -> a -> IO ()
+ Numeric.PrimBytes: bPokeElemOff :: forall (a :: Type). PrimBytes a => Ptr a -> Int -> a -> IO ()
+ Numeric.PrimBytes: bSizeOf :: (PrimBytes a, Num b) => a -> b
+ Numeric.PrimBytes: byteFieldOffset :: (PrimBytes a, Generic a, GPrimBytes (Rep a), KnownSymbol name) => Proxy# name -> a -> Int#
+ Numeric.PrimBytes: getBytesPinned :: PrimBytes a => a -> ByteArray#
+ Numeric.PrimBytes: instance (Numeric.PrimBytes.PrimBytes a, Numeric.PrimBytes.PrimBytes b) => Numeric.PrimBytes.PrimBytes (a, b)
+ Numeric.PrimBytes: instance (Numeric.PrimBytes.PrimBytes a, Numeric.PrimBytes.PrimBytes b, Numeric.PrimBytes.PrimBytes c) => Numeric.PrimBytes.PrimBytes (a, b, c)
+ Numeric.PrimBytes: instance (Numeric.PrimBytes.PrimBytes a, Numeric.PrimBytes.PrimBytes b, Numeric.PrimBytes.PrimBytes c, Numeric.PrimBytes.PrimBytes d) => Numeric.PrimBytes.PrimBytes (a, b, c, d)
+ Numeric.PrimBytes: 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)
+ Numeric.PrimBytes: 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)
+ Numeric.PrimBytes: 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)
+ Numeric.PrimBytes: instance (Numeric.TypedList.RepresentableList xs, Data.Type.List.All Numeric.PrimBytes.PrimBytes xs) => Numeric.PrimBytes.PrimBytes (Numeric.Tuple.Lazy.Tuple xs)
+ Numeric.PrimBytes: instance (Numeric.TypedList.RepresentableList xs, Data.Type.List.All Numeric.PrimBytes.PrimBytes xs) => Numeric.PrimBytes.PrimBytes (Numeric.Tuple.Strict.Tuple xs)
+ Numeric.PrimBytes: instance GHC.Show.Show (Numeric.PrimBytes.PrimTag a)
+ Numeric.PrimBytes: instance Numeric.PrimBytes.PrimBytes ()
+ Numeric.PrimBytes: instance Numeric.PrimBytes.PrimBytes GHC.Types.Char
+ Numeric.PrimBytes: instance Numeric.PrimBytes.PrimTagged GHC.Types.Char
+ Numeric.PrimBytes: instance forall k (f :: k -> *) (g :: k -> *). (Numeric.PrimBytes.GPrimBytes f, Numeric.PrimBytes.GPrimBytes g) => Numeric.PrimBytes.GPrimBytes (f GHC.Generics.:*: g)
+ Numeric.PrimBytes: instance forall k (f :: k -> *) (g :: k -> *). (Numeric.PrimBytes.GPrimBytes f, Numeric.PrimBytes.GPrimBytes g) => Numeric.PrimBytes.GPrimBytes (f GHC.Generics.:+: g)
+ Numeric.PrimBytes: 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)
+ Numeric.PrimBytes: instance forall k (f :: k -> *) i (c :: GHC.Generics.Meta). Numeric.PrimBytes.GPrimBytes f => Numeric.PrimBytes.GPrimBytes (GHC.Generics.M1 i c f)
+ Numeric.PrimBytes: instance forall k (x :: k). Numeric.PrimBytes.PrimBytes (Numeric.Dimensions.Idx.Idx x)
+ Numeric.PrimBytes: instance forall k (xs :: [k]). Numeric.TypedList.RepresentableList xs => Numeric.PrimBytes.PrimBytes (Numeric.Dimensions.Idx.Idxs xs)
+ Numeric.PrimBytes: type PrimFields a = GPrimFields (Rep a);
+ Numeric.PrimBytes: type family PrimFields a :: [Symbol];
+ Numeric.PrimBytes: }
+ Numeric.ProductOrd: Incomparable :: PartialOrdering
+ Numeric.ProductOrd: PEQ :: PartialOrdering
+ Numeric.ProductOrd: PGT :: PartialOrdering
+ Numeric.ProductOrd: PLT :: PartialOrdering
+ Numeric.ProductOrd: class ProductOrder a
+ Numeric.ProductOrd: cmp :: ProductOrder a => a -> a -> PartialOrdering
+ Numeric.ProductOrd: data PartialOrdering
+ Numeric.ProductOrd: fromOrdering :: Ordering -> PartialOrdering
+ Numeric.ProductOrd: instance (GHC.Classes.Ord a1, GHC.Classes.Ord a2) => Numeric.ProductOrd.ProductOrder (a1, a2)
+ Numeric.ProductOrd: instance (GHC.Classes.Ord a1, GHC.Classes.Ord a2, GHC.Classes.Ord a3) => Numeric.ProductOrd.ProductOrder (a1, a2, a3)
+ Numeric.ProductOrd: instance (GHC.Classes.Ord a1, GHC.Classes.Ord a2, GHC.Classes.Ord a3, GHC.Classes.Ord a4) => Numeric.ProductOrd.ProductOrder (a1, a2, a3, a4)
+ Numeric.ProductOrd: 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)
+ Numeric.ProductOrd: 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)
+ Numeric.ProductOrd: 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)
+ Numeric.ProductOrd: 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)
+ Numeric.ProductOrd: 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)
+ Numeric.ProductOrd: instance Data.Data.Data Numeric.ProductOrd.PartialOrdering
+ Numeric.ProductOrd: instance GHC.Base.Monoid Numeric.ProductOrd.PartialOrdering
+ Numeric.ProductOrd: instance GHC.Base.Semigroup Numeric.ProductOrd.PartialOrdering
+ Numeric.ProductOrd: instance GHC.Classes.Eq Numeric.ProductOrd.PartialOrdering
+ Numeric.ProductOrd: instance GHC.Classes.Ord Numeric.ProductOrd.PartialOrdering
+ Numeric.ProductOrd: instance GHC.Enum.Bounded Numeric.ProductOrd.PartialOrdering
+ Numeric.ProductOrd: instance GHC.Enum.Enum Numeric.ProductOrd.PartialOrdering
+ Numeric.ProductOrd: instance GHC.Generics.Generic Numeric.ProductOrd.PartialOrdering
+ Numeric.ProductOrd: instance GHC.Read.Read Numeric.ProductOrd.PartialOrdering
+ Numeric.ProductOrd: instance GHC.Show.Show Numeric.ProductOrd.PartialOrdering
+ Numeric.ProductOrd: 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)
+ Numeric.ProductOrd.NonTransitive: ProductOrd :: a -> ProductOrd a
+ Numeric.ProductOrd.NonTransitive: [getProductOrd] :: ProductOrd a -> a
+ Numeric.ProductOrd.NonTransitive: instance (GHC.Classes.Ord (Numeric.ProductOrd.NonTransitive.ProductOrd a), Data.Bits.Bits a) => Data.Bits.Bits (Numeric.ProductOrd.NonTransitive.ProductOrd a)
+ Numeric.ProductOrd.NonTransitive: instance (GHC.Classes.Ord (Numeric.ProductOrd.NonTransitive.ProductOrd a), Data.Bits.FiniteBits a) => Data.Bits.FiniteBits (Numeric.ProductOrd.NonTransitive.ProductOrd a)
+ Numeric.ProductOrd.NonTransitive: instance (GHC.Classes.Ord (Numeric.ProductOrd.NonTransitive.ProductOrd a), GHC.Float.RealFloat a) => GHC.Float.RealFloat (Numeric.ProductOrd.NonTransitive.ProductOrd a)
+ Numeric.ProductOrd.NonTransitive: instance (GHC.Classes.Ord (Numeric.ProductOrd.NonTransitive.ProductOrd a), GHC.Real.Integral a) => GHC.Real.Integral (Numeric.ProductOrd.NonTransitive.ProductOrd a)
+ Numeric.ProductOrd.NonTransitive: instance (GHC.Classes.Ord (Numeric.ProductOrd.NonTransitive.ProductOrd a), GHC.Real.Real a) => GHC.Real.Real (Numeric.ProductOrd.NonTransitive.ProductOrd a)
+ Numeric.ProductOrd.NonTransitive: instance (GHC.Classes.Ord (Numeric.ProductOrd.NonTransitive.ProductOrd a), GHC.Real.RealFrac a) => GHC.Real.RealFrac (Numeric.ProductOrd.NonTransitive.ProductOrd a)
+ Numeric.ProductOrd.NonTransitive: instance (GHC.Classes.Ord a1, GHC.Classes.Ord a2) => GHC.Classes.Ord (Numeric.ProductOrd.NonTransitive.ProductOrd (a1, a2))
+ Numeric.ProductOrd.NonTransitive: instance (GHC.Classes.Ord a1, GHC.Classes.Ord a2, GHC.Classes.Ord a3) => GHC.Classes.Ord (Numeric.ProductOrd.NonTransitive.ProductOrd (a1, a2, a3))
+ Numeric.ProductOrd.NonTransitive: 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))
+ Numeric.ProductOrd.NonTransitive: 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))
+ Numeric.ProductOrd.NonTransitive: 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))
+ Numeric.ProductOrd.NonTransitive: 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))
+ Numeric.ProductOrd.NonTransitive: 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))
+ Numeric.ProductOrd.NonTransitive: 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))
+ Numeric.ProductOrd.NonTransitive: instance Control.Monad.Fix.MonadFix Numeric.ProductOrd.NonTransitive.ProductOrd
+ Numeric.ProductOrd.NonTransitive: instance Control.Monad.Zip.MonadZip Numeric.ProductOrd.NonTransitive.ProductOrd
+ Numeric.ProductOrd.NonTransitive: instance Data.Data.Data a => Data.Data.Data (Numeric.ProductOrd.NonTransitive.ProductOrd a)
+ Numeric.ProductOrd.NonTransitive: instance Data.Foldable.Foldable Numeric.ProductOrd.NonTransitive.ProductOrd
+ Numeric.ProductOrd.NonTransitive: instance Data.Traversable.Traversable Numeric.ProductOrd.NonTransitive.ProductOrd
+ Numeric.ProductOrd.NonTransitive: instance Foreign.Storable.Storable a => Foreign.Storable.Storable (Numeric.ProductOrd.NonTransitive.ProductOrd a)
+ Numeric.ProductOrd.NonTransitive: instance GHC.Base.Applicative Numeric.ProductOrd.NonTransitive.ProductOrd
+ Numeric.ProductOrd.NonTransitive: instance GHC.Base.Functor Numeric.ProductOrd.NonTransitive.ProductOrd
+ Numeric.ProductOrd.NonTransitive: instance GHC.Base.Monad Numeric.ProductOrd.NonTransitive.ProductOrd
+ Numeric.ProductOrd.NonTransitive: instance GHC.Base.Monoid a => GHC.Base.Monoid (Numeric.ProductOrd.NonTransitive.ProductOrd a)
+ Numeric.ProductOrd.NonTransitive: instance GHC.Base.Semigroup a => GHC.Base.Semigroup (Numeric.ProductOrd.NonTransitive.ProductOrd a)
+ Numeric.ProductOrd.NonTransitive: instance GHC.Classes.Ord (Numeric.ProductOrd.NonTransitive.ProductOrd a) => GHC.Classes.Eq (Numeric.ProductOrd.NonTransitive.ProductOrd a)
+ Numeric.ProductOrd.NonTransitive: instance GHC.Enum.Bounded a => GHC.Enum.Bounded (Numeric.ProductOrd.NonTransitive.ProductOrd a)
+ Numeric.ProductOrd.NonTransitive: instance GHC.Enum.Enum a => GHC.Enum.Enum (Numeric.ProductOrd.NonTransitive.ProductOrd a)
+ Numeric.ProductOrd.NonTransitive: instance GHC.Float.Floating a => GHC.Float.Floating (Numeric.ProductOrd.NonTransitive.ProductOrd a)
+ Numeric.ProductOrd.NonTransitive: instance GHC.Generics.Generic (Numeric.ProductOrd.NonTransitive.ProductOrd a)
+ Numeric.ProductOrd.NonTransitive: instance GHC.Generics.Generic1 Numeric.ProductOrd.NonTransitive.ProductOrd
+ Numeric.ProductOrd.NonTransitive: instance GHC.Num.Num a => GHC.Num.Num (Numeric.ProductOrd.NonTransitive.ProductOrd a)
+ Numeric.ProductOrd.NonTransitive: instance GHC.Read.Read a => GHC.Read.Read (Numeric.ProductOrd.NonTransitive.ProductOrd a)
+ Numeric.ProductOrd.NonTransitive: instance GHC.Real.Fractional a => GHC.Real.Fractional (Numeric.ProductOrd.NonTransitive.ProductOrd a)
+ Numeric.ProductOrd.NonTransitive: instance GHC.Show.Show a => GHC.Show.Show (Numeric.ProductOrd.NonTransitive.ProductOrd a)
+ Numeric.ProductOrd.NonTransitive: 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))
+ Numeric.ProductOrd.NonTransitive: newtype ProductOrd a
+ Numeric.ProductOrd.NonTransitive: toOrdering :: PartialOrdering -> Ordering
+ Numeric.ProductOrd.Partial: ProductOrd :: a -> ProductOrd a
+ Numeric.ProductOrd.Partial: [getProductOrd] :: ProductOrd a -> a
+ Numeric.ProductOrd.Partial: instance (GHC.Classes.Ord (Numeric.ProductOrd.Partial.ProductOrd a), GHC.Float.RealFloat a) => GHC.Float.RealFloat (Numeric.ProductOrd.Partial.ProductOrd a)
+ Numeric.ProductOrd.Partial: instance (GHC.Classes.Ord (Numeric.ProductOrd.Partial.ProductOrd a), GHC.Real.Integral a) => GHC.Real.Integral (Numeric.ProductOrd.Partial.ProductOrd a)
+ Numeric.ProductOrd.Partial: instance (GHC.Classes.Ord (Numeric.ProductOrd.Partial.ProductOrd a), GHC.Real.Real a) => GHC.Real.Real (Numeric.ProductOrd.Partial.ProductOrd a)
+ Numeric.ProductOrd.Partial: instance (GHC.Classes.Ord (Numeric.ProductOrd.Partial.ProductOrd a), GHC.Real.RealFrac a) => GHC.Real.RealFrac (Numeric.ProductOrd.Partial.ProductOrd a)
+ Numeric.ProductOrd.Partial: instance (GHC.Classes.Ord a1, GHC.Classes.Ord a2) => GHC.Classes.Ord (Numeric.ProductOrd.Partial.ProductOrd (a1, a2))
+ Numeric.ProductOrd.Partial: instance (GHC.Classes.Ord a1, GHC.Classes.Ord a2, GHC.Classes.Ord a3) => GHC.Classes.Ord (Numeric.ProductOrd.Partial.ProductOrd (a1, a2, a3))
+ Numeric.ProductOrd.Partial: 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))
+ Numeric.ProductOrd.Partial: 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))
+ Numeric.ProductOrd.Partial: 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))
+ Numeric.ProductOrd.Partial: 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))
+ Numeric.ProductOrd.Partial: 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))
+ Numeric.ProductOrd.Partial: 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))
+ Numeric.ProductOrd.Partial: instance Control.Monad.Fix.MonadFix Numeric.ProductOrd.Partial.ProductOrd
+ Numeric.ProductOrd.Partial: instance Control.Monad.Zip.MonadZip Numeric.ProductOrd.Partial.ProductOrd
+ Numeric.ProductOrd.Partial: instance Data.Bits.Bits a => Data.Bits.Bits (Numeric.ProductOrd.Partial.ProductOrd a)
+ Numeric.ProductOrd.Partial: instance Data.Bits.FiniteBits a => Data.Bits.FiniteBits (Numeric.ProductOrd.Partial.ProductOrd a)
+ Numeric.ProductOrd.Partial: instance Data.Data.Data a => Data.Data.Data (Numeric.ProductOrd.Partial.ProductOrd a)
+ Numeric.ProductOrd.Partial: instance Data.Foldable.Foldable Numeric.ProductOrd.Partial.ProductOrd
+ Numeric.ProductOrd.Partial: instance Data.Traversable.Traversable Numeric.ProductOrd.Partial.ProductOrd
+ Numeric.ProductOrd.Partial: instance Foreign.Storable.Storable a => Foreign.Storable.Storable (Numeric.ProductOrd.Partial.ProductOrd a)
+ Numeric.ProductOrd.Partial: instance GHC.Base.Applicative Numeric.ProductOrd.Partial.ProductOrd
+ Numeric.ProductOrd.Partial: instance GHC.Base.Functor Numeric.ProductOrd.Partial.ProductOrd
+ Numeric.ProductOrd.Partial: instance GHC.Base.Monad Numeric.ProductOrd.Partial.ProductOrd
+ Numeric.ProductOrd.Partial: instance GHC.Base.Monoid a => GHC.Base.Monoid (Numeric.ProductOrd.Partial.ProductOrd a)
+ Numeric.ProductOrd.Partial: instance GHC.Base.Semigroup a => GHC.Base.Semigroup (Numeric.ProductOrd.Partial.ProductOrd a)
+ Numeric.ProductOrd.Partial: instance GHC.Classes.Eq a => GHC.Classes.Eq (Numeric.ProductOrd.Partial.ProductOrd a)
+ Numeric.ProductOrd.Partial: instance GHC.Enum.Bounded a => GHC.Enum.Bounded (Numeric.ProductOrd.Partial.ProductOrd a)
+ Numeric.ProductOrd.Partial: instance GHC.Enum.Enum a => GHC.Enum.Enum (Numeric.ProductOrd.Partial.ProductOrd a)
+ Numeric.ProductOrd.Partial: instance GHC.Float.Floating a => GHC.Float.Floating (Numeric.ProductOrd.Partial.ProductOrd a)
+ Numeric.ProductOrd.Partial: instance GHC.Generics.Generic (Numeric.ProductOrd.Partial.ProductOrd a)
+ Numeric.ProductOrd.Partial: instance GHC.Generics.Generic1 Numeric.ProductOrd.Partial.ProductOrd
+ Numeric.ProductOrd.Partial: instance GHC.Num.Num a => GHC.Num.Num (Numeric.ProductOrd.Partial.ProductOrd a)
+ Numeric.ProductOrd.Partial: instance GHC.Read.Read a => GHC.Read.Read (Numeric.ProductOrd.Partial.ProductOrd a)
+ Numeric.ProductOrd.Partial: instance GHC.Real.Fractional a => GHC.Real.Fractional (Numeric.ProductOrd.Partial.ProductOrd a)
+ Numeric.ProductOrd.Partial: instance GHC.Show.Show a => GHC.Show.Show (Numeric.ProductOrd.Partial.ProductOrd a)
+ Numeric.ProductOrd.Partial: 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))
+ Numeric.ProductOrd.Partial: 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))
+ Numeric.ProductOrd.Partial: newtype ProductOrd a
+ Numeric.ProductOrd.Partial: toOrdering :: PartialOrdering -> Ordering
+ Numeric.Quaternion: -- <tt>(x,y,z,w)</tt>, where <tt>w</tt> is the argument, and <tt>x y
+ Numeric.Quaternion: -- z</tt> are the components of a 3D vector
+ Numeric.Quaternion: unpackQ# :: Quaternion t => Quater t -> (# t, t, t, t #)
+ Numeric.Vector: class Vector2 t
+ Numeric.Vector: class Vector3 t
+ Numeric.Vector: class Vector4 t
+ Numeric.Vector: data family DataFrame (t :: l) (xs :: [k])
+ Numeric.Vector: pattern Vec4 :: Vector4 t => t -> t -> t -> t -> Vector t 4
+ Numeric.Vector: unpackV2# :: Vector2 t => Vector t 2 -> (# t, t #)
+ Numeric.Vector: unpackV3# :: Vector3 t => Vector t 3 -> (# t, t, t #)
+ Numeric.Vector: unpackV4# :: Vector4 t => Vector t 4 -> (# t, t, t, t #)
- Numeric.DataFrame.Contraction: (%*) :: (ConcatList as bs (as ++ bs), Contraction t as bs asbs, KnownDim m, PrimArray t (DataFrame t (as +: m)), PrimArray t (DataFrame t (m :+ bs)), PrimArray t (DataFrame t (as ++ bs))) => DataFrame t (as +: m) -> DataFrame t (m :+ bs) -> DataFrame t (as ++ bs)
+ Numeric.DataFrame.Contraction: (%*) :: (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
- Numeric.DataFrame.IO: copyDataFrame :: forall (t :: Type) (as :: [Nat]) (b' :: Nat) (b :: Nat) (bs :: [Nat]) (asbs :: [Nat]). (PrimBytes t, PrimBytes (DataFrame t (as +: b')), ConcatList as (b :+ bs) asbs, Dimensions (b :+ bs)) => DataFrame t (as +: b') -> Idxs (b :+ bs) -> IODataFrame t asbs -> IO ()
+ Numeric.DataFrame.IO: 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 ()
- Numeric.DataFrame.IO: copyMutableDataFrame :: forall (t :: Type) (as :: [Nat]) (b' :: Nat) (b :: Nat) (bs :: [Nat]) (asbs :: [Nat]). (PrimBytes t, ConcatList as (b :+ bs) asbs, Dimensions (b :+ bs)) => IODataFrame t (as +: b') -> Idxs (b :+ bs) -> IODataFrame t asbs -> IO ()
+ Numeric.DataFrame.IO: 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 ()
- Numeric.DataFrame.IO: isDataFramePinned :: forall (t :: Type) (ns :: [k]). KnownDimKind k => IODataFrame t ns -> Bool
+ Numeric.DataFrame.IO: isDataFramePinned :: forall (k :: Type) (t :: Type) (ns :: [k]). KnownDimKind k => IODataFrame t ns -> Bool
- Numeric.DataFrame.IO: readDataFrame :: forall (t :: Type) (ns :: [Nat]). (PrimBytes t, Dimensions ns) => IODataFrame t ns -> Idxs ns -> IO (DataFrame t ('[] :: [Nat]))
+ Numeric.DataFrame.IO: readDataFrame :: forall (t :: Type) (ns :: [Nat]). PrimBytes t => IODataFrame t ns -> Idxs ns -> IO (DataFrame t ('[] :: [Nat]))
- Numeric.DataFrame.IO: thawDataFrame :: forall (t :: Type) (ns :: [Nat]). (PrimBytes (DataFrame t ns), PrimBytes t) => DataFrame t ns -> IO (IODataFrame t ns)
+ Numeric.DataFrame.IO: thawDataFrame :: forall (t :: Type) (ns :: [Nat]). (Dimensions ns, PrimBytes (DataFrame t ns)) => DataFrame t ns -> IO (IODataFrame t ns)
- Numeric.DataFrame.IO: thawPinDataFrame :: forall (t :: Type) (ns :: [Nat]). (PrimBytes (DataFrame t ns), PrimBytes t) => DataFrame t ns -> IO (IODataFrame t ns)
+ Numeric.DataFrame.IO: thawPinDataFrame :: forall (t :: Type) (ns :: [Nat]). (Dimensions ns, PrimBytes (DataFrame t ns)) => DataFrame t ns -> IO (IODataFrame t ns)
- Numeric.DataFrame.IO: unsafeThawDataFrame :: forall (t :: Type) (ns :: [Nat]). (PrimBytes (DataFrame t ns), PrimBytes t) => DataFrame t ns -> IO (IODataFrame t ns)
+ Numeric.DataFrame.IO: unsafeThawDataFrame :: forall (t :: Type) (ns :: [Nat]). (Dimensions ns, PrimBytes (DataFrame t ns), PrimBytes t) => DataFrame t ns -> IO (IODataFrame t ns)
- Numeric.DataFrame.IO: withDataFramePtr :: forall (t :: Type) (ns :: [k]) (r :: Type). (PrimBytes t, KnownDimKind k) => IODataFrame t ns -> (Ptr t -> IO r) -> IO r
+ Numeric.DataFrame.IO: withDataFramePtr :: forall (k :: Type) (t :: Type) (ns :: [k]) (r :: Type). (PrimBytes t, KnownDimKind k) => IODataFrame t ns -> (Ptr t -> IO r) -> IO r
- Numeric.DataFrame.IO: writeDataFrame :: forall t (ns :: [Nat]). (PrimBytes t, Dimensions ns) => IODataFrame t ns -> Idxs ns -> DataFrame t ('[] :: [Nat]) -> IO ()
+ Numeric.DataFrame.IO: writeDataFrame :: forall t (ns :: [Nat]). PrimBytes t => IODataFrame t ns -> Idxs ns -> DataFrame t ('[] :: [Nat]) -> IO ()
- Numeric.DataFrame.Internal.Mutable: copyDataFrame# :: forall (t :: Type) (as :: [Nat]) (b' :: Nat) (b :: Nat) (bs :: [Nat]) (asbs :: [Nat]) s. (PrimBytes t, PrimBytes (DataFrame t (as +: b')), ConcatList as (b :+ bs) asbs, Dimensions (b :+ bs)) => DataFrame t (as +: b') -> Idxs (b :+ bs) -> MDataFrame s t asbs -> State# s -> (# State# s, () #)
+ Numeric.DataFrame.Internal.Mutable: 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, () #)
- Numeric.DataFrame.Internal.Mutable: copyMDataFrame# :: forall (t :: Type) (as :: [Nat]) (b' :: Nat) (b :: Nat) (bs :: [Nat]) (asbs :: [Nat]) s. (PrimBytes t, ConcatList as (b :+ bs) asbs, Dimensions (b :+ bs)) => MDataFrame s t (as +: b') -> Idxs (b :+ bs) -> MDataFrame s t asbs -> State# s -> (# State# s, () #)
+ Numeric.DataFrame.Internal.Mutable: 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, () #)
- Numeric.DataFrame.Internal.Mutable: readDataFrame# :: forall (t :: Type) (ns :: [Nat]) s. (PrimBytes t, Dimensions ns) => MDataFrame s t ns -> Idxs ns -> State# s -> (# State# s, t #)
+ Numeric.DataFrame.Internal.Mutable: readDataFrame# :: forall (t :: Type) (ns :: [Nat]) s. PrimBytes t => MDataFrame s t ns -> Idxs ns -> State# s -> (# State# s, t #)
- Numeric.DataFrame.Internal.Mutable: thawDataFrame# :: forall (t :: Type) (ns :: [Nat]) s. (PrimBytes (DataFrame t ns), PrimBytes t) => DataFrame t ns -> State# s -> (# State# s, MDataFrame s t ns #)
+ Numeric.DataFrame.Internal.Mutable: thawDataFrame# :: forall (t :: Type) (ns :: [Nat]) s. (Dimensions ns, PrimBytes (DataFrame t ns)) => DataFrame t ns -> State# s -> (# State# s, MDataFrame s t ns #)
- Numeric.DataFrame.Internal.Mutable: thawPinDataFrame# :: forall (t :: Type) (ns :: [Nat]) s. (PrimBytes (DataFrame t ns), PrimBytes t) => DataFrame t ns -> State# s -> (# State# s, MDataFrame s t ns #)
+ Numeric.DataFrame.Internal.Mutable: thawPinDataFrame# :: forall (t :: Type) (ns :: [Nat]) s. (Dimensions ns, PrimBytes (DataFrame t ns)) => DataFrame t ns -> State# s -> (# State# s, MDataFrame s t ns #)
- Numeric.DataFrame.Internal.Mutable: unsafeThawDataFrame# :: forall (t :: Type) (ns :: [Nat]) s. (PrimBytes (DataFrame t ns), PrimBytes t) => DataFrame t ns -> State# s -> (# State# s, MDataFrame s t ns #)
+ Numeric.DataFrame.Internal.Mutable: 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 #)
- Numeric.DataFrame.Internal.Mutable: writeDataFrame# :: forall (t :: Type) (ns :: [Nat]) s. (PrimBytes t, Dimensions ns) => MDataFrame s t ns -> Idxs ns -> t -> State# s -> (# State# s, () #)
+ Numeric.DataFrame.Internal.Mutable: writeDataFrame# :: forall (t :: Type) (ns :: [Nat]) s. PrimBytes t => MDataFrame s t ns -> Idxs ns -> t -> State# s -> (# State# s, () #)
- Numeric.DataFrame.ST: copyDataFrame :: forall (t :: Type) (as :: [Nat]) (b' :: Nat) (b :: Nat) (bs :: [Nat]) (asbs :: [Nat]) s. (PrimBytes t, PrimBytes (DataFrame t (as +: b')), ConcatList as (b :+ bs) asbs, Dimensions (b :+ bs)) => DataFrame t (as +: b') -> Idxs (b :+ bs) -> STDataFrame s t asbs -> ST s ()
+ Numeric.DataFrame.ST: 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 ()
- Numeric.DataFrame.ST: copyMutableDataFrame :: forall (t :: Type) (as :: [Nat]) (b' :: Nat) (b :: Nat) (bs :: [Nat]) (asbs :: [Nat]) s. (PrimBytes t, ConcatList as (b :+ bs) asbs, Dimensions (b :+ bs)) => STDataFrame s t (as +: b') -> Idxs (b :+ bs) -> STDataFrame s t asbs -> ST s ()
+ Numeric.DataFrame.ST: 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 ()
- Numeric.DataFrame.ST: isDataFramePinned :: forall (t :: Type) (ns :: [k]) s. KnownDimKind k => STDataFrame s t ns -> Bool
+ Numeric.DataFrame.ST: isDataFramePinned :: forall (k :: Type) (t :: Type) (ns :: [k]) s. KnownDimKind k => STDataFrame s t ns -> Bool
- Numeric.DataFrame.ST: readDataFrame :: forall (t :: Type) (ns :: [Nat]) s. (PrimBytes t, Dimensions ns) => STDataFrame s t ns -> Idxs ns -> ST s (DataFrame t ('[] :: [Nat]))
+ Numeric.DataFrame.ST: readDataFrame :: forall (t :: Type) (ns :: [Nat]) s. PrimBytes t => STDataFrame s t ns -> Idxs ns -> ST s (DataFrame t ('[] :: [Nat]))
- Numeric.DataFrame.ST: thawDataFrame :: forall (t :: Type) (ns :: [Nat]) s. (PrimBytes (DataFrame t ns), PrimBytes t) => DataFrame t ns -> ST s (STDataFrame s t ns)
+ Numeric.DataFrame.ST: thawDataFrame :: forall (t :: Type) (ns :: [Nat]) s. (Dimensions ns, PrimBytes (DataFrame t ns)) => DataFrame t ns -> ST s (STDataFrame s t ns)
- Numeric.DataFrame.ST: thawPinDataFrame :: forall (t :: Type) (ns :: [Nat]) s. (PrimBytes (DataFrame t ns), PrimBytes t) => DataFrame t ns -> ST s (STDataFrame s t ns)
+ Numeric.DataFrame.ST: thawPinDataFrame :: forall (t :: Type) (ns :: [Nat]) s. (Dimensions ns, PrimBytes (DataFrame t ns)) => DataFrame t ns -> ST s (STDataFrame s t ns)
- Numeric.DataFrame.ST: unsafeThawDataFrame :: forall (t :: Type) (ns :: [Nat]) s. (PrimBytes (DataFrame t ns), PrimBytes t) => DataFrame t ns -> ST s (STDataFrame s t ns)
+ Numeric.DataFrame.ST: unsafeThawDataFrame :: forall (t :: Type) (ns :: [Nat]) s. (Dimensions ns, PrimBytes (DataFrame t ns), PrimBytes t) => DataFrame t ns -> ST s (STDataFrame s t ns)
- Numeric.DataFrame.ST: writeDataFrame :: forall t (ns :: [Nat]) s. (PrimBytes t, Dimensions ns) => STDataFrame s t ns -> Idxs ns -> DataFrame t ('[] :: [Nat]) -> ST s ()
+ Numeric.DataFrame.ST: writeDataFrame :: forall t (ns :: [Nat]) s. PrimBytes t => STDataFrame s t ns -> Idxs ns -> DataFrame t ('[] :: [Nat]) -> ST s ()
- Numeric.DataFrame.SubSpace: (!) :: SubSpace t (as :: [Nat]) (bs :: [Nat]) (asbs :: [Nat]) => DataFrame t asbs -> Idxs bs -> DataFrame t as
+ Numeric.DataFrame.SubSpace: (!) :: SubSpace t (as :: [Nat]) (bs :: [Nat]) (asbs :: [Nat]) => DataFrame t asbs -> Idxs as -> DataFrame t bs
- Numeric.DataFrame.SubSpace: class (ConcatList as bs asbs, Dimensions as, Dimensions bs, Dimensions asbs, PrimArray t (DataFrame t asbs)) => SubSpace (t :: Type) (as :: [Nat]) (bs :: [Nat]) (asbs :: [Nat]) | asbs as -> bs, asbs bs -> as, as bs -> asbs
+ Numeric.DataFrame.SubSpace: 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
- Numeric.DataFrame.SubSpace: element :: forall t (as :: [Nat]) (bs :: [Nat]) (asbs :: [Nat]) f. (SubSpace t as bs asbs, Applicative f) => Idxs bs -> (DataFrame t as -> f (DataFrame t as)) -> DataFrame t asbs -> f (DataFrame t asbs)
+ Numeric.DataFrame.SubSpace: 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)
- Numeric.DataFrame.SubSpace: elementWise :: forall s (as' :: [Nat]) (asbs' :: [Nat]) f. (SubSpace t as bs asbs, Applicative f, SubSpace s as' bs asbs') => (DataFrame s as' -> f (DataFrame t as)) -> DataFrame s asbs' -> f (DataFrame t asbs)
+ Numeric.DataFrame.SubSpace: 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)
- Numeric.DataFrame.SubSpace: elementWise_ :: forall t as bs asbs f b. (SubSpace t as bs asbs, Applicative f) => (DataFrame t as -> f b) -> DataFrame t asbs -> f ()
+ Numeric.DataFrame.SubSpace: elementWise_ :: forall t as bs asbs f b. (SubSpace t as bs asbs, Applicative f) => (DataFrame t bs -> f b) -> DataFrame t asbs -> f ()
- Numeric.DataFrame.SubSpace: ewfoldMap :: forall t (as :: [Nat]) (bs :: [Nat]) (asbs :: [Nat]) m. (Monoid m, SubSpace t as bs asbs) => (DataFrame t as -> m) -> DataFrame t asbs -> m
+ Numeric.DataFrame.SubSpace: 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
- Numeric.DataFrame.SubSpace: ewfoldl :: SubSpace t as bs asbs => (b -> DataFrame t as -> b) -> b -> DataFrame t asbs -> b
+ Numeric.DataFrame.SubSpace: ewfoldl :: SubSpace t as bs asbs => (b -> DataFrame t bs -> b) -> b -> DataFrame t asbs -> b
- Numeric.DataFrame.SubSpace: ewfoldr :: SubSpace t as bs asbs => (DataFrame t as -> b -> b) -> b -> DataFrame t asbs -> b
+ Numeric.DataFrame.SubSpace: ewfoldr :: SubSpace t as bs asbs => (DataFrame t bs -> b -> b) -> b -> DataFrame t asbs -> b
- Numeric.DataFrame.SubSpace: ewgen :: SubSpace t as bs asbs => DataFrame t as -> DataFrame t asbs
+ Numeric.DataFrame.SubSpace: ewgen :: SubSpace t as bs asbs => DataFrame t bs -> DataFrame t asbs
- Numeric.DataFrame.SubSpace: ewmap :: forall s (as' :: [Nat]) (asbs' :: [Nat]). (SubSpace t as bs asbs, SubSpace s as' bs asbs') => (DataFrame s as' -> DataFrame t as) -> DataFrame s asbs' -> DataFrame t asbs
+ Numeric.DataFrame.SubSpace: 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
- Numeric.DataFrame.SubSpace: ewzip :: forall t (as :: [Nat]) (bs :: [Nat]) (asbs :: [Nat]) s (as' :: [Nat]) (asbs' :: [Nat]) r (as'' :: [Nat]) (asbs'' :: [Nat]). (SubSpace t as bs asbs, SubSpace s as' bs asbs', SubSpace r as'' bs asbs'') => (DataFrame t as -> DataFrame s as' -> DataFrame r as'') -> DataFrame t asbs -> DataFrame s asbs' -> DataFrame r asbs''
+ Numeric.DataFrame.SubSpace: 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''
- Numeric.DataFrame.SubSpace: indexOffset# :: SubSpace t as bs asbs => Int# -> Int# -> DataFrame t asbs -> DataFrame t as
+ Numeric.DataFrame.SubSpace: indexOffset# :: SubSpace t as bs asbs => Int# -> DataFrame t asbs -> DataFrame t bs
- Numeric.DataFrame.SubSpace: indexWise :: forall s (as' :: [Nat]) (asbs' :: [Nat]) f. (SubSpace t as bs asbs, Applicative f, SubSpace s as' bs asbs') => (Idxs bs -> DataFrame s as' -> f (DataFrame t as)) -> DataFrame s asbs' -> f (DataFrame t asbs)
+ Numeric.DataFrame.SubSpace: 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)
- Numeric.DataFrame.SubSpace: indexWise_ :: forall t as bs asbs f b. (SubSpace t as bs asbs, Applicative f) => (Idxs bs -> DataFrame t as -> f b) -> DataFrame t asbs -> f ()
+ Numeric.DataFrame.SubSpace: 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 ()
- Numeric.DataFrame.SubSpace: iwfoldMap :: forall t (as :: [Nat]) (bs :: [Nat]) (asbs :: [Nat]) m. (Monoid m, SubSpace t as bs asbs) => (Idxs bs -> DataFrame t as -> m) -> DataFrame t asbs -> m
+ Numeric.DataFrame.SubSpace: 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
- Numeric.DataFrame.SubSpace: iwfoldl :: SubSpace t as bs asbs => (Idxs bs -> b -> DataFrame t as -> b) -> b -> DataFrame t asbs -> b
+ Numeric.DataFrame.SubSpace: iwfoldl :: SubSpace t as bs asbs => (Idxs as -> b -> DataFrame t bs -> b) -> b -> DataFrame t asbs -> b
- Numeric.DataFrame.SubSpace: iwfoldr :: SubSpace t as bs asbs => (Idxs bs -> DataFrame t as -> b -> b) -> b -> DataFrame t asbs -> b
+ Numeric.DataFrame.SubSpace: iwfoldr :: SubSpace t as bs asbs => (Idxs as -> DataFrame t bs -> b -> b) -> b -> DataFrame t asbs -> b
- Numeric.DataFrame.SubSpace: iwgen :: SubSpace t as bs asbs => (Idxs bs -> DataFrame t as) -> DataFrame t asbs
+ Numeric.DataFrame.SubSpace: iwgen :: SubSpace t as bs asbs => (Idxs as -> DataFrame t bs) -> DataFrame t asbs
- Numeric.DataFrame.SubSpace: iwmap :: forall s (as' :: [Nat]) (asbs' :: [Nat]). (SubSpace t as bs asbs, SubSpace s as' bs asbs') => (Idxs bs -> DataFrame s as' -> DataFrame t as) -> DataFrame s asbs' -> DataFrame t asbs
+ Numeric.DataFrame.SubSpace: 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
- Numeric.DataFrame.SubSpace: iwzip :: forall t (as :: [Nat]) (bs :: [Nat]) (asbs :: [Nat]) s (as' :: [Nat]) (asbs' :: [Nat]) r (as'' :: [Nat]) (asbs'' :: [Nat]). (SubSpace t as bs asbs, SubSpace s as' bs asbs', SubSpace r as'' bs asbs'') => (Idxs bs -> DataFrame t as -> DataFrame s as' -> DataFrame r as'') -> DataFrame t asbs -> DataFrame s asbs' -> DataFrame r asbs''
+ Numeric.DataFrame.SubSpace: 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''
- Numeric.DataFrame.SubSpace: update :: SubSpace t as bs asbs => Idxs bs -> DataFrame t as -> DataFrame t asbs -> DataFrame t asbs
+ Numeric.DataFrame.SubSpace: update :: SubSpace t as bs asbs => Idxs as -> DataFrame t bs -> DataFrame t asbs -> DataFrame t asbs
- Numeric.DataFrame.Type: bAlignOf :: PrimBytes a => a -> Int
+ Numeric.DataFrame.Type: bAlignOf :: (PrimBytes a, Num b) => a -> b
- Numeric.DataFrame.Type: bSizeOf :: PrimBytes a => a -> Int
+ Numeric.DataFrame.Type: bSizeOf :: (PrimBytes a, Num b) => a -> b
- Numeric.DataFrame.Type: inferPrimElem :: (DataFrameInference t, ArraySingletons t ds, ds ~ (Head ds : Tail ds)) => DataFrame t ds -> Evidence (AllTypes PrimBytes t)
+ Numeric.DataFrame.Type: inferPrimElem :: forall (t :: Type) (d :: Nat) (ds :: [Nat]). KnownBackend t (d : ds) => DataFrame t (d : ds) -> Dict (PrimBytes t)
- Numeric.DataFrame.Type: pattern Z :: forall (xs :: [Type]) (ns :: [Nat]). () => xs ~ '[] => DataFrame xs ns
+ Numeric.DataFrame.Type: 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)
- Numeric.DataFrame.Type: pattern KnownDims :: forall k (ds :: [k]). () => (All (KnownDim :: k -> Constraint) ds, Dimensions ds) => Dims ds
+ Numeric.DataFrame.Type: pattern KnownDims :: forall (ds :: [Nat]). () => (All KnownDim ds, All (BoundedDim :: Nat -> Constraint) ds, RepresentableList ds, Dimensions ds) => Dims ds
- Numeric.DataFrame.Type: type family PrimFrames (ts :: l) (ns :: [Nat]) :: Constraint
+ Numeric.DataFrame.Type: type family KnownBackends (ts :: l) (ns :: [Nat]) :: Constraint
- Numeric.Matrix: (%*) :: (ConcatList as bs (as ++ bs), Contraction t as bs asbs, KnownDim m, PrimArray t (DataFrame t (as +: m)), PrimArray t (DataFrame t (m :+ bs)), PrimArray t (DataFrame t (as ++ bs))) => DataFrame t (as +: m) -> DataFrame t (m :+ bs) -> DataFrame t (as ++ bs)
+ Numeric.Matrix: (%*) :: (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
- Numeric.Matrix: luSolve :: forall (t :: Type) (n :: Nat). (KnownDim n, Ord t, Fractional t, PrimBytes t, PrimArray t (Matrix t n n), PrimArray t (Vector t n)) => LUFact t n -> Vector t n -> Vector t n
+ Numeric.Matrix: 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
- Numeric.Matrix: mat22 :: (PrimBytes (Vector (t :: Type) 2), PrimBytes (Matrix t 2 2)) => Vector t 2 -> Vector t 2 -> Matrix t 2 2
+ Numeric.Matrix: mat22 :: PrimBytes (t :: Type) => Vector t 2 -> Vector t 2 -> Matrix t 2 2
- Numeric.Matrix: mat33 :: (PrimBytes (t :: Type), PrimBytes (Vector t 3), PrimBytes (Matrix t 3 3)) => Vector t 3 -> Vector t 3 -> Vector t 3 -> Matrix t 3 3
+ Numeric.Matrix: mat33 :: PrimBytes (t :: Type) => Vector t 3 -> Vector t 3 -> Vector t 3 -> Matrix t 3 3
- Numeric.Matrix: mat44 :: forall (t :: Type). (PrimBytes t, PrimBytes (Vector t (4 :: Nat)), PrimBytes (Matrix t (4 :: Nat) (4 :: Nat))) => Vector t (4 :: Nat) -> Vector t (4 :: Nat) -> Vector t (4 :: Nat) -> Vector t (4 :: Nat) -> Matrix t (4 :: Nat) (4 :: Nat)
+ Numeric.Matrix: mat44 :: PrimBytes (t :: Type) => Vector t 4 -> Vector t 4 -> Vector t 4 -> Vector t 4 -> Matrix t 4 4
- Numeric.Matrix: pivotMat :: forall (t :: Type) (n :: k). (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)
+ Numeric.Matrix: 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)
- Numeric.PrimBytes: byteOffset :: (PrimBytes a, Generic a, GPrimBytes (Rep a)) => a -> Int#
+ Numeric.PrimBytes: byteOffset :: PrimBytes a => a -> Int#
- Numeric.PrimBytes: class PrimTagged a => PrimBytes a
+ Numeric.PrimBytes: class PrimTagged a => PrimBytes a where {
- Numeric.PrimBytes: getBytes :: (PrimBytes a, Generic a, GPrimBytes (Rep a)) => a -> ByteArray#
+ Numeric.PrimBytes: getBytes :: PrimBytes a => a -> ByteArray#
- Numeric.Quaternion: -- | Quaternion data type. The ordering of coordinates is <tt>x y z w</tt>,
+ Numeric.Quaternion: -- | Quaternion data type. The ordering of coordinates is
- Numeric.Scalar: fromScalar :: SubSpace t '[] ds ds => Scalar t -> DataFrame t ds
+ Numeric.Scalar: fromScalar :: SubSpace t ds '[] ds => Scalar t -> DataFrame t ds
- Numeric.Vector: (.*.) :: (Num t, Num (Vector t n), SubSpace t '[] '[n] '[n]) => Vector t n -> Vector t n -> Vector t n
+ Numeric.Vector: (.*.) :: (Num t, Num (Vector t n), SubSpace t '[n] '[] '[n]) => Vector t n -> Vector t n -> Vector t n
- Numeric.Vector: (·) :: (Num t, Num (Vector t n), SubSpace t '[] '[n] '[n]) => Vector t n -> Vector t n -> Scalar t
+ Numeric.Vector: (·) :: (Num t, Num (Vector t n), SubSpace t '[n] '[] '[n]) => Vector t n -> Vector t n -> Scalar t
- Numeric.Vector: (×) :: (Num t, SubSpace t '[] '[3] '[3]) => Vector t 3 -> Vector t 3 -> Vector t 3
+ Numeric.Vector: (×) :: (Num t, SubSpace t '[3] '[] '[3]) => Vector t 3 -> Vector t 3 -> Vector t 3
- Numeric.Vector: cross :: (Num t, SubSpace t '[] '[3] '[3]) => Vector t 3 -> Vector t 3 -> Vector t 3
+ Numeric.Vector: cross :: (Num t, SubSpace t '[3] '[] '[3]) => Vector t 3 -> Vector t 3 -> Vector t 3
- Numeric.Vector: det2 :: (Num t, SubSpace t '[] '[2] '[2]) => Vector t 2 -> Vector t 2 -> Scalar t
+ Numeric.Vector: det2 :: (Num t, SubSpace t '[2] '[] '[2]) => Vector t 2 -> Vector t 2 -> Scalar t
- Numeric.Vector: dot :: (Num t, Num (Vector t n), SubSpace t '[] '[n] '[n]) => Vector t n -> Vector t n -> Scalar t
+ Numeric.Vector: dot :: (Num t, Num (Vector t n), SubSpace t '[n] '[] '[n]) => Vector t n -> Vector t n -> Scalar t
- Numeric.Vector: normL1 :: (Num t, SubSpace t '[] '[n] '[n]) => Vector t n -> Scalar t
+ Numeric.Vector: normL1 :: (Num t, SubSpace t '[n] '[] '[n]) => Vector t n -> Scalar t
- Numeric.Vector: normL2 :: (Floating t, SubSpace t '[] '[n] '[n]) => Vector t n -> Scalar t
+ Numeric.Vector: normL2 :: (Floating t, SubSpace t '[n] '[] '[n]) => Vector t n -> Scalar t
- Numeric.Vector: normLNInf :: (Ord t, Num t, SubSpace t '[] '[n] '[n]) => Vector t n -> Scalar t
+ Numeric.Vector: normLNInf :: (Ord t, Num t, SubSpace t '[n] '[] '[n]) => Vector t n -> Scalar t
- Numeric.Vector: normLP :: (Floating t, SubSpace t '[] '[n] '[n]) => Int -> Vector t n -> Scalar t
+ Numeric.Vector: normLP :: (Floating t, SubSpace t '[n] '[] '[n]) => Int -> Vector t n -> Scalar t
- Numeric.Vector: normLPInf :: (Ord t, Num t, SubSpace t '[] '[n] '[n]) => Vector t n -> Scalar t
+ Numeric.Vector: normLPInf :: (Ord t, Num t, SubSpace t '[n] '[] '[n]) => Vector t n -> Scalar t
- Numeric.Vector: normalized :: (Floating t, Fractional (Vector t n), SubSpace t '[] '[n] '[n]) => Vector t n -> Vector t n
+ Numeric.Vector: normalized :: (Floating t, Fractional (Vector t n), SubSpace t '[n] '[] '[n]) => Vector t n -> Vector t n
- Numeric.Vector: vec2 :: SubSpace t '[] '[2] '[2] => t -> t -> Vector t 2
+ Numeric.Vector: vec2 :: Vector2 t => t -> t -> Vector t 2
- Numeric.Vector: vec3 :: SubSpace t '[] '[3] '[3] => t -> t -> t -> Vector t 3
+ Numeric.Vector: vec3 :: Vector3 t => t -> t -> t -> Vector t 3
- Numeric.Vector: vec4 :: SubSpace t '[] '[4] '[4] => t -> t -> t -> t -> Vector t 4
+ Numeric.Vector: vec4 :: Vector4 t => t -> t -> t -> t -> Vector t 4

Files

bench/misc.hs view
@@ -5,70 +5,73 @@  module Main (main) where -import           Numeric.DataFrame-import           Numeric.Dimensions+import Numeric.DataFrame+import Numeric.Dimensions -import qualified Control.Monad.ST as ST+import qualified Control.Monad.ST     as ST import qualified Numeric.DataFrame.ST as ST--- import qualified Numeric.Dimensions.Traverse.ST as ST    main :: IO () main = do     putStrLn "Hello world!"-    print (D @3 :* D @2 :* U)+    print (D3 :* D2 :* U) -    print (fromList D [vec2 1 0, vec2 2 3, vec2 3 4, vec2 5 6]-             :: Maybe (DataFrame Int '[N 2, XN 2]))-    print (fromList D [vec4 1 0 2 11, vec4 2 22 3 0, vec4 3 4 0 0]-             :: Maybe (DataFrame Double '[N 4, XN 0]))-    print (fromList D [vec2 0 0, vec2 2 22, vec2 2 22]-             :: Maybe (DataFrame Float '[N 2, XN 4]))-    print $ fromList (D @3) [0 :: Scf, 1, 3, 5, 7]-    print ( fromList D [9, 13, 2]-             :: Maybe (DataFrame Float '[N 5, N 2, XN 2]))+    print (fromList [vec2 1 0, vec2 2 3, vec2 3 4, vec2 5 6]+             :: DataFrame Int '[XN 0, N 2])+    print (fromList [vec4 1 0 2 11, vec4 2 22 3 0, vec4 3 4 0 0]+             :: DataFrame Double '[XN 0, N 4])+    print (fromList [vec2 0 0, vec2 2 22, vec2 2 22]+             :: DataFrame Float '[XN 0, N 2])+    print $ fromList [0 :: Scf, 1, 3, 5, 7]+    print ( fromList [9, 13, 2]+             :: DataFrame Float '[XN 0, N 5, N 2])     print $ vec2 1 1 %* mat22 1 (vec2 2 (3 :: Float))-    print (toList (42 :: DataFrame Int '[4,3,2]))+     -- Seems like I have to specify known dimension explicitly,     -- because the inference process within the pattern match     -- cannot escape the case expression.     -- On the other hand, if I type wrong dimension it will throw a nice type-level error.-    () <- case fromList D [10, 100, 1000] :: Maybe (DataFrame Double '[N 4, N 2, XN 2]) of-        Just (XFrame m)+    () <- case (fromList [10, 100, 1000] :: DataFrame Double '[XN 0, N 2, N 4]) of+        XFrame m           | KnownDims <- dims `inSpaceOf` m               -- Amazing inference!-              -- m :: KnownNat k => DataFrame '[4,2,k]-            -> print $ vec4 1 2.25 3 0.162 %* m-        Nothing -> print "Failed to construct a DataFrame!"+              -- m :: KnownNat k => DataFrame '[k,2,4]+            -> print $ m %* vec4 1 2.25 3 0.162+        _ -> print "Failed to construct a DataFrame!"     putStrLn "Constructing larger matrices"-    let x :: DataFrame Double '[2,5,4]-        x =   transpose ( (56707.4   <::> 73558.41  <+:> 47950.074  <+:> 83394.61  <+:> 25611.629 )-                     <::> (53704.516 <::> -3277.478 <+:> 99479.92   <+:> 18915.17  <+:> 59666.938 ) )-         <::> transpose ( (-3035.543 <::> 15831.447 <+:> 73256.625  <+:> 80709.38  <+:> 72695.04  )-                     <::> (50932.49  <::> 7865.496  <+:> -4050.5957 <+:> 99839.41  <+:> 10834.297 ) )-         <+:> transpose ( (21961.227 <::> 29640.914 <+:> 39657.19   <+:> 81469.64  <+:> 17815.506 )-                     <::> (-8484.239 <::> 16877.531 <+:> 65145.742  <+:> 80219.67  <+:> 81508.87  ) )-         <+:> transpose ( (53105.71  <::> 16255.646 <+:> 23324.957  <+:> -4438.164 <+:> 35369.824 )-                     <::> (67930.45  <::> 8950.834  <+:> 64451.71   <+:> 76685.57  <+:> 6728.465  ) )-        y :: DataFrame Double '[3,7]-        y = transpose $-               (70096.85  <::> 34332.492 <+:> 3642.8867 <+:> 25242.25  <+:> 59776.234 <+:> 12092.57 <+:> 10708.498)-          <::> (46447.965 <::> 37145.668 <+:> 56899.656 <+:> 85367.56  <+:> 15872.262 <+:> 87466.24 <+:> 82506.76 )-          <+:> (50458.848 <::> 31650.453 <+:> 71432.78  <+:> 53073.203 <+:> 59267.883 <+:> 82369.89 <+:> 78171.56 )-        z = ewgen x :: DataFrame Double '[2,5,4,3,7]-    print $ ewfoldl @_ @'[2] (+) 10 z-    print $ ewfoldr @_ @'[2,5] (+) 0 z + 10-    print $ ewfoldl (+) 10 z - ewfoldr @_ @'[2,5,4] (+) 0 z - 10+    let x :: DataFrame Double '[4,5,2]+        x =  DF4 (transpose $ DF2+                    (DF5  56707.4     73558.41    47950.074  83394.61    25611.629)+                    (DF5  53704.516  (-3277.478)  99479.92   18915.17    59666.938))+                 (transpose $ DF2+                    (DF5 (-3035.543)  15831.447   73256.625   80709.38   72695.04)+                    (DF5  50932.49    7865.496   (-4050.5957) 99839.41   10834.297))+                 (transpose $ DF2+                    (DF5  21961.227   29640.914   39657.19    81469.64   17815.506 )+                    (DF5 (-8484.239)  16877.531  65145.742    80219.67   81508.87  ))+                 (transpose $ DF2+                    (DF5  53105.71    16255.646   23324.957  (-4438.164) 35369.824 )+                    (DF5  67930.45    8950.834    64451.71    76685.57   6728.465  ))+        y :: DataFrame Double '[7,3]+        y = transpose $ DF3+          (DF7 70096.85  34332.492 3642.8867 25242.25  59776.234 12092.57 10708.498)+          (DF7 46447.965 37145.668 56899.656 85367.56  15872.262 87466.24 82506.76 )+          (DF7 50458.848 31650.453 71432.78  53073.203 59267.883 82369.89 78171.56 )+        z = ewgen x :: DataFrame Double '[7,3,4,5,2]+    print $ ewfoldl @_ @_ @'[2] (+) 10 z+    print $ ewfoldr @_ @_ @'[5,2] (+) 0 z + 10+    print $ ewfoldl (+) 10 z - ewfoldr @_ @_ @'[4,5,2] (+) 0 z - 10 -    -- We can map arbitrary prefix dimension over the dataframe,-    -- indexing by suffix dimensions.+    -- We can map arbitrary suffix dimension over the dataframe,+    -- indexing by prefix dimensions.     -- At the same time, we can transform underlying element type-    --  or prefix dimensionality.+    --  or suffix dimensionality.     -- For example, we can do tensor produt of every sub-tensor.     putStrLn "\nConversions between element types and frame sizes."-    print $ iwmap @Int @'[2,2] @'[7] @_-                  (\(Idx i:*U) v -> fromScalar . (scalar (fromIntegral i) +) . round+    print $ iwmap @Int @'[7] @'[2,2] @_+                  (\(i:*U) v -> fromScalar . (scalar (fromIntegral i) +) . round                                      $ vec3 0.02 (-0.01) 0.001 %* v                   ) y @@ -77,27 +80,27 @@     -- This means we can even do arbitrary IO for each subtensor     -- indexed by suffix dimensions.     putStrLn "\nWelement-wise IO!"-    rVec <- elementWise @Double @_ @'[4] @_+    rVec <- elementWise @Double @'[4] @_  @_               (\v -> print v >> return (sqrt . trace $ v %* transpose v)) x     putStrLn "\nTraces for each matrix element:"     print rVec      -- Updating existing frames     print $ update (2:*U) (scalar 777) rVec-    print $ update (2:*3:*U) (vec2 999 999) x+    print $ update (1:*3:*U) (vec2 999 555) x -    let matX = iwgen (scalar . fromEnum) :: DataFrame Int '[2,5,4]+    let matX = iwgen (scalar . fromEnum) :: DataFrame Int '[2,6,4]         matY = iwgen (scalar . fromEnum) :: DataFrame Int '[5,4]     putStrLn "Check carefully that this returns no garbage"     print matX-    print (ewmap (<+:> scalar 111) matX :: DataFrame Int '[3,5,4])+    print (ewmap @_ @'[2,6] (`snocDF` scalar 111) matX :: DataFrame Int '[2,6,5])     print matY-    print (ewmap fromScalar matY :: DataFrame Int '[3,5,4])+    print (ewmap fromScalar matY :: DataFrame Int '[5,4,3])      -- Working with mutable frames     print $ ST.runST $ do       sdf <- ST.thawDataFrame matY-      ST.writeDataFrame sdf (1:*1:*U) 900101-      ST.writeDataFrame sdf (3:*3:*U) 900303-      ST.writeDataFrame sdf (5:*3:*U) 900503+      ST.writeDataFrame sdf (0:*0:*U) 900101+      ST.writeDataFrame sdf (2:*2:*U) 900303+      ST.writeDataFrame sdf (4:*2:*U) 900503       ST.unsafeFreezeDataFrame sdf
bench/subspacefolds.hs view
@@ -5,58 +5,58 @@  module Main (main) where -import           Data.Maybe (fromMaybe)-import           Data.Time.Clock+import Data.Maybe      (fromMaybe)+import Data.Time.Clock -import           Numeric.DataFrame-import           Numeric.Dimensions+import Numeric.DataFrame+import Numeric.Dimensions  -type DList = [6,4,10,7,35,8,12] -- [6,26,8,10,35,8,12]+type DList = [6,14,10,7,2,8,5]  main :: IO () main = do     t0 <- getCurrentTime     putStrLn $ "\nStarting benchmarks, current time is " ++ show t0-    let df = iwgen @Float @'[] @DList (fromIntegral . fromEnum)+    let df = iwgen @Float @DList @'[] (fromIntegral . fromEnum)     t1 <- df `seq` getCurrentTime     seq t1 putStrLn $ "Created DataFrame, elapsed time is " ++ show (diffUTCTime t1 t0)      putStrLn "\nRunning a ewfoldl on scalar elements..."-    let rezEwf = ewfoldl @Float @'[] @DList (\a x -> return $! fromMaybe x a + fromMaybe 0 a / (x+1)) (Just 1)  df+    let rezEwf = ewfoldl @Float @DList @'[] (\a x -> return $! fromMaybe x a + fromMaybe 0 a / (x+1)) (Just 1)  df     t2 <- rezEwf `seq` getCurrentTime     seq t2 putStrLn $ "Done; elapsed time = " ++ show (diffUTCTime t2 t1)     print rezEwf      putStrLn "\nRunning a iwfoldl on scalar elements (not using idx)..."-    let rezIwf = iwfoldl @Float @'[] @DList (\_ a x -> a +  a / (x+1)) 1 df+    let rezIwf = iwfoldl @Float  @DList @'[] (\_ a x -> a +  a / (x+1)) 1 df     t3 <- rezIwf `seq` getCurrentTime     seq t3 putStrLn $ "Done; elapsed time = " ++ show (diffUTCTime t3 t2)     print rezIwf      putStrLn "\nRunning a iwfoldr on scalar elements (using fromEnum idx)..."-    let rezIwf2 = iwfoldr @Float @'[] @DList (\i x a -> return $! fromMaybe 0 a + x / ((1+) . fromIntegral $ fromEnum i)) (Just 0) df+    let rezIwf2 = iwfoldr @Float @DList @'[] (\i x a -> return $! fromMaybe 0 a + x / ((1+) . fromIntegral $ fromEnum i)) (Just 0) df     t4 <- rezIwf2 `seq` getCurrentTime     seq t4 putStrLn $ "Done; elapsed time = " ++ show (diffUTCTime t4 t3)     print rezIwf2      putStrLn "\nRunning a iwfoldl on scalar elements (enforcing idx)..."-    let rezIwf3 = iwfoldl @Float @'[] @DList (\i a x -> i `seq` return $! fromMaybe 0 a + fromMaybe x a / (x+1)) (Just 1) df+    let rezIwf3 = iwfoldl @Float @DList @'[] (\i a x -> i `seq` return $! fromMaybe 0 a + fromMaybe x a / (x+1)) (Just 1) df     t5 <- rezIwf3 `seq` getCurrentTime     seq t5 putStrLn $ "Done; elapsed time = " ++ show (diffUTCTime t5 t4)     print rezIwf3 -    putStrLn "\nRunning a ewfoldl on vector5 elements..."-    let rezEwv1 = ewfoldl @Float @'[Head DList] @(Tail DList)-                          (\a x -> return $! fromMaybe 2 a + fromMaybe 0 a / (1 + iwgen @_ @'[] (\(Idx i:*U) -> Idx (i+1) :* U !. x )) )-                          (Just (3 :: DataFrame Float '[5])) df+    putStrLn "\nRunning a ewfoldl on vector4 elements..."+    let rezEwv1 = ewfoldl @Float @(Init DList) @'[Last DList]+                          (\a x -> return $! fromMaybe 2 a + fromMaybe 0 a / (1 + iwgen @_ @_ @'[] (\(Idx i:*U) -> x ! Idx (i+1) :* U )) )+                          (Just (3 :: DataFrame Float '[4])) df     t6 <- rezEwv1 `seq` getCurrentTime     seq t6 putStrLn $ "Done; elapsed time = " ++ show (diffUTCTime t6 t5)     print rezEwv1      putStrLn "\nRunning a ewfoldr on vector3 elements..."-    let rezEwv2 = ewfoldr @Float @'[Head DList] @(Tail DList)-                          (\x a -> return $! fromMaybe 2 a + fromMaybe 1 a / (1 + iwgen @_ @'[] (\(Idx i:*U) -> Idx (i+1):* U !. x )))+    let rezEwv2 = ewfoldr @Float @(Init DList) @'[Last DList]+                          (\x a -> return $! fromMaybe 2 a + fromMaybe 1 a / (1 + iwgen @_ @_ @'[] (\(Idx i:*U) -> x ! Idx (i+1):* U )))                           (Just (3 :: DataFrame Float '[3])) df     t7 <- rezEwv2 `seq` getCurrentTime     seq t7 putStrLn $ "Done; elapsed time = " ++ show (diffUTCTime t7 t6)@@ -64,8 +64,8 @@      putStrLn "\nRunning a ewfoldr with matrix products..."     let rezEwm = ewfoldr @Float @(Take 3 DList) @(Drop 3 DList)-                          (\x a ->  a + x %* (1 <::> 0.5 <:> 0.1)  )-                          (1 :: DataFrame Float (Take 2 DList +: 3)) df+                          (\x a ->  a + x %* (DF5 1 0.5 0.1 0.01 0.001)  )+                          (1 :: DataFrame Float (Init (Drop 3 DList) +: 3)) df     t8 <- rezEwm `seq` getCurrentTime     seq t8 putStrLn $ "Done; elapsed time = " ++ show (diffUTCTime t8 t7)     print rezEwm@@ -74,4 +74,4 @@       putStrLn "Checking indexes"-    print $ 2:*1:*1:*3:*1:*U !. df+    print $ df ! (2:*1:*1:*3:*1:*U :: Idxs (Take 5 DList))
easytensor.cabal view
@@ -1,136 +1,139 @@-name: easytensor-version: 1.0.1.0-cabal-version: >=1.22-build-type: Simple-license: BSD3-license-file: LICENSE-copyright: (c) Artem Chirkin-maintainer: chirkin@arch.ethz.ch-homepage: https://github.com/achirkin/easytensor#readme-synopsis: Pure, type-indexed haskell vector, matrix, and tensor library.-description:-    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.-category: Math, Geometry-author: Artem Chirkin+cabal-version: 1.12 -source-repository head-    type: git-    location: https://github.com/achirkin/easytensor.git-    subdir: easytensor+-- This file has been generated from package.yaml by hpack version 0.31.1.+--+-- see: https://github.com/sol/hpack+--+-- hash: 295fd017e3f09157b9e9a28d1db9beb6ecb080f0612228ac49f18e78ee08d01b +name:           easytensor+version:        2.0.0.0+synopsis:       Pure, type-indexed haskell vector, matrix, and tensor library.+description:    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>+category:       math, geometry+homepage:       https://github.com/achirkin/easytensor#readme+bug-reports:    https://github.com/achirkin/easytensor/issues+author:         Artem Chirkin+maintainer:     achirkin@users.noreply.github.com+copyright:      Copyright: (c) 2019 Artem Chirkin+license:        BSD3+license-file:   LICENSE+build-type:     Simple -flag unsafeindices-    description:-        Disable bound checks when accessing elements of a tensor, matrix, or vector.-    default: False+source-repository head+  type: git+  location: https://github.com/achirkin/easytensor+  subdir: easytensor +flag unsafeindices+  description: Disable bound checks when accessing elements of a tensor, matrix, or vector.+  manual: True+  default: False  library--    if flag(unsafeindices)-        cpp-options: -DUNSAFE_INDICES-    exposed-modules:-        Numeric.DataFrame-        Numeric.DataFrame.IO-        Numeric.DataFrame.ST-        Numeric.Matrix-        Numeric.Matrix.Class-        Numeric.Vector-        Numeric.Scalar-        Numeric.Quaternion-        Numeric.Semigroup-        Numeric.PrimBytes-        Numeric.DataFrame.Type-        Numeric.DataFrame.Family-        Numeric.DataFrame.Shape-        Numeric.DataFrame.SubSpace-        Numeric.DataFrame.Contraction-        Numeric.DataFrame.Internal.Mutable-        Numeric.DataFrame.Internal.Array-        Numeric.DataFrame.Internal.Array.Class-        Numeric.DataFrame.Internal.Array.Family-        Numeric.DataFrame.Internal.Array.Family.ArrayBase-        Numeric.DataFrame.Internal.Array.Family.ScalarBase-        Numeric.DataFrame.Internal.Array.Family.FloatX2-        Numeric.DataFrame.Internal.Array.Family.FloatX3-        Numeric.DataFrame.Internal.Array.Family.FloatX4-        Numeric.DataFrame.Internal.Array.Family.DoubleX2-        Numeric.DataFrame.Internal.Array.Family.DoubleX3-        Numeric.DataFrame.Internal.Array.Family.DoubleX4-        Numeric.DataFrame.Internal.Array.PrimOps-    build-depends:-        base >=4.10 && <5,-        dimensions >=1.0.0.0-    default-language: Haskell2010-    if impl(ghc >= 8.6)-        default-extensions: NoStarIsType-    hs-source-dirs: src-    other-modules:-        Numeric.Matrix.Mat44d-        Numeric.Matrix.Mat44f-        Numeric.Quaternion.Class-        Numeric.Quaternion.QDouble-        Numeric.Quaternion.QFloat-    ghc-options:-      -Wall-      -fwarn-tabs-      -fwarn-unused-do-bind-      -fwarn-monomorphism-restriction-+  exposed-modules:+      Numeric.DataFrame+      Numeric.DataFrame.Contraction+      Numeric.DataFrame.Internal.Backend+      Numeric.DataFrame.Internal.Mutable+      Numeric.DataFrame.Internal.PrimArray+      Numeric.DataFrame.IO+      Numeric.DataFrame.ST+      Numeric.DataFrame.SubSpace+      Numeric.DataFrame.Type+      Numeric.Matrix+      Numeric.PrimBytes+      Numeric.ProductOrd+      Numeric.ProductOrd.NonTransitive+      Numeric.ProductOrd.Partial+      Numeric.Quaternion+      Numeric.Scalar+      Numeric.Vector+  other-modules:+      Numeric.Matrix.Internal+      Numeric.Matrix.Internal.Mat44d+      Numeric.Matrix.Internal.Mat44f+      Numeric.Scalar.Internal+      Numeric.Vector.Internal+      Numeric.Quaternion.Internal+      Numeric.Quaternion.Internal.QDouble+      Numeric.Quaternion.Internal.QFloat+      Numeric.DataFrame.Internal.Backend.Family+      Numeric.DataFrame.Internal.Backend.Family.ArrayBase+      Numeric.DataFrame.Internal.Backend.Family.DoubleX2+      Numeric.DataFrame.Internal.Backend.Family.DoubleX3+      Numeric.DataFrame.Internal.Backend.Family.DoubleX4+      Numeric.DataFrame.Internal.Backend.Family.FloatX2+      Numeric.DataFrame.Internal.Backend.Family.FloatX3+      Numeric.DataFrame.Internal.Backend.Family.FloatX4+      Numeric.DataFrame.Internal.Backend.Family.ScalarBase+      Numeric.DataFrame.Internal.BackendI+  hs-source-dirs:+      src+      src-base+  ghc-options: -Wall -Wcompat -Wtabs -Wmonomorphism-restriction -Wmissing-local-signatures -Wmissing-home-modules -Widentities -Wredundant-constraints+  build-depends:+      base >=4.11 && <5+    , constraints-deriving >=1.0.4.0 && <2+    , dimensions >=2 && <3+  if flag(unsafeindices)+    cpp-options: -DUNSAFE_INDICES+  default-language: Haskell2010  test-suite et-test--    type: exitcode-stdio-1.0-    main-is: Spec.hs-    other-modules:-        Numeric.DataFrame.Arbitraries-        Numeric.DataFrame.SubSpaceTest-        Numeric.DataFrame.BasicTest-        Numeric.MatrixDoubleTest-        Numeric.MatrixFloatTest-        Numeric.QuaternionTest-    build-depends:-        base -any,-        Cabal -any,-        QuickCheck -any,-        easytensor -any,-        dimensions -any-    default-language: Haskell2010-    if impl(ghc >= 8.6)-        default-extensions: NoStarIsType, NoMonadFailDesugaring-    hs-source-dirs: test-    ghc-options: -Wall -fwarn-tabs -O2-+  type: exitcode-stdio-1.0+  main-is: Spec.hs+  other-modules:+      Numeric.DataFrame.Arbitraries+      Numeric.DataFrame.BasicTest+      Numeric.DataFrame.SubSpaceTest+      Numeric.MatrixDoubleTest+      Numeric.MatrixFloatTest+      Numeric.PrimBytesTest+      Numeric.QuaterDoubleTest+      Numeric.QuaterFloatTest+      Spec.Util+      Paths_easytensor+  hs-source-dirs:+      test+  ghc-options: -Wall -Wcompat -Wtabs -Wmonomorphism-restriction -Wmissing-local-signatures -Wmissing-home-modules -Widentities -Wredundant-constraints+  build-depends:+      Cabal+    , QuickCheck+    , base >=4.11 && <5+    , constraints-deriving >=1.0.4.0 && <2+    , dimensions >=2 && <3+    , easytensor+    , template-haskell+  default-language: Haskell2010  benchmark et-bench-misc--    type: exitcode-stdio-1.0-    main-is: misc.hs-    build-depends:-        base -any,-        easytensor -any,-        dimensions -any-    default-language: Haskell2010-    if impl(ghc >= 8.6)-        default-extensions: NoStarIsType, NoMonadFailDesugaring-    hs-source-dirs: bench-    ghc-options: -Wall -fwarn-tabs -O2-+  type: exitcode-stdio-1.0+  main-is: misc.hs+  other-modules:+      Paths_easytensor+  hs-source-dirs:+      bench+  ghc-options: -Wall -Wcompat -Wtabs -Wmonomorphism-restriction -Wmissing-local-signatures -Wmissing-home-modules -Widentities -Wredundant-constraints+  build-depends:+      base >=4.11 && <5+    , constraints-deriving >=1.0.4.0 && <2+    , dimensions >=2 && <3+    , easytensor+  default-language: Haskell2010  benchmark et-bench-spfolds--    type: exitcode-stdio-1.0-    main-is: subspacefolds.hs-    build-depends:-        base -any,-        easytensor -any,-        dimensions -any,-        time -any-    default-language: Haskell2010-    if impl(ghc >= 8.6)-        default-extensions: NoStarIsType, NoMonadFailDesugaring-    hs-source-dirs: bench-    ghc-options: -Wall -fwarn-tabs -O2+  type: exitcode-stdio-1.0+  main-is: subspacefolds.hs+  other-modules:+      Paths_easytensor+  hs-source-dirs:+      bench+  ghc-options: -Wall -Wcompat -Wtabs -Wmonomorphism-restriction -Wmissing-local-signatures -Wmissing-home-modules -Widentities -Wredundant-constraints+  build-depends:+      base >=4.11 && <5+    , constraints-deriving >=1.0.4.0 && <2+    , dimensions >=2 && <3+    , easytensor+    , time+  default-language: Haskell2010
+ src-base/Numeric/DataFrame/Internal/Backend/Family.hs view
@@ -0,0 +1,183 @@+{-# LANGUAGE CPP                    #-}+{-# LANGUAGE ConstraintKinds        #-}+{-# LANGUAGE DataKinds              #-}+{-# LANGUAGE FlexibleContexts       #-}+{-# LANGUAGE FlexibleInstances      #-}+{-# LANGUAGE GADTs                  #-}+{-# LANGUAGE MagicHash              #-}+{-# LANGUAGE MultiParamTypeClasses  #-}+{-# LANGUAGE PolyKinds              #-}+{-# LANGUAGE RankNTypes             #-}+{-# LANGUAGE RoleAnnotations        #-}+{-# LANGUAGE ScopedTypeVariables    #-}+{-# LANGUAGE TypeApplications       #-}+{-# LANGUAGE TypeFamilyDependencies #-}+{-# LANGUAGE TypeInType             #-}+{-# LANGUAGE TypeOperators          #-}+-- Constraints @b ~ BackendFamily t ds@ is not redundant; they allows to avoid AllowAmbigousTypes.+{-# OPTIONS_GHC -fno-warn-redundant-constraints #-}+{- |+This module is to be reimplemented multiple times based on a platform capabilities.+For example, I can add a SIMD implementation in a separate folder and use AVX+processsor extensions to make faster 4D vector operations.++Various implementations would be picked by activating corresponding cabal flags.++The following export list must be the same for every implementation+ -}+module Numeric.DataFrame.Internal.Backend.Family+  ( BackendFamily, KnownBackend ()+  , inferKnownBackend, inferPrimElem, inferPrimArray, inferBackendInstance+  ) where+++import Data.Constraint+import GHC.Base++import Numeric.DataFrame.Internal.Backend.Family.ArrayBase+import Numeric.DataFrame.Internal.Backend.Family.DoubleX2+import Numeric.DataFrame.Internal.Backend.Family.DoubleX3+import Numeric.DataFrame.Internal.Backend.Family.DoubleX4+import Numeric.DataFrame.Internal.Backend.Family.FloatX2+import Numeric.DataFrame.Internal.Backend.Family.FloatX3+import Numeric.DataFrame.Internal.Backend.Family.FloatX4+import Numeric.DataFrame.Internal.Backend.Family.ScalarBase+import Numeric.DataFrame.Internal.PrimArray+import Numeric.Dimensions+import Numeric.PrimBytes+++-- | 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 where+    BackendFamily t      '[]    = ScalarBase t+    BackendFamily Float  '[2]   = FloatX2+    BackendFamily Float  '[3]   = FloatX3+    BackendFamily Float  '[4]   = FloatX4+    BackendFamily Double '[2]   = DoubleX2+    BackendFamily Double '[3]   = DoubleX3+    BackendFamily Double '[4]   = DoubleX4+    BackendFamily t       ds    = ArrayBase t ds++-- | Promise that we are sure the backend is ArrayBase.+unsafeDefault :: forall t ds . Dict (BackendFamily t ds ~ ArrayBase t ds)+unsafeDefault = unsafeCoerce# (Dict @(ArrayBase t ds ~ ArrayBase t ds))++-- | Singleton type used to determine the currently used DataFrame backend;+--   establishes a good bijection @b <~> t ds@ (better than just using @BackendFamily@ everywhere).+data BackendSing (t :: Type) (ds :: [Nat]) (backend :: Type) where+    BSC :: BackendSing t      '[]  (ScalarBase t)+    BF2 :: BackendSing Float  '[2]  FloatX2+    BF3 :: BackendSing Float  '[3]  FloatX3+    BF4 :: BackendSing Float  '[4]  FloatX4+    BD2 :: BackendSing Double '[2]  DoubleX2+    BD3 :: BackendSing Double '[3]  DoubleX3+    BD4 :: BackendSing Double '[4]  DoubleX4+    BPB :: ( PrimBytes t, BackendFamily t ds ~ ArrayBase t ds )+        => BackendSing t ds (ArrayBase t ds)++-- | A framework for using DataFrame type family instances.+class KnownBackend (t :: Type) (ds :: [Nat]) (backend :: Type) where+    -- | Get DataFrame backend type family instance+    bSing :: BackendSing t ds backend++-- When compiled for haddock, some of the modules complain about missing KnownBackend+-- instance. To workaround this, I add an instance stub.+--+-- Also note, these may be related issues:+--+-- https://github.com/haskell/haddock/issues/680+-- https://github.com/haskell/cabal/issues/4513+--+#if defined(__HADDOCK__) || defined(__HADDOCK_VERSION__)+instance KnownBackend t ds b where bSing = undefined+#else+instance KnownBackend t      '[]  (ScalarBase t)   where bSing = BSC+instance KnownBackend Float  '[2]  FloatX2         where bSing = BF2+instance KnownBackend Float  '[3]  FloatX3         where bSing = BF3+instance KnownBackend Float  '[4]  FloatX4         where bSing = BF4+instance KnownBackend Double '[2]  DoubleX2        where bSing = BD2+instance KnownBackend Double '[3]  DoubleX3        where bSing = BD3+instance KnownBackend Double '[4]  DoubleX4        where bSing = BD4+instance PrimBytes t+      => KnownBackend t       ds  (ArrayBase t ds) where+    bSing = case unsafeDefault @t @ds of Dict -> BPB+#endif++-- | Find an instance of `KnownBackend` class using `PrimBytes` and `Dimensions`.+inferKnownBackend :: forall t ds b+                  . (PrimBytes t, Dimensions ds, b ~ BackendFamily t ds)+                  => Dict (KnownBackend t ds b)+inferKnownBackend = case (dims @ds, primTag @t undefined) of+  (U, _) -> Dict+  (d :* U, PTagFloat)+      | Just Dict <- sameDim (D @2) d -> Dict+      | Just Dict <- sameDim (D @3) d -> Dict+      | Just Dict <- sameDim (D @4) d -> Dict+  (d :* U, PTagDouble)+      | Just Dict <- sameDim (D @2) d -> Dict+      | Just Dict <- sameDim (D @3) d -> Dict+      | Just Dict <- sameDim (D @4) d -> Dict+  _ -> case unsafeDefault @t @ds of Dict -> Dict+{-# INLINE inferKnownBackend #-}+++-- This function determines the logic of instance selection+-- for the type family+inferBackendInstance+  :: forall (t :: Type) (ds :: [Nat]) (b :: Type) (c :: Type -> Constraint)+   . ( KnownBackend t ds b+     , c (ScalarBase t)+     , c FloatX2,  c FloatX3,  c FloatX4+     , c DoubleX2, c DoubleX3, c DoubleX4+     , c (ArrayBase t ds)+     , b ~ BackendFamily t ds+     )+  => Dict (c b)+inferBackendInstance = case bSing @t @ds @b of+    BSC -> Dict+    BF2 -> Dict+    BF3 -> Dict+    BF4 -> Dict+    BD2 -> Dict+    BD3 -> Dict+    BD4 -> Dict+    BPB -> Dict+{-# INLINE inferBackendInstance #-}++inferPrimElem :: forall (t :: Type) (d :: Nat) (ds :: [Nat]) (b :: Type)+               . ( KnownBackend t (d ': ds) b+                 , b ~ BackendFamily t (d ': ds)+                 )+              => b -> Dict (PrimBytes t)+inferPrimElem _ = case bSing @t @(d ': ds) @b of+    BF2 -> Dict+    BF3 -> Dict+    BF4 -> Dict+    BD2 -> Dict+    BD3 -> Dict+    BD4 -> Dict+    BPB -> Dict++-- Need a separate function for this one due to a functional dependency+inferPrimArray+  :: forall (t :: Type) (ds :: [Nat]) (b :: Type)+   . (PrimBytes t, KnownBackend t ds b, b ~ BackendFamily t ds)+  => Dict (PrimArray t b)+inferPrimArray = case bSing @t @ds @b of+    BSC -> Dict+    BF2 -> Dict+    BF3 -> Dict+    BF4 -> Dict+    BD2 -> Dict+    BD3 -> Dict+    BD4 -> Dict+    BPB -> Dict+{-# INLINE inferPrimArray #-}
+ src-base/Numeric/DataFrame/Internal/Backend/Family.hs-boot view
@@ -0,0 +1,28 @@+{-# LANGUAGE CPP                    #-}+{-# LANGUAGE DataKinds              #-}+{-# LANGUAGE FlexibleInstances      #-}+{-# LANGUAGE MultiParamTypeClasses  #-}+{-# LANGUAGE TypeFamilyDependencies #-}++module Numeric.DataFrame.Internal.Backend.Family+  ( BackendFamily, KnownBackend ()+  ) where++import Data.Kind    (Type)+import GHC.TypeLits (Nat)+++type family BackendFamily (t :: Type) (ds :: [Nat]) = (v :: Type) | v -> t ds where ..+class KnownBackend (t :: Type) (ds :: [Nat]) (backend :: Type)++-- When compiled for haddock, some of the modules complain about missing KnownBackend+-- instance. To workaround this, I add an instance stub.+--+-- Also note, these may be related issues:+--+-- https://github.com/haskell/haddock/issues/680+-- https://github.com/haskell/cabal/issues/4513+--+#if defined(__HADDOCK__) || defined(__HADDOCK_VERSION__)+instance KnownBackend t ds b+#endif
+ src-base/Numeric/DataFrame/Internal/Backend/Family/ArrayBase.hs view
@@ -0,0 +1,587 @@+{-# LANGUAGE ConstraintKinds           #-}+{-# LANGUAGE DataKinds                 #-}+{-# LANGUAGE ExistentialQuantification #-}+{-# LANGUAGE FlexibleContexts          #-}+{-# LANGUAGE FlexibleInstances         #-}+{-# LANGUAGE GADTs                     #-}+{-# LANGUAGE MagicHash                 #-}+{-# LANGUAGE MultiParamTypeClasses     #-}+{-# LANGUAGE PolyKinds                 #-}+{-# LANGUAGE RankNTypes                #-}+{-# LANGUAGE ScopedTypeVariables       #-}+{-# LANGUAGE TypeApplications          #-}+{-# LANGUAGE TypeFamilyDependencies    #-}+{-# LANGUAGE TypeInType                #-}+{-# LANGUAGE TypeOperators             #-}+{-# LANGUAGE UnboxedSums               #-}+{-# LANGUAGE UnboxedTuples             #-}++module Numeric.DataFrame.Internal.Backend.Family.ArrayBase+  ( ArrayBase (..)+  ) where++import           Data.Coerce+import           Data.Int+import           Data.Word+import           GHC.Base                             hiding (foldr)+import           Numeric.DataFrame.Internal.PrimArray+import           Numeric.Dimensions+import           Numeric.PrimBytes+import           Numeric.ProductOrd+import qualified Numeric.ProductOrd.NonTransitive     as NonTransitive+import qualified Numeric.ProductOrd.Partial           as Partial++-- | Generic Array implementation.+--   This array can reside in plain `ByteArray#` and can share the @ByteArray#@+--   with other arrays.+--   However, byte offset in the @ByteArray#@ must be multiple of the element size.+data ArrayBase (t :: Type) (ds :: [Nat])+  = ArrayBase+    (# t --  Same value for each element;+         --  this is the cheapest way to initialize an array.+         --  It is also used for Num instances to avoid dependency on Dimensions.+     | (# Int#  -- Offset in Content array (measured in elements)+        , ByteArray# -- Content;+                     -- elements are stored row-by-row, plane-by-plane;+                     -- (C-style, rather than Fortran-style);+                     -- similar to C, OpenCV, etc.+                     -- The data must be contiguous!+                     -- (i.e. stride must be the same size as the element size).+        , CumulDims  -- Steps array; [Word]+                     -- similar to steps in OpenCV::Mat, but counted in elements+                     --        rather than in bytes.+                     -- e.g. 0th element is the size of the content in elements+                     --      (data must be contiguous)+                     --      1th element is the size of subspace data minus outer dim.+        , Dict (PrimBytes t)+        #)+     #)+++instance (PrimBytes t, Dimensions ds) => PrimBytes (ArrayBase t ds) where+    {-# SPECIALIZE instance Dimensions ds => PrimBytes (ArrayBase Float ds)  #-}+    {-# SPECIALIZE instance Dimensions ds => PrimBytes (ArrayBase Double ds) #-}+    {-# SPECIALIZE instance Dimensions ds => PrimBytes (ArrayBase Int ds)    #-}+    {-# SPECIALIZE instance Dimensions ds => PrimBytes (ArrayBase Word ds)   #-}+    {-# SPECIALIZE instance Dimensions ds => PrimBytes (ArrayBase Int8 ds)   #-}+    {-# SPECIALIZE instance Dimensions ds => PrimBytes (ArrayBase Int16 ds)  #-}+    {-# SPECIALIZE instance Dimensions ds => PrimBytes (ArrayBase Int32 ds)  #-}+    {-# SPECIALIZE instance Dimensions ds => PrimBytes (ArrayBase Int64 ds)  #-}+    {-# SPECIALIZE instance Dimensions ds => PrimBytes (ArrayBase Word8 ds)  #-}+    {-# SPECIALIZE instance Dimensions ds => PrimBytes (ArrayBase Word16 ds) #-}+    {-# SPECIALIZE instance Dimensions ds => PrimBytes (ArrayBase Word32 ds) #-}+    {-# SPECIALIZE instance Dimensions ds => PrimBytes (ArrayBase Word64 ds) #-}++    getBytes (ArrayBase a ) = case a of+        (# t | #)+          | W# nw <- totalDim' @ds+          , n <- word2Int# nw+          , tbs <- byteSize t -> go tbs (tbs *# n) t+        (# | (# _, arr, _, _ #) #) ->+          -- very weird trick with touch# allows to workaround GHC bug+          --  "internal error: ARR_WORDS object entered!"+          -- TODO: report this+          case runRW# (\s -> (# touch# arr s, arr #)) of (# _, ba #) -> ba+      where+        go :: Int# -> Int# -> t -> ByteArray#+        go tbs bsize t = case runRW#+         ( \s0 -> case newByteArray# bsize s0 of+             (# s1, mba #) -> unsafeFreezeByteArray# mba+               ( loop# 0# tbs bsize (\i -> writeBytes mba i t) s1 )+         ) of (# _, ba #) -> ba+        {-# NOINLINE go #-}+    {-# INLINE getBytes #-}++    getBytesPinned (ArrayBase a) = case a of+        (# t | #)+          | W# nw <- totalDim' @ds+          , n <- word2Int# nw+          , tbs <- byteSize t -> go tbs (tbs *# n) t+        (# | (# off, arr, steps, _ #) #) ->+          if isTrue# (isByteArrayPinned# arr)+          then case runRW# (\s -> (# touch# arr s, arr #)) of (# _, ba #) -> ba+          else case runRW#+           ( \s0 -> case (# cdTotalDim# steps+                          , byteSize @t undefined+                          , byteAlign @t undefined+                          #) of+               (# n, tbs, tba #)+                 | bsize <- tbs *# n+                 , (# s1, mba #) <- newAlignedPinnedByteArray# bsize tba s0+                 , s2 <- copyByteArray# arr off mba 0# bsize s1+                   -> unsafeFreezeByteArray# mba s2+           ) of (# _, ba #) -> ba+      where+        go :: Int# -> Int# -> t -> ByteArray#+        go tbs bsize t = case runRW#+         ( \s0 -> case newAlignedPinnedByteArray# bsize (byteAlign t) s0 of+             (# s1, mba #) -> unsafeFreezeByteArray# mba+               ( loop# 0# tbs bsize (\i -> writeBytes mba i t) s1 )+         ) of (# _, ba #) -> ba+        {-# NOINLINE go #-}+    {-# INLINE getBytesPinned #-}+++    fromBytes bOff ba+      | tbs <- byteSize (undefined :: t)+      , (# offN, offRem #) <- quotRemInt# bOff tbs+      = case offRem of+          0# -> ArrayBase (# | (#  offN, ba, steps, Dict #) #)+          _  -> case cdTotalDim# steps of n -> go (tbs *# n)+      where+        steps = cumulDims $ dims @ds+        go bsize = case runRW#+         ( \s0 -> case ( if isTrue# (isByteArrayPinned# ba)+                         then newAlignedPinnedByteArray# bsize+                                (byteAlign @t undefined)+                         else newByteArray# bsize+                       ) s0+                  of+            (# s1, mba #) -> unsafeFreezeByteArray# mba+                              (copyByteArray# ba bOff mba 0# bsize s1)+         ) of (# _, r #) -> ArrayBase (# | (# 0#, r, steps, Dict #) #)+        {-# NOINLINE go #-}+    {-# INLINE fromBytes #-}++    readBytes mba bOff s0+      | steps <- cumulDims $ dims @ds+      , n <- cdTotalDim# steps+      , tbs <- byteSize (undefined :: t)+      , bsize <- tbs *# n+      = case newByteArray# bsize s0 of+         (# s1, mba1 #) -> case unsafeFreezeByteArray# mba1+                                (copyMutableByteArray# mba bOff mba1 0# bsize s1) of+           (# s2, ba #) -> (# s2, ArrayBase (# | (# 0#, ba, steps, Dict #) #) #)+    {-# INLINE readBytes #-}++    writeBytes mba bOff (ArrayBase c)+      | tbs <- byteSize (undefined :: t) = case c of+        (# t | #) | W# n <- totalDim' @ds ->+          loop# bOff tbs (bOff +# word2Int# n *# tbs) (\i -> writeBytes mba i t)+        (# | (# offContent, arrContent, steps, _ #) #)+           | n <- cdTotalDim# steps->+          copyByteArray# arrContent (offContent *# tbs) mba bOff (n *# tbs)+    {-# INLINE writeBytes #-}++    readAddr addr s0+      | steps <- cumulDims $ dims @ds+      , n <- cdTotalDim# steps+      , tbs <- byteSize (undefined :: t)+      , bsize <- tbs *# n+      = case newByteArray# bsize s0 of+         (# s1, mba1 #) -> case unsafeFreezeByteArray# mba1+                                (copyAddrToByteArray# addr mba1 0# bsize s1) of+           (# s2, ba #) -> (# s2, ArrayBase (# | (# 0# , ba, steps, Dict #) #) #)+    {-# INLINE readAddr #-}++    writeAddr (ArrayBase c) addr+      | tbs <- byteSize (undefined :: t) = case c of+        (# t | #) | W# n <- totalDim' @ds ->+          loop# 0# tbs (word2Int# n *# tbs) (\i -> writeAddr t (plusAddr# addr i))+        (# | (# offContent, arrContent, steps, _ #) #)+           | n <- cdTotalDim# steps ->+          copyByteArrayToAddr# arrContent (offContent *# tbs) addr (n *# tbs)+    {-# INLINE writeAddr #-}+++    byteSize  _ = case totalDim' @ds of -- WARNING: slow!+      W# n -> byteSize (undefined :: t) *# word2Int# n+    {-# INLINE byteSize #-}++    byteAlign _ = byteAlign (undefined :: t)+    {-# INLINE byteAlign #-}++    byteOffset (ArrayBase a) = case a of+      (# _ | #)                  -> 0#+      (# | (# off, _, _, _ #) #) -> off *# byteSize (undefined :: t)+    {-# INLINE byteOffset #-}++    byteFieldOffset _ _ = negateInt# 1#+    {-# INLINE byteFieldOffset #-}++    indexArray ba off+      | steps <- cumulDims $ dims @ds+      , n <- cdTotalDim# steps+      = ArrayBase (# | (# off *# n, ba, steps, Dict #) #)+    {-# INLINE indexArray #-}++++-- | Accumulates only idempotent operations!+--   Being applied to FromScalars, executes only once!+--   Here, idempotance means: assuming @f a b = g x@, @g (g x) = g x@+--+--   Also, I assume the sizes of arrays are the same.+--+--   Inside, this function uses foldr; thus, if the combining function is+--   lazy in the second argument, it may avoid some unnecessary work.+accumV2Idempotent :: a+                  -> (t -> t -> a)+                  -> (a -> a -> a)+                  -> ArrayBase t ds -> ArrayBase t ds -> a+accumV2Idempotent x f comb+  (ArrayBase (# a | #))+  (ArrayBase (# b | #))+    = comb x (f a b)+accumV2Idempotent x f comb+  a@(ArrayBase (# | (# _, _, steps, Dict #) #))+  b@(ArrayBase (# | _ #))+    = foldr (comb . (\i -> f (ixOff i a) (ixOff i b))) x+                          [0 .. fromIntegral (cdTotalDim steps) - 1]+accumV2Idempotent x f comb+    (ArrayBase (# a | #))+  b@(ArrayBase (# | (# _, _, steps, Dict #) #))+    = foldr (comb . (\i -> f a (ixOff i b))) x+                          [0 .. fromIntegral (cdTotalDim steps) - 1]+accumV2Idempotent x f comb+  a@(ArrayBase (# | (# _, _, steps, Dict #) #))+    (ArrayBase (# b | #))+    = foldr (comb . (\i -> f (ixOff i a) b)) x+                          [0 .. fromIntegral (cdTotalDim steps) - 1]+{-# INLINE accumV2Idempotent #-}+++mapV :: (t -> t) -> ArrayBase t ds -> ArrayBase t ds+mapV f (ArrayBase (# t | #))+    = ArrayBase (# f t | #)+mapV f x@(ArrayBase (# | (# offN, ba, steps, Dict #) #))+    | tbs <- byteSize (undefEl x)+    , n <- cdTotalDim# steps+    = case runRW#+     ( \s0 -> case newByteArray# (tbs *# n) s0 of+         (# s1, mba #) -> unsafeFreezeByteArray# mba+           ( loop1# n+               (\i -> writeArray mba i (f (indexArray ba (offN +# i)))) s1+           )+     ) of (# _, r #) -> ArrayBase (# | (# 0#, r, steps, Dict #) #)+{-# INLINE mapV #-}+++zipV :: (t -> t -> t)+     -> ArrayBase t ds -> ArrayBase t ds -> ArrayBase t ds+zipV f (ArrayBase (# x | #)) b = mapV (f x) b+zipV f a (ArrayBase (# y | #)) = mapV (`f` y) a+zipV f a@(ArrayBase (# | (# oa, ba, steps, Dict #) #))+         (ArrayBase (# | (# ob, bb, _, _ #) #))+    | n <- cdTotalDim# steps+    = case runRW#+     ( \s0 -> case newByteArray# (byteSize (undefEl a) *# n) s0 of+         (# s1, mba #) -> unsafeFreezeByteArray# mba+           ( loop1# n+               (\i -> writeArray mba i+                        (f (indexArray ba (oa +# i))+                           (indexArray bb (ob +# i))+                        )+               ) s1+           )+     ) of (# _, r #) -> ArrayBase (# | (# 0#, r, steps, Dict #) #)+{-# INLINE zipV #-}+++-- TODO: to improve performance, I can either compare bytearrays using memcmp+--       or implement early termination if the first elements do not match.+--       On the other hand, hopefully @(&&)@ and @(||)@ ops take care of that.+instance Eq t => Eq (ArrayBase t ds) where+    {-# SPECIALIZE instance Eq (ArrayBase Float ds)  #-}+    {-# SPECIALIZE instance Eq (ArrayBase Double ds) #-}+    {-# SPECIALIZE instance Eq (ArrayBase Int ds)    #-}+    {-# SPECIALIZE instance Eq (ArrayBase Word ds)   #-}+    {-# SPECIALIZE instance Eq (ArrayBase Int8 ds)   #-}+    {-# SPECIALIZE instance Eq (ArrayBase Int16 ds)  #-}+    {-# SPECIALIZE instance Eq (ArrayBase Int32 ds)  #-}+    {-# SPECIALIZE instance Eq (ArrayBase Int64 ds)  #-}+    {-# SPECIALIZE instance Eq (ArrayBase Word8 ds)  #-}+    {-# SPECIALIZE instance Eq (ArrayBase Word16 ds) #-}+    {-# SPECIALIZE instance Eq (ArrayBase Word32 ds) #-}+    {-# SPECIALIZE instance Eq (ArrayBase Word64 ds) #-}+    (==) = accumV2Idempotent True (==) (&&)+    (/=) = accumV2Idempotent False (/=) (||)++instance Ord t => ProductOrder (ArrayBase t ds) where+    {-# SPECIALIZE instance ProductOrder (ArrayBase Float ds)  #-}+    {-# SPECIALIZE instance ProductOrder (ArrayBase Double ds) #-}+    {-# SPECIALIZE instance ProductOrder (ArrayBase Int ds)    #-}+    {-# SPECIALIZE instance ProductOrder (ArrayBase Word ds)   #-}+    {-# SPECIALIZE instance ProductOrder (ArrayBase Int8 ds)   #-}+    {-# SPECIALIZE instance ProductOrder (ArrayBase Int16 ds)  #-}+    {-# SPECIALIZE instance ProductOrder (ArrayBase Int32 ds)  #-}+    {-# SPECIALIZE instance ProductOrder (ArrayBase Int64 ds)  #-}+    {-# SPECIALIZE instance ProductOrder (ArrayBase Word8 ds)  #-}+    {-# SPECIALIZE instance ProductOrder (ArrayBase Word16 ds) #-}+    {-# SPECIALIZE instance ProductOrder (ArrayBase Word32 ds) #-}+    {-# SPECIALIZE instance ProductOrder (ArrayBase Word64 ds) #-}+    cmp = accumV2Idempotent PEQ (\x y -> fromOrdering (compare x y)) (<>)+    {-# INLINE cmp #-}++instance Ord t => Ord (NonTransitive.ProductOrd (ArrayBase t ds)) where+    {-# SPECIALIZE instance Ord (NonTransitive.ProductOrd (ArrayBase Float ds))  #-}+    {-# SPECIALIZE instance Ord (NonTransitive.ProductOrd (ArrayBase Double ds)) #-}+    {-# SPECIALIZE instance Ord (NonTransitive.ProductOrd (ArrayBase Int ds))    #-}+    {-# SPECIALIZE instance Ord (NonTransitive.ProductOrd (ArrayBase Word ds))   #-}+    {-# SPECIALIZE instance Ord (NonTransitive.ProductOrd (ArrayBase Int8 ds))   #-}+    {-# SPECIALIZE instance Ord (NonTransitive.ProductOrd (ArrayBase Int16 ds))  #-}+    {-# SPECIALIZE instance Ord (NonTransitive.ProductOrd (ArrayBase Int32 ds))  #-}+    {-# SPECIALIZE instance Ord (NonTransitive.ProductOrd (ArrayBase Int64 ds))  #-}+    {-# SPECIALIZE instance Ord (NonTransitive.ProductOrd (ArrayBase Word8 ds))  #-}+    {-# SPECIALIZE instance Ord (NonTransitive.ProductOrd (ArrayBase Word16 ds)) #-}+    {-# SPECIALIZE instance Ord (NonTransitive.ProductOrd (ArrayBase Word32 ds)) #-}+    {-# SPECIALIZE instance Ord (NonTransitive.ProductOrd (ArrayBase Word64 ds)) #-}+    NonTransitive.ProductOrd x > NonTransitive.ProductOrd y = cmp x y == PGT+    {-# INLINE (>) #-}+    NonTransitive.ProductOrd x < NonTransitive.ProductOrd y = cmp x y == PLT+    {-# INLINE (<) #-}+    (>=) = coerce (accumV2Idempotent True (>=) (&&))+    {-# INLINE (>=) #-}+    (<=) = coerce (accumV2Idempotent True (<=) (&&))+    {-# INLINE (<=) #-}+    compare (NonTransitive.ProductOrd a) (NonTransitive.ProductOrd b)+      = NonTransitive.toOrdering $ cmp a b+    {-# INLINE compare #-}+    min = coerce (zipV min)+    {-# INLINE min #-}+    max = coerce (zipV max)+    {-# INLINE max #-}++instance Ord t => Ord (Partial.ProductOrd (ArrayBase t ds)) where+    {-# SPECIALIZE instance Ord (Partial.ProductOrd (ArrayBase Float ds))  #-}+    {-# SPECIALIZE instance Ord (Partial.ProductOrd (ArrayBase Double ds)) #-}+    {-# SPECIALIZE instance Ord (Partial.ProductOrd (ArrayBase Int ds))    #-}+    {-# SPECIALIZE instance Ord (Partial.ProductOrd (ArrayBase Word ds))   #-}+    {-# SPECIALIZE instance Ord (Partial.ProductOrd (ArrayBase Int8 ds))   #-}+    {-# SPECIALIZE instance Ord (Partial.ProductOrd (ArrayBase Int16 ds))  #-}+    {-# SPECIALIZE instance Ord (Partial.ProductOrd (ArrayBase Int32 ds))  #-}+    {-# SPECIALIZE instance Ord (Partial.ProductOrd (ArrayBase Int64 ds))  #-}+    {-# SPECIALIZE instance Ord (Partial.ProductOrd (ArrayBase Word8 ds))  #-}+    {-# SPECIALIZE instance Ord (Partial.ProductOrd (ArrayBase Word16 ds)) #-}+    {-# SPECIALIZE instance Ord (Partial.ProductOrd (ArrayBase Word32 ds)) #-}+    {-# SPECIALIZE instance Ord (Partial.ProductOrd (ArrayBase Word64 ds)) #-}+    Partial.ProductOrd x > Partial.ProductOrd y = cmp x y == PGT+    {-# INLINE (>) #-}+    Partial.ProductOrd x < Partial.ProductOrd y = cmp x y == PLT+    {-# INLINE (<) #-}+    (>=) = coerce (accumV2Idempotent True (>=) (&&))+    {-# INLINE (>=) #-}+    (<=) = coerce (accumV2Idempotent True (<=) (&&))+    {-# INLINE (<=) #-}+    compare (Partial.ProductOrd a) (Partial.ProductOrd b)+      = Partial.toOrdering $ cmp a b+    {-# INLINE compare #-}+    min = coerce (zipV min)+    {-# INLINE min #-}+    max = coerce (zipV max)+    {-# INLINE max #-}++-- | Lexicographical ordering+instance Ord t => Ord (ArrayBase t ds) where+    {-# SPECIALIZE instance Ord (ArrayBase Float ds)  #-}+    {-# SPECIALIZE instance Ord (ArrayBase Double ds) #-}+    {-# SPECIALIZE instance Ord (ArrayBase Int ds)    #-}+    {-# SPECIALIZE instance Ord (ArrayBase Word ds)   #-}+    {-# SPECIALIZE instance Ord (ArrayBase Int8 ds)   #-}+    {-# SPECIALIZE instance Ord (ArrayBase Int16 ds)  #-}+    {-# SPECIALIZE instance Ord (ArrayBase Int32 ds)  #-}+    {-# SPECIALIZE instance Ord (ArrayBase Int64 ds)  #-}+    {-# SPECIALIZE instance Ord (ArrayBase Word8 ds)  #-}+    {-# SPECIALIZE instance Ord (ArrayBase Word16 ds) #-}+    {-# SPECIALIZE instance Ord (ArrayBase Word32 ds) #-}+    {-# SPECIALIZE instance Ord (ArrayBase Word64 ds) #-}+    compare = accumV2Idempotent EQ compare (<>)+    {-# INLINE compare #-}++instance Bounded t => Bounded (ArrayBase t ds) where+    {-# SPECIALIZE instance Bounded (ArrayBase Int ds)    #-}+    {-# SPECIALIZE instance Bounded (ArrayBase Word ds)   #-}+    {-# SPECIALIZE instance Bounded (ArrayBase Int8 ds)   #-}+    {-# SPECIALIZE instance Bounded (ArrayBase Int16 ds)  #-}+    {-# SPECIALIZE instance Bounded (ArrayBase Int32 ds)  #-}+    {-# SPECIALIZE instance Bounded (ArrayBase Int64 ds)  #-}+    {-# SPECIALIZE instance Bounded (ArrayBase Word8 ds)  #-}+    {-# SPECIALIZE instance Bounded (ArrayBase Word16 ds) #-}+    {-# SPECIALIZE instance Bounded (ArrayBase Word32 ds) #-}+    {-# SPECIALIZE instance Bounded (ArrayBase Word64 ds) #-}+    maxBound = ArrayBase (# maxBound | #)+    minBound = ArrayBase (# minBound | #)++instance Num t => Num (ArrayBase t ds)  where+    {-# SPECIALIZE instance Num (ArrayBase Float ds)  #-}+    {-# SPECIALIZE instance Num (ArrayBase Double ds) #-}+    {-# SPECIALIZE instance Num (ArrayBase Int ds)    #-}+    {-# SPECIALIZE instance Num (ArrayBase Word ds)   #-}+    {-# SPECIALIZE instance Num (ArrayBase Int8 ds)   #-}+    {-# SPECIALIZE instance Num (ArrayBase Int16 ds)  #-}+    {-# SPECIALIZE instance Num (ArrayBase Int32 ds)  #-}+    {-# SPECIALIZE instance Num (ArrayBase Int64 ds)  #-}+    {-# SPECIALIZE instance Num (ArrayBase Word8 ds)  #-}+    {-# SPECIALIZE instance Num (ArrayBase Word16 ds) #-}+    {-# SPECIALIZE instance Num (ArrayBase Word32 ds) #-}+    {-# SPECIALIZE instance Num (ArrayBase Word64 ds) #-}+    (+) = zipV (+)+    {-# INLINE (+) #-}+    (-) = zipV (-)+    {-# INLINE (-) #-}+    (*) = zipV (*)+    {-# INLINE (*) #-}+    negate = mapV negate+    {-# INLINE negate #-}+    abs = mapV abs+    {-# INLINE abs #-}+    signum = mapV signum+    {-# INLINE signum #-}+    fromInteger i = ArrayBase (# fromInteger i | #)+    {-# INLINE fromInteger #-}++instance Fractional t => Fractional (ArrayBase t ds)  where+    {-# SPECIALIZE instance Fractional (ArrayBase Float ds)  #-}+    {-# SPECIALIZE instance Fractional (ArrayBase Double ds) #-}+    (/) = zipV (/)+    {-# INLINE (/) #-}+    recip = mapV recip+    {-# INLINE recip #-}+    fromRational r = ArrayBase (# fromRational r | #)+    {-# INLINE fromRational #-}+++instance Floating t => Floating (ArrayBase t ds) where+    {-# SPECIALIZE instance Floating (ArrayBase Float ds)  #-}+    {-# SPECIALIZE instance Floating (ArrayBase Double ds) #-}+    pi = ArrayBase (# pi | #)+    {-# INLINE pi #-}+    exp = mapV exp+    {-# INLINE exp #-}+    log = mapV log+    {-# INLINE log #-}+    sqrt = mapV sqrt+    {-# INLINE sqrt #-}+    sin = mapV sin+    {-# INLINE sin #-}+    cos = mapV cos+    {-# INLINE cos #-}+    tan = mapV tan+    {-# INLINE tan #-}+    asin = mapV asin+    {-# INLINE asin #-}+    acos = mapV acos+    {-# INLINE acos #-}+    atan = mapV atan+    {-# INLINE atan #-}+    sinh = mapV sinh+    {-# INLINE sinh #-}+    cosh = mapV cosh+    {-# INLINE cosh #-}+    tanh = mapV tanh+    {-# INLINE tanh #-}+    (**) = zipV (**)+    {-# INLINE (**) #-}+    logBase = zipV logBase+    {-# INLINE logBase #-}+    asinh = mapV asinh+    {-# INLINE asinh #-}+    acosh = mapV acosh+    {-# INLINE acosh #-}+    atanh = mapV atanh+    {-# INLINE atanh #-}++instance PrimBytes t => PrimArray t (ArrayBase t ds) where+    {-# SPECIALIZE instance PrimArray Float  (ArrayBase Float ds)  #-}+    {-# SPECIALIZE instance PrimArray Double (ArrayBase Double ds) #-}+    {-# SPECIALIZE instance PrimArray Int    (ArrayBase Int ds)    #-}+    {-# SPECIALIZE instance PrimArray Word   (ArrayBase Word ds)   #-}+    {-# SPECIALIZE instance PrimArray Int8   (ArrayBase Int8 ds)   #-}+    {-# SPECIALIZE instance PrimArray Int16  (ArrayBase Int16 ds)  #-}+    {-# SPECIALIZE instance PrimArray Int32  (ArrayBase Int32 ds)  #-}+    {-# SPECIALIZE instance PrimArray Int64  (ArrayBase Int64 ds)  #-}+    {-# SPECIALIZE instance PrimArray Word8  (ArrayBase Word8 ds)  #-}+    {-# SPECIALIZE instance PrimArray Word16 (ArrayBase Word16 ds) #-}+    {-# SPECIALIZE instance PrimArray Word32 (ArrayBase Word32 ds) #-}+    {-# SPECIALIZE instance PrimArray Word64 (ArrayBase Word64 ds) #-}++    broadcast t = ArrayBase (# t | #)+    {-# INLINE broadcast #-}++    ix# i (ArrayBase a) = case a of+      (# t | #)                    -> t+      (# | (# off, arr, _, _ #) #) -> indexArray arr (off +# i)+    {-# INLINE ix# #-}++    gen# steps f z0 = go (byteSize @t undefined *# n)+      where+        n = cdTotalDim# steps+        go bsize = case runRW#+         ( \s0 -> case newByteArray# bsize s0 of+             (# s1, mba #) -> case loop0 mba 0# z0 s1 of+               (# s2, z1 #) -> case unsafeFreezeByteArray# mba s2 of+                 (# s3, ba #) -> (# s3, (# z1, ba #) #)+         ) of (# _, (# z1, ba #) #)+                   -> (# z1, ArrayBase (# | (# 0# , ba, steps, Dict #) #) #)+        {-# NOINLINE go #-}+        loop0 mba i z s+          | isTrue# (i ==# n) = (# s, z #)+          | otherwise = case f z of+              (# z', x #) -> loop0 mba (i +# 1#) z' (writeArray mba i x s)+    {-# INLINE gen# #-}++    upd# steps i x (ArrayBase (# a | #)) = go (byteSize x)+      where+        n = cdTotalDim# steps+        go tbs = case runRW#+         ( \s0 -> case newByteArray# (tbs *# n) s0 of+             (# s1, mba #) -> unsafeFreezeByteArray# mba+               (writeArray mba i x+                 (loop1# n (\j -> writeArray mba j a) s1)+               )+         ) of (# _, r #) -> ArrayBase (# |  (# 0# , r, steps, Dict #) #)+        {-# NOINLINE go #-}+    upd# _ i x (ArrayBase (# | (# offN, ba, steps, Dict #) #))+        = go (byteSize x)+      where+        n = cdTotalDim# steps+        go tbs = case runRW#+         ( \s0 -> case newByteArray# (tbs *# n) s0 of+             (# s1, mba #) -> unsafeFreezeByteArray# mba+               (writeArray mba i x+                 (copyByteArray# ba (offN *# tbs) mba 0# (tbs *# n) s1)+               )+         ) of (# _, r #) -> ArrayBase (# | (# 0#, r, steps, Dict #) #)+        {-# NOINLINE go #-}+    {-# INLINE upd# #-}++    arrayContent# (ArrayBase a) = case a of+      (# x | #)                     -> (# x | #)+      (# | (# off, arr, cd, _ #) #) -> (# | (# cd, off, arr #) #)+    {-# INLINE arrayContent# #-}++    offsetElems (ArrayBase a) = case a of+      (# _ | #)                  -> 0#+      (# | (# off, _, _, _ #) #) -> off+    {-# INLINE offsetElems #-}++    uniqueOrCumulDims (ArrayBase a) = case a of+      (# t | #)                    -> Left t+      (# | (# _, _, steps, _ #) #) -> Right steps+    {-# INLINE uniqueOrCumulDims #-}++    fromElems steps off ba = ArrayBase (# | (# off, ba, steps, Dict #) #)+    {-# INLINE fromElems #-}+++loop# :: Int# -- ^ initial value+      -> Int# -- ^ step+      -> Int# -- ^ final value (LESS THAN condition)+      -> (Int# -> State# s -> State# s) -> State# s -> State# s+loop# n0 di n1 f = loop0 n0+  where+    loop0 i s | isTrue# (i >=# n1) = s+              | otherwise = loop0 (i +# di) (f i s)+{-# INLINE loop# #-}+++-- | Do something in a loop for int i from 0 to (n-1)+loop1# :: Int# -> (Int# -> State# s -> State# s) -> State# s -> State# s+loop1# n f = loop0 0#+  where+    loop0 i s | isTrue# (i ==# n) = s+              | otherwise = loop0 (i +# 1#) (f i s)+{-# INLINE loop1# #-}++undefEl :: ArrayBase t ds -> t+undefEl = const undefined
+ src-base/Numeric/DataFrame/Internal/Backend/Family/DoubleX2.hs view
@@ -0,0 +1,401 @@+{-# LANGUAGE CPP                   #-}+{-# LANGUAGE FlexibleContexts      #-}+{-# LANGUAGE FlexibleInstances     #-}+{-# LANGUAGE MagicHash             #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE TypeApplications      #-}+{-# LANGUAGE UnboxedSums           #-}+{-# LANGUAGE UnboxedTuples         #-}+{-# LANGUAGE UndecidableInstances  #-}+module Numeric.DataFrame.Internal.Backend.Family.DoubleX2 (DoubleX2 (..)) where+++import           GHC.Base+import           Numeric.DataFrame.Internal.PrimArray+import           Numeric.PrimBytes+import           Numeric.ProductOrd+import qualified Numeric.ProductOrd.NonTransitive     as NonTransitive+import qualified Numeric.ProductOrd.Partial           as Partial+++data DoubleX2 = DoubleX2# Double# Double#++-- | Since @Bounded@ is not implemented for floating point types, this instance+--   has an unresolvable constraint.+--   Nevetheless, it is good to have it here for nicer error messages.+instance Bounded Double => Bounded DoubleX2 where+    maxBound = case maxBound of D# x -> DoubleX2# x x+    minBound = case minBound of D# x -> DoubleX2# x x+++instance Eq DoubleX2 where++    DoubleX2# a1 a2 == DoubleX2# b1 b2 =+      isTrue#+      (       (a1 ==## b1)+      `andI#` (a2 ==## b2)+      )+    {-# INLINE (==) #-}++    DoubleX2# a1 a2 /= DoubleX2# b1 b2 =+      isTrue#+      (      (a1 /=## b1)+      `orI#` (a2 /=## b2)+      )+    {-# INLINE (/=) #-}++++cmp' :: Double# -> Double# -> PartialOrdering+cmp' a b+  | isTrue# (a >## b) = PGT+  | isTrue# (a <## b) = PLT+  | otherwise  = PEQ++instance ProductOrder DoubleX2 where+    cmp (DoubleX2# a1 a2) (DoubleX2# b1 b2)+      = cmp' a1 b1 <> cmp' a2 b2+    {-# INLINE cmp #-}++instance Ord (NonTransitive.ProductOrd DoubleX2) where+    NonTransitive.ProductOrd x > NonTransitive.ProductOrd y = cmp x y == PGT+    {-# INLINE (>) #-}+    NonTransitive.ProductOrd x < NonTransitive.ProductOrd y = cmp x y == PLT+    {-# INLINE (<) #-}+    (>=) (NonTransitive.ProductOrd (DoubleX2# a1 a2))+         (NonTransitive.ProductOrd (DoubleX2# b1 b2)) = isTrue#+      ((a1 >=## b1) `andI#` (a2 >=## b2))+    {-# INLINE (>=) #-}+    (<=) (NonTransitive.ProductOrd (DoubleX2# a1 a2))+         (NonTransitive.ProductOrd (DoubleX2# b1 b2)) = isTrue#+      ((a1 <=## b1) `andI#` (a2 <=## b2))+    {-# INLINE (<=) #-}+    compare (NonTransitive.ProductOrd a) (NonTransitive.ProductOrd b)+      = NonTransitive.toOrdering $ cmp a b+    {-# INLINE compare #-}+    min (NonTransitive.ProductOrd (DoubleX2# a1 a2))+        (NonTransitive.ProductOrd (DoubleX2# b1 b2))+      = NonTransitive.ProductOrd+        ( DoubleX2#+          (if isTrue# (a1 >## b1) then b1 else a1)+          (if isTrue# (a2 >## b2) then b2 else a2)+        )+    {-# INLINE min #-}+    max (NonTransitive.ProductOrd (DoubleX2# a1 a2))+        (NonTransitive.ProductOrd (DoubleX2# b1 b2))+      = NonTransitive.ProductOrd+        ( DoubleX2#+          (if isTrue# (a1 <## b1) then b1 else a1)+          (if isTrue# (a2 <## b2) then b2 else a2)+        )+    {-# INLINE max #-}++instance Ord (Partial.ProductOrd DoubleX2) where+    Partial.ProductOrd x > Partial.ProductOrd y = cmp x y == PGT+    {-# INLINE (>) #-}+    Partial.ProductOrd x < Partial.ProductOrd y = cmp x y == PLT+    {-# INLINE (<) #-}+    (>=) (Partial.ProductOrd (DoubleX2# a1 a2))+         (Partial.ProductOrd (DoubleX2# b1 b2)) = isTrue#+      ((a1 >=## b1) `andI#` (a2 >=## b2))+    {-# INLINE (>=) #-}+    (<=) (Partial.ProductOrd (DoubleX2# a1 a2))+         (Partial.ProductOrd (DoubleX2# b1 b2)) = isTrue#+      ((a1 <=## b1) `andI#` (a2 <=## b2))+    {-# INLINE (<=) #-}+    compare (Partial.ProductOrd a) (Partial.ProductOrd b)+      = Partial.toOrdering $ cmp a b+    {-# INLINE compare #-}+    min (Partial.ProductOrd (DoubleX2# a1 a2))+        (Partial.ProductOrd (DoubleX2# b1 b2))+      = Partial.ProductOrd+        ( DoubleX2#+          (if isTrue# (a1 >## b1) then b1 else a1)+          (if isTrue# (a2 >## b2) then b2 else a2)+        )+    {-# INLINE min #-}+    max (Partial.ProductOrd (DoubleX2# a1 a2))+        (Partial.ProductOrd (DoubleX2# b1 b2))+      = Partial.ProductOrd+        ( DoubleX2#+          (if isTrue# (a1 <## b1) then b1 else a1)+          (if isTrue# (a2 <## b2) then b2 else a2)+        )+    {-# INLINE max #-}++instance Ord DoubleX2 where+    DoubleX2# a1 a2 > DoubleX2# b1 b2+      | isTrue# (a1 >## b1) = True+      | isTrue# (a1 <## b1) = False+      | isTrue# (a2 >## b2) = True+      | otherwise           = False+    {-# INLINE (>) #-}++    DoubleX2# a1 a2 < DoubleX2# b1 b2+      | isTrue# (a1 <## b1) = True+      | isTrue# (a1 >## b1) = False+      | isTrue# (a2 <## b2) = True+      | otherwise           = False+    {-# INLINE (<) #-}++    DoubleX2# a1 a2 >= DoubleX2# b1 b2+      | isTrue# (a1 <## b1) = False+      | isTrue# (a1 >## b1) = True+      | isTrue# (a2 <## b2) = False+      | otherwise           = True+    {-# INLINE (>=) #-}++    DoubleX2# a1 a2 <= DoubleX2# b1 b2+      | isTrue# (a1 >## b1) = False+      | isTrue# (a1 <## b1) = True+      | isTrue# (a2 >## b2) = False+      | otherwise           = True+    {-# INLINE (<=) #-}++    compare (DoubleX2# a1 a2) (DoubleX2# b1 b2)+      | isTrue# (a1 >## b1) = GT+      | isTrue# (a1 <## b1) = LT+      | isTrue# (a2 >## b2) = GT+      | isTrue# (a2 <## b2) = LT+      | otherwise           = EQ+    {-# INLINE compare #-}++++-- | element-wise operations for vectors+instance Num DoubleX2 where++    DoubleX2# a1 a2 + DoubleX2# b1 b2+      = DoubleX2# ((+##) a1 b1) ((+##) a2 b2)+    {-# INLINE (+) #-}++    DoubleX2# a1 a2 - DoubleX2# b1 b2+      = DoubleX2# ((-##) a1 b1) ((-##) a2 b2)+    {-# INLINE (-) #-}++    DoubleX2# a1 a2 * DoubleX2# b1 b2+      = DoubleX2# ((*##) a1 b1) ((*##) a2 b2)+    {-# INLINE (*) #-}++    negate (DoubleX2# a1 a2) = DoubleX2#+      (negateDouble# a1) (negateDouble# a2)+    {-# INLINE negate #-}++    abs (DoubleX2# a1 a2)+      = DoubleX2#+      (if isTrue# (a1 >=## 0.0##) then a1 else negateDouble# a1)+      (if isTrue# (a2 >=## 0.0##) then a2 else negateDouble# a2)+    {-# INLINE abs #-}++    signum (DoubleX2# a1 a2)+      = DoubleX2# (if isTrue# (a1 >## 0.0##)+                  then 1.0##+                  else if isTrue# (a1 <## 0.0##) then -1.0## else 0.0## )+                 (if isTrue# (a2 >## 0.0##)+                  then 1.0##+                  else if isTrue# (a2 <## 0.0##) then -1.0## else 0.0## )+    {-# INLINE signum #-}++    fromInteger n = case fromInteger n of D# x -> DoubleX2# x x+    {-# INLINE fromInteger #-}++++instance Fractional DoubleX2 where++    DoubleX2# a1 a2 / DoubleX2# b1 b2 = DoubleX2#+      ((/##) a1 b1) ((/##) a2 b2)+    {-# INLINE (/) #-}++    recip (DoubleX2# a1 a2) = DoubleX2#+      ((/##) 1.0## a1) ((/##) 1.0## a2)+    {-# INLINE recip #-}++    fromRational r = case fromRational r of D# x -> DoubleX2# x x+    {-# INLINE fromRational #-}++++instance Floating DoubleX2 where++    pi = DoubleX2#+      3.141592653589793238##+      3.141592653589793238##+    {-# INLINE pi #-}++    exp (DoubleX2# a1 a2) = DoubleX2#+      (expDouble# a1) (expDouble# a2)+    {-# INLINE exp #-}++    log (DoubleX2# a1 a2) = DoubleX2#+      (logDouble# a1) (logDouble# a2)+    {-# INLINE log #-}++    sqrt (DoubleX2# a1 a2) = DoubleX2#+      (sqrtDouble# a1) (sqrtDouble# a2)+    {-# INLINE sqrt #-}++    sin (DoubleX2# a1 a2) = DoubleX2#+      (sinDouble# a1) (sinDouble# a2)+    {-# INLINE sin #-}++    cos (DoubleX2# a1 a2) = DoubleX2#+      (cosDouble# a1) (cosDouble# a2)+    {-# INLINE cos #-}++    tan (DoubleX2# a1 a2) = DoubleX2#+      (tanDouble# a1) (tanDouble# a2)+    {-# INLINE tan #-}++    asin (DoubleX2# a1 a2) = DoubleX2#+      (asinDouble# a1) (asinDouble# a2)+    {-# INLINE asin #-}++    acos (DoubleX2# a1 a2) = DoubleX2#+      (acosDouble# a1) (acosDouble# a2)+    {-# INLINE acos #-}++    atan (DoubleX2# a1 a2) = DoubleX2#+      (atanDouble# a1) (atanDouble# a2)+    {-# INLINE atan #-}++    sinh (DoubleX2# a1 a2) = DoubleX2#+      (sinhDouble# a1) (sinhDouble# a2)+    {-# INLINE sinh #-}++    cosh (DoubleX2# a1 a2) = DoubleX2#+      (coshDouble# a1) (coshDouble# a2)+    {-# INLINE cosh #-}++    tanh (DoubleX2# a1 a2) = DoubleX2#+      (tanhDouble# a1) (tanhDouble# a2)+    {-# INLINE tanh #-}++    DoubleX2# a1 a2 ** DoubleX2# b1 b2 = DoubleX2#+      ((**##) a1 b1) ((**##) a2 b2)+    {-# INLINE (**) #-}++    logBase x y         =  log y / log x+    {-# INLINE logBase #-}++    asinh x = log (x + sqrt (1.0+x*x))+    {-# INLINE asinh #-}++    acosh x = log (x + (x+1.0) * sqrt ((x-1.0)/(x+1.0)))+    {-# INLINE acosh #-}++    atanh x = 0.5 * log ((1.0+x) / (1.0-x))+    {-# INLINE atanh #-}++-- offset in bytes is S times bigger than offset in prim elements,+-- when S is power of two, this is equal to shift+#define BOFF_TO_PRIMOFF(off) uncheckedIShiftRL# off 3#+#define ELEM_N 2++instance PrimBytes DoubleX2 where++    getBytes (DoubleX2# a1 a2) = case runRW#+       ( \s0 -> case newByteArray# (byteSize @DoubleX2 undefined) s0 of+           (# s1, marr #) -> case writeDoubleArray# marr 0# a1 s1 of+             s2 -> case writeDoubleArray# marr 1# a2 s2 of+               s3 -> unsafeFreezeByteArray# marr s3+       ) of (# _, a #) -> a+    {-# INLINE getBytes #-}++    fromBytes off arr+      | i <- BOFF_TO_PRIMOFF(off)+      = DoubleX2#+      (indexDoubleArray# arr i)+      (indexDoubleArray# arr (i +# 1#))+    {-# INLINE fromBytes #-}++    readBytes mba off s0+      | i <- BOFF_TO_PRIMOFF(off)+      = case readDoubleArray# mba i s0 of+      (# s1, a1 #) -> case readDoubleArray# mba (i +# 1#) s1 of+        (# s2, a2 #) -> (# s2, DoubleX2# a1 a2 #)+    {-# INLINE readBytes #-}++    writeBytes mba off (DoubleX2# a1 a2) s+      | i <- BOFF_TO_PRIMOFF(off)+      = writeDoubleArray# mba (i +# 1#) a2+      ( writeDoubleArray# mba  i        a1 s )+    {-# INLINE writeBytes #-}++    readAddr addr s0+      = case readDoubleOffAddr# addr 0# s0 of+      (# s1, a1 #) -> case readDoubleOffAddr# addr 1# s1 of+        (# s2, a2 #) -> (# s2, DoubleX2# a1 a2 #)+    {-# INLINE readAddr #-}++    writeAddr (DoubleX2# a1 a2) addr s+      = writeDoubleOffAddr# addr 1# a2+      ( writeDoubleOffAddr# addr 0# a1 s )+    {-# INLINE writeAddr #-}++    byteSize _ = byteSize @Double undefined *# ELEM_N#+    {-# INLINE byteSize #-}++    byteAlign _ = byteAlign @Double undefined+    {-# INLINE byteAlign #-}++    byteOffset _ = 0#+    {-# INLINE byteOffset #-}++    byteFieldOffset _ _ = negateInt# 1#+    {-# INLINE byteFieldOffset #-}++    indexArray ba off+      | i <- off *# ELEM_N#+      = DoubleX2#+      (indexDoubleArray# ba i)+      (indexDoubleArray# ba (i +# 1#))+    {-# INLINE indexArray #-}++    readArray mba off s0+      | i <- off *# ELEM_N#+      = case readDoubleArray# mba i s0 of+      (# s1, a1 #) -> case readDoubleArray# mba (i +# 1#) s1 of+        (# s2, a2 #) -> (# s2, DoubleX2# a1 a2 #)+    {-# INLINE readArray #-}++    writeArray mba off (DoubleX2# a1 a2) s+      | i <- off *# ELEM_N#+      = writeDoubleArray# mba (i +# 1#) a2+      ( writeDoubleArray# mba  i        a1 s )+    {-# INLINE writeArray #-}+++instance PrimArray Double DoubleX2 where++    broadcast (D# x) = DoubleX2# x x+    {-# INLINE broadcast #-}++    ix# 0# (DoubleX2# a1 _) = D# a1+    ix# 1# (DoubleX2# _ a2) = D# a2+    ix# _   _               = undefined+    {-# INLINE ix# #-}++    gen# _ f s0 = case f s0 of+      (# s1, D# a1 #) -> case f s1 of+        (# s2, D# a2 #) -> (# s2, DoubleX2# a1 a2 #)+++    upd# _ 0# (D# q) (DoubleX2# _ y) = DoubleX2# q y+    upd# _ 1# (D# q) (DoubleX2# x _) = DoubleX2# x q+    upd# _ _ _ x                     = x+    {-# INLINE upd# #-}++    arrayContent# x = (# | (# CumulDims [ELEM_N, 1], 0#, getBytes x #) #)+    {-# INLINE arrayContent# #-}++    offsetElems _ = 0#+    {-# INLINE offsetElems #-}++    uniqueOrCumulDims _ = Right (CumulDims [ELEM_N, 1])+    {-# INLINE uniqueOrCumulDims #-}++    fromElems _ off ba = DoubleX2#+      (indexDoubleArray# ba off)+      (indexDoubleArray# ba (off +# 1#))+    {-# INLINE fromElems #-}
+ src-base/Numeric/DataFrame/Internal/Backend/Family/DoubleX3.hs view
@@ -0,0 +1,436 @@+{-# LANGUAGE CPP                   #-}+{-# LANGUAGE FlexibleContexts      #-}+{-# LANGUAGE FlexibleInstances     #-}+{-# LANGUAGE MagicHash             #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE TypeApplications      #-}+{-# LANGUAGE UnboxedSums           #-}+{-# LANGUAGE UnboxedTuples         #-}+{-# LANGUAGE UndecidableInstances  #-}+module Numeric.DataFrame.Internal.Backend.Family.DoubleX3 (DoubleX3 (..)) where+++import           GHC.Base+import           Numeric.DataFrame.Internal.PrimArray+import           Numeric.PrimBytes+import           Numeric.ProductOrd+import qualified Numeric.ProductOrd.NonTransitive     as NonTransitive+import qualified Numeric.ProductOrd.Partial           as Partial+++data DoubleX3 = DoubleX3# Double# Double# Double#++-- | Since @Bounded@ is not implemented for floating point types, this instance+--   has an unresolvable constraint.+--   Nevetheless, it is good to have it here for nicer error messages.+instance Bounded Double => Bounded DoubleX3 where+    maxBound = case maxBound of D# x -> DoubleX3# x x x+    minBound = case minBound of D# x -> DoubleX3# x x x+++instance Eq DoubleX3 where++    DoubleX3# a1 a2 a3 == DoubleX3# b1 b2 b3 =+      isTrue#+      (       (a1 ==## b1)+      `andI#` (a2 ==## b2)+      `andI#` (a3 ==## b3)+      )+    {-# INLINE (==) #-}++    DoubleX3# a1 a2 a3 /= DoubleX3# b1 b2 b3 =+      isTrue#+      (      (a1 /=## b1)+      `orI#` (a2 /=## b2)+      `orI#` (a3 /=## b3)+      )+    {-# INLINE (/=) #-}++++cmp' :: Double# -> Double# -> PartialOrdering+cmp' a b+  | isTrue# (a >## b) = PGT+  | isTrue# (a <## b) = PLT+  | otherwise  = PEQ++instance ProductOrder DoubleX3 where+    cmp (DoubleX3# a1 a2 a3) (DoubleX3# b1 b2 b3)+      = cmp' a1 b1 <> cmp' a2 b2 <> cmp' a3 b3+    {-# INLINE cmp #-}++instance Ord (NonTransitive.ProductOrd DoubleX3) where+    NonTransitive.ProductOrd x > NonTransitive.ProductOrd y = cmp x y == PGT+    {-# INLINE (>) #-}+    NonTransitive.ProductOrd x < NonTransitive.ProductOrd y = cmp x y == PLT+    {-# INLINE (<) #-}+    (>=) (NonTransitive.ProductOrd (DoubleX3# a1 a2 a3))+         (NonTransitive.ProductOrd (DoubleX3# b1 b2 b3)) = isTrue#+      ((a1 >=## b1) `andI#` (a2 >=## b2) `andI#` (a3 >=## b3))+    {-# INLINE (>=) #-}+    (<=) (NonTransitive.ProductOrd (DoubleX3# a1 a2 a3))+         (NonTransitive.ProductOrd (DoubleX3# b1 b2 b3)) = isTrue#+      ((a1 <=## b1) `andI#` (a2 <=## b2) `andI#` (a3 <=## b3))+    {-# INLINE (<=) #-}+    compare (NonTransitive.ProductOrd a) (NonTransitive.ProductOrd b)+      = NonTransitive.toOrdering $ cmp a b+    {-# INLINE compare #-}+    min (NonTransitive.ProductOrd (DoubleX3# a1 a2 a3))+        (NonTransitive.ProductOrd (DoubleX3# b1 b2 b3))+      = NonTransitive.ProductOrd+        ( DoubleX3#+          (if isTrue# (a1 >## b1) then b1 else a1)+          (if isTrue# (a2 >## b2) then b2 else a2)+          (if isTrue# (a3 >## b3) then b3 else a3)+        )+    {-# INLINE min #-}+    max (NonTransitive.ProductOrd (DoubleX3# a1 a2 a3))+        (NonTransitive.ProductOrd (DoubleX3# b1 b2 b3))+      = NonTransitive.ProductOrd+        ( DoubleX3#+          (if isTrue# (a1 <## b1) then b1 else a1)+          (if isTrue# (a2 <## b2) then b2 else a2)+          (if isTrue# (a3 <## b3) then b3 else a3)+        )+    {-# INLINE max #-}++instance Ord (Partial.ProductOrd DoubleX3) where+    Partial.ProductOrd x > Partial.ProductOrd y = cmp x y == PGT+    {-# INLINE (>) #-}+    Partial.ProductOrd x < Partial.ProductOrd y = cmp x y == PLT+    {-# INLINE (<) #-}+    (>=) (Partial.ProductOrd (DoubleX3# a1 a2 a3))+         (Partial.ProductOrd (DoubleX3# b1 b2 b3)) = isTrue#+      ((a1 >=## b1) `andI#` (a2 >=## b2) `andI#` (a3 >=## b3))+    {-# INLINE (>=) #-}+    (<=) (Partial.ProductOrd (DoubleX3# a1 a2 a3))+         (Partial.ProductOrd (DoubleX3# b1 b2 b3)) = isTrue#+      ((a1 <=## b1) `andI#` (a2 <=## b2) `andI#` (a3 <=## b3))+    {-# INLINE (<=) #-}+    compare (Partial.ProductOrd a) (Partial.ProductOrd b)+      = Partial.toOrdering $ cmp a b+    {-# INLINE compare #-}+    min (Partial.ProductOrd (DoubleX3# a1 a2 a3))+        (Partial.ProductOrd (DoubleX3# b1 b2 b3))+      = Partial.ProductOrd+        ( DoubleX3#+          (if isTrue# (a1 >## b1) then b1 else a1)+          (if isTrue# (a2 >## b2) then b2 else a2)+          (if isTrue# (a3 >## b3) then b3 else a3)+        )+    {-# INLINE min #-}+    max (Partial.ProductOrd (DoubleX3# a1 a2 a3))+        (Partial.ProductOrd (DoubleX3# b1 b2 b3))+      = Partial.ProductOrd+        ( DoubleX3#+          (if isTrue# (a1 <## b1) then b1 else a1)+          (if isTrue# (a2 <## b2) then b2 else a2)+          (if isTrue# (a3 <## b3) then b3 else a3)+        )+    {-# INLINE max #-}++instance Ord DoubleX3 where+    DoubleX3# a1 a2 a3 > DoubleX3# b1 b2 b3+      | isTrue# (a1 >## b1) = True+      | isTrue# (a1 <## b1) = False+      | isTrue# (a2 >## b2) = True+      | isTrue# (a2 <## b2) = False+      | isTrue# (a3 >## b3) = True+      | otherwise           = False+    {-# INLINE (>) #-}++    DoubleX3# a1 a2 a3 < DoubleX3# b1 b2 b3+      | isTrue# (a1 <## b1) = True+      | isTrue# (a1 >## b1) = False+      | isTrue# (a2 <## b2) = True+      | isTrue# (a2 >## b2) = False+      | isTrue# (a3 <## b3) = True+      | otherwise           = False+    {-# INLINE (<) #-}++    DoubleX3# a1 a2 a3 >= DoubleX3# b1 b2 b3+      | isTrue# (a1 <## b1) = False+      | isTrue# (a1 >## b1) = True+      | isTrue# (a2 <## b2) = False+      | isTrue# (a2 >## b2) = True+      | isTrue# (a3 <## b3) = False+      | otherwise           = True+    {-# INLINE (>=) #-}++    DoubleX3# a1 a2 a3 <= DoubleX3# b1 b2 b3+      | isTrue# (a1 >## b1) = False+      | isTrue# (a1 <## b1) = True+      | isTrue# (a2 >## b2) = False+      | isTrue# (a2 <## b2) = True+      | isTrue# (a3 >## b3) = False+      | otherwise           = True+    {-# INLINE (<=) #-}++    compare (DoubleX3# a1 a2 a3) (DoubleX3# b1 b2 b3)+      | isTrue# (a1 >## b1) = GT+      | isTrue# (a1 <## b1) = LT+      | isTrue# (a2 >## b2) = GT+      | isTrue# (a2 <## b2) = LT+      | isTrue# (a3 >## b3) = GT+      | isTrue# (a3 <## b3) = LT+      | otherwise           = EQ+    {-# INLINE compare #-}+++++-- | element-wise operations for vectors+instance Num DoubleX3 where++    DoubleX3# a1 a2 a3 + DoubleX3# b1 b2 b3+      = DoubleX3# ((+##) a1 b1) ((+##) a2 b2) ((+##) a3 b3)+    {-# INLINE (+) #-}++    DoubleX3# a1 a2 a3 - DoubleX3# b1 b2 b3+      = DoubleX3# ((-##) a1 b1) ((-##) a2 b2) ((-##) a3 b3)+    {-# INLINE (-) #-}++    DoubleX3# a1 a2 a3 * DoubleX3# b1 b2 b3+      = DoubleX3# ((*##) a1 b1) ((*##) a2 b2) ((*##) a3 b3)+    {-# INLINE (*) #-}++    negate (DoubleX3# a1 a2 a3) = DoubleX3#+      (negateDouble# a1) (negateDouble# a2) (negateDouble# a3)+    {-# INLINE negate #-}++    abs (DoubleX3# a1 a2 a3)+      = DoubleX3#+      (if isTrue# (a1 >=## 0.0##) then a1 else negateDouble# a1)+      (if isTrue# (a2 >=## 0.0##) then a2 else negateDouble# a2)+      (if isTrue# (a3 >=## 0.0##) then a3 else negateDouble# a3)+    {-# INLINE abs #-}++    signum (DoubleX3# a1 a2 a3)+      = DoubleX3# (if isTrue# (a1 >## 0.0##)+                  then 1.0##+                  else if isTrue# (a1 <## 0.0##) then -1.0## else 0.0## )+                 (if isTrue# (a2 >## 0.0##)+                  then 1.0##+                  else if isTrue# (a2 <## 0.0##) then -1.0## else 0.0## )+                 (if isTrue# (a3 >## 0.0##)+                  then 1.0##+                  else if isTrue# (a3 <## 0.0##) then -1.0## else 0.0## )+    {-# INLINE signum #-}++    fromInteger n = case fromInteger n of D# x -> DoubleX3# x x x+    {-# INLINE fromInteger #-}++++instance Fractional DoubleX3 where++    DoubleX3# a1 a2 a3 / DoubleX3# b1 b2 b3 = DoubleX3#+      ((/##) a1 b1) ((/##) a2 b2) ((/##) a3 b3)+    {-# INLINE (/) #-}++    recip (DoubleX3# a1 a2 a3) = DoubleX3#+      ((/##) 1.0## a1) ((/##) 1.0## a2) ((/##) 1.0## a3)+    {-# INLINE recip #-}++    fromRational r = case fromRational r of D# x -> DoubleX3# x x x+    {-# INLINE fromRational #-}++++instance Floating DoubleX3 where++    pi = DoubleX3#+      3.141592653589793238##+      3.141592653589793238##+      3.141592653589793238##+    {-# INLINE pi #-}++    exp (DoubleX3# a1 a2 a3) = DoubleX3#+      (expDouble# a1) (expDouble# a2) (expDouble# a3)+    {-# INLINE exp #-}++    log (DoubleX3# a1 a2 a3) = DoubleX3#+      (logDouble# a1) (logDouble# a2) (logDouble# a3)+    {-# INLINE log #-}++    sqrt (DoubleX3# a1 a2 a3) = DoubleX3#+      (sqrtDouble# a1) (sqrtDouble# a2) (sqrtDouble# a3)+    {-# INLINE sqrt #-}++    sin (DoubleX3# a1 a2 a3) = DoubleX3#+      (sinDouble# a1) (sinDouble# a2) (sinDouble# a3)+    {-# INLINE sin #-}++    cos (DoubleX3# a1 a2 a3) = DoubleX3#+      (cosDouble# a1) (cosDouble# a2) (cosDouble# a3)+    {-# INLINE cos #-}++    tan (DoubleX3# a1 a2 a3) = DoubleX3#+      (tanDouble# a1) (tanDouble# a2) (tanDouble# a3)+    {-# INLINE tan #-}++    asin (DoubleX3# a1 a2 a3) = DoubleX3#+      (asinDouble# a1) (asinDouble# a2) (asinDouble# a3)+    {-# INLINE asin #-}++    acos (DoubleX3# a1 a2 a3) = DoubleX3#+      (acosDouble# a1) (acosDouble# a2) (acosDouble# a3)+    {-# INLINE acos #-}++    atan (DoubleX3# a1 a2 a3) = DoubleX3#+      (atanDouble# a1) (atanDouble# a2) (atanDouble# a3)+    {-# INLINE atan #-}++    sinh (DoubleX3# a1 a2 a3) = DoubleX3#+      (sinhDouble# a1) (sinhDouble# a2) (sinhDouble# a3)+    {-# INLINE sinh #-}++    cosh (DoubleX3# a1 a2 a3) = DoubleX3#+      (coshDouble# a1) (coshDouble# a2) (coshDouble# a3)+    {-# INLINE cosh #-}++    tanh (DoubleX3# a1 a2 a3) = DoubleX3#+      (tanhDouble# a1) (tanhDouble# a2) (tanhDouble# a3)+    {-# INLINE tanh #-}++    DoubleX3# a1 a2 a3 ** DoubleX3# b1 b2 b3 = DoubleX3#+      ((**##) a1 b1) ((**##) a2 b2) ((**##) a3 b3)+    {-# INLINE (**) #-}++    logBase x y         =  log y / log x+    {-# INLINE logBase #-}++    asinh x = log (x + sqrt (1.0+x*x))+    {-# INLINE asinh #-}++    acosh x = log (x + (x+1.0) * sqrt ((x-1.0)/(x+1.0)))+    {-# INLINE acosh #-}++    atanh x = 0.5 * log ((1.0+x) / (1.0-x))+    {-# INLINE atanh #-}++-- offset in bytes is S times bigger than offset in prim elements,+-- when S is power of two, this is equal to shift+#define BOFF_TO_PRIMOFF(off) uncheckedIShiftRL# off 3#+#define ELEM_N 3++instance PrimBytes DoubleX3 where++    getBytes (DoubleX3# a1 a2 a3) = case runRW#+       ( \s0 -> case newByteArray# (byteSize @DoubleX3 undefined) s0 of+           (# s1, marr #) -> case writeDoubleArray# marr 0# a1 s1 of+             s2 -> case writeDoubleArray# marr 1# a2 s2 of+               s3 -> case writeDoubleArray# marr 2# a3 s3 of+                 s4 -> unsafeFreezeByteArray# marr s4+       ) of (# _, a #) -> a+    {-# INLINE getBytes #-}++    fromBytes off arr+      | i <- BOFF_TO_PRIMOFF(off)+      = DoubleX3#+      (indexDoubleArray# arr i)+      (indexDoubleArray# arr (i +# 1#))+      (indexDoubleArray# arr (i +# 2#))+    {-# INLINE fromBytes #-}++    readBytes mba off s0+      | i <- BOFF_TO_PRIMOFF(off)+      = case readDoubleArray# mba i s0 of+      (# s1, a1 #) -> case readDoubleArray# mba (i +# 1#) s1 of+        (# s2, a2 #) -> case readDoubleArray# mba (i +# 2#) s2 of+          (# s3, a3 #) -> (# s3, DoubleX3# a1 a2 a3 #)+    {-# INLINE readBytes #-}++    writeBytes mba off (DoubleX3# a1 a2 a3) s+      | i <- BOFF_TO_PRIMOFF(off)+      = writeDoubleArray# mba (i +# 2#) a3+      ( writeDoubleArray# mba (i +# 1#) a2+      ( writeDoubleArray# mba  i        a1 s ))+    {-# INLINE writeBytes #-}++    readAddr addr s0+      = case readDoubleOffAddr# addr 0# s0 of+      (# s1, a1 #) -> case readDoubleOffAddr# addr 1# s1 of+        (# s2, a2 #) -> case readDoubleOffAddr# addr 2# s2 of+          (# s3, a3 #) -> (# s3, DoubleX3# a1 a2 a3 #)+    {-# INLINE readAddr #-}++    writeAddr (DoubleX3# a1 a2 a3) addr s+      = writeDoubleOffAddr# addr 2# a3+      ( writeDoubleOffAddr# addr 1# a2+      ( writeDoubleOffAddr# addr 0# a1 s ))+    {-# INLINE writeAddr #-}++    byteSize _ = byteSize @Double undefined *# ELEM_N#+    {-# INLINE byteSize #-}++    byteAlign _ = byteAlign @Double undefined+    {-# INLINE byteAlign #-}++    byteOffset _ = 0#+    {-# INLINE byteOffset #-}++    byteFieldOffset _ _ = negateInt# 1#+    {-# INLINE byteFieldOffset #-}++    indexArray ba off+      | i <- off *# ELEM_N#+      = DoubleX3#+      (indexDoubleArray# ba i)+      (indexDoubleArray# ba (i +# 1#))+      (indexDoubleArray# ba (i +# 2#))+    {-# INLINE indexArray #-}++    readArray mba off s0+      | i <- off *# ELEM_N#+      = case readDoubleArray# mba i s0 of+      (# s1, a1 #) -> case readDoubleArray# mba (i +# 1#) s1 of+        (# s2, a2 #) -> case readDoubleArray# mba (i +# 2#) s2 of+          (# s3, a3 #) -> (# s3, DoubleX3# a1 a2 a3 #)+    {-# INLINE readArray #-}++    writeArray mba off (DoubleX3# a1 a2 a3) s+      | i <- off *# ELEM_N#+      = writeDoubleArray# mba (i +# 2#) a3+      ( writeDoubleArray# mba (i +# 1#) a2+      ( writeDoubleArray# mba  i        a1 s ))+    {-# INLINE writeArray #-}+++instance PrimArray Double DoubleX3 where++    broadcast (D# x) = DoubleX3# x x x+    {-# INLINE broadcast #-}++    ix# 0# (DoubleX3# a1 _ _) = D# a1+    ix# 1# (DoubleX3# _ a2 _) = D# a2+    ix# 2# (DoubleX3# _ _ a3) = D# a3+    ix# _   _                 = undefined+    {-# INLINE ix# #-}++    gen# _ f s0 = case f s0 of+      (# s1, D# a1 #) -> case f s1 of+        (# s2, D# a2 #) -> case f s2 of+          (# s3, D# a3 #) -> (# s3, DoubleX3# a1 a2 a3 #)+++    upd# _ 0# (D# q) (DoubleX3# _ y z) = DoubleX3# q y z+    upd# _ 1# (D# q) (DoubleX3# x _ z) = DoubleX3# x q z+    upd# _ 2# (D# q) (DoubleX3# x y _) = DoubleX3# x y q+    upd# _ _ _ x                       = x+    {-# INLINE upd# #-}++    arrayContent# x = (# | (# CumulDims [ELEM_N, 1], 0#, getBytes x #) #)+    {-# INLINE arrayContent# #-}++    offsetElems _ = 0#+    {-# INLINE offsetElems #-}++    uniqueOrCumulDims _ = Right (CumulDims [ELEM_N, 1])+    {-# INLINE uniqueOrCumulDims #-}++    fromElems _ off ba = DoubleX3#+      (indexDoubleArray# ba off)+      (indexDoubleArray# ba (off +# 1#))+      (indexDoubleArray# ba (off +# 2#))+    {-# INLINE fromElems #-}
+ src-base/Numeric/DataFrame/Internal/Backend/Family/DoubleX4.hs view
@@ -0,0 +1,467 @@+{-# LANGUAGE CPP                   #-}+{-# LANGUAGE FlexibleContexts      #-}+{-# LANGUAGE FlexibleInstances     #-}+{-# LANGUAGE MagicHash             #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE TypeApplications      #-}+{-# LANGUAGE UnboxedSums           #-}+{-# LANGUAGE UnboxedTuples         #-}+{-# LANGUAGE UndecidableInstances  #-}+module Numeric.DataFrame.Internal.Backend.Family.DoubleX4 (DoubleX4 (..)) where+++import           GHC.Base+import           Numeric.DataFrame.Internal.PrimArray+import           Numeric.PrimBytes+import           Numeric.ProductOrd+import qualified Numeric.ProductOrd.NonTransitive     as NonTransitive+import qualified Numeric.ProductOrd.Partial           as Partial+++data DoubleX4 = DoubleX4# Double# Double# Double# Double#++-- | Since @Bounded@ is not implemented for floating point types, this instance+--   has an unresolvable constraint.+--   Nevetheless, it is good to have it here for nicer error messages.+instance Bounded Double => Bounded DoubleX4 where+    maxBound = case maxBound of D# x -> DoubleX4# x x x x+    minBound = case minBound of D# x -> DoubleX4# x x x x+++instance Eq DoubleX4 where++    DoubleX4# a1 a2 a3 a4 == DoubleX4# b1 b2 b3 b4 =+      isTrue#+      (       (a1 ==## b1)+      `andI#` (a2 ==## b2)+      `andI#` (a3 ==## b3)+      `andI#` (a4 ==## b4)+      )+    {-# INLINE (==) #-}++    DoubleX4# a1 a2 a3 a4 /= DoubleX4# b1 b2 b3 b4 =+      isTrue#+      (      (a1 /=## b1)+      `orI#` (a2 /=## b2)+      `orI#` (a3 /=## b3)+      `orI#` (a4 /=## b4)+      )+    {-# INLINE (/=) #-}++cmp' :: Double# -> Double# -> PartialOrdering+cmp' a b+  | isTrue# (a >## b) = PGT+  | isTrue# (a <## b) = PLT+  | otherwise  = PEQ++instance ProductOrder DoubleX4 where+    cmp (DoubleX4# a1 a2 a3 a4) (DoubleX4# b1 b2 b3 b4)+      = cmp' a1 b1 <> cmp' a2 b2 <> cmp' a3 b3 <> cmp' a4 b4+    {-# INLINE cmp #-}++instance Ord (NonTransitive.ProductOrd DoubleX4) where+    NonTransitive.ProductOrd x > NonTransitive.ProductOrd y = cmp x y == PGT+    {-# INLINE (>) #-}+    NonTransitive.ProductOrd x < NonTransitive.ProductOrd y = cmp x y == PLT+    {-# INLINE (<) #-}+    (>=) (NonTransitive.ProductOrd (DoubleX4# a1 a2 a3 a4))+         (NonTransitive.ProductOrd (DoubleX4# b1 b2 b3 b4)) = isTrue#+      ((a1 >=## b1) `andI#` (a2 >=## b2) `andI#` (a3 >=## b3) `andI#` (a4 >=## b4))+    {-# INLINE (>=) #-}+    (<=) (NonTransitive.ProductOrd (DoubleX4# a1 a2 a3 a4))+         (NonTransitive.ProductOrd (DoubleX4# b1 b2 b3 b4)) = isTrue#+      ((a1 <=## b1) `andI#` (a2 <=## b2) `andI#` (a3 <=## b3) `andI#` (a4 <=## b4))+    {-# INLINE (<=) #-}+    compare (NonTransitive.ProductOrd a) (NonTransitive.ProductOrd b)+      = NonTransitive.toOrdering $ cmp a b+    {-# INLINE compare #-}+    min (NonTransitive.ProductOrd (DoubleX4# a1 a2 a3 a4))+        (NonTransitive.ProductOrd (DoubleX4# b1 b2 b3 b4))+      = NonTransitive.ProductOrd+        ( DoubleX4#+          (if isTrue# (a1 >## b1) then b1 else a1)+          (if isTrue# (a2 >## b2) then b2 else a2)+          (if isTrue# (a3 >## b3) then b3 else a3)+          (if isTrue# (a4 >## b4) then b4 else a4)+        )+    {-# INLINE min #-}+    max (NonTransitive.ProductOrd (DoubleX4# a1 a2 a3 a4))+        (NonTransitive.ProductOrd (DoubleX4# b1 b2 b3 b4))+      = NonTransitive.ProductOrd+        ( DoubleX4#+          (if isTrue# (a1 <## b1) then b1 else a1)+          (if isTrue# (a2 <## b2) then b2 else a2)+          (if isTrue# (a3 <## b3) then b3 else a3)+          (if isTrue# (a4 <## b4) then b4 else a4)+        )+    {-# INLINE max #-}++instance Ord (Partial.ProductOrd DoubleX4) where+    Partial.ProductOrd x > Partial.ProductOrd y = cmp x y == PGT+    {-# INLINE (>) #-}+    Partial.ProductOrd x < Partial.ProductOrd y = cmp x y == PLT+    {-# INLINE (<) #-}+    (>=) (Partial.ProductOrd (DoubleX4# a1 a2 a3 a4))+         (Partial.ProductOrd (DoubleX4# b1 b2 b3 b4)) = isTrue#+      ((a1 >=## b1) `andI#` (a2 >=## b2) `andI#` (a3 >=## b3) `andI#` (a4 >=## b4))+    {-# INLINE (>=) #-}+    (<=) (Partial.ProductOrd (DoubleX4# a1 a2 a3 a4))+         (Partial.ProductOrd (DoubleX4# b1 b2 b3 b4)) = isTrue#+      ((a1 <=## b1) `andI#` (a2 <=## b2) `andI#` (a3 <=## b3) `andI#` (a4 <=## b4))+    {-# INLINE (<=) #-}+    compare (Partial.ProductOrd a) (Partial.ProductOrd b)+      = Partial.toOrdering $ cmp a b+    {-# INLINE compare #-}+    min (Partial.ProductOrd (DoubleX4# a1 a2 a3 a4))+        (Partial.ProductOrd (DoubleX4# b1 b2 b3 b4))+      = Partial.ProductOrd+        ( DoubleX4#+          (if isTrue# (a1 >## b1) then b1 else a1)+          (if isTrue# (a2 >## b2) then b2 else a2)+          (if isTrue# (a3 >## b3) then b3 else a3)+          (if isTrue# (a4 >## b4) then b4 else a4)+        )+    {-# INLINE min #-}+    max (Partial.ProductOrd (DoubleX4# a1 a2 a3 a4))+        (Partial.ProductOrd (DoubleX4# b1 b2 b3 b4))+      = Partial.ProductOrd+        ( DoubleX4#+          (if isTrue# (a1 <## b1) then b1 else a1)+          (if isTrue# (a2 <## b2) then b2 else a2)+          (if isTrue# (a3 <## b3) then b3 else a3)+          (if isTrue# (a4 <## b4) then b4 else a4)+        )+    {-# INLINE max #-}++instance Ord DoubleX4 where+    DoubleX4# a1 a2 a3 a4 > DoubleX4# b1 b2 b3 b4+      | isTrue# (a1 >## b1) = True+      | isTrue# (a1 <## b1) = False+      | isTrue# (a2 >## b2) = True+      | isTrue# (a2 <## b2) = False+      | isTrue# (a3 >## b3) = True+      | isTrue# (a3 <## b3) = False+      | isTrue# (a4 >## b4) = True+      | otherwise           = False+    {-# INLINE (>) #-}++    DoubleX4# a1 a2 a3 a4 < DoubleX4# b1 b2 b3 b4+      | isTrue# (a1 <## b1) = True+      | isTrue# (a1 >## b1) = False+      | isTrue# (a2 <## b2) = True+      | isTrue# (a2 >## b2) = False+      | isTrue# (a3 <## b3) = True+      | isTrue# (a3 >## b3) = False+      | isTrue# (a4 <## b4) = True+      | otherwise           = False+    {-# INLINE (<) #-}++    DoubleX4# a1 a2 a3 a4 >= DoubleX4# b1 b2 b3 b4+      | isTrue# (a1 <## b1) = False+      | isTrue# (a1 >## b1) = True+      | isTrue# (a2 <## b2) = False+      | isTrue# (a2 >## b2) = True+      | isTrue# (a3 <## b3) = False+      | isTrue# (a3 >## b3) = True+      | isTrue# (a4 <## b4) = False+      | otherwise           = True+    {-# INLINE (>=) #-}++    DoubleX4# a1 a2 a3 a4 <= DoubleX4# b1 b2 b3 b4+      | isTrue# (a1 >## b1) = False+      | isTrue# (a1 <## b1) = True+      | isTrue# (a2 >## b2) = False+      | isTrue# (a2 <## b2) = True+      | isTrue# (a3 >## b3) = False+      | isTrue# (a3 <## b3) = True+      | isTrue# (a4 >## b4) = False+      | otherwise           = True+    {-# INLINE (<=) #-}++    compare (DoubleX4# a1 a2 a3 a4) (DoubleX4# b1 b2 b3 b4)+      | isTrue# (a1 >## b1) = GT+      | isTrue# (a1 <## b1) = LT+      | isTrue# (a2 >## b2) = GT+      | isTrue# (a2 <## b2) = LT+      | isTrue# (a3 >## b3) = GT+      | isTrue# (a3 <## b3) = LT+      | isTrue# (a4 >## b4) = GT+      | isTrue# (a4 <## b4) = LT+      | otherwise           = EQ+    {-# INLINE compare #-}++++-- | element-wise operations for vectors+instance Num DoubleX4 where++    DoubleX4# a1 a2 a3 a4 + DoubleX4# b1 b2 b3 b4+      = DoubleX4# ((+##) a1 b1) ((+##) a2 b2) ((+##) a3 b3) ((+##) a4 b4)+    {-# INLINE (+) #-}++    DoubleX4# a1 a2 a3 a4 - DoubleX4# b1 b2 b3 b4+      = DoubleX4# ((-##) a1 b1) ((-##) a2 b2) ((-##) a3 b3) ((-##) a4 b4)+    {-# INLINE (-) #-}++    DoubleX4# a1 a2 a3 a4 * DoubleX4# b1 b2 b3 b4+      = DoubleX4# ((*##) a1 b1) ((*##) a2 b2) ((*##) a3 b3) ((*##) a4 b4)+    {-# INLINE (*) #-}++    negate (DoubleX4# a1 a2 a3 a4) = DoubleX4#+      (negateDouble# a1) (negateDouble# a2) (negateDouble# a3) (negateDouble# a4)+    {-# INLINE negate #-}++    abs (DoubleX4# a1 a2 a3 a4)+      = DoubleX4#+      (if isTrue# (a1 >=## 0.0##) then a1 else negateDouble# a1)+      (if isTrue# (a2 >=## 0.0##) then a2 else negateDouble# a2)+      (if isTrue# (a3 >=## 0.0##) then a3 else negateDouble# a3)+      (if isTrue# (a4 >=## 0.0##) then a4 else negateDouble# a4)+    {-# INLINE abs #-}++    signum (DoubleX4# a1 a2 a3 a4)+      = DoubleX4# (if isTrue# (a1 >## 0.0##)+                  then 1.0##+                  else if isTrue# (a1 <## 0.0##) then -1.0## else 0.0## )+                 (if isTrue# (a2 >## 0.0##)+                  then 1.0##+                  else if isTrue# (a2 <## 0.0##) then -1.0## else 0.0## )+                 (if isTrue# (a3 >## 0.0##)+                  then 1.0##+                  else if isTrue# (a3 <## 0.0##) then -1.0## else 0.0## )+                 (if isTrue# (a4 >## 0.0##)+                  then 1.0##+                  else if isTrue# (a4 <## 0.0##) then -1.0## else 0.0## )+    {-# INLINE signum #-}++    fromInteger n = case fromInteger n of D# x -> DoubleX4# x x x x+    {-# INLINE fromInteger #-}++++instance Fractional DoubleX4 where++    DoubleX4# a1 a2 a3 a4 / DoubleX4# b1 b2 b3 b4 = DoubleX4#+      ((/##) a1 b1) ((/##) a2 b2) ((/##) a3 b3) ((/##) a4 b4)+    {-# INLINE (/) #-}++    recip (DoubleX4# a1 a2 a3 a4) = DoubleX4#+      ((/##) 1.0## a1) ((/##) 1.0## a2) ((/##) 1.0## a3) ((/##) 1.0## a4)+    {-# INLINE recip #-}++    fromRational r = case fromRational r of D# x -> DoubleX4# x x x x+    {-# INLINE fromRational #-}++++instance Floating DoubleX4 where++    pi = DoubleX4#+      3.141592653589793238##+      3.141592653589793238##+      3.141592653589793238##+      3.141592653589793238##+    {-# INLINE pi #-}++    exp (DoubleX4# a1 a2 a3 a4) = DoubleX4#+      (expDouble# a1) (expDouble# a2) (expDouble# a3) (expDouble# a4)+    {-# INLINE exp #-}++    log (DoubleX4# a1 a2 a3 a4) = DoubleX4#+      (logDouble# a1) (logDouble# a2) (logDouble# a3) (logDouble# a4)+    {-# INLINE log #-}++    sqrt (DoubleX4# a1 a2 a3 a4) = DoubleX4#+      (sqrtDouble# a1) (sqrtDouble# a2) (sqrtDouble# a3) (sqrtDouble# a4)+    {-# INLINE sqrt #-}++    sin (DoubleX4# a1 a2 a3 a4) = DoubleX4#+      (sinDouble# a1) (sinDouble# a2) (sinDouble# a3) (sinDouble# a4)+    {-# INLINE sin #-}++    cos (DoubleX4# a1 a2 a3 a4) = DoubleX4#+      (cosDouble# a1) (cosDouble# a2) (cosDouble# a3) (cosDouble# a4)+    {-# INLINE cos #-}++    tan (DoubleX4# a1 a2 a3 a4) = DoubleX4#+      (tanDouble# a1) (tanDouble# a2) (tanDouble# a3) (tanDouble# a4)+    {-# INLINE tan #-}++    asin (DoubleX4# a1 a2 a3 a4) = DoubleX4#+      (asinDouble# a1) (asinDouble# a2) (asinDouble# a3) (asinDouble# a4)+    {-# INLINE asin #-}++    acos (DoubleX4# a1 a2 a3 a4) = DoubleX4#+      (acosDouble# a1) (acosDouble# a2) (acosDouble# a3) (acosDouble# a4)+    {-# INLINE acos #-}++    atan (DoubleX4# a1 a2 a3 a4) = DoubleX4#+      (atanDouble# a1) (atanDouble# a2) (atanDouble# a3) (atanDouble# a4)+    {-# INLINE atan #-}++    sinh (DoubleX4# a1 a2 a3 a4) = DoubleX4#+      (sinhDouble# a1) (sinhDouble# a2) (sinhDouble# a3) (sinhDouble# a4)+    {-# INLINE sinh #-}++    cosh (DoubleX4# a1 a2 a3 a4) = DoubleX4#+      (coshDouble# a1) (coshDouble# a2) (coshDouble# a3) (coshDouble# a4)+    {-# INLINE cosh #-}++    tanh (DoubleX4# a1 a2 a3 a4) = DoubleX4#+      (tanhDouble# a1) (tanhDouble# a2) (tanhDouble# a3) (tanhDouble# a4)+    {-# INLINE tanh #-}++    DoubleX4# a1 a2 a3 a4 ** DoubleX4# b1 b2 b3 b4 = DoubleX4#+      ((**##) a1 b1) ((**##) a2 b2) ((**##) a3 b3) ((**##) a4 b4)+    {-# INLINE (**) #-}++    logBase x y         =  log y / log x+    {-# INLINE logBase #-}++    asinh x = log (x + sqrt (1.0+x*x))+    {-# INLINE asinh #-}++    acosh x = log (x + (x+1.0) * sqrt ((x-1.0)/(x+1.0)))+    {-# INLINE acosh #-}++    atanh x = 0.5 * log ((1.0+x) / (1.0-x))+    {-# INLINE atanh #-}++-- offset in bytes is S times bigger than offset in prim elements,+-- when S is power of two, this is equal to shift+#define BOFF_TO_PRIMOFF(off) uncheckedIShiftRL# off 3#+#define ELEM_N 4++instance PrimBytes DoubleX4 where++    getBytes (DoubleX4# a1 a2 a3 a4) = case runRW#+       ( \s0 -> case newByteArray# (byteSize @DoubleX4 undefined) s0 of+           (# s1, marr #) -> case writeDoubleArray# marr 0# a1 s1 of+             s2 -> case writeDoubleArray# marr 1# a2 s2 of+               s3 -> case writeDoubleArray# marr 2# a3 s3 of+                 s4 -> case writeDoubleArray# marr 3# a4 s4 of+                   s5 -> unsafeFreezeByteArray# marr s5+       ) of (# _, a #) -> a+    {-# INLINE getBytes #-}++    fromBytes off arr+      | i <- BOFF_TO_PRIMOFF(off)+      = DoubleX4#+      (indexDoubleArray# arr i)+      (indexDoubleArray# arr (i +# 1#))+      (indexDoubleArray# arr (i +# 2#))+      (indexDoubleArray# arr (i +# 3#))+    {-# INLINE fromBytes #-}++    readBytes mba off s0+      | i <- BOFF_TO_PRIMOFF(off)+      = case readDoubleArray# mba i s0 of+      (# s1, a1 #) -> case readDoubleArray# mba (i +# 1#) s1 of+        (# s2, a2 #) -> case readDoubleArray# mba (i +# 2#) s2 of+          (# s3, a3 #) -> case readDoubleArray# mba (i +# 3#) s3 of+            (# s4, a4 #) -> (# s4, DoubleX4# a1 a2 a3 a4 #)+    {-# INLINE readBytes #-}++    writeBytes mba off (DoubleX4# a1 a2 a3 a4) s+      | i <- BOFF_TO_PRIMOFF(off)+      = writeDoubleArray# mba (i +# 3#) a4+      ( writeDoubleArray# mba (i +# 2#) a3+      ( writeDoubleArray# mba (i +# 1#) a2+      ( writeDoubleArray# mba  i        a1 s )))+    {-# INLINE writeBytes #-}++    readAddr addr s0+      = case readDoubleOffAddr# addr 0# s0 of+      (# s1, a1 #) -> case readDoubleOffAddr# addr 1# s1 of+        (# s2, a2 #) -> case readDoubleOffAddr# addr 2# s2 of+          (# s3, a3 #) -> case readDoubleOffAddr# addr 3# s3 of+            (# s4, a4 #) -> (# s4, DoubleX4# a1 a2 a3 a4 #)+    {-# INLINE readAddr #-}++    writeAddr (DoubleX4# a1 a2 a3 a4) addr s+      = writeDoubleOffAddr# addr 3# a4+      ( writeDoubleOffAddr# addr 2# a3+      ( writeDoubleOffAddr# addr 1# a2+      ( writeDoubleOffAddr# addr 0# a1 s )))+    {-# INLINE writeAddr #-}++    byteSize _ = byteSize @Double undefined *# ELEM_N#+    {-# INLINE byteSize #-}++    byteAlign _ = byteAlign @Double undefined+    {-# INLINE byteAlign #-}++    byteOffset _ = 0#+    {-# INLINE byteOffset #-}++    byteFieldOffset _ _ = negateInt# 1#+    {-# INLINE byteFieldOffset #-}++    indexArray ba off+      | i <- off *# ELEM_N#+      = DoubleX4#+      (indexDoubleArray# ba i)+      (indexDoubleArray# ba (i +# 1#))+      (indexDoubleArray# ba (i +# 2#))+      (indexDoubleArray# ba (i +# 3#))+    {-# INLINE indexArray #-}++    readArray mba off s0+      | i <- off *# ELEM_N#+      = case readDoubleArray# mba i s0 of+      (# s1, a1 #) -> case readDoubleArray# mba (i +# 1#) s1 of+        (# s2, a2 #) -> case readDoubleArray# mba (i +# 2#) s2 of+          (# s3, a3 #) -> case readDoubleArray# mba (i +# 3#) s3 of+            (# s4, a4 #) -> (# s4, DoubleX4# a1 a2 a3 a4 #)+    {-# INLINE readArray #-}++    writeArray mba off (DoubleX4# a1 a2 a3 a4) s+      | i <- off *# ELEM_N#+      = writeDoubleArray# mba (i +# 3#) a4+      ( writeDoubleArray# mba (i +# 2#) a3+      ( writeDoubleArray# mba (i +# 1#) a2+      ( writeDoubleArray# mba  i        a1 s )))+    {-# INLINE writeArray #-}+++instance PrimArray Double DoubleX4 where++    broadcast (D# x) = DoubleX4# x x x x+    {-# INLINE broadcast #-}++    ix# 0# (DoubleX4# a1 _ _ _) = D# a1+    ix# 1# (DoubleX4# _ a2 _ _) = D# a2+    ix# 2# (DoubleX4# _ _ a3 _) = D# a3+    ix# 3# (DoubleX4# _ _ _ a4) = D# a4+    ix# _   _                   = undefined+    {-# INLINE ix# #-}++    gen# _ f s0 = case f s0 of+      (# s1, D# a1 #) -> case f s1 of+        (# s2, D# a2 #) -> case f s2 of+          (# s3, D# a3 #) -> case f s3 of+            (# s4, D# a4 #) -> (# s4, DoubleX4# a1 a2 a3 a4 #)+++    upd# _ 0# (D# q) (DoubleX4# _ y z w) = DoubleX4# q y z w+    upd# _ 1# (D# q) (DoubleX4# x _ z w) = DoubleX4# x q z w+    upd# _ 2# (D# q) (DoubleX4# x y _ w) = DoubleX4# x y q w+    upd# _ 3# (D# q) (DoubleX4# x y z _) = DoubleX4# x y z q+    upd# _ _ _ x                         = x+    {-# INLINE upd# #-}++    arrayContent# x = (# | (# CumulDims [ELEM_N, 1], 0#, getBytes x #) #)+    {-# INLINE arrayContent# #-}++    offsetElems _ = 0#+    {-# INLINE offsetElems #-}++    uniqueOrCumulDims _ = Right (CumulDims [ELEM_N, 1])+    {-# INLINE uniqueOrCumulDims #-}++    fromElems _ off ba = DoubleX4#+      (indexDoubleArray# ba off)+      (indexDoubleArray# ba (off +# 1#))+      (indexDoubleArray# ba (off +# 2#))+      (indexDoubleArray# ba (off +# 3#))+    {-# INLINE fromElems #-}
+ src-base/Numeric/DataFrame/Internal/Backend/Family/FloatX2.hs view
@@ -0,0 +1,401 @@+{-# LANGUAGE CPP                   #-}+{-# LANGUAGE FlexibleContexts      #-}+{-# LANGUAGE FlexibleInstances     #-}+{-# LANGUAGE MagicHash             #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE TypeApplications      #-}+{-# LANGUAGE UnboxedSums           #-}+{-# LANGUAGE UnboxedTuples         #-}+{-# LANGUAGE UndecidableInstances  #-}+module Numeric.DataFrame.Internal.Backend.Family.FloatX2 (FloatX2 (..)) where+++import           GHC.Base+import           Numeric.DataFrame.Internal.PrimArray+import           Numeric.PrimBytes+import           Numeric.ProductOrd+import qualified Numeric.ProductOrd.NonTransitive     as NonTransitive+import qualified Numeric.ProductOrd.Partial           as Partial+++data FloatX2 = FloatX2# Float# Float#++-- | Since @Bounded@ is not implemented for floating point types, this instance+--   has an unresolvable constraint.+--   Nevetheless, it is good to have it here for nicer error messages.+instance Bounded Float => Bounded FloatX2 where+    maxBound = case maxBound of F# x -> FloatX2# x x+    minBound = case minBound of F# x -> FloatX2# x x+++instance Eq FloatX2 where++    FloatX2# a1 a2 == FloatX2# b1 b2 =+      isTrue#+      (       (a1 `eqFloat#` b1)+      `andI#` (a2 `eqFloat#` b2)+      )+    {-# INLINE (==) #-}++    FloatX2# a1 a2 /= FloatX2# b1 b2 =+      isTrue#+      (      (a1 `neFloat#` b1)+      `orI#` (a2 `neFloat#` b2)+      )+    {-# INLINE (/=) #-}++++cmp' :: Float# -> Float# -> PartialOrdering+cmp' a b+  | isTrue# (a `gtFloat#` b) = PGT+  | isTrue# (a `ltFloat#` b) = PLT+  | otherwise  = PEQ++instance ProductOrder FloatX2 where+    cmp (FloatX2# a1 a2) (FloatX2# b1 b2)+      = cmp' a1 b1 <> cmp' a2 b2+    {-# INLINE cmp #-}++instance Ord (NonTransitive.ProductOrd FloatX2) where+    NonTransitive.ProductOrd x > NonTransitive.ProductOrd y = cmp x y == PGT+    {-# INLINE (>) #-}+    NonTransitive.ProductOrd x < NonTransitive.ProductOrd y = cmp x y == PLT+    {-# INLINE (<) #-}+    (>=) (NonTransitive.ProductOrd (FloatX2# a1 a2))+         (NonTransitive.ProductOrd (FloatX2# b1 b2)) = isTrue#+      ((a1 `geFloat#` b1) `andI#` (a2 `geFloat#` b2))+    {-# INLINE (>=) #-}+    (<=) (NonTransitive.ProductOrd (FloatX2# a1 a2))+         (NonTransitive.ProductOrd (FloatX2# b1 b2)) = isTrue#+      ((a1 `leFloat#` b1) `andI#` (a2 `leFloat#` b2))+    {-# INLINE (<=) #-}+    compare (NonTransitive.ProductOrd a) (NonTransitive.ProductOrd b)+      = NonTransitive.toOrdering $ cmp a b+    {-# INLINE compare #-}+    min (NonTransitive.ProductOrd (FloatX2# a1 a2))+        (NonTransitive.ProductOrd (FloatX2# b1 b2))+      = NonTransitive.ProductOrd+        ( FloatX2#+          (if isTrue# (a1 `gtFloat#` b1) then b1 else a1)+          (if isTrue# (a2 `gtFloat#` b2) then b2 else a2)+        )+    {-# INLINE min #-}+    max (NonTransitive.ProductOrd (FloatX2# a1 a2))+        (NonTransitive.ProductOrd (FloatX2# b1 b2))+      = NonTransitive.ProductOrd+        ( FloatX2#+          (if isTrue# (a1 `ltFloat#` b1) then b1 else a1)+          (if isTrue# (a2 `ltFloat#` b2) then b2 else a2)+        )+    {-# INLINE max #-}++instance Ord (Partial.ProductOrd FloatX2) where+    Partial.ProductOrd x > Partial.ProductOrd y = cmp x y == PGT+    {-# INLINE (>) #-}+    Partial.ProductOrd x < Partial.ProductOrd y = cmp x y == PLT+    {-# INLINE (<) #-}+    (>=) (Partial.ProductOrd (FloatX2# a1 a2))+         (Partial.ProductOrd (FloatX2# b1 b2)) = isTrue#+      ((a1 `geFloat#` b1) `andI#` (a2 `geFloat#` b2))+    {-# INLINE (>=) #-}+    (<=) (Partial.ProductOrd (FloatX2# a1 a2))+         (Partial.ProductOrd (FloatX2# b1 b2)) = isTrue#+      ((a1 `leFloat#` b1) `andI#` (a2 `leFloat#` b2))+    {-# INLINE (<=) #-}+    compare (Partial.ProductOrd a) (Partial.ProductOrd b)+      = Partial.toOrdering $ cmp a b+    {-# INLINE compare #-}+    min (Partial.ProductOrd (FloatX2# a1 a2))+        (Partial.ProductOrd (FloatX2# b1 b2))+      = Partial.ProductOrd+        ( FloatX2#+          (if isTrue# (a1 `gtFloat#` b1) then b1 else a1)+          (if isTrue# (a2 `gtFloat#` b2) then b2 else a2)+        )+    {-# INLINE min #-}+    max (Partial.ProductOrd (FloatX2# a1 a2))+        (Partial.ProductOrd (FloatX2# b1 b2))+      = Partial.ProductOrd+        ( FloatX2#+          (if isTrue# (a1 `ltFloat#` b1) then b1 else a1)+          (if isTrue# (a2 `ltFloat#` b2) then b2 else a2)+        )+    {-# INLINE max #-}++instance Ord FloatX2 where+    FloatX2# a1 a2 > FloatX2# b1 b2+      | isTrue# (a1 `gtFloat#` b1) = True+      | isTrue# (a1 `ltFloat#` b1) = False+      | isTrue# (a2 `gtFloat#` b2) = True+      | otherwise           = False+    {-# INLINE (>) #-}++    FloatX2# a1 a2 < FloatX2# b1 b2+      | isTrue# (a1 `ltFloat#` b1) = True+      | isTrue# (a1 `gtFloat#` b1) = False+      | isTrue# (a2 `ltFloat#` b2) = True+      | otherwise           = False+    {-# INLINE (<) #-}++    FloatX2# a1 a2 >= FloatX2# b1 b2+      | isTrue# (a1 `ltFloat#` b1) = False+      | isTrue# (a1 `gtFloat#` b1) = True+      | isTrue# (a2 `ltFloat#` b2) = False+      | otherwise           = True+    {-# INLINE (>=) #-}++    FloatX2# a1 a2 <= FloatX2# b1 b2+      | isTrue# (a1 `gtFloat#` b1) = False+      | isTrue# (a1 `ltFloat#` b1) = True+      | isTrue# (a2 `gtFloat#` b2) = False+      | otherwise           = True+    {-# INLINE (<=) #-}++    compare (FloatX2# a1 a2) (FloatX2# b1 b2)+      | isTrue# (a1 `gtFloat#` b1) = GT+      | isTrue# (a1 `ltFloat#` b1) = LT+      | isTrue# (a2 `gtFloat#` b2) = GT+      | isTrue# (a2 `ltFloat#` b2) = LT+      | otherwise           = EQ+    {-# INLINE compare #-}++++-- | element-wise operations for vectors+instance Num FloatX2 where++    FloatX2# a1 a2 + FloatX2# b1 b2+      = FloatX2# (plusFloat# a1 b1) (plusFloat# a2 b2)+    {-# INLINE (+) #-}++    FloatX2# a1 a2 - FloatX2# b1 b2+      = FloatX2# (minusFloat# a1 b1) (minusFloat# a2 b2)+    {-# INLINE (-) #-}++    FloatX2# a1 a2 * FloatX2# b1 b2+      = FloatX2# (timesFloat# a1 b1) (timesFloat# a2 b2)+    {-# INLINE (*) #-}++    negate (FloatX2# a1 a2) = FloatX2#+      (negateFloat# a1) (negateFloat# a2)+    {-# INLINE negate #-}++    abs (FloatX2# a1 a2)+      = FloatX2#+      (if isTrue# (a1 `geFloat#` 0.0#) then a1 else negateFloat# a1)+      (if isTrue# (a2 `geFloat#` 0.0#) then a2 else negateFloat# a2)+    {-# INLINE abs #-}++    signum (FloatX2# a1 a2)+      = FloatX2# (if isTrue# (a1 `gtFloat#` 0.0#)+                  then 1.0#+                  else if isTrue# (a1 `ltFloat#` 0.0#) then -1.0# else 0.0# )+                 (if isTrue# (a2 `gtFloat#` 0.0#)+                  then 1.0#+                  else if isTrue# (a2 `ltFloat#` 0.0#) then -1.0# else 0.0# )+    {-# INLINE signum #-}++    fromInteger n = case fromInteger n of F# x -> FloatX2# x x+    {-# INLINE fromInteger #-}++++instance Fractional FloatX2 where++    FloatX2# a1 a2 / FloatX2# b1 b2 = FloatX2#+      (divideFloat# a1 b1) (divideFloat# a2 b2)+    {-# INLINE (/) #-}++    recip (FloatX2# a1 a2) = FloatX2#+      (divideFloat# 1.0# a1) (divideFloat# 1.0# a2)+    {-# INLINE recip #-}++    fromRational r = case fromRational r of F# x -> FloatX2# x x+    {-# INLINE fromRational #-}++++instance Floating FloatX2 where++    pi = FloatX2#+      3.141592653589793238#+      3.141592653589793238#+    {-# INLINE pi #-}++    exp (FloatX2# a1 a2) = FloatX2#+      (expFloat# a1) (expFloat# a2)+    {-# INLINE exp #-}++    log (FloatX2# a1 a2) = FloatX2#+      (logFloat# a1) (logFloat# a2)+    {-# INLINE log #-}++    sqrt (FloatX2# a1 a2) = FloatX2#+      (sqrtFloat# a1) (sqrtFloat# a2)+    {-# INLINE sqrt #-}++    sin (FloatX2# a1 a2) = FloatX2#+      (sinFloat# a1) (sinFloat# a2)+    {-# INLINE sin #-}++    cos (FloatX2# a1 a2) = FloatX2#+      (cosFloat# a1) (cosFloat# a2)+    {-# INLINE cos #-}++    tan (FloatX2# a1 a2) = FloatX2#+      (tanFloat# a1) (tanFloat# a2)+    {-# INLINE tan #-}++    asin (FloatX2# a1 a2) = FloatX2#+      (asinFloat# a1) (asinFloat# a2)+    {-# INLINE asin #-}++    acos (FloatX2# a1 a2) = FloatX2#+      (acosFloat# a1) (acosFloat# a2)+    {-# INLINE acos #-}++    atan (FloatX2# a1 a2) = FloatX2#+      (atanFloat# a1) (atanFloat# a2)+    {-# INLINE atan #-}++    sinh (FloatX2# a1 a2) = FloatX2#+      (sinhFloat# a1) (sinhFloat# a2)+    {-# INLINE sinh #-}++    cosh (FloatX2# a1 a2) = FloatX2#+      (coshFloat# a1) (coshFloat# a2)+    {-# INLINE cosh #-}++    tanh (FloatX2# a1 a2) = FloatX2#+      (tanhFloat# a1) (tanhFloat# a2)+    {-# INLINE tanh #-}++    FloatX2# a1 a2 ** FloatX2# b1 b2 = FloatX2#+      (powerFloat# a1 b1) (powerFloat# a2 b2)+    {-# INLINE (**) #-}++    logBase x y         =  log y / log x+    {-# INLINE logBase #-}++    asinh x = log (x + sqrt (1.0+x*x))+    {-# INLINE asinh #-}++    acosh x = log (x + (x+1.0) * sqrt ((x-1.0)/(x+1.0)))+    {-# INLINE acosh #-}++    atanh x = 0.5 * log ((1.0+x) / (1.0-x))+    {-# INLINE atanh #-}++-- offset in bytes is S times bigger than offset in prim elements,+-- when S is power of two, this is equal to shift+#define BOFF_TO_PRIMOFF(off) uncheckedIShiftRL# off 2#+#define ELEM_N 2++instance PrimBytes FloatX2 where++    getBytes (FloatX2# a1 a2) = case runRW#+       ( \s0 -> case newByteArray# (byteSize @FloatX2 undefined) s0 of+           (# s1, marr #) -> case writeFloatArray# marr 0# a1 s1 of+             s2 -> case writeFloatArray# marr 1# a2 s2 of+               s3 -> unsafeFreezeByteArray# marr s3+       ) of (# _, a #) -> a+    {-# INLINE getBytes #-}++    fromBytes off arr+      | i <- BOFF_TO_PRIMOFF(off)+      = FloatX2#+      (indexFloatArray# arr i)+      (indexFloatArray# arr (i +# 1#))+    {-# INLINE fromBytes #-}++    readBytes mba off s0+      | i <- BOFF_TO_PRIMOFF(off)+      = case readFloatArray# mba i s0 of+      (# s1, a1 #) -> case readFloatArray# mba (i +# 1#) s1 of+        (# s2, a2 #) -> (# s2, FloatX2# a1 a2 #)+    {-# INLINE readBytes #-}++    writeBytes mba off (FloatX2# a1 a2) s+      | i <- BOFF_TO_PRIMOFF(off)+      = writeFloatArray# mba (i +# 1#) a2+      ( writeFloatArray# mba  i        a1 s )+    {-# INLINE writeBytes #-}++    readAddr addr s0+      = case readFloatOffAddr# addr 0# s0 of+      (# s1, a1 #) -> case readFloatOffAddr# addr 1# s1 of+        (# s2, a2 #) -> (# s2, FloatX2# a1 a2 #)+    {-# INLINE readAddr #-}++    writeAddr (FloatX2# a1 a2) addr s+      = writeFloatOffAddr# addr 1# a2+      ( writeFloatOffAddr# addr 0# a1 s )+    {-# INLINE writeAddr #-}++    byteSize _ = byteSize @Float undefined *# ELEM_N#+    {-# INLINE byteSize #-}++    byteAlign _ = byteAlign @Float undefined+    {-# INLINE byteAlign #-}++    byteOffset _ = 0#+    {-# INLINE byteOffset #-}++    byteFieldOffset _ _ = negateInt# 1#+    {-# INLINE byteFieldOffset #-}++    indexArray ba off+      | i <- off *# ELEM_N#+      = FloatX2#+      (indexFloatArray# ba i)+      (indexFloatArray# ba (i +# 1#))+    {-# INLINE indexArray #-}++    readArray mba off s0+      | i <- off *# ELEM_N#+      = case readFloatArray# mba i s0 of+      (# s1, a1 #) -> case readFloatArray# mba (i +# 1#) s1 of+        (# s2, a2 #) -> (# s2, FloatX2# a1 a2 #)+    {-# INLINE readArray #-}++    writeArray mba off (FloatX2# a1 a2) s+      | i <- off *# ELEM_N#+      = writeFloatArray# mba (i +# 1#) a2+      ( writeFloatArray# mba  i        a1 s )+    {-# INLINE writeArray #-}+++instance PrimArray Float FloatX2 where++    broadcast (F# x) = FloatX2# x x+    {-# INLINE broadcast #-}++    ix# 0# (FloatX2# a1 _) = F# a1+    ix# 1# (FloatX2# _ a2) = F# a2+    ix# _   _              = undefined+    {-# INLINE ix# #-}++    gen# _ f s0 = case f s0 of+      (# s1, F# a1 #) -> case f s1 of+        (# s2, F# a2 #) -> (# s2, FloatX2# a1 a2 #)+++    upd# _ 0# (F# q) (FloatX2# _ y) = FloatX2# q y+    upd# _ 1# (F# q) (FloatX2# x _) = FloatX2# x q+    upd# _ _ _ x                    = x+    {-# INLINE upd# #-}++    arrayContent# x = (# | (# CumulDims [ELEM_N, 1], 0#, getBytes x #) #)+    {-# INLINE arrayContent# #-}++    offsetElems _ = 0#+    {-# INLINE offsetElems #-}++    uniqueOrCumulDims _ = Right (CumulDims [ELEM_N, 1])+    {-# INLINE uniqueOrCumulDims #-}++    fromElems _ off ba = FloatX2#+      (indexFloatArray# ba off)+      (indexFloatArray# ba (off +# 1#))+    {-# INLINE fromElems #-}
+ src-base/Numeric/DataFrame/Internal/Backend/Family/FloatX3.hs view
@@ -0,0 +1,437 @@+{-# LANGUAGE CPP                   #-}+{-# LANGUAGE FlexibleContexts      #-}+{-# LANGUAGE FlexibleInstances     #-}+{-# LANGUAGE MagicHash             #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE TypeApplications      #-}+{-# LANGUAGE UnboxedSums           #-}+{-# LANGUAGE UnboxedTuples         #-}+{-# LANGUAGE UndecidableInstances  #-}+module Numeric.DataFrame.Internal.Backend.Family.FloatX3 (FloatX3 (..)) where+++import           GHC.Base+import           Numeric.DataFrame.Internal.PrimArray+import           Numeric.PrimBytes+import           Numeric.ProductOrd+import qualified Numeric.ProductOrd.NonTransitive     as NonTransitive+import qualified Numeric.ProductOrd.Partial           as Partial+++data FloatX3 = FloatX3# Float# Float# Float#++-- | Since @Bounded@ is not implemented for floating point types, this instance+--   has an unresolvable constraint.+--   Nevetheless, it is good to have it here for nicer error messages.+instance Bounded Float => Bounded FloatX3 where+    maxBound = case maxBound of F# x -> FloatX3# x x x+    minBound = case minBound of F# x -> FloatX3# x x x+++instance Eq FloatX3 where++    FloatX3# a1 a2 a3 == FloatX3# b1 b2 b3 =+      isTrue#+      (       (a1 `eqFloat#` b1)+      `andI#` (a2 `eqFloat#` b2)+      `andI#` (a3 `eqFloat#` b3)+      )+    {-# INLINE (==) #-}++    FloatX3# a1 a2 a3 /= FloatX3# b1 b2 b3 =+      isTrue#+      (      (a1 `neFloat#` b1)+      `orI#` (a2 `neFloat#` b2)+      `orI#` (a3 `neFloat#` b3)+      )+    {-# INLINE (/=) #-}+++++cmp' :: Float# -> Float# -> PartialOrdering+cmp' a b+  | isTrue# (a `gtFloat#` b) = PGT+  | isTrue# (a `ltFloat#` b) = PLT+  | otherwise  = PEQ++instance ProductOrder FloatX3 where+    cmp (FloatX3# a1 a2 a3) (FloatX3# b1 b2 b3)+      = cmp' a1 b1 <> cmp' a2 b2 <> cmp' a3 b3+    {-# INLINE cmp #-}++instance Ord (NonTransitive.ProductOrd FloatX3) where+    NonTransitive.ProductOrd x > NonTransitive.ProductOrd y = cmp x y == PGT+    {-# INLINE (>) #-}+    NonTransitive.ProductOrd x < NonTransitive.ProductOrd y = cmp x y == PLT+    {-# INLINE (<) #-}+    (>=) (NonTransitive.ProductOrd (FloatX3# a1 a2 a3))+         (NonTransitive.ProductOrd (FloatX3# b1 b2 b3)) = isTrue#+      ((a1 `geFloat#` b1) `andI#` (a2 `geFloat#` b2) `andI#` (a3 `geFloat#` b3))+    {-# INLINE (>=) #-}+    (<=) (NonTransitive.ProductOrd (FloatX3# a1 a2 a3))+         (NonTransitive.ProductOrd (FloatX3# b1 b2 b3)) = isTrue#+      ((a1 `leFloat#` b1) `andI#` (a2 `leFloat#` b2) `andI#` (a3 `leFloat#` b3))+    {-# INLINE (<=) #-}+    compare (NonTransitive.ProductOrd a) (NonTransitive.ProductOrd b)+      = NonTransitive.toOrdering $ cmp a b+    {-# INLINE compare #-}+    min (NonTransitive.ProductOrd (FloatX3# a1 a2 a3))+        (NonTransitive.ProductOrd (FloatX3# b1 b2 b3))+      = NonTransitive.ProductOrd+        ( FloatX3#+          (if isTrue# (a1 `gtFloat#` b1) then b1 else a1)+          (if isTrue# (a2 `gtFloat#` b2) then b2 else a2)+          (if isTrue# (a3 `gtFloat#` b3) then b3 else a3)+        )+    {-# INLINE min #-}+    max (NonTransitive.ProductOrd (FloatX3# a1 a2 a3))+        (NonTransitive.ProductOrd (FloatX3# b1 b2 b3))+      = NonTransitive.ProductOrd+        ( FloatX3#+          (if isTrue# (a1 `ltFloat#` b1) then b1 else a1)+          (if isTrue# (a2 `ltFloat#` b2) then b2 else a2)+          (if isTrue# (a3 `ltFloat#` b3) then b3 else a3)+        )+    {-# INLINE max #-}++instance Ord (Partial.ProductOrd FloatX3) where+    Partial.ProductOrd x > Partial.ProductOrd y = cmp x y == PGT+    {-# INLINE (>) #-}+    Partial.ProductOrd x < Partial.ProductOrd y = cmp x y == PLT+    {-# INLINE (<) #-}+    (>=) (Partial.ProductOrd (FloatX3# a1 a2 a3))+         (Partial.ProductOrd (FloatX3# b1 b2 b3)) = isTrue#+      ((a1 `geFloat#` b1) `andI#` (a2 `geFloat#` b2) `andI#` (a3 `geFloat#` b3))+    {-# INLINE (>=) #-}+    (<=) (Partial.ProductOrd (FloatX3# a1 a2 a3))+         (Partial.ProductOrd (FloatX3# b1 b2 b3)) = isTrue#+      ((a1 `leFloat#` b1) `andI#` (a2 `leFloat#` b2) `andI#` (a3 `leFloat#` b3))+    {-# INLINE (<=) #-}+    compare (Partial.ProductOrd a) (Partial.ProductOrd b)+      = Partial.toOrdering $ cmp a b+    {-# INLINE compare #-}+    min (Partial.ProductOrd (FloatX3# a1 a2 a3))+        (Partial.ProductOrd (FloatX3# b1 b2 b3))+      = Partial.ProductOrd+        ( FloatX3#+          (if isTrue# (a1 `gtFloat#` b1) then b1 else a1)+          (if isTrue# (a2 `gtFloat#` b2) then b2 else a2)+          (if isTrue# (a3 `gtFloat#` b3) then b3 else a3)+        )+    {-# INLINE min #-}+    max (Partial.ProductOrd (FloatX3# a1 a2 a3))+        (Partial.ProductOrd (FloatX3# b1 b2 b3))+      = Partial.ProductOrd+        ( FloatX3#+          (if isTrue# (a1 `ltFloat#` b1) then b1 else a1)+          (if isTrue# (a2 `ltFloat#` b2) then b2 else a2)+          (if isTrue# (a3 `ltFloat#` b3) then b3 else a3)+        )+    {-# INLINE max #-}++instance Ord FloatX3 where+    FloatX3# a1 a2 a3 > FloatX3# b1 b2 b3+      | isTrue# (a1 `gtFloat#` b1) = True+      | isTrue# (a1 `ltFloat#` b1) = False+      | isTrue# (a2 `gtFloat#` b2) = True+      | isTrue# (a2 `ltFloat#` b2) = False+      | isTrue# (a3 `gtFloat#` b3) = True+      | otherwise           = False+    {-# INLINE (>) #-}++    FloatX3# a1 a2 a3 < FloatX3# b1 b2 b3+      | isTrue# (a1 `ltFloat#` b1) = True+      | isTrue# (a1 `gtFloat#` b1) = False+      | isTrue# (a2 `ltFloat#` b2) = True+      | isTrue# (a2 `gtFloat#` b2) = False+      | isTrue# (a3 `ltFloat#` b3) = True+      | otherwise           = False+    {-# INLINE (<) #-}++    FloatX3# a1 a2 a3 >= FloatX3# b1 b2 b3+      | isTrue# (a1 `ltFloat#` b1) = False+      | isTrue# (a1 `gtFloat#` b1) = True+      | isTrue# (a2 `ltFloat#` b2) = False+      | isTrue# (a2 `gtFloat#` b2) = True+      | isTrue# (a3 `ltFloat#` b3) = False+      | otherwise           = True+    {-# INLINE (>=) #-}++    FloatX3# a1 a2 a3 <= FloatX3# b1 b2 b3+      | isTrue# (a1 `gtFloat#` b1) = False+      | isTrue# (a1 `ltFloat#` b1) = True+      | isTrue# (a2 `gtFloat#` b2) = False+      | isTrue# (a2 `ltFloat#` b2) = True+      | isTrue# (a3 `gtFloat#` b3) = False+      | otherwise           = True+    {-# INLINE (<=) #-}++    compare (FloatX3# a1 a2 a3) (FloatX3# b1 b2 b3)+      | isTrue# (a1 `gtFloat#` b1) = GT+      | isTrue# (a1 `ltFloat#` b1) = LT+      | isTrue# (a2 `gtFloat#` b2) = GT+      | isTrue# (a2 `ltFloat#` b2) = LT+      | isTrue# (a3 `gtFloat#` b3) = GT+      | isTrue# (a3 `ltFloat#` b3) = LT+      | otherwise           = EQ+    {-# INLINE compare #-}+++++-- | element-wise operations for vectors+instance Num FloatX3 where++    FloatX3# a1 a2 a3 + FloatX3# b1 b2 b3+      = FloatX3# (plusFloat# a1 b1) (plusFloat# a2 b2) (plusFloat# a3 b3)+    {-# INLINE (+) #-}++    FloatX3# a1 a2 a3 - FloatX3# b1 b2 b3+      = FloatX3# (minusFloat# a1 b1) (minusFloat# a2 b2) (minusFloat# a3 b3)+    {-# INLINE (-) #-}++    FloatX3# a1 a2 a3 * FloatX3# b1 b2 b3+      = FloatX3# (timesFloat# a1 b1) (timesFloat# a2 b2) (timesFloat# a3 b3)+    {-# INLINE (*) #-}++    negate (FloatX3# a1 a2 a3) = FloatX3#+      (negateFloat# a1) (negateFloat# a2) (negateFloat# a3)+    {-# INLINE negate #-}++    abs (FloatX3# a1 a2 a3)+      = FloatX3#+      (if isTrue# (a1 `geFloat#` 0.0#) then a1 else negateFloat# a1)+      (if isTrue# (a2 `geFloat#` 0.0#) then a2 else negateFloat# a2)+      (if isTrue# (a3 `geFloat#` 0.0#) then a3 else negateFloat# a3)+    {-# INLINE abs #-}++    signum (FloatX3# a1 a2 a3)+      = FloatX3# (if isTrue# (a1 `gtFloat#` 0.0#)+                  then 1.0#+                  else if isTrue# (a1 `ltFloat#` 0.0#) then -1.0# else 0.0# )+                 (if isTrue# (a2 `gtFloat#` 0.0#)+                  then 1.0#+                  else if isTrue# (a2 `ltFloat#` 0.0#) then -1.0# else 0.0# )+                 (if isTrue# (a3 `gtFloat#` 0.0#)+                  then 1.0#+                  else if isTrue# (a3 `ltFloat#` 0.0#) then -1.0# else 0.0# )+    {-# INLINE signum #-}++    fromInteger n = case fromInteger n of F# x -> FloatX3# x x x+    {-# INLINE fromInteger #-}++++instance Fractional FloatX3 where++    FloatX3# a1 a2 a3 / FloatX3# b1 b2 b3 = FloatX3#+      (divideFloat# a1 b1) (divideFloat# a2 b2) (divideFloat# a3 b3)+    {-# INLINE (/) #-}++    recip (FloatX3# a1 a2 a3) = FloatX3#+      (divideFloat# 1.0# a1) (divideFloat# 1.0# a2) (divideFloat# 1.0# a3)+    {-# INLINE recip #-}++    fromRational r = case fromRational r of F# x -> FloatX3# x x x+    {-# INLINE fromRational #-}++++instance Floating FloatX3 where++    pi = FloatX3#+      3.141592653589793238#+      3.141592653589793238#+      3.141592653589793238#+    {-# INLINE pi #-}++    exp (FloatX3# a1 a2 a3) = FloatX3#+      (expFloat# a1) (expFloat# a2) (expFloat# a3)+    {-# INLINE exp #-}++    log (FloatX3# a1 a2 a3) = FloatX3#+      (logFloat# a1) (logFloat# a2) (logFloat# a3)+    {-# INLINE log #-}++    sqrt (FloatX3# a1 a2 a3) = FloatX3#+      (sqrtFloat# a1) (sqrtFloat# a2) (sqrtFloat# a3)+    {-# INLINE sqrt #-}++    sin (FloatX3# a1 a2 a3) = FloatX3#+      (sinFloat# a1) (sinFloat# a2) (sinFloat# a3)+    {-# INLINE sin #-}++    cos (FloatX3# a1 a2 a3) = FloatX3#+      (cosFloat# a1) (cosFloat# a2) (cosFloat# a3)+    {-# INLINE cos #-}++    tan (FloatX3# a1 a2 a3) = FloatX3#+      (tanFloat# a1) (tanFloat# a2) (tanFloat# a3)+    {-# INLINE tan #-}++    asin (FloatX3# a1 a2 a3) = FloatX3#+      (asinFloat# a1) (asinFloat# a2) (asinFloat# a3)+    {-# INLINE asin #-}++    acos (FloatX3# a1 a2 a3) = FloatX3#+      (acosFloat# a1) (acosFloat# a2) (acosFloat# a3)+    {-# INLINE acos #-}++    atan (FloatX3# a1 a2 a3) = FloatX3#+      (atanFloat# a1) (atanFloat# a2) (atanFloat# a3)+    {-# INLINE atan #-}++    sinh (FloatX3# a1 a2 a3) = FloatX3#+      (sinhFloat# a1) (sinhFloat# a2) (sinhFloat# a3)+    {-# INLINE sinh #-}++    cosh (FloatX3# a1 a2 a3) = FloatX3#+      (coshFloat# a1) (coshFloat# a2) (coshFloat# a3)+    {-# INLINE cosh #-}++    tanh (FloatX3# a1 a2 a3) = FloatX3#+      (tanhFloat# a1) (tanhFloat# a2) (tanhFloat# a3)+    {-# INLINE tanh #-}++    FloatX3# a1 a2 a3 ** FloatX3# b1 b2 b3 = FloatX3#+      (powerFloat# a1 b1) (powerFloat# a2 b2) (powerFloat# a3 b3)+    {-# INLINE (**) #-}++    logBase x y         =  log y / log x+    {-# INLINE logBase #-}++    asinh x = log (x + sqrt (1.0+x*x))+    {-# INLINE asinh #-}++    acosh x = log (x + (x+1.0) * sqrt ((x-1.0)/(x+1.0)))+    {-# INLINE acosh #-}++    atanh x = 0.5 * log ((1.0+x) / (1.0-x))+    {-# INLINE atanh #-}++-- offset in bytes is S times bigger than offset in prim elements,+-- when S is power of two, this is equal to shift+#define BOFF_TO_PRIMOFF(off) uncheckedIShiftRL# off 2#+#define ELEM_N 3++instance PrimBytes FloatX3 where++    getBytes (FloatX3# a1 a2 a3) = case runRW#+       ( \s0 -> case newByteArray# (byteSize @FloatX3 undefined) s0 of+           (# s1, marr #) -> case writeFloatArray# marr 0# a1 s1 of+             s2 -> case writeFloatArray# marr 1# a2 s2 of+               s3 -> case writeFloatArray# marr 2# a3 s3 of+                 s4 -> unsafeFreezeByteArray# marr s4+       ) of (# _, a #) -> a+    {-# INLINE getBytes #-}++    fromBytes off arr+      | i <- BOFF_TO_PRIMOFF(off)+      = FloatX3#+      (indexFloatArray# arr i)+      (indexFloatArray# arr (i +# 1#))+      (indexFloatArray# arr (i +# 2#))+    {-# INLINE fromBytes #-}++    readBytes mba off s0+      | i <- BOFF_TO_PRIMOFF(off)+      = case readFloatArray# mba i s0 of+      (# s1, a1 #) -> case readFloatArray# mba (i +# 1#) s1 of+        (# s2, a2 #) -> case readFloatArray# mba (i +# 2#) s2 of+          (# s3, a3 #) -> (# s3, FloatX3# a1 a2 a3 #)+    {-# INLINE readBytes #-}++    writeBytes mba off (FloatX3# a1 a2 a3) s+      | i <- BOFF_TO_PRIMOFF(off)+      = writeFloatArray# mba (i +# 2#) a3+      ( writeFloatArray# mba (i +# 1#) a2+      ( writeFloatArray# mba  i        a1 s ))+    {-# INLINE writeBytes #-}++    readAddr addr s0+      = case readFloatOffAddr# addr 0# s0 of+      (# s1, a1 #) -> case readFloatOffAddr# addr 1# s1 of+        (# s2, a2 #) -> case readFloatOffAddr# addr 2# s2 of+          (# s3, a3 #) -> (# s3, FloatX3# a1 a2 a3 #)+    {-# INLINE readAddr #-}++    writeAddr (FloatX3# a1 a2 a3) addr s+      = writeFloatOffAddr# addr 2# a3+      ( writeFloatOffAddr# addr 1# a2+      ( writeFloatOffAddr# addr 0# a1 s ))+    {-# INLINE writeAddr #-}++    byteSize _ = byteSize @Float undefined *# ELEM_N#+    {-# INLINE byteSize #-}++    byteAlign _ = byteAlign @Float undefined+    {-# INLINE byteAlign #-}++    byteOffset _ = 0#+    {-# INLINE byteOffset #-}++    byteFieldOffset _ _ = negateInt# 1#+    {-# INLINE byteFieldOffset #-}++    indexArray ba off+      | i <- off *# ELEM_N#+      = FloatX3#+      (indexFloatArray# ba i)+      (indexFloatArray# ba (i +# 1#))+      (indexFloatArray# ba (i +# 2#))+    {-# INLINE indexArray #-}++    readArray mba off s0+      | i <- off *# ELEM_N#+      = case readFloatArray# mba i s0 of+      (# s1, a1 #) -> case readFloatArray# mba (i +# 1#) s1 of+        (# s2, a2 #) -> case readFloatArray# mba (i +# 2#) s2 of+          (# s3, a3 #) -> (# s3, FloatX3# a1 a2 a3 #)+    {-# INLINE readArray #-}++    writeArray mba off (FloatX3# a1 a2 a3) s+      | i <- off *# ELEM_N#+      = writeFloatArray# mba (i +# 2#) a3+      ( writeFloatArray# mba (i +# 1#) a2+      ( writeFloatArray# mba  i        a1 s ))+    {-# INLINE writeArray #-}+++instance PrimArray Float FloatX3 where++    broadcast (F# x) = FloatX3# x x x+    {-# INLINE broadcast #-}++    ix# 0# (FloatX3# a1 _ _) = F# a1+    ix# 1# (FloatX3# _ a2 _) = F# a2+    ix# 2# (FloatX3# _ _ a3) = F# a3+    ix# _   _                = undefined+    {-# INLINE ix# #-}++    gen# _ f s0 = case f s0 of+      (# s1, F# a1 #) -> case f s1 of+        (# s2, F# a2 #) -> case f s2 of+          (# s3, F# a3 #) -> (# s3, FloatX3# a1 a2 a3 #)+++    upd# _ 0# (F# q) (FloatX3# _ y z) = FloatX3# q y z+    upd# _ 1# (F# q) (FloatX3# x _ z) = FloatX3# x q z+    upd# _ 2# (F# q) (FloatX3# x y _) = FloatX3# x y q+    upd# _ _ _ x                      = x+    {-# INLINE upd# #-}++    arrayContent# x = (# | (# CumulDims [ELEM_N, 1], 0#, getBytes x #) #)+    {-# INLINE arrayContent# #-}++    offsetElems _ = 0#+    {-# INLINE offsetElems #-}++    uniqueOrCumulDims _ = Right (CumulDims [ELEM_N, 1])+    {-# INLINE uniqueOrCumulDims #-}++    fromElems _ off ba = FloatX3#+      (indexFloatArray# ba off)+      (indexFloatArray# ba (off +# 1#))+      (indexFloatArray# ba (off +# 2#))+    {-# INLINE fromElems #-}
+ src-base/Numeric/DataFrame/Internal/Backend/Family/FloatX4.hs view
@@ -0,0 +1,498 @@+{-# LANGUAGE CPP                   #-}+{-# LANGUAGE DataKinds             #-}+{-# LANGUAGE FlexibleContexts      #-}+{-# LANGUAGE FlexibleInstances     #-}+{-# LANGUAGE MagicHash             #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE TypeApplications      #-}+{-# LANGUAGE UnboxedSums           #-}+{-# LANGUAGE UnboxedTuples         #-}+{-# LANGUAGE UndecidableInstances  #-}+{-# OPTIONS_GHC -fno-warn-orphans  #-}+module Numeric.DataFrame.Internal.Backend.Family.FloatX4 (FloatX4 (..)) where+++import           GHC.Base+import           Numeric.DataFrame.Internal.PrimArray+import           Numeric.DataFrame.SubSpace+import           Numeric.Dimensions+import           Numeric.PrimBytes+import           Numeric.ProductOrd+import qualified Numeric.ProductOrd.NonTransitive     as NonTransitive+import qualified Numeric.ProductOrd.Partial           as Partial+++data FloatX4 = FloatX4# Float# Float# Float# Float#++-- | Since @Bounded@ is not implemented for floating point types, this instance+--   has an unresolvable constraint.+--   Nevetheless, it is good to have it here for nicer error messages.+instance Bounded Float => Bounded FloatX4 where+    maxBound = case maxBound of F# x -> FloatX4# x x x x+    minBound = case minBound of F# x -> FloatX4# x x x x+++instance Eq FloatX4 where++    FloatX4# a1 a2 a3 a4 == FloatX4# b1 b2 b3 b4 =+      isTrue#+      (       (a1 `eqFloat#` b1)+      `andI#` (a2 `eqFloat#` b2)+      `andI#` (a3 `eqFloat#` b3)+      `andI#` (a4 `eqFloat#` b4)+      )+    {-# INLINE (==) #-}++    FloatX4# a1 a2 a3 a4 /= FloatX4# b1 b2 b3 b4 =+      isTrue#+      (      (a1 `neFloat#` b1)+      `orI#` (a2 `neFloat#` b2)+      `orI#` (a3 `neFloat#` b3)+      `orI#` (a4 `neFloat#` b4)+      )+    {-# INLINE (/=) #-}+++++cmp' :: Float# -> Float# -> PartialOrdering+cmp' a b+  | isTrue# (a `gtFloat#` b) = PGT+  | isTrue# (a `ltFloat#` b) = PLT+  | otherwise  = PEQ++instance ProductOrder FloatX4 where+    cmp (FloatX4# a1 a2 a3 a4) (FloatX4# b1 b2 b3 b4)+      = cmp' a1 b1 <> cmp' a2 b2 <> cmp' a3 b3 <> cmp' a4 b4+    {-# INLINE cmp #-}++instance Ord (NonTransitive.ProductOrd FloatX4) where+    NonTransitive.ProductOrd x > NonTransitive.ProductOrd y = cmp x y == PGT+    {-# INLINE (>) #-}+    NonTransitive.ProductOrd x < NonTransitive.ProductOrd y = cmp x y == PLT+    {-# INLINE (<) #-}+    (>=) (NonTransitive.ProductOrd (FloatX4# a1 a2 a3 a4))+         (NonTransitive.ProductOrd (FloatX4# b1 b2 b3 b4)) = isTrue#+      ((a1 `geFloat#` b1) `andI#` (a2 `geFloat#` b2) `andI#` (a3 `geFloat#` b3) `andI#` (a4 `geFloat#` b4))+    {-# INLINE (>=) #-}+    (<=) (NonTransitive.ProductOrd (FloatX4# a1 a2 a3 a4))+         (NonTransitive.ProductOrd (FloatX4# b1 b2 b3 b4)) = isTrue#+      ((a1 `leFloat#` b1) `andI#` (a2 `leFloat#` b2) `andI#` (a3 `leFloat#` b3) `andI#` (a4 `leFloat#` b4))+    {-# INLINE (<=) #-}+    compare (NonTransitive.ProductOrd a) (NonTransitive.ProductOrd b)+      = NonTransitive.toOrdering $ cmp a b+    {-# INLINE compare #-}+    min (NonTransitive.ProductOrd (FloatX4# a1 a2 a3 a4))+        (NonTransitive.ProductOrd (FloatX4# b1 b2 b3 b4))+      = NonTransitive.ProductOrd+        ( FloatX4#+          (if isTrue# (a1 `gtFloat#` b1) then b1 else a1)+          (if isTrue# (a2 `gtFloat#` b2) then b2 else a2)+          (if isTrue# (a3 `gtFloat#` b3) then b3 else a3)+          (if isTrue# (a4 `gtFloat#` b4) then b4 else a4)+        )+    {-# INLINE min #-}+    max (NonTransitive.ProductOrd (FloatX4# a1 a2 a3 a4))+        (NonTransitive.ProductOrd (FloatX4# b1 b2 b3 b4))+      = NonTransitive.ProductOrd+        ( FloatX4#+          (if isTrue# (a1 `ltFloat#` b1) then b1 else a1)+          (if isTrue# (a2 `ltFloat#` b2) then b2 else a2)+          (if isTrue# (a3 `ltFloat#` b3) then b3 else a3)+          (if isTrue# (a4 `ltFloat#` b4) then b4 else a4)+        )+    {-# INLINE max #-}++instance Ord (Partial.ProductOrd FloatX4) where+    Partial.ProductOrd x > Partial.ProductOrd y = cmp x y == PGT+    {-# INLINE (>) #-}+    Partial.ProductOrd x < Partial.ProductOrd y = cmp x y == PLT+    {-# INLINE (<) #-}+    (>=) (Partial.ProductOrd (FloatX4# a1 a2 a3 a4))+         (Partial.ProductOrd (FloatX4# b1 b2 b3 b4)) = isTrue#+      ((a1 `geFloat#` b1) `andI#` (a2 `geFloat#` b2) `andI#` (a3 `geFloat#` b3) `andI#` (a4 `geFloat#` b4))+    {-# INLINE (>=) #-}+    (<=) (Partial.ProductOrd (FloatX4# a1 a2 a3 a4))+         (Partial.ProductOrd (FloatX4# b1 b2 b3 b4)) = isTrue#+      ((a1 `leFloat#` b1) `andI#` (a2 `leFloat#` b2) `andI#` (a3 `leFloat#` b3) `andI#` (a4 `leFloat#` b4))+    {-# INLINE (<=) #-}+    compare (Partial.ProductOrd a) (Partial.ProductOrd b)+      = Partial.toOrdering $ cmp a b+    {-# INLINE compare #-}+    min (Partial.ProductOrd (FloatX4# a1 a2 a3 a4))+        (Partial.ProductOrd (FloatX4# b1 b2 b3 b4))+      = Partial.ProductOrd+        ( FloatX4#+          (if isTrue# (a1 `gtFloat#` b1) then b1 else a1)+          (if isTrue# (a2 `gtFloat#` b2) then b2 else a2)+          (if isTrue# (a3 `gtFloat#` b3) then b3 else a3)+          (if isTrue# (a4 `gtFloat#` b4) then b4 else a4)+        )+    {-# INLINE min #-}+    max (Partial.ProductOrd (FloatX4# a1 a2 a3 a4))+        (Partial.ProductOrd (FloatX4# b1 b2 b3 b4))+      = Partial.ProductOrd+        ( FloatX4#+          (if isTrue# (a1 `ltFloat#` b1) then b1 else a1)+          (if isTrue# (a2 `ltFloat#` b2) then b2 else a2)+          (if isTrue# (a3 `ltFloat#` b3) then b3 else a3)+          (if isTrue# (a4 `ltFloat#` b4) then b4 else a4)+        )+    {-# INLINE max #-}++instance Ord FloatX4 where+    FloatX4# a1 a2 a3 a4 > FloatX4# b1 b2 b3 b4+      | isTrue# (a1 `gtFloat#` b1) = True+      | isTrue# (a1 `ltFloat#` b1) = False+      | isTrue# (a2 `gtFloat#` b2) = True+      | isTrue# (a2 `ltFloat#` b2) = False+      | isTrue# (a3 `gtFloat#` b3) = True+      | isTrue# (a3 `ltFloat#` b3) = False+      | isTrue# (a4 `gtFloat#` b4) = True+      | otherwise           = False+    {-# INLINE (>) #-}++    FloatX4# a1 a2 a3 a4 < FloatX4# b1 b2 b3 b4+      | isTrue# (a1 `ltFloat#` b1) = True+      | isTrue# (a1 `gtFloat#` b1) = False+      | isTrue# (a2 `ltFloat#` b2) = True+      | isTrue# (a2 `gtFloat#` b2) = False+      | isTrue# (a3 `ltFloat#` b3) = True+      | isTrue# (a3 `gtFloat#` b3) = False+      | isTrue# (a4 `ltFloat#` b4) = True+      | otherwise           = False+    {-# INLINE (<) #-}++    FloatX4# a1 a2 a3 a4 >= FloatX4# b1 b2 b3 b4+      | isTrue# (a1 `ltFloat#` b1) = False+      | isTrue# (a1 `gtFloat#` b1) = True+      | isTrue# (a2 `ltFloat#` b2) = False+      | isTrue# (a2 `gtFloat#` b2) = True+      | isTrue# (a3 `ltFloat#` b3) = False+      | isTrue# (a3 `gtFloat#` b3) = True+      | isTrue# (a4 `ltFloat#` b4) = False+      | otherwise           = True+    {-# INLINE (>=) #-}++    FloatX4# a1 a2 a3 a4 <= FloatX4# b1 b2 b3 b4+      | isTrue# (a1 `gtFloat#` b1) = False+      | isTrue# (a1 `ltFloat#` b1) = True+      | isTrue# (a2 `gtFloat#` b2) = False+      | isTrue# (a2 `ltFloat#` b2) = True+      | isTrue# (a3 `gtFloat#` b3) = False+      | isTrue# (a3 `ltFloat#` b3) = True+      | isTrue# (a4 `gtFloat#` b4) = False+      | otherwise           = True+    {-# INLINE (<=) #-}++    compare (FloatX4# a1 a2 a3 a4) (FloatX4# b1 b2 b3 b4)+      | isTrue# (a1 `gtFloat#` b1) = GT+      | isTrue# (a1 `ltFloat#` b1) = LT+      | isTrue# (a2 `gtFloat#` b2) = GT+      | isTrue# (a2 `ltFloat#` b2) = LT+      | isTrue# (a3 `gtFloat#` b3) = GT+      | isTrue# (a3 `ltFloat#` b3) = LT+      | isTrue# (a4 `gtFloat#` b4) = GT+      | isTrue# (a4 `ltFloat#` b4) = LT+      | otherwise           = EQ+    {-# INLINE compare #-}+++-- | element-wise operations for vectors+instance Num FloatX4 where++    FloatX4# a1 a2 a3 a4 + FloatX4# b1 b2 b3 b4+      = FloatX4# (plusFloat# a1 b1) (plusFloat# a2 b2) (plusFloat# a3 b3) (plusFloat# a4 b4)+    {-# INLINE (+) #-}++    FloatX4# a1 a2 a3 a4 - FloatX4# b1 b2 b3 b4+      = FloatX4# (minusFloat# a1 b1) (minusFloat# a2 b2) (minusFloat# a3 b3) (minusFloat# a4 b4)+    {-# INLINE (-) #-}++    FloatX4# a1 a2 a3 a4 * FloatX4# b1 b2 b3 b4+      = FloatX4# (timesFloat# a1 b1) (timesFloat# a2 b2) (timesFloat# a3 b3) (timesFloat# a4 b4)+    {-# INLINE (*) #-}++    negate (FloatX4# a1 a2 a3 a4) = FloatX4#+      (negateFloat# a1) (negateFloat# a2) (negateFloat# a3) (negateFloat# a4)+    {-# INLINE negate #-}++    abs (FloatX4# a1 a2 a3 a4)+      = FloatX4#+      (if isTrue# (a1 `geFloat#` 0.0#) then a1 else negateFloat# a1)+      (if isTrue# (a2 `geFloat#` 0.0#) then a2 else negateFloat# a2)+      (if isTrue# (a3 `geFloat#` 0.0#) then a3 else negateFloat# a3)+      (if isTrue# (a4 `geFloat#` 0.0#) then a4 else negateFloat# a4)+    {-# INLINE abs #-}++    signum (FloatX4# a1 a2 a3 a4)+      = FloatX4# (if isTrue# (a1 `gtFloat#` 0.0#)+                  then 1.0#+                  else if isTrue# (a1 `ltFloat#` 0.0#) then -1.0# else 0.0# )+                 (if isTrue# (a2 `gtFloat#` 0.0#)+                  then 1.0#+                  else if isTrue# (a2 `ltFloat#` 0.0#) then -1.0# else 0.0# )+                 (if isTrue# (a3 `gtFloat#` 0.0#)+                  then 1.0#+                  else if isTrue# (a3 `ltFloat#` 0.0#) then -1.0# else 0.0# )+                 (if isTrue# (a4 `gtFloat#` 0.0#)+                  then 1.0#+                  else if isTrue# (a4 `ltFloat#` 0.0#) then -1.0# else 0.0# )+    {-# INLINE signum #-}++    fromInteger n = case fromInteger n of F# x -> FloatX4# x x x x+    {-# INLINE fromInteger #-}++++instance Fractional FloatX4 where++    FloatX4# a1 a2 a3 a4 / FloatX4# b1 b2 b3 b4 = FloatX4#+      (divideFloat# a1 b1) (divideFloat# a2 b2) (divideFloat# a3 b3) (divideFloat# a4 b4)+    {-# INLINE (/) #-}++    recip (FloatX4# a1 a2 a3 a4) = FloatX4#+      (divideFloat# 1.0# a1) (divideFloat# 1.0# a2) (divideFloat# 1.0# a3) (divideFloat# 1.0# a4)+    {-# INLINE recip #-}++    fromRational r = case fromRational r of F# x -> FloatX4# x x x x+    {-# INLINE fromRational #-}++++instance Floating FloatX4 where++    pi = FloatX4#+      3.141592653589793238#+      3.141592653589793238#+      3.141592653589793238#+      3.141592653589793238#+    {-# INLINE pi #-}++    exp (FloatX4# a1 a2 a3 a4) = FloatX4#+      (expFloat# a1) (expFloat# a2) (expFloat# a3) (expFloat# a4)+    {-# INLINE exp #-}++    log (FloatX4# a1 a2 a3 a4) = FloatX4#+      (logFloat# a1) (logFloat# a2) (logFloat# a3) (logFloat# a4)+    {-# INLINE log #-}++    sqrt (FloatX4# a1 a2 a3 a4) = FloatX4#+      (sqrtFloat# a1) (sqrtFloat# a2) (sqrtFloat# a3) (sqrtFloat# a4)+    {-# INLINE sqrt #-}++    sin (FloatX4# a1 a2 a3 a4) = FloatX4#+      (sinFloat# a1) (sinFloat# a2) (sinFloat# a3) (sinFloat# a4)+    {-# INLINE sin #-}++    cos (FloatX4# a1 a2 a3 a4) = FloatX4#+      (cosFloat# a1) (cosFloat# a2) (cosFloat# a3) (cosFloat# a4)+    {-# INLINE cos #-}++    tan (FloatX4# a1 a2 a3 a4) = FloatX4#+      (tanFloat# a1) (tanFloat# a2) (tanFloat# a3) (tanFloat# a4)+    {-# INLINE tan #-}++    asin (FloatX4# a1 a2 a3 a4) = FloatX4#+      (asinFloat# a1) (asinFloat# a2) (asinFloat# a3) (asinFloat# a4)+    {-# INLINE asin #-}++    acos (FloatX4# a1 a2 a3 a4) = FloatX4#+      (acosFloat# a1) (acosFloat# a2) (acosFloat# a3) (acosFloat# a4)+    {-# INLINE acos #-}++    atan (FloatX4# a1 a2 a3 a4) = FloatX4#+      (atanFloat# a1) (atanFloat# a2) (atanFloat# a3) (atanFloat# a4)+    {-# INLINE atan #-}++    sinh (FloatX4# a1 a2 a3 a4) = FloatX4#+      (sinhFloat# a1) (sinhFloat# a2) (sinhFloat# a3) (sinhFloat# a4)+    {-# INLINE sinh #-}++    cosh (FloatX4# a1 a2 a3 a4) = FloatX4#+      (coshFloat# a1) (coshFloat# a2) (coshFloat# a3) (coshFloat# a4)+    {-# INLINE cosh #-}++    tanh (FloatX4# a1 a2 a3 a4) = FloatX4#+      (tanhFloat# a1) (tanhFloat# a2) (tanhFloat# a3) (tanhFloat# a4)+    {-# INLINE tanh #-}++    FloatX4# a1 a2 a3 a4 ** FloatX4# b1 b2 b3 b4 = FloatX4#+      (powerFloat# a1 b1) (powerFloat# a2 b2) (powerFloat# a3 b3) (powerFloat# a4 b4)+    {-# INLINE (**) #-}++    logBase x y         =  log y / log x+    {-# INLINE logBase #-}++    asinh x = log (x + sqrt (1.0+x*x))+    {-# INLINE asinh #-}++    acosh x = log (x + (x+1.0) * sqrt ((x-1.0)/(x+1.0)))+    {-# INLINE acosh #-}++    atanh x = 0.5 * log ((1.0+x) / (1.0-x))+    {-# INLINE atanh #-}++-- offset in bytes is S times bigger than offset in prim elements,+-- when S is power of two, this is equal to shift+#define BOFF_TO_PRIMOFF(off) uncheckedIShiftRL# off 2#+#define ELEM_N 4++instance PrimBytes FloatX4 where++    getBytes (FloatX4# a1 a2 a3 a4) = case runRW#+       ( \s0 -> case newByteArray# (byteSize @FloatX4 undefined) s0 of+           (# s1, marr #) -> case writeFloatArray# marr 0# a1 s1 of+             s2 -> case writeFloatArray# marr 1# a2 s2 of+               s3 -> case writeFloatArray# marr 2# a3 s3 of+                 s4 -> case writeFloatArray# marr 3# a4 s4 of+                   s5 -> unsafeFreezeByteArray# marr s5+       ) of (# _, a #) -> a+    {-# INLINE getBytes #-}++    fromBytes off arr+      | i <- BOFF_TO_PRIMOFF(off)+      = FloatX4#+      (indexFloatArray# arr i)+      (indexFloatArray# arr (i +# 1#))+      (indexFloatArray# arr (i +# 2#))+      (indexFloatArray# arr (i +# 3#))+    {-# INLINE fromBytes #-}++    readBytes mba off s0+      | i <- BOFF_TO_PRIMOFF(off)+      = case readFloatArray# mba i s0 of+      (# s1, a1 #) -> case readFloatArray# mba (i +# 1#) s1 of+        (# s2, a2 #) -> case readFloatArray# mba (i +# 2#) s2 of+          (# s3, a3 #) -> case readFloatArray# mba (i +# 3#) s3 of+            (# s4, a4 #) -> (# s4, FloatX4# a1 a2 a3 a4 #)+    {-# INLINE readBytes #-}++    writeBytes mba off (FloatX4# a1 a2 a3 a4) s+      | i <- BOFF_TO_PRIMOFF(off)+      = writeFloatArray# mba (i +# 3#) a4+      ( writeFloatArray# mba (i +# 2#) a3+      ( writeFloatArray# mba (i +# 1#) a2+      ( writeFloatArray# mba  i        a1 s )))+    {-# INLINE writeBytes #-}++    readAddr addr s0+      = case readFloatOffAddr# addr 0# s0 of+      (# s1, a1 #) -> case readFloatOffAddr# addr 1# s1 of+        (# s2, a2 #) -> case readFloatOffAddr# addr 2# s2 of+          (# s3, a3 #) -> case readFloatOffAddr# addr 3# s3 of+            (# s4, a4 #) -> (# s4, FloatX4# a1 a2 a3 a4 #)+    {-# INLINE readAddr #-}++    writeAddr (FloatX4# a1 a2 a3 a4) addr s+      = writeFloatOffAddr# addr 3# a4+      ( writeFloatOffAddr# addr 2# a3+      ( writeFloatOffAddr# addr 1# a2+      ( writeFloatOffAddr# addr 0# a1 s )))+    {-# INLINE writeAddr #-}++    byteSize _ = byteSize @Float undefined *# ELEM_N#+    {-# INLINE byteSize #-}++    byteAlign _ = byteAlign @Float undefined+    {-# INLINE byteAlign #-}++    byteOffset _ = 0#+    {-# INLINE byteOffset #-}++    byteFieldOffset _ _ = negateInt# 1#+    {-# INLINE byteFieldOffset #-}++    indexArray ba off+      | i <- off *# ELEM_N#+      = FloatX4#+      (indexFloatArray# ba i)+      (indexFloatArray# ba (i +# 1#))+      (indexFloatArray# ba (i +# 2#))+      (indexFloatArray# ba (i +# 3#))+    {-# INLINE indexArray #-}++    readArray mba off s0+      | i <- off *# ELEM_N#+      = case readFloatArray# mba i s0 of+      (# s1, a1 #) -> case readFloatArray# mba (i +# 1#) s1 of+        (# s2, a2 #) -> case readFloatArray# mba (i +# 2#) s2 of+          (# s3, a3 #) -> case readFloatArray# mba (i +# 3#) s3 of+            (# s4, a4 #) -> (# s4, FloatX4# a1 a2 a3 a4 #)+    {-# INLINE readArray #-}++    writeArray mba off (FloatX4# a1 a2 a3 a4) s+      | i <- off *# ELEM_N#+      = writeFloatArray# mba (i +# 3#) a4+      ( writeFloatArray# mba (i +# 2#) a3+      ( writeFloatArray# mba (i +# 1#) a2+      ( writeFloatArray# mba  i        a1 s )))+    {-# INLINE writeArray #-}+++instance PrimArray Float FloatX4 where++    broadcast (F# x) = FloatX4# x x x x+    {-# INLINE broadcast #-}++    ix# 0# (FloatX4# a1 _ _ _) = F# a1+    ix# 1# (FloatX4# _ a2 _ _) = F# a2+    ix# 2# (FloatX4# _ _ a3 _) = F# a3+    ix# 3# (FloatX4# _ _ _ a4) = F# a4+    ix# _   _                  = undefined+    {-# INLINE ix# #-}++    gen# _ f s0 = case f s0 of+      (# s1, F# a1 #) -> case f s1 of+        (# s2, F# a2 #) -> case f s2 of+          (# s3, F# a3 #) -> case f s3 of+            (# s4, F# a4 #) -> (# s4, FloatX4# a1 a2 a3 a4 #)+++    upd# _ 0# (F# q) (FloatX4# _ y z w) = FloatX4# q y z w+    upd# _ 1# (F# q) (FloatX4# x _ z w) = FloatX4# x q z w+    upd# _ 2# (F# q) (FloatX4# x y _ w) = FloatX4# x y q w+    upd# _ 3# (F# q) (FloatX4# x y z _) = FloatX4# x y z q+    upd# _ _ _ x                        = x+    {-# INLINE upd# #-}++    arrayContent# x = (# | (# CumulDims [ELEM_N, 1], 0#, getBytes x #) #)+    {-# INLINE arrayContent# #-}++    offsetElems _ = 0#+    {-# INLINE offsetElems #-}++    uniqueOrCumulDims _ = Right (CumulDims [ELEM_N, 1])+    {-# INLINE uniqueOrCumulDims #-}++    fromElems _ off ba = FloatX4#+      (indexFloatArray# ba off)+      (indexFloatArray# ba (off +# 1#))+      (indexFloatArray# ba (off +# 2#))+      (indexFloatArray# ba (off +# 3#))+    {-# INLINE fromElems #-}+++--------------------------------------------------------------------------------+-- Rewrite rules to improve efficiency of algorithms+--+-- Here we don't have access to DataFrame constructors, because we cannot import+-- Numeric.DataFrame.Type module.+-- However, we know that all DataFrame instances are just newtype wrappers+-- (as well as Scalar). Thus, we can use unsafeCoerce# to get access to Arrays+-- inside DataFrames.+--+--------------------------------------------------------------------------------++getIdxOffset :: Idxs '[4] -> Int#+getIdxOffset is = case unsafeCoerce# is of+  [W# i] -> word2Int# i+  _      -> 0#+{-# INLINE getIdxOffset #-}+++{-# RULES+"index/FloatX4" forall i . index @Float @'[4] i+  = unsafeCoerce# (ix# @Float @FloatX4 (getIdxOffset i))++  #-}
+ src-base/Numeric/DataFrame/Internal/Backend/Family/ScalarBase.hs view
@@ -0,0 +1,50 @@+{-# LANGUAGE FlexibleInstances          #-}+{-# LANGUAGE GeneralizedNewtypeDeriving #-}+{-# LANGUAGE MagicHash                  #-}+{-# LANGUAGE MultiParamTypeClasses      #-}+{-# LANGUAGE StandaloneDeriving         #-}+{-# LANGUAGE TypeInType                 #-}+{-# LANGUAGE UnboxedSums                #-}+{-# LANGUAGE UnboxedTuples              #-}+module Numeric.DataFrame.Internal.Backend.Family.ScalarBase (ScalarBase (..)) where+++import           GHC.Base+import           Numeric.DataFrame.Internal.PrimArray+import           Numeric.PrimBytes+import           Numeric.ProductOrd+import qualified Numeric.ProductOrd.NonTransitive     as NonTransitive+import qualified Numeric.ProductOrd.Partial           as Partial++-- | Specialize ScalarBase type without any arrays+newtype ScalarBase t = ScalarBase { _unScalarBase :: t }+  deriving ( Enum, Eq, Bounded, Integral+           , Num, Fractional, Floating, Ord, Real, RealFrac, RealFloat+           , PrimBytes)++instance Ord t => ProductOrder (ScalarBase t) where+  cmp a b = fromOrdering (compare (_unScalarBase a) (_unScalarBase b))+deriving instance Ord t => Ord (NonTransitive.ProductOrd (ScalarBase t))+deriving instance Ord t => Ord (Partial.ProductOrd (ScalarBase t))++instance PrimBytes t => PrimArray t (ScalarBase t) where+  broadcast = unsafeCoerce#+  {-# INLINE broadcast #-}+  ix# _ = unsafeCoerce#+  {-# INLINE ix# #-}+  gen# _ = unsafeCoerce#+  {-# INLINE gen# #-}+  upd# _ 0# = const . ScalarBase+  upd# _ _  = const id+  {-# INLINE upd# #-}+  arrayContent# x = (# _unScalarBase x | #)+  {-# INLINE arrayContent# #-}+  offsetElems _ = 0#+  {-# INLINE offsetElems #-}+  uniqueOrCumulDims = Left . _unScalarBase+  {-# INLINE uniqueOrCumulDims #-}+  fromElems _ off ba = indexArray ba off+  {-# INLINE fromElems #-}++_suppressHlintUnboxedTuplesWarning :: () -> (# (), () #)+_suppressHlintUnboxedTuplesWarning = undefined
src/Numeric/DataFrame.hs view
@@ -1,5 +1,3 @@-{-# LANGUAGE PatternSynonyms #-}- module Numeric.DataFrame   ( module Numeric.DataFrame.Type     -- * Simplified type aliases@@ -9,16 +7,14 @@     -- * Functionality   , module Numeric.DataFrame.SubSpace   , module Numeric.DataFrame.Contraction-  , module Numeric.DataFrame.Shape   ) where -import           Numeric.DataFrame.Internal.Array ()+import Numeric.DataFrame.Internal.Backend () -import           Numeric.DataFrame.Contraction-import           Numeric.DataFrame.Shape-import           Numeric.DataFrame.SubSpace-import           Numeric.DataFrame.Type+import Numeric.DataFrame.Contraction+import Numeric.DataFrame.SubSpace+import Numeric.DataFrame.Type -import           Numeric.Matrix-import           Numeric.Scalar-import           Numeric.Vector+import Numeric.Matrix+import Numeric.Scalar+import Numeric.Vector
src/Numeric/DataFrame/Contraction.hs view
@@ -30,11 +30,11 @@   ( Contraction (..), (%*)   ) where -import           GHC.Base+import GHC.Base -import           Numeric.DataFrame.Family-import           Numeric.DataFrame.Internal.Array.Class-import           Numeric.Dimensions+import Numeric.DataFrame.Internal.PrimArray+import Numeric.DataFrame.Type+import Numeric.Dimensions   @@ -55,13 +55,12 @@ --     1. matrix-matrix product --     2. matrix-vector or vector-matrix product --     3. dot product of two vectors.-(%*) :: ( ConcatList as bs (as ++ bs)-        , Contraction t as bs asbs+(%*) :: ( Contraction t as bs asbs         , KnownDim m         , PrimArray t (DataFrame t (as +: m))         , PrimArray t (DataFrame t (m :+ bs))-        , PrimArray t (DataFrame t (as ++ bs))-        )  => DataFrame t (as +: m) -> DataFrame t (m :+ bs) -> DataFrame t (as ++ bs)+        , PrimArray t (DataFrame t asbs)+        )  => DataFrame t (as +: m) -> DataFrame t (m :+ bs) -> DataFrame t asbs (%*) = contract {-# INLINE (%*) #-} infixl 7 %*@@ -73,6 +72,7 @@          , Dimensions bs          , Num t          ) => Contraction t as bs asbs where+     contract :: forall m .                 ( KnownDim m                 , PrimArray t (DataFrame t (as +: m))@@ -80,19 +80,40 @@                 , PrimArray t (DataFrame t asbs)                 )              => DataFrame t (as +: m) -> DataFrame t (m :+ bs) -> DataFrame t asbs-    contract x y-        | I# m <- fromIntegral $ dimVal' @m-        , I# n <- fromIntegral $ totalDim' @as-        , I# k <- fromIntegral $ totalDim' @bs-        , nk <- n *# k-        = let loop i j l r | isTrue# (l ==# m) = r+    contract x y = case (# uniqueOrCumulDims x, uniqueOrCumulDims y #) of+      (# Left x0, Left y0 #) -> broadcast (x0 * y0)+      (# ux, uy #)+        | dm <- dim @m+        , (ixX, xs) <- getStepsAndIx (Snoc dims dm) x ux+        , (ixY, ys) <- getStepsAndIx (Cons dm dims) y uy+        , (# n, m, k, steps #) <- conSteps xs ys ->+          let loop i j l r | isTrue# (l ==# m) = r                            | otherwise = loop i j (l +# 1#)-                              (r + ix# (i +# n *# l) x * ix# (l +# m *# j) y)+                              (r + ixX (i *# m +# l) * ixY (l *# k +# j)) -              loop2 (T# i j) | isTrue# (j ==# k) = (# T# i j, 0 #)-                             | isTrue# (i ==# n) = loop2 (T# 0# (j +# 1#))-                             | otherwise = (# T# (i +# 1#) j, loop i j 0# 0 #)-          in case gen# nk loop2 (T# 0# 0#) of+              loop2 (T# i j) | isTrue# (i ==# n) = (# T# i j, 0 #)+                             | isTrue# (j ==# k) = loop2 (T# (i +# 1#) 0#)+                             | otherwise = (# T# i (j +# 1#), loop i j 0# 0 #)+          in case gen# steps loop2 (T# 0# 0#) of               (# _, r #) -> r+      where+        getStepsAndIx :: forall (ns :: [Nat])+                       . PrimArray t (DataFrame t ns)+                      => Dims ns+                      -> DataFrame t ns+                      -> Either t CumulDims+                      -> (Int# -> t, CumulDims)+        getStepsAndIx _  df (Right cds) = ((`ix#` df), cds)+        getStepsAndIx ds _  (Left  e)   = (\_ -> e, cumulDims ds)+        conSteps (CumulDims xs) (CumulDims ys) = case conSteps' xs ys of+          (W# n, W# m, W# k, zs)+            -> (# word2Int# n, word2Int# m, word2Int# k, CumulDims zs #)+        conSteps' :: [Word] -> [Word] -> (Word, Word, Word, [Word])+        conSteps' [m, _] (_:ys@(k:_)) = (1, m, k, ys)+        conSteps' (nm:ns) cys+          | (_, m, k, ys) <- conSteps' ns cys+          , n <- nm `quot` m+            = (n, m, k, n*k : ys )+        conSteps' _ _ = error "Numeric.DataFrame.Contraction: impossible match"  data T# = T# Int# Int#
− src/Numeric/DataFrame/Family.hs
@@ -1,9 +0,0 @@-{-# LANGUAGE DataKinds    #-}-{-# LANGUAGE PolyKinds    #-}-{-# LANGUAGE TypeFamilies #-}--- | The very core of DataFrame: definition of the data family.-module Numeric.DataFrame.Family ( DataFrame ) where---- | Keep data in a primitive data frame---    and maintain information about Dimensions in the type system-data family DataFrame (t :: l) (xs :: [k])
src/Numeric/DataFrame/IO.hs view
@@ -2,7 +2,6 @@ {-# LANGUAGE ExistentialQuantification #-} {-# LANGUAGE FlexibleContexts          #-} {-# LANGUAGE FlexibleInstances         #-}-{-# LANGUAGE KindSignatures            #-} {-# LANGUAGE MagicHash                 #-} {-# LANGUAGE MultiParamTypeClasses     #-} {-# LANGUAGE PolyKinds                 #-}@@ -17,8 +16,6 @@ -- Copyright   :  (c) Artem Chirkin -- License     :  BSD3 ----- Maintainer  :  chirkin@arch.ethz.ch--- -- Mutable DataFrames living in IO. -- -----------------------------------------------------------------------------@@ -27,6 +24,7 @@     ( IODataFrame (XIOFrame), SomeIODataFrame (..)     , newDataFrame, newPinnedDataFrame     , copyDataFrame, copyMutableDataFrame+    , copyDataFrame', copyMutableDataFrame'     , freezeDataFrame, unsafeFreezeDataFrame     , thawDataFrame, thawPinDataFrame, unsafeThawDataFrame     , writeDataFrame, writeDataFrameOff@@ -35,15 +33,14 @@     ) where  -import           GHC.Base-import           GHC.IO                                 (IO (..))-import           GHC.Ptr                                (Ptr (..))+import GHC.Base+import GHC.IO   (IO (..))+import GHC.Ptr  (Ptr (..)) -import           Numeric.DataFrame.Family-import           Numeric.DataFrame.Internal.Array.Class-import           Numeric.DataFrame.Internal.Mutable-import           Numeric.Dimensions-import           Numeric.PrimBytes+import Numeric.DataFrame.Internal.Mutable+import Numeric.DataFrame.Internal.PrimArray+import Numeric.DataFrame.Type+import Numeric.Dimensions   -- | Mutable DataFrame that lives in IO.@@ -80,31 +77,69 @@   -- | Copy one DataFrame into another mutable DataFrame at specified position.-copyDataFrame :: forall (t :: Type) (as :: [Nat]) (b' :: Nat) (b :: Nat)-                                    (bs :: [Nat]) (asbs :: [Nat])-               . ( PrimBytes t-                 , PrimBytes (DataFrame t (as +: b'))+--+--   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-                 , Dimensions (b :+ bs)                  )-               => DataFrame t (as +: b') -> Idxs (b :+ bs) -> IODataFrame t asbs -> IO ()-copyDataFrame df ei (IODataFrame mdf) = IO (copyDataFrame# df ei mdf)+              => Idxs (as +: bi) -> DataFrame t (bd :+ bs)+              -> IODataFrame t asbs -> IO ()+copyDataFrame ei df (IODataFrame mdf) = IO (copyDataFrame# ei df mdf) {-# INLINE copyDataFrame #-}  -- | Copy one mutable DataFrame into another mutable DataFrame at specified position.-copyMutableDataFrame :: forall (t :: Type) (as :: [Nat]) (b' :: Nat) (b :: Nat)-                               (bs :: [Nat]) (asbs :: [Nat])-                      . ( PrimBytes t+--+--   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-                        , Dimensions (b :+ bs)                         )-                     => IODataFrame t (as +: b') -> Idxs (b :+ bs)+                     => Idxs (as +: bi) -> IODataFrame t (bd :+ bs)                      -> IODataFrame t asbs -> IO ()-copyMutableDataFrame (IODataFrame mdfA) ei (IODataFrame mdfB)-    = IO (copyMDataFrame# mdfA ei mdfB)+copyMutableDataFrame ei (IODataFrame mdfA) (IODataFrame mdfB)+    = IO (copyMDataFrame# ei mdfA mdfB) {-# INLINE copyMutableDataFrame #-} +-- | 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 ()+copyDataFrame' ei df (IODataFrame mdf) = IO (copyDataFrame'# ei df mdf)+{-# INLINE copyDataFrame' #-} +-- | 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 ()+copyMutableDataFrame' ei (IODataFrame mdfA) (IODataFrame mdfB)+  = IO (copyMDataFrame'# ei mdfA mdfB)+{-# INLINE copyMutableDataFrame' #-}+ -- | Make a mutable DataFrame immutable, without copying. unsafeFreezeDataFrame :: forall (t :: Type) (ns :: [Nat])                        . PrimArray t (DataFrame t ns)@@ -122,7 +157,7 @@  -- | Create a new mutable DataFrame and copy content of immutable one in there. thawDataFrame :: forall (t :: Type) (ns :: [Nat])-               . (PrimBytes (DataFrame t ns), PrimBytes t)+               . (Dimensions ns, PrimBytes (DataFrame t ns))               => DataFrame t ns -> IO (IODataFrame t ns) thawDataFrame df = IODataFrame <$> IO (thawDataFrame# df) {-# INLINE thawDataFrame #-}@@ -130,14 +165,15 @@ -- | 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])-                  . (PrimBytes (DataFrame t ns), PrimBytes t)+                  . (Dimensions ns, PrimBytes (DataFrame t ns))                  => DataFrame t ns -> IO (IODataFrame t ns) thawPinDataFrame df = IODataFrame <$> IO (thawPinDataFrame# df) {-# INLINE thawPinDataFrame #-}  -- | UnsafeCoerces an underlying byte array. unsafeThawDataFrame :: forall (t :: Type) (ns :: [Nat])-                     . (PrimBytes (DataFrame t ns), PrimBytes t)+                     . ( Dimensions ns+                       , PrimBytes (DataFrame t ns), PrimBytes t)                     => DataFrame t ns -> IO (IODataFrame t ns) unsafeThawDataFrame df = IODataFrame <$> IO (unsafeThawDataFrame# df) {-# INLINE unsafeThawDataFrame #-}@@ -145,7 +181,7 @@  -- | Write a single element at the specified index writeDataFrame :: forall t (ns :: [Nat])-                . ( PrimBytes t, Dimensions ns )+                . PrimBytes t                => IODataFrame t ns -> Idxs ns -> DataFrame t ('[] :: [Nat]) -> IO () writeDataFrame (IODataFrame mdf) ei = IO . writeDataFrame# mdf ei . unsafeCoerce# {-# INLINE writeDataFrame #-}@@ -153,7 +189,7 @@  -- | Read a single element at the specified index readDataFrame :: forall (t :: Type) (ns :: [Nat])-               . ( PrimBytes t, Dimensions ns )+               . PrimBytes t               => IODataFrame t ns -> Idxs ns -> IO (DataFrame t ('[] :: [Nat])) readDataFrame (IODataFrame mdf) = unsafeCoerce# . IO . readDataFrame# mdf {-# INLINE readDataFrame #-}@@ -177,6 +213,18 @@ {-# INLINE readDataFrameOff #-}  +-- | 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+isDataFramePinned df = case dimKind @k of+    DimNat -> case df of+      IODataFrame x -> isDataFramePinned# x+    DimXNat -> case df of+      XIOFrame (IODataFrame x) -> isDataFramePinned# x++ -- | Allow arbitrary IO operations on a pointer to the beginning of the data --   keeping the data from garbage collecting until the arg function returns. --@@ -185,7 +233,7 @@ -- --   Warning: use this function on a pinned DataFrame only; --            otherwise, the data may be relocated before the arg fun finishes.-withDataFramePtr :: forall (t :: Type) (ns :: [k]) (r :: Type)+withDataFramePtr :: forall (k :: Type) (t :: Type) (ns :: [k]) (r :: Type)                   . (PrimBytes t, KnownDimKind k)                  => IODataFrame t ns                  -> ( Ptr t -> IO r )@@ -197,15 +245,3 @@     DimXNat -> case df of       XIOFrame (IODataFrame x)         -> IO $ withDataFramePtr# x (\p -> case k (Ptr p) of IO f -> f)----- | Check if the byte array wrapped by this DataFrame is pinned,---   which means cannot be relocated by GC.-isDataFramePinned :: forall (t :: Type) (ns :: [k])-                   . KnownDimKind k-                  => IODataFrame t ns -> Bool-isDataFramePinned df = case dimKind @k of-    DimNat -> case df of-      IODataFrame x -> isDataFramePinned# x-    DimXNat -> case df of-      XIOFrame (IODataFrame x) -> isDataFramePinned# x
− src/Numeric/DataFrame/Internal/Array.hs
@@ -1,26 +0,0 @@--------------------------------------------------------------------------------- |--- Module      :  Numeric.DataFrame.Internal.Array--- Copyright   :  (c) Artem Chirkin--- License     :  BSD3------ Maintainer  :  chirkin@arch.ethz.ch------ Low-level implementations of data frames-----------------------------------------------------------------------------------module Numeric.DataFrame.Internal.Array-  ( module Numeric.DataFrame.Internal.Array.Family-  ) where--import           Numeric.DataFrame.Internal.Array.Family--- import           Numeric.DataFrame.Internal.Array.Family.ArrayBase ()---- import           Numeric.DataFrame.Internal.Array.Family.FloatX2   ()--- import           Numeric.DataFrame.Internal.Array.Family.FloatX3   ()--- import           Numeric.DataFrame.Internal.Array.Family.FloatX4   ()------ import           Numeric.DataFrame.Internal.Array.Family.DoubleX2  ()--- import           Numeric.DataFrame.Internal.Array.Family.DoubleX3  ()--- import           Numeric.DataFrame.Internal.Array.Family.DoubleX4  ()
− src/Numeric/DataFrame/Internal/Array/Class.hs
@@ -1,51 +0,0 @@-{-# LANGUAGE DataKinds              #-}-{-# LANGUAGE FunctionalDependencies #-}-{-# LANGUAGE MagicHash              #-}-{-# LANGUAGE MultiParamTypeClasses  #-}-{-# LANGUAGE UnboxedTuples          #-}-module Numeric.DataFrame.Internal.Array.Class-  ( PrimArray (..)-  , ixOff, unsafeFromFlatList-  ) where--import           GHC.Base          (ByteArray#, Int#, Int (..))-import           Numeric.PrimBytes---class PrimBytes t => PrimArray t a | a -> t where-    -- | Broadcast element into array-    broadcast :: t -> a-    -- | Index an array given an offset-    ix# :: Int# -> a -> t-    -- | Generate an array using an accumulator funtion-    gen# :: Int# -- ^ number of elements, not checked!-                 --   Avoid using this argument if possible.-         -> (s -> (# s, t #))-         -> s -> (# s, a #)-    -- | update a single element in an array given an offset-    upd# :: Int# -- ^ number of elements, not checked!-                 --   Avoid using this argument if possible.-         -> Int# -> t -> a -> a--    -- | Offset of an array in number of elements-    elemOffset :: a -> Int#--    -- | Number of elements in an array.-    --   Returns zero if this information is not available at runtime.-    --   This is possible only if all elements are same in an array.-    elemSize0 :: a -> Int#--    -- | Get array by its offset and size in a ByteArray.-    --   Both offset and size are given in element number.-    fromElems :: Int# -> Int# -> ByteArray# -> a---- | Index array by an integer offset (starting from 0).-ixOff :: PrimArray t a => Int -> a -> t-ixOff (I# i) = ix# i---- | Construct an array from a flat list and length-unsafeFromFlatList :: PrimArray t a => Int -> [t] -> a-unsafeFromFlatList (I# n) vs = case gen# n f vs of (# _, r #) -> r-  where-    f [] = (# [], undefined #)-    f (x:xs) = (# xs, x #)
− src/Numeric/DataFrame/Internal/Array/Family.hs
@@ -1,216 +0,0 @@-{-# LANGUAGE AllowAmbiguousTypes    #-}-{-# LANGUAGE CPP                    #-}-{-# LANGUAGE ConstraintKinds        #-}-{-# LANGUAGE DataKinds              #-}-{-# LANGUAGE FlexibleContexts       #-}-{-# LANGUAGE FlexibleInstances      #-}-{-# LANGUAGE GADTs                  #-}-{-# LANGUAGE MagicHash              #-}-{-# LANGUAGE MultiParamTypeClasses  #-}-{-# LANGUAGE PolyKinds              #-}-{-# LANGUAGE Rank2Types             #-}-{-# LANGUAGE ScopedTypeVariables    #-}-{-# LANGUAGE StandaloneDeriving     #-}-{-# LANGUAGE TypeApplications       #-}-{-# LANGUAGE TypeFamilies           #-}-{-# LANGUAGE TypeFamilyDependencies #-}-{-# LANGUAGE TypeInType             #-}-{-# LANGUAGE TypeOperators          #-}--------------------------------------------------------------------------------- |--- Module      :  Numeric.DataFrame.Internal.Array.Family--- Copyright   :  (c) Artem Chirkin--- License     :  BSD3------ Maintainer  :  chirkin@arch.ethz.ch--------------------------------------------------------------------------------------module Numeric.DataFrame.Internal.Array.Family-  ( Array, ScalarBase (..), ArrayBase (..)-  , ArraySingleton (..)-  , ArraySing (..), aSingEv, inferASing-  , inferPrimElem, inferPrim, inferEq, inferShow, inferOrd, inferNum-  , inferFractional, inferFloating-  ) where---import           GHC.Base---import           Numeric.DataFrame.Internal.Array.Class-import           Numeric.DataFrame.Internal.Array.Family.ArrayBase-import           Numeric.DataFrame.Internal.Array.Family.DoubleX2-import           Numeric.DataFrame.Internal.Array.Family.DoubleX3-import           Numeric.DataFrame.Internal.Array.Family.DoubleX4-import           Numeric.DataFrame.Internal.Array.Family.FloatX2-import           Numeric.DataFrame.Internal.Array.Family.FloatX3-import           Numeric.DataFrame.Internal.Array.Family.FloatX4-import           Numeric.DataFrame.Internal.Array.Family.ScalarBase-import           Numeric.Dimensions-import           Numeric.PrimBytes----- | 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 an array at compile time, it chooses---   a more efficient specialized instance of Array, 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 Array (t :: Type) (ds :: [Nat]) = (v :: Type) | v -> t ds where-    Array t      '[]    = ScalarBase t-    Array Float  '[2]   = FloatX2-    Array Float  '[3]   = FloatX3-    Array Float  '[4]   = FloatX4-    Array Double '[2]   = DoubleX2-    Array Double '[3]   = DoubleX3-    Array Double '[4]   = DoubleX4-    Array t       ds    = ArrayBase t ds---- | A framework for using Array type family instances.-class ArraySingleton (t :: Type) (ds :: [Nat]) where-    -- | Get Array type family instance-    aSing :: ArraySing t ds--data ArraySing t (ds :: [Nat]) where-    AScalar :: (Array t ds ~ ScalarBase t)   => ArraySing t      '[]-    AF2     :: (Array t ds ~ FloatX2)        => ArraySing Float  '[2]-    AF3     :: (Array t ds ~ FloatX3)        => ArraySing Float  '[3]-    AF4     :: (Array t ds ~ FloatX4)        => ArraySing Float  '[4]-    AD2     :: (Array t ds ~ DoubleX2)       => ArraySing Double '[2]-    AD3     :: (Array t ds ~ DoubleX3)       => ArraySing Double '[3]-    AD4     :: (Array t ds ~ DoubleX4)       => ArraySing Double '[4]-    ABase   :: ( Array t ds ~ ArrayBase t ds-               , PrimBytes t-               ) => ArraySing t ds--deriving instance Eq (ArraySing t ds)-deriving instance Ord (ArraySing t ds)-deriving instance Show (ArraySing t ds)------ | This function does GHC's magic to convert user-supplied `aSing` function---   to create an instance of `ArraySingleton` typeclass at runtime.---   The trick is taken from Edward Kmett's reflection library explained---   in https://www.schoolofhaskell.com/user/thoughtpolice/using-reflection-reifyArraySing :: forall r t ds-                . ArraySing t ds -> ( ArraySingleton t ds => r) -> r-reifyArraySing as k-  = unsafeCoerce# (MagicArraySing k :: MagicArraySing t ds r) as-{-# INLINE reifyArraySing #-}-newtype MagicArraySing t (ds :: [Nat]) r-  = MagicArraySing (ArraySingleton t ds => r)---- | Use `ArraySing` GADT to construct an `ArraySingleton` dictionary.---   In other words, bring an evidence of `ArraySingleton` instance into---   a scope at runtime.-aSingEv :: ArraySing t ds -> Evidence (ArraySingleton t ds)-aSingEv ds = reifyArraySing ds E-{-# INLINE aSingEv #-}---- | Use `ArraySing` GADT to construct an `ArraySingleton` dictionary.---   The same as `aSingEv`, but relies on `PrimBytes` and `Dimensions`.-inferASing :: forall t ds-            . (PrimBytes t, Dimensions ds)-           => Evidence (ArraySingleton t ds)-inferASing = case (dims @_ @ds, primTag @t undefined) of-  (U, _) -> E-  (d :* U, PTagFloat)-      | Just E <- sameDim (D @2) d -> E-      | Just E <- sameDim (D @3) d -> E-      | Just E <- sameDim (D @4) d -> E-  (d :* U, PTagDouble)-      | Just E <- sameDim (D @2) d -> E-      | Just E <- sameDim (D @3) d -> E-      | Just E <- sameDim (D @4) d -> E-  _ -> case (unsafeCoerce# (E @(ds ~ ds)) :: Evidence (ds ~ '[0])) of E -> E-{-# INLINE inferASing #-}---instance {-# OVERLAPPABLE #-}-         (Array t ds ~ ArrayBase t ds, PrimBytes t)-         => ArraySingleton t ds where-    aSing = ABase-instance {-# OVERLAPPING #-}  ArraySingleton t      '[]    where-    aSing = AScalar-instance {-# OVERLAPPING #-}  ArraySingleton Float  '[2]   where-    aSing = AF2-instance {-# OVERLAPPING #-}  ArraySingleton Float  '[3]   where-    aSing = AF3-instance {-# OVERLAPPING #-}  ArraySingleton Float  '[4]   where-    aSing = AF4-instance {-# OVERLAPPING #-}  ArraySingleton Double '[2]   where-    aSing = AD2-instance {-# OVERLAPPING #-}  ArraySingleton Double '[3]   where-    aSing = AD3-instance {-# OVERLAPPING #-}  ArraySingleton Double '[4]   where-    aSing = AD4---- | This is a special function, because Scalar does not require PrimBytes.---   That is why the dimension list in the argument is not empty.-inferPrimElem :: forall t d ds-               . ArraySingleton t (d ': ds)-              => Evidence (PrimBytes t)-inferPrimElem = case (aSing :: ArraySing t (d ': ds)) of-  AF2   -> E-  AF3   -> E-  AF4   -> E-  AD2   -> E-  AD3   -> E-  AD4   -> E-  ABase -> E---- Rather verbose way to show that there is an instance of a required type class--- for every instance of the type family.-#define WITNESS case (aSing :: ArraySing t ds) of {\-  AScalar -> E;\-  AF2     -> E;\-  AF3     -> E;\-  AF4     -> E;\-  AD2     -> E;\-  AD3     -> E;\-  AD4     -> E;\-  ABase   -> E}--inferPrim :: forall t ds-           . ( PrimBytes t-             , ArraySingleton t ds-             , Dimensions ds-             )-          => Evidence (PrimBytes (Array t ds), PrimArray t (Array t ds))-inferPrim = WITNESS--inferEq :: forall t ds-         . (Eq t, ArraySingleton t ds)-        => Evidence (Eq (Array t ds))-inferEq = WITNESS--inferOrd :: forall t ds-            . (Ord t, ArraySingleton t ds)-           => Evidence (Ord (Array t ds))-inferOrd = WITNESS--inferNum :: forall t ds-          . (Num t, ArraySingleton t ds)-         => Evidence (Num (Array t ds))-inferNum = WITNESS--inferFractional :: forall t ds-                 . (Fractional t, ArraySingleton t ds)-                => Evidence (Fractional (Array t ds))-inferFractional = WITNESS--inferFloating :: forall t ds-               . (Floating t, ArraySingleton t ds)-              => Evidence (Floating (Array t ds))-inferFloating = WITNESS--inferShow :: forall t ds-           . (Show t, Dimensions ds, ArraySingleton t ds)-          => Evidence (Show (Array t ds))-inferShow = WITNESS
− src/Numeric/DataFrame/Internal/Array/Family/ArrayBase.hs
@@ -1,498 +0,0 @@-{-# LANGUAGE ConstraintKinds           #-}-{-# LANGUAGE DataKinds                 #-}-{-# LANGUAGE ExistentialQuantification #-}-{-# LANGUAGE FlexibleContexts          #-}-{-# LANGUAGE FlexibleInstances         #-}-{-# LANGUAGE GADTs                     #-}-{-# LANGUAGE MagicHash                 #-}-{-# LANGUAGE MultiParamTypeClasses     #-}-{-# LANGUAGE PolyKinds                 #-}-{-# LANGUAGE Rank2Types                #-}-{-# LANGUAGE ScopedTypeVariables       #-}-{-# LANGUAGE TypeApplications          #-}-{-# LANGUAGE TypeFamilies              #-}-{-# LANGUAGE TypeFamilyDependencies    #-}-{-# LANGUAGE TypeInType                #-}-{-# LANGUAGE TypeOperators             #-}-{-# LANGUAGE UnboxedSums               #-}-{-# LANGUAGE UnboxedTuples             #-}--module Numeric.DataFrame.Internal.Array.Family.ArrayBase-  ( ArrayBase (..)-  ) where--import           Data.Int-import           Data.Word-import           GHC.Base                                 hiding (foldr)-import           Numeric.DataFrame.Internal.Array.Class-import           Numeric.DataFrame.Internal.Array.PrimOps-import           Numeric.Dimensions-import           Numeric.PrimBytes---- | Generic Array implementation.---   This array can reside in plain `ByteArray#` and can share the @ByteArray#@---   with other arrays.---   However, byte offset in the @ByteArray#@ must be multiple of the element size.-data ArrayBase (t :: Type) (ds :: [Nat])-  = ArrayBase-    (# t-       --  Same value for each element;-       --  this is the cheapest way to initialize an array.-       --  It is also used for Num instances to avoid dependency on Dimensions.-     | (# Int#  -- Offset measured in elements.-        , Int#  -- Number of elements.-        , ByteArray# -- Content.-        , Evidence (PrimBytes t)-        #)-     #)---instance (PrimBytes t, Dimensions ds) => PrimBytes (ArrayBase t ds) where-    {-# SPECIALIZE instance Dimensions ds => PrimBytes (ArrayBase Float ds)  #-}-    {-# SPECIALIZE instance Dimensions ds => PrimBytes (ArrayBase Double ds) #-}-    {-# SPECIALIZE instance Dimensions ds => PrimBytes (ArrayBase Int ds)    #-}-    {-# SPECIALIZE instance Dimensions ds => PrimBytes (ArrayBase Word ds)   #-}-    {-# SPECIALIZE instance Dimensions ds => PrimBytes (ArrayBase Int8 ds)   #-}-    {-# SPECIALIZE instance Dimensions ds => PrimBytes (ArrayBase Int16 ds)  #-}-    {-# SPECIALIZE instance Dimensions ds => PrimBytes (ArrayBase Int32 ds)  #-}-    {-# SPECIALIZE instance Dimensions ds => PrimBytes (ArrayBase Int64 ds)  #-}-    {-# SPECIALIZE instance Dimensions ds => PrimBytes (ArrayBase Word8 ds)  #-}-    {-# SPECIALIZE instance Dimensions ds => PrimBytes (ArrayBase Word16 ds) #-}-    {-# SPECIALIZE instance Dimensions ds => PrimBytes (ArrayBase Word32 ds) #-}-    {-# SPECIALIZE instance Dimensions ds => PrimBytes (ArrayBase Word64 ds) #-}--    getBytes (ArrayBase a ) = case a of-        (# t | #)-          | W# nw <- totalDim' @ds-          , n <- word2Int# nw-          , tbs <- byteSize t   -> go tbs (tbs *# n) t-        (# | (# _, _, arr, _ #) #) ->-          -- very weird trick with touch# allows to workaround GHC bug-          --  "internal error: ARR_WORDS object entered!"-          -- TODO: report this-          case runRW# (\s -> (# touch# arr s, arr #)) of (# _, ba #) -> ba-      where-        go tbs bsize t = case runRW#-         ( \s0 -> case newByteArray# bsize s0 of-             (# s1, mba #) -> unsafeFreezeByteArray# mba-               ( loop# 0# tbs bsize (\i -> writeBytes mba i t) s1 )-         ) of (# _, ba #) -> ba-        {-# NOINLINE go #-}-    {-# INLINE getBytes #-}--    fromBytes bOff ba-      | W# nw <- totalDim' @ds-      , n <- word2Int# nw-      , tbs <- byteSize (undefined :: t)-      , (# offN, offRem #) <- quotRemInt# bOff tbs-      = case offRem of-          0# -> ArrayBase (# | (# offN, n , ba, E #) #)-          _  -> go n (tbs *# n)-      where-        go n bsize = case runRW#-         ( \s0 -> case ( if isTrue# (isByteArrayPinned# ba)-                         then newAlignedPinnedByteArray# bsize-                                (byteAlign @t undefined)-                         else newByteArray# bsize-                       ) s0-                  of-            (# s1, mba #) -> unsafeFreezeByteArray# mba-                              (copyByteArray# ba bOff mba 0# bsize s1)-         ) of (# _, r #) -> ArrayBase (# | (# 0# , n , r, E #) #)-        {-# NOINLINE go #-}-    {-# INLINE fromBytes #-}--    readBytes mba bOff s0-      | W# nw <- totalDim' @ds-      , n <- word2Int# nw-      , tbs <- byteSize (undefined :: t)-      , bsize <- tbs *# n-      = case newByteArray# bsize s0 of-         (# s1, mba1 #) -> case unsafeFreezeByteArray# mba1-                                (copyMutableByteArray# mba bOff mba1 0# bsize s1) of-           (# s2, ba #) -> (# s2, ArrayBase (# | (# 0# , n , ba, E #) #) #)-    {-# INLINE readBytes #-}--    writeBytes mba bOff (ArrayBase c)-      | tbs <- byteSize (undefined :: t) = case c of-        (# t | #) | W# n <- totalDim' @ds ->-          loop# bOff tbs (bOff +# word2Int# n *# tbs) (\i -> writeBytes mba i t)-        (# | (# offN, n, arr, _ #) #) ->-          copyByteArray# arr (offN *# tbs) mba bOff (n *# tbs)-    {-# INLINE writeBytes #-}--    readAddr addr s0-      | W# nw <- totalDim' @ds-      , n <- word2Int# nw-      , tbs <- byteSize (undefined :: t)-      , bsize <- tbs *# n-      = case newByteArray# bsize s0 of-         (# s1, mba1 #) -> case unsafeFreezeByteArray# mba1-                                (copyAddrToByteArray# addr mba1 0# bsize s1) of-           (# s2, ba #) -> (# s2, ArrayBase (# | (# 0# , n , ba, E #) #) #)-    {-# INLINE readAddr #-}--    writeAddr (ArrayBase c) addr-      | tbs <- byteSize (undefined :: t) = case c of-        (# t | #) | W# n <- totalDim' @ds ->-          loop# 0# tbs (word2Int# n *# tbs) (\i -> writeAddr t (plusAddr# addr i))-        (# | (# offN, n, arr, _ #) #) ->-          copyByteArrayToAddr# arr (offN *# tbs) addr (n *# tbs)-    {-# INLINE writeAddr #-}---    byteSize  _ = case totalDim' @ds of -- WARNING: slow!-      W# n -> byteSize (undefined :: t) *# word2Int# n-    {-# INLINE byteSize #-}--    byteAlign _ = byteAlign (undefined :: t)-    {-# INLINE byteAlign #-}--    byteOffset (ArrayBase a) = case a of-      (# _ | #)                  -> 0#-      (# | (# off, _, _, _ #) #) -> off *# byteSize (undefined :: t)-    {-# INLINE byteOffset #-}--    indexArray ba off-      | W# nw <- totalDim' @ds-      , n <- word2Int# nw-      = ArrayBase (# | (# off *# n, n, ba, E #) #)-    {-# INLINE indexArray #-}------ | Accumulates only idempotent operations!---   Being applied to FromScalars, executes only once!---   Here, idempotance means: assuming @f a b = g x@, @g (g x) = g x@------   Also, I assume the sizes of arrays are the same-accumV2Idempotent :: a-                  -> (t -> t -> a -> a)-                  -> ArrayBase t ds -> ArrayBase t ds -> a-accumV2Idempotent x f-  (ArrayBase (# a | #))-  (ArrayBase (# b | #))-    = f a b x-accumV2Idempotent x f-  a@(ArrayBase (# | (# _, nA, _, E #) #))-  b@(ArrayBase (# | (# _, nB, _, _ #) #))-    = loop1a# (minInt# nA nB) (\i -> f (ix# i a) (ix# i b)) x-accumV2Idempotent x f-    (ArrayBase (# a | #))-  b@(ArrayBase (# | (# _, n, _, E #) #))-    = loop1a# n (\i -> f a (ix# i b)) x-accumV2Idempotent x f-  a@(ArrayBase (# | (# _, n, _, E #) #))-    (ArrayBase (# b | #))-    = loop1a# n (\i -> f (ix# i a) b) x-{-# INLINE accumV2Idempotent #-}--mapV :: (t -> t) -> ArrayBase t ds -> ArrayBase t ds-mapV f (ArrayBase (# t | #))-    = ArrayBase (# f t | #)-mapV f x@(ArrayBase (# | (# offN, n, ba, E #) #))-    | tbs <- byteSize (undefEl x)-    = go (tbs *# n)-  where-    go bsize = case runRW#-     ( \s0 -> case newByteArray# bsize s0 of-         (# s1, mba #) -> unsafeFreezeByteArray# mba-           ( loop1# n-               (\i -> writeArray mba i (f (indexArray ba (offN +# i)))) s1-           )-     ) of (# _, r #) -> ArrayBase (# | (# 0#, n, r, E #) #)-    {-# NOINLINE go #-}-{-# INLINE mapV #-}---zipV :: (t -> t -> t)-     -> ArrayBase t ds -> ArrayBase t ds -> ArrayBase t ds-zipV f (ArrayBase (# x | #)) b = mapV (f x) b-zipV f a (ArrayBase (# y | #)) = mapV (`f` y) a-zipV f a@(ArrayBase (# | (# oa, na, ba, E #) #))-         (ArrayBase (# | (# ob, nb, bb, _ #) #))-    | n <- minInt# na nb-    = go n (byteSize (undefEl a) *# n)-  where-    go n bsize = case runRW#-     ( \s0 -> case newByteArray# bsize s0 of-         (# s1, mba #) -> unsafeFreezeByteArray# mba-           ( loop1# n-               (\i -> writeArray mba i-                        (f (indexArray ba (oa +# i))-                           (indexArray bb (ob +# i))-                        )-               ) s1-           )-     ) of (# _, r #) -> ArrayBase (# | (# 0#, n, r, E #) #)-    {-# NOINLINE go #-}-{-# INLINE zipV #-}----- TODO: to improve performance, I can either compare bytearrays using memcmp---       or implement early termination if the first elements do not match.---       On the other hand, hopefully @(&&)@ and @(||)@ ops take care of that.-instance Eq t => Eq (ArrayBase t ds) where-    {-# SPECIALIZE instance Eq (ArrayBase Float ds)  #-}-    {-# SPECIALIZE instance Eq (ArrayBase Double ds) #-}-    {-# SPECIALIZE instance Eq (ArrayBase Int ds)    #-}-    {-# SPECIALIZE instance Eq (ArrayBase Word ds)   #-}-    {-# SPECIALIZE instance Eq (ArrayBase Int8 ds)   #-}-    {-# SPECIALIZE instance Eq (ArrayBase Int16 ds)  #-}-    {-# SPECIALIZE instance Eq (ArrayBase Int32 ds)  #-}-    {-# SPECIALIZE instance Eq (ArrayBase Int64 ds)  #-}-    {-# SPECIALIZE instance Eq (ArrayBase Word8 ds)  #-}-    {-# SPECIALIZE instance Eq (ArrayBase Word16 ds) #-}-    {-# SPECIALIZE instance Eq (ArrayBase Word32 ds) #-}-    {-# SPECIALIZE instance Eq (ArrayBase Word64 ds) #-}-    (==) = accumV2Idempotent True  (\x y r -> r && x == y)-    (/=) = accumV2Idempotent False (\x y r -> r || x /= y)---- | Implement partial ordering for `>`, `<`, `>=`, `<=`---     and lexicographical ordering for `compare`-instance Ord t => Ord (ArrayBase t ds)  where-    {-# SPECIALIZE instance Ord (ArrayBase Float ds)  #-}-    {-# SPECIALIZE instance Ord (ArrayBase Double ds) #-}-    {-# SPECIALIZE instance Ord (ArrayBase Int ds)    #-}-    {-# SPECIALIZE instance Ord (ArrayBase Word ds)   #-}-    {-# SPECIALIZE instance Ord (ArrayBase Int8 ds)   #-}-    {-# SPECIALIZE instance Ord (ArrayBase Int16 ds)  #-}-    {-# SPECIALIZE instance Ord (ArrayBase Int32 ds)  #-}-    {-# SPECIALIZE instance Ord (ArrayBase Int64 ds)  #-}-    {-# SPECIALIZE instance Ord (ArrayBase Word8 ds)  #-}-    {-# SPECIALIZE instance Ord (ArrayBase Word16 ds) #-}-    {-# SPECIALIZE instance Ord (ArrayBase Word32 ds) #-}-    {-# SPECIALIZE instance Ord (ArrayBase Word64 ds) #-}-    -- | Partiall ordering: all elements GT-    (>)  = accumV2Idempotent True (\x y r -> r && x > y)-    {-# INLINE (>) #-}-    -- | Partiall ordering: all elements LT-    (<)  = accumV2Idempotent True (\x y r -> r && x < y)-    {-# INLINE (<) #-}-    -- | Partiall ordering: all elements GE-    (>=) = accumV2Idempotent True (\x y r -> r && x >= y)-    {-# INLINE (>=) #-}-    -- | Partiall ordering: all elements LE-    (<=) = accumV2Idempotent True (\x y r -> r && x <= y)-    {-# INLINE (<=) #-}-    -- | Compare lexicographically-    compare = accumV2Idempotent EQ (\x y  -> flip mappend (compare x y))-    {-# INLINE compare #-}-    -- | Element-wise minimum-    min = zipV min-    {-# INLINE min #-}-    -- | Element-wise maximum-    max = zipV max-    {-# INLINE max #-}--instance (Dimensions ds, Show t)-      => Show (ArrayBase t ds) where-  show x = case dims @_ @ds of-    U -> "{ " ++ show (ix U x) ++ " }"-    Dim :* U -> ('{' :) . drop 1 $-                    foldr (\i s -> ", " ++ show (ix i x) ++ s) " }"-                            [minBound .. maxBound]-    (Dim :: Dim n) :* (Dim :: Dim m) :* (Dims :: Dims dss) ->-      let loopInner :: Idxs dss -> Idxs '[n,m] -> String-          loopInner ods (n:*m:*_) = ('{' :) . drop 2 $-                          foldr (\i ss -> '\n':-                                  foldr (\j s ->-                                           ", " ++ show (ix (i :* j :* ods) x) ++ s-                                        ) ss [1..m]-                                ) " }" [1..n]-          loopOuter ::  Idxs dss -> String -> String-          loopOuter U s  = "\n" ++ loopInner U maxBound ++ s-          loopOuter ds s = "\n(i j" ++ drop 4 (show ds) ++ "):\n"-                                ++ loopInner ds maxBound ++ s-      in drop 1 $ foldr loopOuter "" [minBound..maxBound]--instance {-# OVERLAPPING #-} Bounded (ArrayBase Double ds) where-    maxBound = ArrayBase (# inftyD | #)-    minBound = ArrayBase (# negate inftyD | #)--instance {-# OVERLAPPING #-} Bounded (ArrayBase Float ds) where-    maxBound = ArrayBase (# inftyF | #)-    minBound = ArrayBase (# negate inftyF | #)--instance {-# OVERLAPPABLE #-} Bounded t => Bounded (ArrayBase t ds) where-    {-# SPECIALIZE instance Bounded (ArrayBase Int ds)    #-}-    {-# SPECIALIZE instance Bounded (ArrayBase Word ds)   #-}-    {-# SPECIALIZE instance Bounded (ArrayBase Int8 ds)   #-}-    {-# SPECIALIZE instance Bounded (ArrayBase Int16 ds)  #-}-    {-# SPECIALIZE instance Bounded (ArrayBase Int32 ds)  #-}-    {-# SPECIALIZE instance Bounded (ArrayBase Int64 ds)  #-}-    {-# SPECIALIZE instance Bounded (ArrayBase Word8 ds)  #-}-    {-# SPECIALIZE instance Bounded (ArrayBase Word16 ds) #-}-    {-# SPECIALIZE instance Bounded (ArrayBase Word32 ds) #-}-    {-# SPECIALIZE instance Bounded (ArrayBase Word64 ds) #-}-    maxBound = ArrayBase (# maxBound | #)-    minBound = ArrayBase (# minBound | #)--instance Num t => Num (ArrayBase t ds)  where-    {-# SPECIALIZE instance Num (ArrayBase Float ds)  #-}-    {-# SPECIALIZE instance Num (ArrayBase Double ds) #-}-    {-# SPECIALIZE instance Num (ArrayBase Int ds)    #-}-    {-# SPECIALIZE instance Num (ArrayBase Word ds)   #-}-    {-# SPECIALIZE instance Num (ArrayBase Int8 ds)   #-}-    {-# SPECIALIZE instance Num (ArrayBase Int16 ds)  #-}-    {-# SPECIALIZE instance Num (ArrayBase Int32 ds)  #-}-    {-# SPECIALIZE instance Num (ArrayBase Int64 ds)  #-}-    {-# SPECIALIZE instance Num (ArrayBase Word8 ds)  #-}-    {-# SPECIALIZE instance Num (ArrayBase Word16 ds) #-}-    {-# SPECIALIZE instance Num (ArrayBase Word32 ds) #-}-    {-# SPECIALIZE instance Num (ArrayBase Word64 ds) #-}-    (+) = zipV (+)-    {-# INLINE (+) #-}-    (-) = zipV (-)-    {-# INLINE (-) #-}-    (*) = zipV (*)-    {-# INLINE (*) #-}-    negate = mapV negate-    {-# INLINE negate #-}-    abs = mapV abs-    {-# INLINE abs #-}-    signum = mapV signum-    {-# INLINE signum #-}-    fromInteger i = ArrayBase (# fromInteger i | #)-    {-# INLINE fromInteger #-}--instance Fractional t => Fractional (ArrayBase t ds)  where-    {-# SPECIALIZE instance Fractional (ArrayBase Float ds)  #-}-    {-# SPECIALIZE instance Fractional (ArrayBase Double ds) #-}-    (/) = zipV (/)-    {-# INLINE (/) #-}-    recip = mapV recip-    {-# INLINE recip #-}-    fromRational r = ArrayBase (# fromRational r | #)-    {-# INLINE fromRational #-}---instance Floating t => Floating (ArrayBase t ds) where-    {-# SPECIALIZE instance Floating (ArrayBase Float ds)  #-}-    {-# SPECIALIZE instance Floating (ArrayBase Double ds) #-}-    pi = ArrayBase (# pi | #)-    {-# INLINE pi #-}-    exp = mapV exp-    {-# INLINE exp #-}-    log = mapV log-    {-# INLINE log #-}-    sqrt = mapV sqrt-    {-# INLINE sqrt #-}-    sin = mapV sin-    {-# INLINE sin #-}-    cos = mapV cos-    {-# INLINE cos #-}-    tan = mapV tan-    {-# INLINE tan #-}-    asin = mapV asin-    {-# INLINE asin #-}-    acos = mapV acos-    {-# INLINE acos #-}-    atan = mapV atan-    {-# INLINE atan #-}-    sinh = mapV sinh-    {-# INLINE sinh #-}-    cosh = mapV cosh-    {-# INLINE cosh #-}-    tanh = mapV tanh-    {-# INLINE tanh #-}-    (**) = zipV (**)-    {-# INLINE (**) #-}-    logBase = zipV logBase-    {-# INLINE logBase #-}-    asinh = mapV asinh-    {-# INLINE asinh #-}-    acosh = mapV acosh-    {-# INLINE acosh #-}-    atanh = mapV atanh-    {-# INLINE atanh #-}--instance PrimBytes t => PrimArray t (ArrayBase t ds) where-    {-# SPECIALIZE instance PrimArray Float  (ArrayBase Float ds)  #-}-    {-# SPECIALIZE instance PrimArray Double (ArrayBase Double ds) #-}-    {-# SPECIALIZE instance PrimArray Int    (ArrayBase Int ds)    #-}-    {-# SPECIALIZE instance PrimArray Word   (ArrayBase Word ds)   #-}-    {-# SPECIALIZE instance PrimArray Int8   (ArrayBase Int8 ds)   #-}-    {-# SPECIALIZE instance PrimArray Int16  (ArrayBase Int16 ds)  #-}-    {-# SPECIALIZE instance PrimArray Int32  (ArrayBase Int32 ds)  #-}-    {-# SPECIALIZE instance PrimArray Int64  (ArrayBase Int64 ds)  #-}-    {-# SPECIALIZE instance PrimArray Word8  (ArrayBase Word8 ds)  #-}-    {-# SPECIALIZE instance PrimArray Word16 (ArrayBase Word16 ds) #-}-    {-# SPECIALIZE instance PrimArray Word32 (ArrayBase Word32 ds) #-}-    {-# SPECIALIZE instance PrimArray Word64 (ArrayBase Word64 ds) #-}--    broadcast t = ArrayBase (# t | #)-    {-# INLINE broadcast #-}--    ix# i (ArrayBase a) = case a of-      (# t | #)                    -> t-      (# | (# off, _, arr, _ #) #) -> indexArray arr (off +# i)-    {-# INLINE ix# #-}--    gen# n f z0 = go (byteSize @t undefined *# n)-      where-        go bsize = case runRW#-         ( \s0 -> case newByteArray# bsize s0 of-             (# s1, mba #) -> case loop0 mba 0# z0 s1 of-               (# s2, z1 #) -> case unsafeFreezeByteArray# mba s2 of-                 (# s3, ba #) -> (# s3, (# z1, ba #) #)-         ) of (# _, (# z1, ba #) #) -> (# z1, ArrayBase (# | (# 0# , n , ba, E #) #) #)-        {-# NOINLINE go #-}-        loop0 mba i z s-          | isTrue# (i ==# n) = (# s, z #)-          | otherwise = case f z of-              (# z', x #) -> loop0 mba (i +# 1#) z' (writeArray mba i x s)-    {-# INLINE gen# #-}--    upd# n i x (ArrayBase (# a | #)) = go (byteSize x)-      where-        go tbs = case runRW#-         ( \s0 -> case newByteArray# (tbs *# n) s0 of-             (# s1, mba #) -> unsafeFreezeByteArray# mba-               (writeArray mba i x-                 (loop1# n (\j -> writeArray mba j a) s1)-               )-         ) of (# _, r #) -> ArrayBase (# | (# 0# , n , r, E #) #)-        {-# NOINLINE go #-}-    upd# _ i x (ArrayBase (# | (# offN , n , ba, E #) #)) = go (byteSize x)-      where-        go tbs = case runRW#-         ( \s0 -> case newByteArray# (tbs *# n) s0 of-             (# s1, mba #) -> unsafeFreezeByteArray# mba-               (writeArray mba i x-                 (copyByteArray# ba (offN *# tbs) mba 0# (tbs *# n) s1)-               )-         ) of (# _, r #) -> ArrayBase (# | (# 0# , n , r, E #) #)-        {-# NOINLINE go #-}-    {-# INLINE upd# #-}--    elemOffset (ArrayBase a) = case a of-      (# _ | #)                  -> 0#-      (# | (# off, _, _, _ #) #) -> off-    {-# INLINE elemOffset #-}--    elemSize0 (ArrayBase a) = case a of-      (# _ | #)                -> 0#-      (# | (# _, n, _, _ #) #) -> n-    {-# INLINE elemSize0 #-}--    fromElems off n ba = ArrayBase (# | (# off , n , ba, E #) #)-    {-# INLINE fromElems #-}--------------------------------------------------------------------------------------- * Utility functions------------------------------------------------------------------------------------ix :: Dimensions ds => Idxs ds -> ArrayBase t ds -> t-ix i (ArrayBase a) = case a of-  (# t | #)  -> t-  (# | (# off, _, arr, E #) #) -> case fromEnum i of-    I# i# -> indexArray arr (off +# i#)-{-# INLINE ix #-}---undefEl :: ArrayBase t ds -> t-undefEl = const undefined
− src/Numeric/DataFrame/Internal/Array/Family/DoubleX2.hs
@@ -1,333 +0,0 @@-{-# LANGUAGE CPP                   #-}-{-# LANGUAGE MagicHash             #-}-{-# LANGUAGE MultiParamTypeClasses #-}-{-# LANGUAGE TypeApplications      #-}-{-# LANGUAGE UnboxedTuples         #-}-module Numeric.DataFrame.Internal.Array.Family.DoubleX2 (DoubleX2 (..)) where---import           GHC.Base-import           Numeric.DataFrame.Internal.Array.Class-import           Numeric.DataFrame.Internal.Array.PrimOps-import           Numeric.PrimBytes---data DoubleX2 = DoubleX2# Double# Double#---instance Bounded DoubleX2 where-    maxBound = case inftyD of D# x -> DoubleX2# x x-    minBound = case negate inftyD of D# x -> DoubleX2# x x---instance Show DoubleX2 where-    show (DoubleX2# a1 a2)-      =  "{ " ++ show (D# a1)-      ++ ", " ++ show (D# a2)-      ++ " }"----instance Eq DoubleX2 where--    DoubleX2# a1 a2 == DoubleX2# b1 b2 =-      isTrue#-      (       (a1 ==## b1)-      `andI#` (a2 ==## b2)-      )-    {-# INLINE (==) #-}--    DoubleX2# a1 a2 /= DoubleX2# b1 b2 =-      isTrue#-      (      (a1 /=## b1)-      `orI#` (a2 /=## b2)-      )-    {-# INLINE (/=) #-}------ | Implement partial ordering for `>`, `<`, `>=`, `<=`---           and lexicographical ordering for `compare`-instance Ord DoubleX2 where-    DoubleX2# a1 a2 > DoubleX2# b1 b2 =-      isTrue#-      (       (a1 >## b1)-      `andI#` (a2 >## b2)-      )-    {-# INLINE (>) #-}--    DoubleX2# a1 a2 < DoubleX2# b1 b2 =-      isTrue#-      (       (a1 <## b1)-      `andI#` (a2 <## b2)-      )-    {-# INLINE (<) #-}--    DoubleX2# a1 a2 >= DoubleX2# b1 b2 =-      isTrue#-      (       (a1 >=## b1)-      `andI#` (a2 >=## b2)-      )-    {-# INLINE (>=) #-}--    DoubleX2# a1 a2 <= DoubleX2# b1 b2 =-      isTrue#-      (       (a1 <=## b1)-      `andI#` (a2 <=## b2)-      )-    {-# INLINE (<=) #-}--    -- | Compare lexicographically-    compare (DoubleX2# a1 a2) (DoubleX2# b1 b2)-      | isTrue# (a1 >## b1) = GT-      | isTrue# (a1 <## b1) = LT-      | isTrue# (a2 >## b2) = GT-      | isTrue# (a2 <## b2) = LT-      | otherwise = EQ-    {-# INLINE compare #-}--    -- | Element-wise minimum-    min (DoubleX2# a1 a2) (DoubleX2# b1 b2) = DoubleX2#-      (if isTrue# (a1 >## b1) then b1 else a1)-      (if isTrue# (a2 >## b2) then b2 else a2)-    {-# INLINE min #-}--    -- | Element-wise maximum-    max (DoubleX2# a1 a2) (DoubleX2# b1 b2) = DoubleX2#-      (if isTrue# (a1 >## b1) then a1 else b1)-      (if isTrue# (a2 >## b2) then a2 else b2)-    {-# INLINE max #-}------ | element-wise operations for vectors-instance Num DoubleX2 where--    DoubleX2# a1 a2 + DoubleX2# b1 b2-      = DoubleX2# ((+##) a1 b1) ((+##) a2 b2)-    {-# INLINE (+) #-}--    DoubleX2# a1 a2 - DoubleX2# b1 b2-      = DoubleX2# ((-##) a1 b1) ((-##) a2 b2)-    {-# INLINE (-) #-}--    DoubleX2# a1 a2 * DoubleX2# b1 b2-      = DoubleX2# ((*##) a1 b1) ((*##) a2 b2)-    {-# INLINE (*) #-}--    negate (DoubleX2# a1 a2) = DoubleX2#-      (negateDouble# a1) (negateDouble# a2)-    {-# INLINE negate #-}--    abs (DoubleX2# a1 a2)-      = DoubleX2#-      (if isTrue# (a1 >=## 0.0##) then a1 else negateDouble# a1)-      (if isTrue# (a2 >=## 0.0##) then a2 else negateDouble# a2)-    {-# INLINE abs #-}--    signum (DoubleX2# a1 a2)-      = DoubleX2# (if isTrue# (a1 >## 0.0##)-                  then 1.0##-                  else if isTrue# (a1 <## 0.0##) then -1.0## else 0.0## )-                 (if isTrue# (a2 >## 0.0##)-                  then 1.0##-                  else if isTrue# (a2 <## 0.0##) then -1.0## else 0.0## )-    {-# INLINE signum #-}--    fromInteger n = case fromInteger n of D# x -> DoubleX2# x x-    {-# INLINE fromInteger #-}----instance Fractional DoubleX2 where--    DoubleX2# a1 a2 / DoubleX2# b1 b2 = DoubleX2#-      ((/##) a1 b1) ((/##) a2 b2)-    {-# INLINE (/) #-}--    recip (DoubleX2# a1 a2) = DoubleX2#-      ((/##) 1.0## a1) ((/##) 1.0## a2)-    {-# INLINE recip #-}--    fromRational r = case fromRational r of D# x -> DoubleX2# x x-    {-# INLINE fromRational #-}----instance Floating DoubleX2 where--    pi = DoubleX2#-      3.141592653589793238##-      3.141592653589793238##-    {-# INLINE pi #-}--    exp (DoubleX2# a1 a2) = DoubleX2#-      (expDouble# a1) (expDouble# a2)-    {-# INLINE exp #-}--    log (DoubleX2# a1 a2) = DoubleX2#-      (logDouble# a1) (logDouble# a2)-    {-# INLINE log #-}--    sqrt (DoubleX2# a1 a2) = DoubleX2#-      (sqrtDouble# a1) (sqrtDouble# a2)-    {-# INLINE sqrt #-}--    sin (DoubleX2# a1 a2) = DoubleX2#-      (sinDouble# a1) (sinDouble# a2)-    {-# INLINE sin #-}--    cos (DoubleX2# a1 a2) = DoubleX2#-      (cosDouble# a1) (cosDouble# a2)-    {-# INLINE cos #-}--    tan (DoubleX2# a1 a2) = DoubleX2#-      (tanDouble# a1) (tanDouble# a2)-    {-# INLINE tan #-}--    asin (DoubleX2# a1 a2) = DoubleX2#-      (asinDouble# a1) (asinDouble# a2)-    {-# INLINE asin #-}--    acos (DoubleX2# a1 a2) = DoubleX2#-      (acosDouble# a1) (acosDouble# a2)-    {-# INLINE acos #-}--    atan (DoubleX2# a1 a2) = DoubleX2#-      (atanDouble# a1) (atanDouble# a2)-    {-# INLINE atan #-}--    sinh (DoubleX2# a1 a2) = DoubleX2#-      (sinhDouble# a1) (sinhDouble# a2)-    {-# INLINE sinh #-}--    cosh (DoubleX2# a1 a2) = DoubleX2#-      (coshDouble# a1) (coshDouble# a2)-    {-# INLINE cosh #-}--    tanh (DoubleX2# a1 a2) = DoubleX2#-      (tanhDouble# a1) (tanhDouble# a2)-    {-# INLINE tanh #-}--    DoubleX2# a1 a2 ** DoubleX2# b1 b2 = DoubleX2#-      ((**##) a1 b1) ((**##) a2 b2)-    {-# INLINE (**) #-}--    logBase x y         =  log y / log x-    {-# INLINE logBase #-}--    asinh x = log (x + sqrt (1.0+x*x))-    {-# INLINE asinh #-}--    acosh x = log (x + (x+1.0) * sqrt ((x-1.0)/(x+1.0)))-    {-# INLINE acosh #-}--    atanh x = 0.5 * log ((1.0+x) / (1.0-x))-    {-# INLINE atanh #-}---- offset in bytes is S times bigger than offset in prim elements,--- when S is power of two, this is equal to shift-#define BOFF_TO_PRIMOFF(off) uncheckedIShiftRL# off 3#-#define ELEM_N 2--instance PrimBytes DoubleX2 where--    getBytes (DoubleX2# a1 a2) = case runRW#-       ( \s0 -> case newByteArray# (byteSize @DoubleX2 undefined) s0 of-           (# s1, marr #) -> case writeDoubleArray# marr 0# a1 s1 of-             s2 -> case writeDoubleArray# marr 1# a2 s2 of-               s3 -> unsafeFreezeByteArray# marr s3-       ) of (# _, a #) -> a-    {-# INLINE getBytes #-}--    fromBytes off arr-      | i <- BOFF_TO_PRIMOFF(off)-      = DoubleX2#-      (indexDoubleArray# arr i)-      (indexDoubleArray# arr (i +# 1#))-    {-# INLINE fromBytes #-}--    readBytes mba off s0-      | i <- BOFF_TO_PRIMOFF(off)-      = case readDoubleArray# mba i s0 of-      (# s1, a1 #) -> case readDoubleArray# mba (i +# 1#) s1 of-        (# s2, a2 #) -> (# s2, DoubleX2# a1 a2 #)-    {-# INLINE readBytes #-}--    writeBytes mba off (DoubleX2# a1 a2) s-      | i <- BOFF_TO_PRIMOFF(off)-      = writeDoubleArray# mba (i +# 1#) a2-      ( writeDoubleArray# mba  i        a1 s )-    {-# INLINE writeBytes #-}--    readAddr addr s0-      = case readDoubleOffAddr# addr 0# s0 of-      (# s1, a1 #) -> case readDoubleOffAddr# addr 1# s1 of-        (# s2, a2 #) -> (# s2, DoubleX2# a1 a2 #)-    {-# INLINE readAddr #-}--    writeAddr (DoubleX2# a1 a2) addr s-      = writeDoubleOffAddr# addr 1# a2-      ( writeDoubleOffAddr# addr 0# a1 s )-    {-# INLINE writeAddr #-}--    byteSize _ = byteSize @Double undefined *# ELEM_N#-    {-# INLINE byteSize #-}--    byteAlign _ = byteAlign @Double undefined-    {-# INLINE byteAlign #-}--    byteOffset _ = 0#-    {-# INLINE byteOffset #-}--    indexArray ba off-      | i <- off *# ELEM_N#-      = DoubleX2#-      (indexDoubleArray# ba i)-      (indexDoubleArray# ba (i +# 1#))-    {-# INLINE indexArray #-}--    readArray mba off s0-      | i <- off *# ELEM_N#-      = case readDoubleArray# mba i s0 of-      (# s1, a1 #) -> case readDoubleArray# mba (i +# 1#) s1 of-        (# s2, a2 #) -> (# s2, DoubleX2# a1 a2 #)-    {-# INLINE readArray #-}--    writeArray mba off (DoubleX2# a1 a2) s-      | i <- off *# ELEM_N#-      = writeDoubleArray# mba (i +# 1#) a2-      ( writeDoubleArray# mba  i        a1 s )-    {-# INLINE writeArray #-}---instance PrimArray Double DoubleX2 where--    broadcast (D# x) = DoubleX2# x x-    {-# INLINE broadcast #-}--    ix# 0# (DoubleX2# a1 _) = D# a1-    ix# 1# (DoubleX2# _ a2) = D# a2-    ix# _   _               = undefined-    {-# INLINE ix# #-}--    gen# _ f s0 = case f s0 of-      (# s1, D# a1 #) -> case f s1 of-        (# s2, D# a2 #) -> (# s2, DoubleX2# a1 a2 #)---    upd# _ 0# (D# q) (DoubleX2# _ y) = DoubleX2# q y-    upd# _ 1# (D# q) (DoubleX2# x _) = DoubleX2# x q-    upd# _ _ _ x                     = x-    {-# INLINE upd# #-}--    elemOffset _ = 0#-    {-# INLINE elemOffset #-}--    elemSize0 _  = ELEM_N#-    {-# INLINE elemSize0 #-}--    fromElems off _ ba = DoubleX2#-      (indexDoubleArray# ba off)-      (indexDoubleArray# ba (off +# 1#))-    {-# INLINE fromElems #-}
− src/Numeric/DataFrame/Internal/Array/Family/DoubleX3.hs
@@ -1,362 +0,0 @@-{-# LANGUAGE CPP                   #-}-{-# LANGUAGE MagicHash             #-}-{-# LANGUAGE MultiParamTypeClasses #-}-{-# LANGUAGE TypeApplications      #-}-{-# LANGUAGE UnboxedTuples         #-}-module Numeric.DataFrame.Internal.Array.Family.DoubleX3 (DoubleX3 (..)) where---import           GHC.Base-import           Numeric.DataFrame.Internal.Array.Class-import           Numeric.DataFrame.Internal.Array.PrimOps-import           Numeric.PrimBytes---data DoubleX3 = DoubleX3# Double# Double# Double#---instance Bounded DoubleX3 where-    maxBound = case inftyD of D# x -> DoubleX3# x x x-    minBound = case negate inftyD of D# x -> DoubleX3# x x x---instance Show DoubleX3 where-    show (DoubleX3# a1 a2 a3)-      =  "{ " ++ show (D# a1)-      ++ ", " ++ show (D# a2)-      ++ ", " ++ show (D# a3)-      ++ " }"----instance Eq DoubleX3 where--    DoubleX3# a1 a2 a3 == DoubleX3# b1 b2 b3 =-      isTrue#-      (       (a1 ==## b1)-      `andI#` (a2 ==## b2)-      `andI#` (a3 ==## b3)-      )-    {-# INLINE (==) #-}--    DoubleX3# a1 a2 a3 /= DoubleX3# b1 b2 b3 =-      isTrue#-      (      (a1 /=## b1)-      `orI#` (a2 /=## b2)-      `orI#` (a3 /=## b3)-      )-    {-# INLINE (/=) #-}------ | Implement partial ordering for `>`, `<`, `>=`, `<=`---           and lexicographical ordering for `compare`-instance Ord DoubleX3 where-    DoubleX3# a1 a2 a3 > DoubleX3# b1 b2 b3 =-      isTrue#-      (       (a1 >## b1)-      `andI#` (a2 >## b2)-      `andI#` (a3 >## b3)-      )-    {-# INLINE (>) #-}--    DoubleX3# a1 a2 a3 < DoubleX3# b1 b2 b3 =-      isTrue#-      (       (a1 <## b1)-      `andI#` (a2 <## b2)-      `andI#` (a3 <## b3)-      )-    {-# INLINE (<) #-}--    DoubleX3# a1 a2 a3 >= DoubleX3# b1 b2 b3 =-      isTrue#-      (       (a1 >=## b1)-      `andI#` (a2 >=## b2)-      `andI#` (a3 >=## b3)-      )-    {-# INLINE (>=) #-}--    DoubleX3# a1 a2 a3 <= DoubleX3# b1 b2 b3 =-      isTrue#-      (       (a1 <=## b1)-      `andI#` (a2 <=## b2)-      `andI#` (a3 <=## b3)-      )-    {-# INLINE (<=) #-}--    -- | Compare lexicographically-    compare (DoubleX3# a1 a2 a3) (DoubleX3# b1 b2 b3)-      | isTrue# (a1 >## b1) = GT-      | isTrue# (a1 <## b1) = LT-      | isTrue# (a2 >## b2) = GT-      | isTrue# (a2 <## b2) = LT-      | isTrue# (a3 >## b3) = GT-      | isTrue# (a3 <## b3) = LT-      | otherwise = EQ-    {-# INLINE compare #-}--    -- | Element-wise minimum-    min (DoubleX3# a1 a2 a3) (DoubleX3# b1 b2 b3) = DoubleX3#-      (if isTrue# (a1 >## b1) then b1 else a1)-      (if isTrue# (a2 >## b2) then b2 else a2)-      (if isTrue# (a3 >## b3) then b3 else a3)-    {-# INLINE min #-}--    -- | Element-wise maximum-    max (DoubleX3# a1 a2 a3) (DoubleX3# b1 b2 b3) = DoubleX3#-      (if isTrue# (a1 >## b1) then a1 else b1)-      (if isTrue# (a2 >## b2) then a2 else b2)-      (if isTrue# (a3 >## b3) then a3 else b3)-    {-# INLINE max #-}------ | element-wise operations for vectors-instance Num DoubleX3 where--    DoubleX3# a1 a2 a3 + DoubleX3# b1 b2 b3-      = DoubleX3# ((+##) a1 b1) ((+##) a2 b2) ((+##) a3 b3)-    {-# INLINE (+) #-}--    DoubleX3# a1 a2 a3 - DoubleX3# b1 b2 b3-      = DoubleX3# ((-##) a1 b1) ((-##) a2 b2) ((-##) a3 b3)-    {-# INLINE (-) #-}--    DoubleX3# a1 a2 a3 * DoubleX3# b1 b2 b3-      = DoubleX3# ((*##) a1 b1) ((*##) a2 b2) ((*##) a3 b3)-    {-# INLINE (*) #-}--    negate (DoubleX3# a1 a2 a3) = DoubleX3#-      (negateDouble# a1) (negateDouble# a2) (negateDouble# a3)-    {-# INLINE negate #-}--    abs (DoubleX3# a1 a2 a3)-      = DoubleX3#-      (if isTrue# (a1 >=## 0.0##) then a1 else negateDouble# a1)-      (if isTrue# (a2 >=## 0.0##) then a2 else negateDouble# a2)-      (if isTrue# (a3 >=## 0.0##) then a3 else negateDouble# a3)-    {-# INLINE abs #-}--    signum (DoubleX3# a1 a2 a3)-      = DoubleX3# (if isTrue# (a1 >## 0.0##)-                  then 1.0##-                  else if isTrue# (a1 <## 0.0##) then -1.0## else 0.0## )-                 (if isTrue# (a2 >## 0.0##)-                  then 1.0##-                  else if isTrue# (a2 <## 0.0##) then -1.0## else 0.0## )-                 (if isTrue# (a3 >## 0.0##)-                  then 1.0##-                  else if isTrue# (a3 <## 0.0##) then -1.0## else 0.0## )-    {-# INLINE signum #-}--    fromInteger n = case fromInteger n of D# x -> DoubleX3# x x x-    {-# INLINE fromInteger #-}----instance Fractional DoubleX3 where--    DoubleX3# a1 a2 a3 / DoubleX3# b1 b2 b3 = DoubleX3#-      ((/##) a1 b1) ((/##) a2 b2) ((/##) a3 b3)-    {-# INLINE (/) #-}--    recip (DoubleX3# a1 a2 a3) = DoubleX3#-      ((/##) 1.0## a1) ((/##) 1.0## a2) ((/##) 1.0## a3)-    {-# INLINE recip #-}--    fromRational r = case fromRational r of D# x -> DoubleX3# x x x-    {-# INLINE fromRational #-}----instance Floating DoubleX3 where--    pi = DoubleX3#-      3.141592653589793238##-      3.141592653589793238##-      3.141592653589793238##-    {-# INLINE pi #-}--    exp (DoubleX3# a1 a2 a3) = DoubleX3#-      (expDouble# a1) (expDouble# a2) (expDouble# a3)-    {-# INLINE exp #-}--    log (DoubleX3# a1 a2 a3) = DoubleX3#-      (logDouble# a1) (logDouble# a2) (logDouble# a3)-    {-# INLINE log #-}--    sqrt (DoubleX3# a1 a2 a3) = DoubleX3#-      (sqrtDouble# a1) (sqrtDouble# a2) (sqrtDouble# a3)-    {-# INLINE sqrt #-}--    sin (DoubleX3# a1 a2 a3) = DoubleX3#-      (sinDouble# a1) (sinDouble# a2) (sinDouble# a3)-    {-# INLINE sin #-}--    cos (DoubleX3# a1 a2 a3) = DoubleX3#-      (cosDouble# a1) (cosDouble# a2) (cosDouble# a3)-    {-# INLINE cos #-}--    tan (DoubleX3# a1 a2 a3) = DoubleX3#-      (tanDouble# a1) (tanDouble# a2) (tanDouble# a3)-    {-# INLINE tan #-}--    asin (DoubleX3# a1 a2 a3) = DoubleX3#-      (asinDouble# a1) (asinDouble# a2) (asinDouble# a3)-    {-# INLINE asin #-}--    acos (DoubleX3# a1 a2 a3) = DoubleX3#-      (acosDouble# a1) (acosDouble# a2) (acosDouble# a3)-    {-# INLINE acos #-}--    atan (DoubleX3# a1 a2 a3) = DoubleX3#-      (atanDouble# a1) (atanDouble# a2) (atanDouble# a3)-    {-# INLINE atan #-}--    sinh (DoubleX3# a1 a2 a3) = DoubleX3#-      (sinhDouble# a1) (sinhDouble# a2) (sinhDouble# a3)-    {-# INLINE sinh #-}--    cosh (DoubleX3# a1 a2 a3) = DoubleX3#-      (coshDouble# a1) (coshDouble# a2) (coshDouble# a3)-    {-# INLINE cosh #-}--    tanh (DoubleX3# a1 a2 a3) = DoubleX3#-      (tanhDouble# a1) (tanhDouble# a2) (tanhDouble# a3)-    {-# INLINE tanh #-}--    DoubleX3# a1 a2 a3 ** DoubleX3# b1 b2 b3 = DoubleX3#-      ((**##) a1 b1) ((**##) a2 b2) ((**##) a3 b3)-    {-# INLINE (**) #-}--    logBase x y         =  log y / log x-    {-# INLINE logBase #-}--    asinh x = log (x + sqrt (1.0+x*x))-    {-# INLINE asinh #-}--    acosh x = log (x + (x+1.0) * sqrt ((x-1.0)/(x+1.0)))-    {-# INLINE acosh #-}--    atanh x = 0.5 * log ((1.0+x) / (1.0-x))-    {-# INLINE atanh #-}---- offset in bytes is S times bigger than offset in prim elements,--- when S is power of two, this is equal to shift-#define BOFF_TO_PRIMOFF(off) uncheckedIShiftRL# off 3#-#define ELEM_N 3--instance PrimBytes DoubleX3 where--    getBytes (DoubleX3# a1 a2 a3) = case runRW#-       ( \s0 -> case newByteArray# (byteSize @DoubleX3 undefined) s0 of-           (# s1, marr #) -> case writeDoubleArray# marr 0# a1 s1 of-             s2 -> case writeDoubleArray# marr 1# a2 s2 of-               s3 -> case writeDoubleArray# marr 2# a3 s3 of-                 s4 -> unsafeFreezeByteArray# marr s4-       ) of (# _, a #) -> a-    {-# INLINE getBytes #-}--    fromBytes off arr-      | i <- BOFF_TO_PRIMOFF(off)-      = DoubleX3#-      (indexDoubleArray# arr i)-      (indexDoubleArray# arr (i +# 1#))-      (indexDoubleArray# arr (i +# 2#))-    {-# INLINE fromBytes #-}--    readBytes mba off s0-      | i <- BOFF_TO_PRIMOFF(off)-      = case readDoubleArray# mba i s0 of-      (# s1, a1 #) -> case readDoubleArray# mba (i +# 1#) s1 of-        (# s2, a2 #) -> case readDoubleArray# mba (i +# 2#) s2 of-          (# s3, a3 #) -> (# s3, DoubleX3# a1 a2 a3 #)-    {-# INLINE readBytes #-}--    writeBytes mba off (DoubleX3# a1 a2 a3) s-      | i <- BOFF_TO_PRIMOFF(off)-      = writeDoubleArray# mba (i +# 2#) a3-      ( writeDoubleArray# mba (i +# 1#) a2-      ( writeDoubleArray# mba  i        a1 s ))-    {-# INLINE writeBytes #-}--    readAddr addr s0-      = case readDoubleOffAddr# addr 0# s0 of-      (# s1, a1 #) -> case readDoubleOffAddr# addr 1# s1 of-        (# s2, a2 #) -> case readDoubleOffAddr# addr 2# s2 of-          (# s3, a3 #) -> (# s3, DoubleX3# a1 a2 a3 #)-    {-# INLINE readAddr #-}--    writeAddr (DoubleX3# a1 a2 a3) addr s-      = writeDoubleOffAddr# addr 2# a3-      ( writeDoubleOffAddr# addr 1# a2-      ( writeDoubleOffAddr# addr 0# a1 s ))-    {-# INLINE writeAddr #-}--    byteSize _ = byteSize @Double undefined *# ELEM_N#-    {-# INLINE byteSize #-}--    byteAlign _ = byteAlign @Double undefined-    {-# INLINE byteAlign #-}--    byteOffset _ = 0#-    {-# INLINE byteOffset #-}--    indexArray ba off-      | i <- off *# ELEM_N#-      = DoubleX3#-      (indexDoubleArray# ba i)-      (indexDoubleArray# ba (i +# 1#))-      (indexDoubleArray# ba (i +# 2#))-    {-# INLINE indexArray #-}--    readArray mba off s0-      | i <- off *# ELEM_N#-      = case readDoubleArray# mba i s0 of-      (# s1, a1 #) -> case readDoubleArray# mba (i +# 1#) s1 of-        (# s2, a2 #) -> case readDoubleArray# mba (i +# 2#) s2 of-          (# s3, a3 #) -> (# s3, DoubleX3# a1 a2 a3 #)-    {-# INLINE readArray #-}--    writeArray mba off (DoubleX3# a1 a2 a3) s-      | i <- off *# ELEM_N#-      = writeDoubleArray# mba (i +# 2#) a3-      ( writeDoubleArray# mba (i +# 1#) a2-      ( writeDoubleArray# mba  i        a1 s ))-    {-# INLINE writeArray #-}---instance PrimArray Double DoubleX3 where--    broadcast (D# x) = DoubleX3# x x x-    {-# INLINE broadcast #-}--    ix# 0# (DoubleX3# a1 _ _) = D# a1-    ix# 1# (DoubleX3# _ a2 _) = D# a2-    ix# 2# (DoubleX3# _ _ a3) = D# a3-    ix# _   _                 = undefined-    {-# INLINE ix# #-}--    gen# _ f s0 = case f s0 of-      (# s1, D# a1 #) -> case f s1 of-        (# s2, D# a2 #) -> case f s2 of-          (# s3, D# a3 #) -> (# s3, DoubleX3# a1 a2 a3 #)---    upd# _ 0# (D# q) (DoubleX3# _ y z) = DoubleX3# q y z-    upd# _ 1# (D# q) (DoubleX3# x _ z) = DoubleX3# x q z-    upd# _ 2# (D# q) (DoubleX3# x y _) = DoubleX3# x y q-    upd# _ _ _ x                       = x-    {-# INLINE upd# #-}--    elemOffset _ = 0#-    {-# INLINE elemOffset #-}--    elemSize0 _  = ELEM_N#-    {-# INLINE elemSize0 #-}--    fromElems off _ ba = DoubleX3#-      (indexDoubleArray# ba off)-      (indexDoubleArray# ba (off +# 1#))-      (indexDoubleArray# ba (off +# 2#))-    {-# INLINE fromElems #-}
− src/Numeric/DataFrame/Internal/Array/Family/DoubleX4.hs
@@ -1,391 +0,0 @@-{-# LANGUAGE CPP                   #-}-{-# LANGUAGE MagicHash             #-}-{-# LANGUAGE MultiParamTypeClasses #-}-{-# LANGUAGE TypeApplications      #-}-{-# LANGUAGE UnboxedTuples         #-}-module Numeric.DataFrame.Internal.Array.Family.DoubleX4 (DoubleX4 (..)) where---import           GHC.Base-import           Numeric.DataFrame.Internal.Array.Class-import           Numeric.DataFrame.Internal.Array.PrimOps-import           Numeric.PrimBytes---data DoubleX4 = DoubleX4# Double# Double# Double# Double#---instance Bounded DoubleX4 where-    maxBound = case inftyD of D# x -> DoubleX4# x x x x-    minBound = case negate inftyD of D# x -> DoubleX4# x x x x---instance Show DoubleX4 where-    show (DoubleX4# a1 a2 a3 a4)-      =  "{ " ++ show (D# a1)-      ++ ", " ++ show (D# a2)-      ++ ", " ++ show (D# a3)-      ++ ", " ++ show (D# a4)-      ++ " }"----instance Eq DoubleX4 where--    DoubleX4# a1 a2 a3 a4 == DoubleX4# b1 b2 b3 b4 =-      isTrue#-      (       (a1 ==## b1)-      `andI#` (a2 ==## b2)-      `andI#` (a3 ==## b3)-      `andI#` (a4 ==## b4)-      )-    {-# INLINE (==) #-}--    DoubleX4# a1 a2 a3 a4 /= DoubleX4# b1 b2 b3 b4 =-      isTrue#-      (      (a1 /=## b1)-      `orI#` (a2 /=## b2)-      `orI#` (a3 /=## b3)-      `orI#` (a4 /=## b4)-      )-    {-# INLINE (/=) #-}------ | Implement partial ordering for `>`, `<`, `>=`, `<=`---           and lexicographical ordering for `compare`-instance Ord DoubleX4 where-    DoubleX4# a1 a2 a3 a4 > DoubleX4# b1 b2 b3 b4 =-      isTrue#-      (       (a1 >## b1)-      `andI#` (a2 >## b2)-      `andI#` (a3 >## b3)-      `andI#` (a4 >## b4)-      )-    {-# INLINE (>) #-}--    DoubleX4# a1 a2 a3 a4 < DoubleX4# b1 b2 b3 b4 =-      isTrue#-      (       (a1 <## b1)-      `andI#` (a2 <## b2)-      `andI#` (a3 <## b3)-      `andI#` (a4 <## b4)-      )-    {-# INLINE (<) #-}--    DoubleX4# a1 a2 a3 a4 >= DoubleX4# b1 b2 b3 b4 =-      isTrue#-      (       (a1 >=## b1)-      `andI#` (a2 >=## b2)-      `andI#` (a3 >=## b3)-      `andI#` (a4 >=## b4)-      )-    {-# INLINE (>=) #-}--    DoubleX4# a1 a2 a3 a4 <= DoubleX4# b1 b2 b3 b4 =-      isTrue#-      (       (a1 <=## b1)-      `andI#` (a2 <=## b2)-      `andI#` (a3 <=## b3)-      `andI#` (a4 <=## b4)-      )-    {-# INLINE (<=) #-}--    -- | Compare lexicographically-    compare (DoubleX4# a1 a2 a3 a4) (DoubleX4# b1 b2 b3 b4)-      | isTrue# (a1 >## b1) = GT-      | isTrue# (a1 <## b1) = LT-      | isTrue# (a2 >## b2) = GT-      | isTrue# (a2 <## b2) = LT-      | isTrue# (a3 >## b3) = GT-      | isTrue# (a3 <## b3) = LT-      | isTrue# (a4 >## b4) = GT-      | isTrue# (a4 <## b4) = LT-      | otherwise = EQ-    {-# INLINE compare #-}--    -- | Element-wise minimum-    min (DoubleX4# a1 a2 a3 a4) (DoubleX4# b1 b2 b3 b4) = DoubleX4#-      (if isTrue# (a1 >## b1) then b1 else a1)-      (if isTrue# (a2 >## b2) then b2 else a2)-      (if isTrue# (a3 >## b3) then b3 else a3)-      (if isTrue# (a4 >## b4) then b4 else a4)-    {-# INLINE min #-}--    -- | Element-wise maximum-    max (DoubleX4# a1 a2 a3 a4) (DoubleX4# b1 b2 b3 b4) = DoubleX4#-      (if isTrue# (a1 >## b1) then a1 else b1)-      (if isTrue# (a2 >## b2) then a2 else b2)-      (if isTrue# (a3 >## b3) then a3 else b3)-      (if isTrue# (a4 >## b4) then a4 else b4)-    {-# INLINE max #-}------ | element-wise operations for vectors-instance Num DoubleX4 where--    DoubleX4# a1 a2 a3 a4 + DoubleX4# b1 b2 b3 b4-      = DoubleX4# ((+##) a1 b1) ((+##) a2 b2) ((+##) a3 b3) ((+##) a4 b4)-    {-# INLINE (+) #-}--    DoubleX4# a1 a2 a3 a4 - DoubleX4# b1 b2 b3 b4-      = DoubleX4# ((-##) a1 b1) ((-##) a2 b2) ((-##) a3 b3) ((-##) a4 b4)-    {-# INLINE (-) #-}--    DoubleX4# a1 a2 a3 a4 * DoubleX4# b1 b2 b3 b4-      = DoubleX4# ((*##) a1 b1) ((*##) a2 b2) ((*##) a3 b3) ((*##) a4 b4)-    {-# INLINE (*) #-}--    negate (DoubleX4# a1 a2 a3 a4) = DoubleX4#-      (negateDouble# a1) (negateDouble# a2) (negateDouble# a3) (negateDouble# a4)-    {-# INLINE negate #-}--    abs (DoubleX4# a1 a2 a3 a4)-      = DoubleX4#-      (if isTrue# (a1 >=## 0.0##) then a1 else negateDouble# a1)-      (if isTrue# (a2 >=## 0.0##) then a2 else negateDouble# a2)-      (if isTrue# (a3 >=## 0.0##) then a3 else negateDouble# a3)-      (if isTrue# (a4 >=## 0.0##) then a4 else negateDouble# a4)-    {-# INLINE abs #-}--    signum (DoubleX4# a1 a2 a3 a4)-      = DoubleX4# (if isTrue# (a1 >## 0.0##)-                  then 1.0##-                  else if isTrue# (a1 <## 0.0##) then -1.0## else 0.0## )-                 (if isTrue# (a2 >## 0.0##)-                  then 1.0##-                  else if isTrue# (a2 <## 0.0##) then -1.0## else 0.0## )-                 (if isTrue# (a3 >## 0.0##)-                  then 1.0##-                  else if isTrue# (a3 <## 0.0##) then -1.0## else 0.0## )-                 (if isTrue# (a4 >## 0.0##)-                  then 1.0##-                  else if isTrue# (a4 <## 0.0##) then -1.0## else 0.0## )-    {-# INLINE signum #-}--    fromInteger n = case fromInteger n of D# x -> DoubleX4# x x x x-    {-# INLINE fromInteger #-}----instance Fractional DoubleX4 where--    DoubleX4# a1 a2 a3 a4 / DoubleX4# b1 b2 b3 b4 = DoubleX4#-      ((/##) a1 b1) ((/##) a2 b2) ((/##) a3 b3) ((/##) a4 b4)-    {-# INLINE (/) #-}--    recip (DoubleX4# a1 a2 a3 a4) = DoubleX4#-      ((/##) 1.0## a1) ((/##) 1.0## a2) ((/##) 1.0## a3) ((/##) 1.0## a4)-    {-# INLINE recip #-}--    fromRational r = case fromRational r of D# x -> DoubleX4# x x x x-    {-# INLINE fromRational #-}----instance Floating DoubleX4 where--    pi = DoubleX4#-      3.141592653589793238##-      3.141592653589793238##-      3.141592653589793238##-      3.141592653589793238##-    {-# INLINE pi #-}--    exp (DoubleX4# a1 a2 a3 a4) = DoubleX4#-      (expDouble# a1) (expDouble# a2) (expDouble# a3) (expDouble# a4)-    {-# INLINE exp #-}--    log (DoubleX4# a1 a2 a3 a4) = DoubleX4#-      (logDouble# a1) (logDouble# a2) (logDouble# a3) (logDouble# a4)-    {-# INLINE log #-}--    sqrt (DoubleX4# a1 a2 a3 a4) = DoubleX4#-      (sqrtDouble# a1) (sqrtDouble# a2) (sqrtDouble# a3) (sqrtDouble# a4)-    {-# INLINE sqrt #-}--    sin (DoubleX4# a1 a2 a3 a4) = DoubleX4#-      (sinDouble# a1) (sinDouble# a2) (sinDouble# a3) (sinDouble# a4)-    {-# INLINE sin #-}--    cos (DoubleX4# a1 a2 a3 a4) = DoubleX4#-      (cosDouble# a1) (cosDouble# a2) (cosDouble# a3) (cosDouble# a4)-    {-# INLINE cos #-}--    tan (DoubleX4# a1 a2 a3 a4) = DoubleX4#-      (tanDouble# a1) (tanDouble# a2) (tanDouble# a3) (tanDouble# a4)-    {-# INLINE tan #-}--    asin (DoubleX4# a1 a2 a3 a4) = DoubleX4#-      (asinDouble# a1) (asinDouble# a2) (asinDouble# a3) (asinDouble# a4)-    {-# INLINE asin #-}--    acos (DoubleX4# a1 a2 a3 a4) = DoubleX4#-      (acosDouble# a1) (acosDouble# a2) (acosDouble# a3) (acosDouble# a4)-    {-# INLINE acos #-}--    atan (DoubleX4# a1 a2 a3 a4) = DoubleX4#-      (atanDouble# a1) (atanDouble# a2) (atanDouble# a3) (atanDouble# a4)-    {-# INLINE atan #-}--    sinh (DoubleX4# a1 a2 a3 a4) = DoubleX4#-      (sinhDouble# a1) (sinhDouble# a2) (sinhDouble# a3) (sinhDouble# a4)-    {-# INLINE sinh #-}--    cosh (DoubleX4# a1 a2 a3 a4) = DoubleX4#-      (coshDouble# a1) (coshDouble# a2) (coshDouble# a3) (coshDouble# a4)-    {-# INLINE cosh #-}--    tanh (DoubleX4# a1 a2 a3 a4) = DoubleX4#-      (tanhDouble# a1) (tanhDouble# a2) (tanhDouble# a3) (tanhDouble# a4)-    {-# INLINE tanh #-}--    DoubleX4# a1 a2 a3 a4 ** DoubleX4# b1 b2 b3 b4 = DoubleX4#-      ((**##) a1 b1) ((**##) a2 b2) ((**##) a3 b3) ((**##) a4 b4)-    {-# INLINE (**) #-}--    logBase x y         =  log y / log x-    {-# INLINE logBase #-}--    asinh x = log (x + sqrt (1.0+x*x))-    {-# INLINE asinh #-}--    acosh x = log (x + (x+1.0) * sqrt ((x-1.0)/(x+1.0)))-    {-# INLINE acosh #-}--    atanh x = 0.5 * log ((1.0+x) / (1.0-x))-    {-# INLINE atanh #-}---- offset in bytes is S times bigger than offset in prim elements,--- when S is power of two, this is equal to shift-#define BOFF_TO_PRIMOFF(off) uncheckedIShiftRL# off 3#-#define ELEM_N 4--instance PrimBytes DoubleX4 where--    getBytes (DoubleX4# a1 a2 a3 a4) = case runRW#-       ( \s0 -> case newByteArray# (byteSize @DoubleX4 undefined) s0 of-           (# s1, marr #) -> case writeDoubleArray# marr 0# a1 s1 of-             s2 -> case writeDoubleArray# marr 1# a2 s2 of-               s3 -> case writeDoubleArray# marr 2# a3 s3 of-                 s4 -> case writeDoubleArray# marr 3# a4 s4 of-                   s5 -> unsafeFreezeByteArray# marr s5-       ) of (# _, a #) -> a-    {-# INLINE getBytes #-}--    fromBytes off arr-      | i <- BOFF_TO_PRIMOFF(off)-      = DoubleX4#-      (indexDoubleArray# arr i)-      (indexDoubleArray# arr (i +# 1#))-      (indexDoubleArray# arr (i +# 2#))-      (indexDoubleArray# arr (i +# 3#))-    {-# INLINE fromBytes #-}--    readBytes mba off s0-      | i <- BOFF_TO_PRIMOFF(off)-      = case readDoubleArray# mba i s0 of-      (# s1, a1 #) -> case readDoubleArray# mba (i +# 1#) s1 of-        (# s2, a2 #) -> case readDoubleArray# mba (i +# 2#) s2 of-          (# s3, a3 #) -> case readDoubleArray# mba (i +# 3#) s3 of-            (# s4, a4 #) -> (# s4, DoubleX4# a1 a2 a3 a4 #)-    {-# INLINE readBytes #-}--    writeBytes mba off (DoubleX4# a1 a2 a3 a4) s-      | i <- BOFF_TO_PRIMOFF(off)-      = writeDoubleArray# mba (i +# 3#) a4-      ( writeDoubleArray# mba (i +# 2#) a3-      ( writeDoubleArray# mba (i +# 1#) a2-      ( writeDoubleArray# mba  i        a1 s )))-    {-# INLINE writeBytes #-}--    readAddr addr s0-      = case readDoubleOffAddr# addr 0# s0 of-      (# s1, a1 #) -> case readDoubleOffAddr# addr 1# s1 of-        (# s2, a2 #) -> case readDoubleOffAddr# addr 2# s2 of-          (# s3, a3 #) -> case readDoubleOffAddr# addr 3# s3 of-            (# s4, a4 #) -> (# s4, DoubleX4# a1 a2 a3 a4 #)-    {-# INLINE readAddr #-}--    writeAddr (DoubleX4# a1 a2 a3 a4) addr s-      = writeDoubleOffAddr# addr 3# a4-      ( writeDoubleOffAddr# addr 2# a3-      ( writeDoubleOffAddr# addr 1# a2-      ( writeDoubleOffAddr# addr 0# a1 s )))-    {-# INLINE writeAddr #-}--    byteSize _ = byteSize @Double undefined *# ELEM_N#-    {-# INLINE byteSize #-}--    byteAlign _ = byteAlign @Double undefined-    {-# INLINE byteAlign #-}--    byteOffset _ = 0#-    {-# INLINE byteOffset #-}--    indexArray ba off-      | i <- off *# ELEM_N#-      = DoubleX4#-      (indexDoubleArray# ba i)-      (indexDoubleArray# ba (i +# 1#))-      (indexDoubleArray# ba (i +# 2#))-      (indexDoubleArray# ba (i +# 3#))-    {-# INLINE indexArray #-}--    readArray mba off s0-      | i <- off *# ELEM_N#-      = case readDoubleArray# mba i s0 of-      (# s1, a1 #) -> case readDoubleArray# mba (i +# 1#) s1 of-        (# s2, a2 #) -> case readDoubleArray# mba (i +# 2#) s2 of-          (# s3, a3 #) -> case readDoubleArray# mba (i +# 3#) s3 of-            (# s4, a4 #) -> (# s4, DoubleX4# a1 a2 a3 a4 #)-    {-# INLINE readArray #-}--    writeArray mba off (DoubleX4# a1 a2 a3 a4) s-      | i <- off *# ELEM_N#-      = writeDoubleArray# mba (i +# 3#) a4-      ( writeDoubleArray# mba (i +# 2#) a3-      ( writeDoubleArray# mba (i +# 1#) a2-      ( writeDoubleArray# mba  i        a1 s )))-    {-# INLINE writeArray #-}---instance PrimArray Double DoubleX4 where--    broadcast (D# x) = DoubleX4# x x x x-    {-# INLINE broadcast #-}--    ix# 0# (DoubleX4# a1 _ _ _) = D# a1-    ix# 1# (DoubleX4# _ a2 _ _) = D# a2-    ix# 2# (DoubleX4# _ _ a3 _) = D# a3-    ix# 3# (DoubleX4# _ _ _ a4) = D# a4-    ix# _   _                   = undefined-    {-# INLINE ix# #-}--    gen# _ f s0 = case f s0 of-      (# s1, D# a1 #) -> case f s1 of-        (# s2, D# a2 #) -> case f s2 of-          (# s3, D# a3 #) -> case f s3 of-            (# s4, D# a4 #) -> (# s4, DoubleX4# a1 a2 a3 a4 #)---    upd# _ 0# (D# q) (DoubleX4# _ y z w) = DoubleX4# q y z w-    upd# _ 1# (D# q) (DoubleX4# x _ z w) = DoubleX4# x q z w-    upd# _ 2# (D# q) (DoubleX4# x y _ w) = DoubleX4# x y q w-    upd# _ 3# (D# q) (DoubleX4# x y z _) = DoubleX4# x y z q-    upd# _ _ _ x                         = x-    {-# INLINE upd# #-}--    elemOffset _ = 0#-    {-# INLINE elemOffset #-}--    elemSize0 _  = ELEM_N#-    {-# INLINE elemSize0 #-}--    fromElems off _ ba = DoubleX4#-      (indexDoubleArray# ba off)-      (indexDoubleArray# ba (off +# 1#))-      (indexDoubleArray# ba (off +# 2#))-      (indexDoubleArray# ba (off +# 3#))-    {-# INLINE fromElems #-}
− src/Numeric/DataFrame/Internal/Array/Family/FloatX2.hs
@@ -1,333 +0,0 @@-{-# LANGUAGE CPP                   #-}-{-# LANGUAGE MagicHash             #-}-{-# LANGUAGE MultiParamTypeClasses #-}-{-# LANGUAGE TypeApplications      #-}-{-# LANGUAGE UnboxedTuples         #-}-module Numeric.DataFrame.Internal.Array.Family.FloatX2 (FloatX2 (..)) where---import           GHC.Base-import           Numeric.DataFrame.Internal.Array.Class-import           Numeric.DataFrame.Internal.Array.PrimOps-import           Numeric.PrimBytes---data FloatX2 = FloatX2# Float# Float#---instance Bounded FloatX2 where-    maxBound = case inftyF of F# x -> FloatX2# x x-    minBound = case negate inftyF of F# x -> FloatX2# x x---instance Show FloatX2 where-    show (FloatX2# a1 a2)-      =  "{ " ++ show (F# a1)-      ++ ", " ++ show (F# a2)-      ++ " }"----instance Eq FloatX2 where--    FloatX2# a1 a2 == FloatX2# b1 b2 =-      isTrue#-      (       (a1 `eqFloat#` b1)-      `andI#` (a2 `eqFloat#` b2)-      )-    {-# INLINE (==) #-}--    FloatX2# a1 a2 /= FloatX2# b1 b2 =-      isTrue#-      (      (a1 `neFloat#` b1)-      `orI#` (a2 `neFloat#` b2)-      )-    {-# INLINE (/=) #-}------ | Implement partial ordering for `>`, `<`, `>=`, `<=`---           and lexicographical ordering for `compare`-instance Ord FloatX2 where-    FloatX2# a1 a2 > FloatX2# b1 b2 =-      isTrue#-      (       (a1 `gtFloat#` b1)-      `andI#` (a2 `gtFloat#` b2)-      )-    {-# INLINE (>) #-}--    FloatX2# a1 a2 < FloatX2# b1 b2 =-      isTrue#-      (       (a1 `ltFloat#` b1)-      `andI#` (a2 `ltFloat#` b2)-      )-    {-# INLINE (<) #-}--    FloatX2# a1 a2 >= FloatX2# b1 b2 =-      isTrue#-      (       (a1 `geFloat#` b1)-      `andI#` (a2 `geFloat#` b2)-      )-    {-# INLINE (>=) #-}--    FloatX2# a1 a2 <= FloatX2# b1 b2 =-      isTrue#-      (       (a1 `leFloat#` b1)-      `andI#` (a2 `leFloat#` b2)-      )-    {-# INLINE (<=) #-}--    -- | Compare lexicographically-    compare (FloatX2# a1 a2) (FloatX2# b1 b2)-      | isTrue# (a1 `gtFloat#` b1) = GT-      | isTrue# (a1 `ltFloat#` b1) = LT-      | isTrue# (a2 `gtFloat#` b2) = GT-      | isTrue# (a2 `ltFloat#` b2) = LT-      | otherwise = EQ-    {-# INLINE compare #-}--    -- | Element-wise minimum-    min (FloatX2# a1 a2) (FloatX2# b1 b2) = FloatX2#-      (if isTrue# (a1 `gtFloat#` b1) then b1 else a1)-      (if isTrue# (a2 `gtFloat#` b2) then b2 else a2)-    {-# INLINE min #-}--    -- | Element-wise maximum-    max (FloatX2# a1 a2) (FloatX2# b1 b2) = FloatX2#-      (if isTrue# (a1 `gtFloat#` b1) then a1 else b1)-      (if isTrue# (a2 `gtFloat#` b2) then a2 else b2)-    {-# INLINE max #-}------ | element-wise operations for vectors-instance Num FloatX2 where--    FloatX2# a1 a2 + FloatX2# b1 b2-      = FloatX2# (plusFloat# a1 b1) (plusFloat# a2 b2)-    {-# INLINE (+) #-}--    FloatX2# a1 a2 - FloatX2# b1 b2-      = FloatX2# (minusFloat# a1 b1) (minusFloat# a2 b2)-    {-# INLINE (-) #-}--    FloatX2# a1 a2 * FloatX2# b1 b2-      = FloatX2# (timesFloat# a1 b1) (timesFloat# a2 b2)-    {-# INLINE (*) #-}--    negate (FloatX2# a1 a2) = FloatX2#-      (negateFloat# a1) (negateFloat# a2)-    {-# INLINE negate #-}--    abs (FloatX2# a1 a2)-      = FloatX2#-      (if isTrue# (a1 `geFloat#` 0.0#) then a1 else negateFloat# a1)-      (if isTrue# (a2 `geFloat#` 0.0#) then a2 else negateFloat# a2)-    {-# INLINE abs #-}--    signum (FloatX2# a1 a2)-      = FloatX2# (if isTrue# (a1 `gtFloat#` 0.0#)-                  then 1.0#-                  else if isTrue# (a1 `ltFloat#` 0.0#) then -1.0# else 0.0# )-                 (if isTrue# (a2 `gtFloat#` 0.0#)-                  then 1.0#-                  else if isTrue# (a2 `ltFloat#` 0.0#) then -1.0# else 0.0# )-    {-# INLINE signum #-}--    fromInteger n = case fromInteger n of F# x -> FloatX2# x x-    {-# INLINE fromInteger #-}----instance Fractional FloatX2 where--    FloatX2# a1 a2 / FloatX2# b1 b2 = FloatX2#-      (divideFloat# a1 b1) (divideFloat# a2 b2)-    {-# INLINE (/) #-}--    recip (FloatX2# a1 a2) = FloatX2#-      (divideFloat# 1.0# a1) (divideFloat# 1.0# a2)-    {-# INLINE recip #-}--    fromRational r = case fromRational r of F# x -> FloatX2# x x-    {-# INLINE fromRational #-}----instance Floating FloatX2 where--    pi = FloatX2#-      3.141592653589793238#-      3.141592653589793238#-    {-# INLINE pi #-}--    exp (FloatX2# a1 a2) = FloatX2#-      (expFloat# a1) (expFloat# a2)-    {-# INLINE exp #-}--    log (FloatX2# a1 a2) = FloatX2#-      (logFloat# a1) (logFloat# a2)-    {-# INLINE log #-}--    sqrt (FloatX2# a1 a2) = FloatX2#-      (sqrtFloat# a1) (sqrtFloat# a2)-    {-# INLINE sqrt #-}--    sin (FloatX2# a1 a2) = FloatX2#-      (sinFloat# a1) (sinFloat# a2)-    {-# INLINE sin #-}--    cos (FloatX2# a1 a2) = FloatX2#-      (cosFloat# a1) (cosFloat# a2)-    {-# INLINE cos #-}--    tan (FloatX2# a1 a2) = FloatX2#-      (tanFloat# a1) (tanFloat# a2)-    {-# INLINE tan #-}--    asin (FloatX2# a1 a2) = FloatX2#-      (asinFloat# a1) (asinFloat# a2)-    {-# INLINE asin #-}--    acos (FloatX2# a1 a2) = FloatX2#-      (acosFloat# a1) (acosFloat# a2)-    {-# INLINE acos #-}--    atan (FloatX2# a1 a2) = FloatX2#-      (atanFloat# a1) (atanFloat# a2)-    {-# INLINE atan #-}--    sinh (FloatX2# a1 a2) = FloatX2#-      (sinhFloat# a1) (sinhFloat# a2)-    {-# INLINE sinh #-}--    cosh (FloatX2# a1 a2) = FloatX2#-      (coshFloat# a1) (coshFloat# a2)-    {-# INLINE cosh #-}--    tanh (FloatX2# a1 a2) = FloatX2#-      (tanhFloat# a1) (tanhFloat# a2)-    {-# INLINE tanh #-}--    FloatX2# a1 a2 ** FloatX2# b1 b2 = FloatX2#-      (powerFloat# a1 b1) (powerFloat# a2 b2)-    {-# INLINE (**) #-}--    logBase x y         =  log y / log x-    {-# INLINE logBase #-}--    asinh x = log (x + sqrt (1.0+x*x))-    {-# INLINE asinh #-}--    acosh x = log (x + (x+1.0) * sqrt ((x-1.0)/(x+1.0)))-    {-# INLINE acosh #-}--    atanh x = 0.5 * log ((1.0+x) / (1.0-x))-    {-# INLINE atanh #-}---- offset in bytes is S times bigger than offset in prim elements,--- when S is power of two, this is equal to shift-#define BOFF_TO_PRIMOFF(off) uncheckedIShiftRL# off 2#-#define ELEM_N 2--instance PrimBytes FloatX2 where--    getBytes (FloatX2# a1 a2) = case runRW#-       ( \s0 -> case newByteArray# (byteSize @FloatX2 undefined) s0 of-           (# s1, marr #) -> case writeFloatArray# marr 0# a1 s1 of-             s2 -> case writeFloatArray# marr 1# a2 s2 of-               s3 -> unsafeFreezeByteArray# marr s3-       ) of (# _, a #) -> a-    {-# INLINE getBytes #-}--    fromBytes off arr-      | i <- BOFF_TO_PRIMOFF(off)-      = FloatX2#-      (indexFloatArray# arr i)-      (indexFloatArray# arr (i +# 1#))-    {-# INLINE fromBytes #-}--    readBytes mba off s0-      | i <- BOFF_TO_PRIMOFF(off)-      = case readFloatArray# mba i s0 of-      (# s1, a1 #) -> case readFloatArray# mba (i +# 1#) s1 of-        (# s2, a2 #) -> (# s2, FloatX2# a1 a2 #)-    {-# INLINE readBytes #-}--    writeBytes mba off (FloatX2# a1 a2) s-      | i <- BOFF_TO_PRIMOFF(off)-      = writeFloatArray# mba (i +# 1#) a2-      ( writeFloatArray# mba  i        a1 s )-    {-# INLINE writeBytes #-}--    readAddr addr s0-      = case readFloatOffAddr# addr 0# s0 of-      (# s1, a1 #) -> case readFloatOffAddr# addr 1# s1 of-        (# s2, a2 #) -> (# s2, FloatX2# a1 a2 #)-    {-# INLINE readAddr #-}--    writeAddr (FloatX2# a1 a2) addr s-      = writeFloatOffAddr# addr 1# a2-      ( writeFloatOffAddr# addr 0# a1 s )-    {-# INLINE writeAddr #-}--    byteSize _ = byteSize @Float undefined *# ELEM_N#-    {-# INLINE byteSize #-}--    byteAlign _ = byteAlign @Float undefined-    {-# INLINE byteAlign #-}--    byteOffset _ = 0#-    {-# INLINE byteOffset #-}--    indexArray ba off-      | i <- off *# ELEM_N#-      = FloatX2#-      (indexFloatArray# ba i)-      (indexFloatArray# ba (i +# 1#))-    {-# INLINE indexArray #-}--    readArray mba off s0-      | i <- off *# ELEM_N#-      = case readFloatArray# mba i s0 of-      (# s1, a1 #) -> case readFloatArray# mba (i +# 1#) s1 of-        (# s2, a2 #) -> (# s2, FloatX2# a1 a2 #)-    {-# INLINE readArray #-}--    writeArray mba off (FloatX2# a1 a2) s-      | i <- off *# ELEM_N#-      = writeFloatArray# mba (i +# 1#) a2-      ( writeFloatArray# mba  i        a1 s )-    {-# INLINE writeArray #-}---instance PrimArray Float FloatX2 where--    broadcast (F# x) = FloatX2# x x-    {-# INLINE broadcast #-}--    ix# 0# (FloatX2# a1 _) = F# a1-    ix# 1# (FloatX2# _ a2) = F# a2-    ix# _   _              = undefined-    {-# INLINE ix# #-}--    gen# _ f s0 = case f s0 of-      (# s1, F# a1 #) -> case f s1 of-        (# s2, F# a2 #) -> (# s2, FloatX2# a1 a2 #)---    upd# _ 0# (F# q) (FloatX2# _ y) = FloatX2# q y-    upd# _ 1# (F# q) (FloatX2# x _) = FloatX2# x q-    upd# _ _ _ x                    = x-    {-# INLINE upd# #-}--    elemOffset _ = 0#-    {-# INLINE elemOffset #-}--    elemSize0 _  = ELEM_N#-    {-# INLINE elemSize0 #-}--    fromElems off _ ba = FloatX2#-      (indexFloatArray# ba off)-      (indexFloatArray# ba (off +# 1#))-    {-# INLINE fromElems #-}
− src/Numeric/DataFrame/Internal/Array/Family/FloatX3.hs
@@ -1,362 +0,0 @@-{-# LANGUAGE CPP                   #-}-{-# LANGUAGE MagicHash             #-}-{-# LANGUAGE MultiParamTypeClasses #-}-{-# LANGUAGE TypeApplications      #-}-{-# LANGUAGE UnboxedTuples         #-}-module Numeric.DataFrame.Internal.Array.Family.FloatX3 (FloatX3 (..)) where---import           GHC.Base-import           Numeric.DataFrame.Internal.Array.Class-import           Numeric.DataFrame.Internal.Array.PrimOps-import           Numeric.PrimBytes---data FloatX3 = FloatX3# Float# Float# Float#---instance Bounded FloatX3 where-    maxBound = case inftyF of F# x -> FloatX3# x x x-    minBound = case negate inftyF of F# x -> FloatX3# x x x---instance Show FloatX3 where-    show (FloatX3# a1 a2 a3)-      =  "{ " ++ show (F# a1)-      ++ ", " ++ show (F# a2)-      ++ ", " ++ show (F# a3)-      ++ " }"----instance Eq FloatX3 where--    FloatX3# a1 a2 a3 == FloatX3# b1 b2 b3 =-      isTrue#-      (       (a1 `eqFloat#` b1)-      `andI#` (a2 `eqFloat#` b2)-      `andI#` (a3 `eqFloat#` b3)-      )-    {-# INLINE (==) #-}--    FloatX3# a1 a2 a3 /= FloatX3# b1 b2 b3 =-      isTrue#-      (      (a1 `neFloat#` b1)-      `orI#` (a2 `neFloat#` b2)-      `orI#` (a3 `neFloat#` b3)-      )-    {-# INLINE (/=) #-}------ | Implement partial ordering for `>`, `<`, `>=`, `<=`---           and lexicographical ordering for `compare`-instance Ord FloatX3 where-    FloatX3# a1 a2 a3 > FloatX3# b1 b2 b3 =-      isTrue#-      (       (a1 `gtFloat#` b1)-      `andI#` (a2 `gtFloat#` b2)-      `andI#` (a3 `gtFloat#` b3)-      )-    {-# INLINE (>) #-}--    FloatX3# a1 a2 a3 < FloatX3# b1 b2 b3 =-      isTrue#-      (       (a1 `ltFloat#` b1)-      `andI#` (a2 `ltFloat#` b2)-      `andI#` (a3 `ltFloat#` b3)-      )-    {-# INLINE (<) #-}--    FloatX3# a1 a2 a3 >= FloatX3# b1 b2 b3 =-      isTrue#-      (       (a1 `geFloat#` b1)-      `andI#` (a2 `geFloat#` b2)-      `andI#` (a3 `geFloat#` b3)-      )-    {-# INLINE (>=) #-}--    FloatX3# a1 a2 a3 <= FloatX3# b1 b2 b3 =-      isTrue#-      (       (a1 `leFloat#` b1)-      `andI#` (a2 `leFloat#` b2)-      `andI#` (a3 `leFloat#` b3)-      )-    {-# INLINE (<=) #-}--    -- | Compare lexicographically-    compare (FloatX3# a1 a2 a3) (FloatX3# b1 b2 b3)-      | isTrue# (a1 `gtFloat#` b1) = GT-      | isTrue# (a1 `ltFloat#` b1) = LT-      | isTrue# (a2 `gtFloat#` b2) = GT-      | isTrue# (a2 `ltFloat#` b2) = LT-      | isTrue# (a3 `gtFloat#` b3) = GT-      | isTrue# (a3 `ltFloat#` b3) = LT-      | otherwise = EQ-    {-# INLINE compare #-}--    -- | Element-wise minimum-    min (FloatX3# a1 a2 a3) (FloatX3# b1 b2 b3) = FloatX3#-      (if isTrue# (a1 `gtFloat#` b1) then b1 else a1)-      (if isTrue# (a2 `gtFloat#` b2) then b2 else a2)-      (if isTrue# (a3 `gtFloat#` b3) then b3 else a3)-    {-# INLINE min #-}--    -- | Element-wise maximum-    max (FloatX3# a1 a2 a3) (FloatX3# b1 b2 b3) = FloatX3#-      (if isTrue# (a1 `gtFloat#` b1) then a1 else b1)-      (if isTrue# (a2 `gtFloat#` b2) then a2 else b2)-      (if isTrue# (a3 `gtFloat#` b3) then a3 else b3)-    {-# INLINE max #-}------ | element-wise operations for vectors-instance Num FloatX3 where--    FloatX3# a1 a2 a3 + FloatX3# b1 b2 b3-      = FloatX3# (plusFloat# a1 b1) (plusFloat# a2 b2) (plusFloat# a3 b3)-    {-# INLINE (+) #-}--    FloatX3# a1 a2 a3 - FloatX3# b1 b2 b3-      = FloatX3# (minusFloat# a1 b1) (minusFloat# a2 b2) (minusFloat# a3 b3)-    {-# INLINE (-) #-}--    FloatX3# a1 a2 a3 * FloatX3# b1 b2 b3-      = FloatX3# (timesFloat# a1 b1) (timesFloat# a2 b2) (timesFloat# a3 b3)-    {-# INLINE (*) #-}--    negate (FloatX3# a1 a2 a3) = FloatX3#-      (negateFloat# a1) (negateFloat# a2) (negateFloat# a3)-    {-# INLINE negate #-}--    abs (FloatX3# a1 a2 a3)-      = FloatX3#-      (if isTrue# (a1 `geFloat#` 0.0#) then a1 else negateFloat# a1)-      (if isTrue# (a2 `geFloat#` 0.0#) then a2 else negateFloat# a2)-      (if isTrue# (a3 `geFloat#` 0.0#) then a3 else negateFloat# a3)-    {-# INLINE abs #-}--    signum (FloatX3# a1 a2 a3)-      = FloatX3# (if isTrue# (a1 `gtFloat#` 0.0#)-                  then 1.0#-                  else if isTrue# (a1 `ltFloat#` 0.0#) then -1.0# else 0.0# )-                 (if isTrue# (a2 `gtFloat#` 0.0#)-                  then 1.0#-                  else if isTrue# (a2 `ltFloat#` 0.0#) then -1.0# else 0.0# )-                 (if isTrue# (a3 `gtFloat#` 0.0#)-                  then 1.0#-                  else if isTrue# (a3 `ltFloat#` 0.0#) then -1.0# else 0.0# )-    {-# INLINE signum #-}--    fromInteger n = case fromInteger n of F# x -> FloatX3# x x x-    {-# INLINE fromInteger #-}----instance Fractional FloatX3 where--    FloatX3# a1 a2 a3 / FloatX3# b1 b2 b3 = FloatX3#-      (divideFloat# a1 b1) (divideFloat# a2 b2) (divideFloat# a3 b3)-    {-# INLINE (/) #-}--    recip (FloatX3# a1 a2 a3) = FloatX3#-      (divideFloat# 1.0# a1) (divideFloat# 1.0# a2) (divideFloat# 1.0# a3)-    {-# INLINE recip #-}--    fromRational r = case fromRational r of F# x -> FloatX3# x x x-    {-# INLINE fromRational #-}----instance Floating FloatX3 where--    pi = FloatX3#-      3.141592653589793238#-      3.141592653589793238#-      3.141592653589793238#-    {-# INLINE pi #-}--    exp (FloatX3# a1 a2 a3) = FloatX3#-      (expFloat# a1) (expFloat# a2) (expFloat# a3)-    {-# INLINE exp #-}--    log (FloatX3# a1 a2 a3) = FloatX3#-      (logFloat# a1) (logFloat# a2) (logFloat# a3)-    {-# INLINE log #-}--    sqrt (FloatX3# a1 a2 a3) = FloatX3#-      (sqrtFloat# a1) (sqrtFloat# a2) (sqrtFloat# a3)-    {-# INLINE sqrt #-}--    sin (FloatX3# a1 a2 a3) = FloatX3#-      (sinFloat# a1) (sinFloat# a2) (sinFloat# a3)-    {-# INLINE sin #-}--    cos (FloatX3# a1 a2 a3) = FloatX3#-      (cosFloat# a1) (cosFloat# a2) (cosFloat# a3)-    {-# INLINE cos #-}--    tan (FloatX3# a1 a2 a3) = FloatX3#-      (tanFloat# a1) (tanFloat# a2) (tanFloat# a3)-    {-# INLINE tan #-}--    asin (FloatX3# a1 a2 a3) = FloatX3#-      (asinFloat# a1) (asinFloat# a2) (asinFloat# a3)-    {-# INLINE asin #-}--    acos (FloatX3# a1 a2 a3) = FloatX3#-      (acosFloat# a1) (acosFloat# a2) (acosFloat# a3)-    {-# INLINE acos #-}--    atan (FloatX3# a1 a2 a3) = FloatX3#-      (atanFloat# a1) (atanFloat# a2) (atanFloat# a3)-    {-# INLINE atan #-}--    sinh (FloatX3# a1 a2 a3) = FloatX3#-      (sinhFloat# a1) (sinhFloat# a2) (sinhFloat# a3)-    {-# INLINE sinh #-}--    cosh (FloatX3# a1 a2 a3) = FloatX3#-      (coshFloat# a1) (coshFloat# a2) (coshFloat# a3)-    {-# INLINE cosh #-}--    tanh (FloatX3# a1 a2 a3) = FloatX3#-      (tanhFloat# a1) (tanhFloat# a2) (tanhFloat# a3)-    {-# INLINE tanh #-}--    FloatX3# a1 a2 a3 ** FloatX3# b1 b2 b3 = FloatX3#-      (powerFloat# a1 b1) (powerFloat# a2 b2) (powerFloat# a3 b3)-    {-# INLINE (**) #-}--    logBase x y         =  log y / log x-    {-# INLINE logBase #-}--    asinh x = log (x + sqrt (1.0+x*x))-    {-# INLINE asinh #-}--    acosh x = log (x + (x+1.0) * sqrt ((x-1.0)/(x+1.0)))-    {-# INLINE acosh #-}--    atanh x = 0.5 * log ((1.0+x) / (1.0-x))-    {-# INLINE atanh #-}---- offset in bytes is S times bigger than offset in prim elements,--- when S is power of two, this is equal to shift-#define BOFF_TO_PRIMOFF(off) uncheckedIShiftRL# off 2#-#define ELEM_N 3--instance PrimBytes FloatX3 where--    getBytes (FloatX3# a1 a2 a3) = case runRW#-       ( \s0 -> case newByteArray# (byteSize @FloatX3 undefined) s0 of-           (# s1, marr #) -> case writeFloatArray# marr 0# a1 s1 of-             s2 -> case writeFloatArray# marr 1# a2 s2 of-               s3 -> case writeFloatArray# marr 2# a3 s3 of-                 s4 -> unsafeFreezeByteArray# marr s4-       ) of (# _, a #) -> a-    {-# INLINE getBytes #-}--    fromBytes off arr-      | i <- BOFF_TO_PRIMOFF(off)-      = FloatX3#-      (indexFloatArray# arr i)-      (indexFloatArray# arr (i +# 1#))-      (indexFloatArray# arr (i +# 2#))-    {-# INLINE fromBytes #-}--    readBytes mba off s0-      | i <- BOFF_TO_PRIMOFF(off)-      = case readFloatArray# mba i s0 of-      (# s1, a1 #) -> case readFloatArray# mba (i +# 1#) s1 of-        (# s2, a2 #) -> case readFloatArray# mba (i +# 2#) s2 of-          (# s3, a3 #) -> (# s3, FloatX3# a1 a2 a3 #)-    {-# INLINE readBytes #-}--    writeBytes mba off (FloatX3# a1 a2 a3) s-      | i <- BOFF_TO_PRIMOFF(off)-      = writeFloatArray# mba (i +# 2#) a3-      ( writeFloatArray# mba (i +# 1#) a2-      ( writeFloatArray# mba  i        a1 s ))-    {-# INLINE writeBytes #-}--    readAddr addr s0-      = case readFloatOffAddr# addr 0# s0 of-      (# s1, a1 #) -> case readFloatOffAddr# addr 1# s1 of-        (# s2, a2 #) -> case readFloatOffAddr# addr 2# s2 of-          (# s3, a3 #) -> (# s3, FloatX3# a1 a2 a3 #)-    {-# INLINE readAddr #-}--    writeAddr (FloatX3# a1 a2 a3) addr s-      = writeFloatOffAddr# addr 2# a3-      ( writeFloatOffAddr# addr 1# a2-      ( writeFloatOffAddr# addr 0# a1 s ))-    {-# INLINE writeAddr #-}--    byteSize _ = byteSize @Float undefined *# ELEM_N#-    {-# INLINE byteSize #-}--    byteAlign _ = byteAlign @Float undefined-    {-# INLINE byteAlign #-}--    byteOffset _ = 0#-    {-# INLINE byteOffset #-}--    indexArray ba off-      | i <- off *# ELEM_N#-      = FloatX3#-      (indexFloatArray# ba i)-      (indexFloatArray# ba (i +# 1#))-      (indexFloatArray# ba (i +# 2#))-    {-# INLINE indexArray #-}--    readArray mba off s0-      | i <- off *# ELEM_N#-      = case readFloatArray# mba i s0 of-      (# s1, a1 #) -> case readFloatArray# mba (i +# 1#) s1 of-        (# s2, a2 #) -> case readFloatArray# mba (i +# 2#) s2 of-          (# s3, a3 #) -> (# s3, FloatX3# a1 a2 a3 #)-    {-# INLINE readArray #-}--    writeArray mba off (FloatX3# a1 a2 a3) s-      | i <- off *# ELEM_N#-      = writeFloatArray# mba (i +# 2#) a3-      ( writeFloatArray# mba (i +# 1#) a2-      ( writeFloatArray# mba  i        a1 s ))-    {-# INLINE writeArray #-}---instance PrimArray Float FloatX3 where--    broadcast (F# x) = FloatX3# x x x-    {-# INLINE broadcast #-}--    ix# 0# (FloatX3# a1 _ _) = F# a1-    ix# 1# (FloatX3# _ a2 _) = F# a2-    ix# 2# (FloatX3# _ _ a3) = F# a3-    ix# _   _                = undefined-    {-# INLINE ix# #-}--    gen# _ f s0 = case f s0 of-      (# s1, F# a1 #) -> case f s1 of-        (# s2, F# a2 #) -> case f s2 of-          (# s3, F# a3 #) -> (# s3, FloatX3# a1 a2 a3 #)---    upd# _ 0# (F# q) (FloatX3# _ y z) = FloatX3# q y z-    upd# _ 1# (F# q) (FloatX3# x _ z) = FloatX3# x q z-    upd# _ 2# (F# q) (FloatX3# x y _) = FloatX3# x y q-    upd# _ _ _ x                      = x-    {-# INLINE upd# #-}--    elemOffset _ = 0#-    {-# INLINE elemOffset #-}--    elemSize0 _  = ELEM_N#-    {-# INLINE elemSize0 #-}--    fromElems off _ ba = FloatX3#-      (indexFloatArray# ba off)-      (indexFloatArray# ba (off +# 1#))-      (indexFloatArray# ba (off +# 2#))-    {-# INLINE fromElems #-}
− src/Numeric/DataFrame/Internal/Array/Family/FloatX4.hs
@@ -1,420 +0,0 @@-{-# LANGUAGE CPP                   #-}-{-# LANGUAGE DataKinds             #-}-{-# LANGUAGE MagicHash             #-}-{-# LANGUAGE MultiParamTypeClasses #-}-{-# LANGUAGE TypeApplications      #-}-{-# LANGUAGE UnboxedTuples         #-}-{-# OPTIONS_GHC -fno-warn-orphans  #-}-module Numeric.DataFrame.Internal.Array.Family.FloatX4 (FloatX4 (..)) where---import           GHC.Base-import           Numeric.DataFrame.Internal.Array.Class-import           Numeric.DataFrame.Internal.Array.PrimOps-import           Numeric.DataFrame.SubSpace-import           Numeric.Dimensions-import           Numeric.PrimBytes---data FloatX4 = FloatX4# Float# Float# Float# Float#---instance Bounded FloatX4 where-    maxBound = case inftyF of F# x -> FloatX4# x x x x-    minBound = case negate inftyF of F# x -> FloatX4# x x x x---instance Show FloatX4 where-    show (FloatX4# a1 a2 a3 a4)-      =  "{ " ++ show (F# a1)-      ++ ", " ++ show (F# a2)-      ++ ", " ++ show (F# a3)-      ++ ", " ++ show (F# a4)-      ++ " }"----instance Eq FloatX4 where--    FloatX4# a1 a2 a3 a4 == FloatX4# b1 b2 b3 b4 =-      isTrue#-      (       (a1 `eqFloat#` b1)-      `andI#` (a2 `eqFloat#` b2)-      `andI#` (a3 `eqFloat#` b3)-      `andI#` (a4 `eqFloat#` b4)-      )-    {-# INLINE (==) #-}--    FloatX4# a1 a2 a3 a4 /= FloatX4# b1 b2 b3 b4 =-      isTrue#-      (      (a1 `neFloat#` b1)-      `orI#` (a2 `neFloat#` b2)-      `orI#` (a3 `neFloat#` b3)-      `orI#` (a4 `neFloat#` b4)-      )-    {-# INLINE (/=) #-}------ | Implement partial ordering for `>`, `<`, `>=`, `<=`---           and lexicographical ordering for `compare`-instance Ord FloatX4 where-    FloatX4# a1 a2 a3 a4 > FloatX4# b1 b2 b3 b4 =-      isTrue#-      (       (a1 `gtFloat#` b1)-      `andI#` (a2 `gtFloat#` b2)-      `andI#` (a3 `gtFloat#` b3)-      `andI#` (a4 `gtFloat#` b4)-      )-    {-# INLINE (>) #-}--    FloatX4# a1 a2 a3 a4 < FloatX4# b1 b2 b3 b4 =-      isTrue#-      (       (a1 `ltFloat#` b1)-      `andI#` (a2 `ltFloat#` b2)-      `andI#` (a3 `ltFloat#` b3)-      `andI#` (a4 `ltFloat#` b4)-      )-    {-# INLINE (<) #-}--    FloatX4# a1 a2 a3 a4 >= FloatX4# b1 b2 b3 b4 =-      isTrue#-      (       (a1 `geFloat#` b1)-      `andI#` (a2 `geFloat#` b2)-      `andI#` (a3 `geFloat#` b3)-      `andI#` (a4 `geFloat#` b4)-      )-    {-# INLINE (>=) #-}--    FloatX4# a1 a2 a3 a4 <= FloatX4# b1 b2 b3 b4 =-      isTrue#-      (       (a1 `leFloat#` b1)-      `andI#` (a2 `leFloat#` b2)-      `andI#` (a3 `leFloat#` b3)-      `andI#` (a4 `leFloat#` b4)-      )-    {-# INLINE (<=) #-}--    -- | Compare lexicographically-    compare (FloatX4# a1 a2 a3 a4) (FloatX4# b1 b2 b3 b4)-      | isTrue# (a1 `gtFloat#` b1) = GT-      | isTrue# (a1 `ltFloat#` b1) = LT-      | isTrue# (a2 `gtFloat#` b2) = GT-      | isTrue# (a2 `ltFloat#` b2) = LT-      | isTrue# (a3 `gtFloat#` b3) = GT-      | isTrue# (a3 `ltFloat#` b3) = LT-      | isTrue# (a4 `gtFloat#` b4) = GT-      | isTrue# (a4 `ltFloat#` b4) = LT-      | otherwise = EQ-    {-# INLINE compare #-}--    -- | Element-wise minimum-    min (FloatX4# a1 a2 a3 a4) (FloatX4# b1 b2 b3 b4) = FloatX4#-      (if isTrue# (a1 `gtFloat#` b1) then b1 else a1)-      (if isTrue# (a2 `gtFloat#` b2) then b2 else a2)-      (if isTrue# (a3 `gtFloat#` b3) then b3 else a3)-      (if isTrue# (a4 `gtFloat#` b4) then b4 else a4)-    {-# INLINE min #-}--    -- | Element-wise maximum-    max (FloatX4# a1 a2 a3 a4) (FloatX4# b1 b2 b3 b4) = FloatX4#-      (if isTrue# (a1 `gtFloat#` b1) then a1 else b1)-      (if isTrue# (a2 `gtFloat#` b2) then a2 else b2)-      (if isTrue# (a3 `gtFloat#` b3) then a3 else b3)-      (if isTrue# (a4 `gtFloat#` b4) then a4 else b4)-    {-# INLINE max #-}------ | element-wise operations for vectors-instance Num FloatX4 where--    FloatX4# a1 a2 a3 a4 + FloatX4# b1 b2 b3 b4-      = FloatX4# (plusFloat# a1 b1) (plusFloat# a2 b2) (plusFloat# a3 b3) (plusFloat# a4 b4)-    {-# INLINE (+) #-}--    FloatX4# a1 a2 a3 a4 - FloatX4# b1 b2 b3 b4-      = FloatX4# (minusFloat# a1 b1) (minusFloat# a2 b2) (minusFloat# a3 b3) (minusFloat# a4 b4)-    {-# INLINE (-) #-}--    FloatX4# a1 a2 a3 a4 * FloatX4# b1 b2 b3 b4-      = FloatX4# (timesFloat# a1 b1) (timesFloat# a2 b2) (timesFloat# a3 b3) (timesFloat# a4 b4)-    {-# INLINE (*) #-}--    negate (FloatX4# a1 a2 a3 a4) = FloatX4#-      (negateFloat# a1) (negateFloat# a2) (negateFloat# a3) (negateFloat# a4)-    {-# INLINE negate #-}--    abs (FloatX4# a1 a2 a3 a4)-      = FloatX4#-      (if isTrue# (a1 `geFloat#` 0.0#) then a1 else negateFloat# a1)-      (if isTrue# (a2 `geFloat#` 0.0#) then a2 else negateFloat# a2)-      (if isTrue# (a3 `geFloat#` 0.0#) then a3 else negateFloat# a3)-      (if isTrue# (a4 `geFloat#` 0.0#) then a4 else negateFloat# a4)-    {-# INLINE abs #-}--    signum (FloatX4# a1 a2 a3 a4)-      = FloatX4# (if isTrue# (a1 `gtFloat#` 0.0#)-                  then 1.0#-                  else if isTrue# (a1 `ltFloat#` 0.0#) then -1.0# else 0.0# )-                 (if isTrue# (a2 `gtFloat#` 0.0#)-                  then 1.0#-                  else if isTrue# (a2 `ltFloat#` 0.0#) then -1.0# else 0.0# )-                 (if isTrue# (a3 `gtFloat#` 0.0#)-                  then 1.0#-                  else if isTrue# (a3 `ltFloat#` 0.0#) then -1.0# else 0.0# )-                 (if isTrue# (a4 `gtFloat#` 0.0#)-                  then 1.0#-                  else if isTrue# (a4 `ltFloat#` 0.0#) then -1.0# else 0.0# )-    {-# INLINE signum #-}--    fromInteger n = case fromInteger n of F# x -> FloatX4# x x x x-    {-# INLINE fromInteger #-}----instance Fractional FloatX4 where--    FloatX4# a1 a2 a3 a4 / FloatX4# b1 b2 b3 b4 = FloatX4#-      (divideFloat# a1 b1) (divideFloat# a2 b2) (divideFloat# a3 b3) (divideFloat# a4 b4)-    {-# INLINE (/) #-}--    recip (FloatX4# a1 a2 a3 a4) = FloatX4#-      (divideFloat# 1.0# a1) (divideFloat# 1.0# a2) (divideFloat# 1.0# a3) (divideFloat# 1.0# a4)-    {-# INLINE recip #-}--    fromRational r = case fromRational r of F# x -> FloatX4# x x x x-    {-# INLINE fromRational #-}----instance Floating FloatX4 where--    pi = FloatX4#-      3.141592653589793238#-      3.141592653589793238#-      3.141592653589793238#-      3.141592653589793238#-    {-# INLINE pi #-}--    exp (FloatX4# a1 a2 a3 a4) = FloatX4#-      (expFloat# a1) (expFloat# a2) (expFloat# a3) (expFloat# a4)-    {-# INLINE exp #-}--    log (FloatX4# a1 a2 a3 a4) = FloatX4#-      (logFloat# a1) (logFloat# a2) (logFloat# a3) (logFloat# a4)-    {-# INLINE log #-}--    sqrt (FloatX4# a1 a2 a3 a4) = FloatX4#-      (sqrtFloat# a1) (sqrtFloat# a2) (sqrtFloat# a3) (sqrtFloat# a4)-    {-# INLINE sqrt #-}--    sin (FloatX4# a1 a2 a3 a4) = FloatX4#-      (sinFloat# a1) (sinFloat# a2) (sinFloat# a3) (sinFloat# a4)-    {-# INLINE sin #-}--    cos (FloatX4# a1 a2 a3 a4) = FloatX4#-      (cosFloat# a1) (cosFloat# a2) (cosFloat# a3) (cosFloat# a4)-    {-# INLINE cos #-}--    tan (FloatX4# a1 a2 a3 a4) = FloatX4#-      (tanFloat# a1) (tanFloat# a2) (tanFloat# a3) (tanFloat# a4)-    {-# INLINE tan #-}--    asin (FloatX4# a1 a2 a3 a4) = FloatX4#-      (asinFloat# a1) (asinFloat# a2) (asinFloat# a3) (asinFloat# a4)-    {-# INLINE asin #-}--    acos (FloatX4# a1 a2 a3 a4) = FloatX4#-      (acosFloat# a1) (acosFloat# a2) (acosFloat# a3) (acosFloat# a4)-    {-# INLINE acos #-}--    atan (FloatX4# a1 a2 a3 a4) = FloatX4#-      (atanFloat# a1) (atanFloat# a2) (atanFloat# a3) (atanFloat# a4)-    {-# INLINE atan #-}--    sinh (FloatX4# a1 a2 a3 a4) = FloatX4#-      (sinhFloat# a1) (sinhFloat# a2) (sinhFloat# a3) (sinhFloat# a4)-    {-# INLINE sinh #-}--    cosh (FloatX4# a1 a2 a3 a4) = FloatX4#-      (coshFloat# a1) (coshFloat# a2) (coshFloat# a3) (coshFloat# a4)-    {-# INLINE cosh #-}--    tanh (FloatX4# a1 a2 a3 a4) = FloatX4#-      (tanhFloat# a1) (tanhFloat# a2) (tanhFloat# a3) (tanhFloat# a4)-    {-# INLINE tanh #-}--    FloatX4# a1 a2 a3 a4 ** FloatX4# b1 b2 b3 b4 = FloatX4#-      (powerFloat# a1 b1) (powerFloat# a2 b2) (powerFloat# a3 b3) (powerFloat# a4 b4)-    {-# INLINE (**) #-}--    logBase x y         =  log y / log x-    {-# INLINE logBase #-}--    asinh x = log (x + sqrt (1.0+x*x))-    {-# INLINE asinh #-}--    acosh x = log (x + (x+1.0) * sqrt ((x-1.0)/(x+1.0)))-    {-# INLINE acosh #-}--    atanh x = 0.5 * log ((1.0+x) / (1.0-x))-    {-# INLINE atanh #-}---- offset in bytes is S times bigger than offset in prim elements,--- when S is power of two, this is equal to shift-#define BOFF_TO_PRIMOFF(off) uncheckedIShiftRL# off 2#-#define ELEM_N 4--instance PrimBytes FloatX4 where--    getBytes (FloatX4# a1 a2 a3 a4) = case runRW#-       ( \s0 -> case newByteArray# (byteSize @FloatX4 undefined) s0 of-           (# s1, marr #) -> case writeFloatArray# marr 0# a1 s1 of-             s2 -> case writeFloatArray# marr 1# a2 s2 of-               s3 -> case writeFloatArray# marr 2# a3 s3 of-                 s4 -> case writeFloatArray# marr 3# a4 s4 of-                   s5 -> unsafeFreezeByteArray# marr s5-       ) of (# _, a #) -> a-    {-# INLINE getBytes #-}--    fromBytes off arr-      | i <- BOFF_TO_PRIMOFF(off)-      = FloatX4#-      (indexFloatArray# arr i)-      (indexFloatArray# arr (i +# 1#))-      (indexFloatArray# arr (i +# 2#))-      (indexFloatArray# arr (i +# 3#))-    {-# INLINE fromBytes #-}--    readBytes mba off s0-      | i <- BOFF_TO_PRIMOFF(off)-      = case readFloatArray# mba i s0 of-      (# s1, a1 #) -> case readFloatArray# mba (i +# 1#) s1 of-        (# s2, a2 #) -> case readFloatArray# mba (i +# 2#) s2 of-          (# s3, a3 #) -> case readFloatArray# mba (i +# 3#) s3 of-            (# s4, a4 #) -> (# s4, FloatX4# a1 a2 a3 a4 #)-    {-# INLINE readBytes #-}--    writeBytes mba off (FloatX4# a1 a2 a3 a4) s-      | i <- BOFF_TO_PRIMOFF(off)-      = writeFloatArray# mba (i +# 3#) a4-      ( writeFloatArray# mba (i +# 2#) a3-      ( writeFloatArray# mba (i +# 1#) a2-      ( writeFloatArray# mba  i        a1 s )))-    {-# INLINE writeBytes #-}--    readAddr addr s0-      = case readFloatOffAddr# addr 0# s0 of-      (# s1, a1 #) -> case readFloatOffAddr# addr 1# s1 of-        (# s2, a2 #) -> case readFloatOffAddr# addr 2# s2 of-          (# s3, a3 #) -> case readFloatOffAddr# addr 3# s3 of-            (# s4, a4 #) -> (# s4, FloatX4# a1 a2 a3 a4 #)-    {-# INLINE readAddr #-}--    writeAddr (FloatX4# a1 a2 a3 a4) addr s-      = writeFloatOffAddr# addr 3# a4-      ( writeFloatOffAddr# addr 2# a3-      ( writeFloatOffAddr# addr 1# a2-      ( writeFloatOffAddr# addr 0# a1 s )))-    {-# INLINE writeAddr #-}--    byteSize _ = byteSize @Float undefined *# ELEM_N#-    {-# INLINE byteSize #-}--    byteAlign _ = byteAlign @Float undefined-    {-# INLINE byteAlign #-}--    byteOffset _ = 0#-    {-# INLINE byteOffset #-}--    indexArray ba off-      | i <- off *# ELEM_N#-      = FloatX4#-      (indexFloatArray# ba i)-      (indexFloatArray# ba (i +# 1#))-      (indexFloatArray# ba (i +# 2#))-      (indexFloatArray# ba (i +# 3#))-    {-# INLINE indexArray #-}--    readArray mba off s0-      | i <- off *# ELEM_N#-      = case readFloatArray# mba i s0 of-      (# s1, a1 #) -> case readFloatArray# mba (i +# 1#) s1 of-        (# s2, a2 #) -> case readFloatArray# mba (i +# 2#) s2 of-          (# s3, a3 #) -> case readFloatArray# mba (i +# 3#) s3 of-            (# s4, a4 #) -> (# s4, FloatX4# a1 a2 a3 a4 #)-    {-# INLINE readArray #-}--    writeArray mba off (FloatX4# a1 a2 a3 a4) s-      | i <- off *# ELEM_N#-      = writeFloatArray# mba (i +# 3#) a4-      ( writeFloatArray# mba (i +# 2#) a3-      ( writeFloatArray# mba (i +# 1#) a2-      ( writeFloatArray# mba  i        a1 s )))-    {-# INLINE writeArray #-}---instance PrimArray Float FloatX4 where--    broadcast (F# x) = FloatX4# x x x x-    {-# INLINE broadcast #-}--    ix# 0# (FloatX4# a1 _ _ _) = F# a1-    ix# 1# (FloatX4# _ a2 _ _) = F# a2-    ix# 2# (FloatX4# _ _ a3 _) = F# a3-    ix# 3# (FloatX4# _ _ _ a4) = F# a4-    ix# _   _                  = undefined-    {-# INLINE ix# #-}--    gen# _ f s0 = case f s0 of-      (# s1, F# a1 #) -> case f s1 of-        (# s2, F# a2 #) -> case f s2 of-          (# s3, F# a3 #) -> case f s3 of-            (# s4, F# a4 #) -> (# s4, FloatX4# a1 a2 a3 a4 #)---    upd# _ 0# (F# q) (FloatX4# _ y z w) = FloatX4# q y z w-    upd# _ 1# (F# q) (FloatX4# x _ z w) = FloatX4# x q z w-    upd# _ 2# (F# q) (FloatX4# x y _ w) = FloatX4# x y q w-    upd# _ 3# (F# q) (FloatX4# x y z _) = FloatX4# x y z q-    upd# _ _ _ x                        = x-    {-# INLINE upd# #-}--    elemOffset _ = 0#-    {-# INLINE elemOffset #-}--    elemSize0 _  = ELEM_N#-    {-# INLINE elemSize0 #-}--    fromElems off _ ba = FloatX4#-      (indexFloatArray# ba off)-      (indexFloatArray# ba (off +# 1#))-      (indexFloatArray# ba (off +# 2#))-      (indexFloatArray# ba (off +# 3#))-    {-# INLINE fromElems #-}-------------------------------------------------------------------------------------- Rewrite rules to improve efficiency of algorithms------ Here we don't have access to DataFrame constructors, because we cannot import--- Numeric.DataFrame.Type module.--- However, we know that all DataFrame instances are just newtype wrappers--- (as well as Scalar). Thus, we can use unsafeCoerce# to get access to Arrays--- inside DataFrames.--------------------------------------------------------------------------------------getIdxOffset :: Idxs '[4] -> Int#-getIdxOffset is = case unsafeCoerce# is of-  [W# i] -> word2Int# i -# 1#-  _      -> 0#-{-# INLINE getIdxOffset #-}---{-# RULES-"index/FloatX4" forall i . (!.) @Float @'[] i-  = unsafeCoerce# (ix# @Float @FloatX4 (getIdxOffset i))--  #-}
− src/Numeric/DataFrame/Internal/Array/Family/ScalarBase.hs
@@ -1,51 +0,0 @@-{-# LANGUAGE FlexibleInstances          #-}-{-# LANGUAGE GeneralizedNewtypeDeriving #-}-{-# LANGUAGE MagicHash                  #-}-{-# LANGUAGE MultiParamTypeClasses      #-}-{-# LANGUAGE StandaloneDeriving         #-}-{-# LANGUAGE TypeInType                 #-}-{-# LANGUAGE UnboxedTuples              #-}-module Numeric.DataFrame.Internal.Array.Family.ScalarBase (ScalarBase (..)) where---import           GHC.Base-import           Numeric.DataFrame.Internal.Array.Class-import           Numeric.DataFrame.Internal.Array.PrimOps-import           Numeric.PrimBytes---- | Specialize ScalarBase type without any arrays-newtype ScalarBase t = ScalarBase { _unScalarBase :: t }-  deriving ( Enum, Eq, Integral-           , Num, Fractional, Floating, Ord, Read, Real, RealFrac, RealFloat-           , PrimBytes)--instance Show t => Show (ScalarBase t) where-  show (ScalarBase t) = "{ " ++ show t ++ " }"--deriving instance {-# OVERLAPPABLE #-} Bounded t => Bounded (ScalarBase t)-instance {-# OVERLAPPING #-} Bounded (ScalarBase Double) where-  maxBound = ScalarBase inftyD-  minBound = ScalarBase $ negate inftyD-instance {-# OVERLAPPING #-} Bounded (ScalarBase Float) where-  maxBound = ScalarBase inftyF-  minBound = ScalarBase $ negate inftyF--instance PrimBytes t => PrimArray t (ScalarBase t) where-  broadcast = unsafeCoerce#-  {-# INLINE broadcast #-}-  ix# _ = unsafeCoerce#-  {-# INLINE ix# #-}-  gen# _ = unsafeCoerce#-  {-# INLINE gen# #-}-  upd# _ 0# = const . ScalarBase-  upd# _ _  = const id-  {-# INLINE upd# #-}-  elemOffset _ = 0#-  {-# INLINE elemOffset #-}-  elemSize0 _ = 1#-  {-# INLINE elemSize0 #-}-  fromElems off _ ba = indexArray ba off-  {-# INLINE fromElems #-}--_suppressHlintUnboxedTuplesWarning :: () -> (# (), () #)-_suppressHlintUnboxedTuplesWarning = undefined
− src/Numeric/DataFrame/Internal/Array/PrimOps.hs
@@ -1,94 +0,0 @@-{-# LANGUAGE DataKinds      #-}-{-# LANGUAGE KindSignatures #-}-{-# LANGUAGE MagicHash      #-}-{-# LANGUAGE PolyKinds      #-}-{-# LANGUAGE UnboxedTuples  #-}--- | Internal primitive functions shared across modules-module Numeric.DataFrame.Internal.Array.PrimOps where--import           GHC.Base-import           Numeric.Dimensions--inftyD :: Double-inftyD = read "Infinity"-{-# INLINE inftyD #-}--inftyF :: Float-inftyF = read "Infinity"-{-# INLINE inftyF #-}----minInt# :: Int# -> Int# -> Int#-minInt# a b | isTrue# (a ># b) = b-            | otherwise        = a-{-# INLINE minInt# #-}---loop# :: Int# -- ^ initial value-      -> Int# -- ^ step-      -> Int# -- ^ final value (LESS THAN condition)-      -> (Int# -> State# s -> State# s) -> State# s -> State# s-loop# n0 di n1 f = loop0 n0-  where-    loop0 i s | isTrue# (i >=# n1) = s-              | otherwise = loop0 (i +# di) (f i s)-{-# INLINE loop# #-}----- | Loop with given increment, plus keep the step number---   in the first argument of the iterated function-loopWithI# :: Int# -- ^ initial value-           -> Int# -- ^ step-           -> Int# -- ^ final value (LESS THAN condition)-           -> (Int# -> Int# -> State# s -> State# s) -> State# s -> State# s-loopWithI# n0 di n1 f = loop0 0# n0-  where-    loop0 j i s | isTrue# (i >=# n1) = s-                | otherwise = loop0 (j +# 1#) (i +# di) (f j i s)-{-# INLINE loopWithI# #-}----- | Do something in a loop for int i from 0 to (n-1)-loop1# :: Int# -> (Int# -> State# s -> State# s) -> State# s -> State# s-loop1# n f = loop0 0#-  where-    loop0 i s | isTrue# (i ==# n) = s-              | otherwise = loop0 (i +# 1#) (f i s)-{-# INLINE loop1# #-}---- | Do something in a loop for int i from 0 to (n-1)-loop1a# :: Int# -> (Int# -> a -> a) -> a -> a-loop1a# n f = loop0 0#-  where-    loop0 i s | isTrue# (i ==# n) = s-              | otherwise = s `seq` case f i s of s1 -> s1 `seq` loop0 (i +# 1#) s1-{-# INLINE loop1a# #-}----- | Same as overDim#, but with no return value-overDim_# :: Dims (ds :: [k])-          -> (Idxs ds -> Int# -> State# s -> State# s) -- ^ function to map over each dimension-          -> Int# -- ^ Initial offset-          -> Int# -- ^ offset step-          -> State# s-          -> State# s-overDim_# ds f off0# step# s0 = case overDim_'# ds g off0# s0 of-                              (# s1, _ #) -> s1-  where-    g i off# s = (# f i off# s, off# +# step# #)-{-# INLINE overDim_# #-}---overDim_'# :: Dims (ds :: [k])-           -> (Idxs ds -> Int# -> State# s -> (# State# s, Int# #)) -- ^ function to map over each dimension-           -> Int# -- ^ Initial offset-           -> State# s-           -> (# State# s, Int# #)-overDim_'# U f = f U-overDim_'# (d :* ds) f = overDim_'# ds (loop 1)-  where-    n = dimVal d-    loop i js off# s | i > n = (# s , off#  #)-                     | otherwise = case f (Idx i :* js) off# s of-                         (# s', off1# #) -> loop (i+1) js off1# s'
+ src/Numeric/DataFrame/Internal/Backend.hs view
@@ -0,0 +1,221 @@+{-# LANGUAGE CPP                   #-}+{-# LANGUAGE ConstraintKinds       #-}+{-# LANGUAGE DataKinds             #-}+{-# LANGUAGE FlexibleContexts      #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE PolyKinds             #-}+{-# LANGUAGE RoleAnnotations       #-}+{-# LANGUAGE ScopedTypeVariables   #-}+{-# LANGUAGE TypeApplications      #-}+{-# LANGUAGE TypeFamilies          #-}+{-# LANGUAGE TypeOperators         #-}+{-# OPTIONS_GHC -fno-warn-redundant-constraints #-}+#if defined(__HADDOCK__) || defined(__HADDOCK_VERSION__)+{-# OPTIONS_GHC -fno-warn-simplifiable-class-constraints #-}+#else+{-# OPTIONS_GHC -fplugin Data.Constraint.Deriving #-}+#endif++module Numeric.DataFrame.Internal.Backend+  ( DFBackend, Backend (..), BackendFamily, KnownBackend ()+  , inferKnownBackend, inferPrimElem+    -- * Auto-deriving instances+  , inferEq, inferOrd+  , inferProductOrder, inferPONonTransitive, inferPOPartial+  , inferBounded, inferNum+  , inferFractional, inferFloating+  , inferPrimBytes, inferPrimArray+  ) where+++import Data.Constraint+import Data.Constraint.Deriving+import Data.Constraint.Unsafe+import Data.Kind                (Type)+import Unsafe.Coerce            (unsafeCoerce)++import           Numeric.DataFrame.Internal.PrimArray+import           Numeric.Dimensions+import           Numeric.PrimBytes+import           Numeric.ProductOrd+import qualified Numeric.ProductOrd.NonTransitive     as NonTransitive+import qualified Numeric.ProductOrd.Partial           as Partial++import           Numeric.DataFrame.Internal.Backend.Family (BackendFamily)+import qualified Numeric.DataFrame.Internal.Backend.Family as Impl (KnownBackend,+                                                                    inferBackendInstance,+                                                                    inferKnownBackend,+                                                                    inferPrimArray,+                                                                    inferPrimElem)+import           Numeric.DataFrame.Internal.BackendI       (I)++-- | Implementation behind the DataFrame+type DFBackend (t :: Type) (ds :: [Nat]) = Backend I t ds (BackendFamily 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]) = Impl.KnownBackend 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 { _getBackend :: backend }+type role Backend phantom phantom phantom representational+type instance DeriveContext (Backend I t ds b) = b ~ BackendFamily t ds+-- When typechecker knows what the third parameter @b@ is, no instances overlap,+-- because @b@ is always always a concrete type.+-- The "dynamic instances" derived via ToInstance have to be incoherent,+-- because @BackendFamily t ds@ as a type family (before resolving it)+--  is no more conrete than just @b@.+{-# ANN type Backend (DeriveAll' NoOverlap ["KnownBackend"]) #-}++++inferKnownBackend+  :: forall (t :: Type) (ds :: [Nat])+   . (PrimBytes t, Dimensions ds)+  => Dict (KnownBackend t ds)+inferKnownBackend+  = Impl.inferKnownBackend @t @ds @(BackendFamily t ds)++inferPrimElem+  :: forall (t :: Type) (d :: Nat) (ds :: [Nat])+   . KnownBackend t (d ': ds)+  => DFBackend t (d ': ds) -> Dict (PrimBytes t)+inferPrimElem = Impl.inferPrimElem @t @d @ds . _getBackend++++inferEq+  :: forall (t :: Type) (ds :: [Nat]) (b :: Type)+   . (Eq t, Impl.KnownBackend t ds b)+  => Dict (Eq (Backend I t ds b))+inferEq+    = mapDict toBackend+    . mapDict (Sub (Impl.inferBackendInstance @t @ds))+    $ inferDeriveContext @t @ds @b undefined++inferOrd+  :: forall (t :: Type) (ds :: [Nat]) (b :: Type)+   . (Ord t, Impl.KnownBackend t ds b)+  => Dict (Ord (Backend I t ds b))+inferOrd+    = mapDict toBackend+    . mapDict (Sub (Impl.inferBackendInstance @t @ds))+    $ inferDeriveContext @t @ds @b undefined++inferProductOrder+  :: forall (t :: Type) (ds :: [Nat]) (b :: Type)+   . (Ord t, Impl.KnownBackend t ds b)+  => Dict (ProductOrder (Backend I t ds b))+inferProductOrder+    = mapDict toBackend+    . mapDict (Sub (Impl.inferBackendInstance @t @ds))+    $ inferDeriveContext @t @ds @b undefined++inferPONonTransitive+  :: forall (t :: Type) (ds :: [Nat]) (b :: Type)+   . (Ord t, Impl.KnownBackend t ds b)+  => Dict (Ord (NonTransitive.ProductOrd (Backend I t ds b)))+inferPONonTransitive+    = mapDict (unsafeDerive NonTransitive.ProductOrd)+    . mapDict toBackend+    . mapDict (Sub (Impl.inferBackendInstance @t @ds))+    $ inferDeriveContext @t @ds @b undefined++inferPOPartial+  :: forall (t :: Type) (ds :: [Nat]) (b :: Type)+   . (Ord t, Impl.KnownBackend t ds b)+  => Dict (Ord (Partial.ProductOrd (Backend I t ds b)))+inferPOPartial+    = mapDict (unsafeDerive Partial.ProductOrd)+    . mapDict toBackend+    . mapDict (Sub (Impl.inferBackendInstance @t @ds))+    $ inferDeriveContext @t @ds @b undefined++inferBounded+  :: forall (t :: Type) (ds :: [Nat]) (b :: Type)+   . (Bounded t, Impl.KnownBackend t ds b)+  => Dict (Bounded (Backend I t ds b))+inferBounded+    -- Here is an ugly trick:+    --  We don't have instance of @Bounded Float@ and @Bounded Double@.+    --  However, we want to have an instance @Bounded t => Bounded (Backend t ds b)@.+    --  Some specialized implementations (e.g. FloatX4) require explicit+    --    constraints @Bounded Float@ or @Bounded Double@.+    --  To satisfy these, I pull @Bounded t@ convincing the compiler that @t ~ Float@.+    --  This should work fine even if a user implements instances of Bounded for+    --    the floating types, because we know that @t ~ Float@ or @t ~ Double@+    --    automatically whenever this instance is called for these types.+  | Dict <- (case (unsafeCoerce (Dict @(t ~ t)) :: Dict (t ~ Float)) of+               Dict -> Dict) :: Dict (Bounded Float)+  , Dict <- (case (unsafeCoerce (Dict @(t ~ t)) :: Dict (t ~ Double)) of+               Dict -> Dict) :: Dict (Bounded Double)+    = mapDict toBackend+    . mapDict (Sub (Impl.inferBackendInstance @t @ds))+    $ inferDeriveContext @t @ds @b undefined++inferNum+  :: forall (t :: Type) (ds :: [Nat]) (b :: Type)+   . (Num t, Impl.KnownBackend t ds b)+  => Dict (Num (Backend I t ds b))+inferNum+    = mapDict toBackend+    . mapDict (Sub (Impl.inferBackendInstance @t @ds))+    $ inferDeriveContext @t @ds @b undefined++inferFractional+  :: forall (t :: Type) (ds :: [Nat]) (b :: Type)+   . (Fractional t, Impl.KnownBackend t ds b)+  => Dict (Fractional (Backend I t ds b))+inferFractional+    = mapDict toBackend+    . mapDict (Sub (Impl.inferBackendInstance @t @ds))+    $ inferDeriveContext @t @ds @b undefined++inferFloating+  :: forall (t :: Type) (ds :: [Nat]) (b :: Type)+   . (Floating t, Impl.KnownBackend t ds b)+  => Dict (Floating (Backend I t ds b))+inferFloating+    = mapDict toBackend+    . mapDict (Sub (Impl.inferBackendInstance @t @ds))+    $ inferDeriveContext @t @ds @b undefined+++inferPrimBytes+  :: forall (t :: Type) (ds :: [Nat]) (b :: Type)+   . (PrimBytes t, Dimensions ds, Impl.KnownBackend t ds b)+  => Dict (PrimBytes (Backend I t ds b))+inferPrimBytes+    = mapDict toBackend+    . mapDict (Sub (Impl.inferBackendInstance @t @ds))+    $ inferDeriveContext @t @ds @b undefined++inferPrimArray+  :: forall (t :: Type) (ds :: [Nat]) (b :: Type)+   . (PrimBytes t, Impl.KnownBackend t ds b)+  => Dict (PrimArray t (Backend I t ds b))+inferPrimArray+    = mapDict toBackend+    . mapDict (Sub (Impl.inferPrimArray @t @ds))+    $ inferDeriveContext @t @ds @b undefined+++-- This is the rule that cannot be encoded in the type system, but enforced+-- as an invariant: Backend t ds b implies DeriveContext t ds b+inferDeriveContext :: forall (t :: Type) (ds :: [Nat]) (b :: Type)+                    . Backend I t ds b+                   -> Dict (DeriveContext (Backend I t ds b))+inferDeriveContext _ = unsafeCoerce (Dict :: Dict (b ~ b))+{-# INLINE inferDeriveContext #-}++-- Backend is the newtype wrapper over b.+-- It has the same represenation and I expect it to have the same instance behavior.+toBackend :: forall c t ds b . c b :- c (Backend I t ds b)+toBackend = unsafeDerive Backend+{-# INLINE toBackend #-}
+ src/Numeric/DataFrame/Internal/Backend.hs-boot view
@@ -0,0 +1,117 @@+{-# LANGUAGE CPP              #-}+{-# LANGUAGE ConstraintKinds  #-}+{-# LANGUAGE DataKinds        #-}+{-# LANGUAGE ExplicitForAll   #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE PolyKinds        #-}+{-# LANGUAGE RoleAnnotations  #-}+{-# LANGUAGE TypeOperators    #-}+#if defined(__HADDOCK__) || defined(__HADDOCK_VERSION__)+{-# OPTIONS_GHC -fno-warn-simplifiable-class-constraints #-}+#endif++module Numeric.DataFrame.Internal.Backend+  ( DFBackend, Backend (..), BackendFamily, KnownBackend ()+  , inferKnownBackend, inferPrimElem+    -- * Auto-deriving instances+  , inferEq, inferOrd+  , inferProductOrder, inferPONonTransitive, inferPOPartial+  , inferBounded, inferNum+  , inferFractional, inferFloating+  , inferPrimBytes, inferPrimArray+  ) where++import           Data.Kind                            (Type)+import           Numeric.DataFrame.Internal.PrimArray (PrimArray)+import           Numeric.Dimensions                   (Dict, Dimensions, Nat)+import           Numeric.PrimBytes                    (PrimBytes)+import           Numeric.ProductOrd                   (ProductOrder)+import qualified Numeric.ProductOrd.NonTransitive     as NonTransitive+import qualified Numeric.ProductOrd.Partial           as Partial++import {-# SOURCE #-} Numeric.DataFrame.Internal.Backend.Family (BackendFamily)+import {-# SOURCE #-} qualified Numeric.DataFrame.Internal.Backend.Family as Impl+                                                                                   (KnownBackend)+import {-# SOURCE #-} Numeric.DataFrame.Internal.BackendI       (I)++-- | Implementation behind the DataFrame+type DFBackend (t :: Type) (ds :: [Nat]) = Backend I t ds (BackendFamily 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]) = Impl.KnownBackend 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 { _getBackend :: backend }+type role Backend phantom phantom phantom representational++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, Impl.KnownBackend t ds b)+  => Dict (Eq (Backend I t ds b))++inferOrd+  :: forall (t :: Type) (ds :: [Nat]) (b :: Type)+   . (Ord t, Impl.KnownBackend t ds b)+  => Dict (Ord (Backend I t ds b))++inferProductOrder+  :: forall (t :: Type) (ds :: [Nat]) (b :: Type)+   . (Ord t, Impl.KnownBackend t ds b)+  => Dict (ProductOrder (Backend I t ds b))++inferPONonTransitive+  :: forall (t :: Type) (ds :: [Nat]) (b :: Type)+   . (Ord t, Impl.KnownBackend t ds b)+  => Dict (Ord (NonTransitive.ProductOrd (Backend I t ds b)))++inferPOPartial+  :: forall (t :: Type) (ds :: [Nat]) (b :: Type)+   . (Ord t, Impl.KnownBackend t ds b)+  => Dict (Ord (Partial.ProductOrd (Backend I t ds b)))++inferBounded+  :: forall (t :: Type) (ds :: [Nat]) (b :: Type)+   . (Bounded t, Impl.KnownBackend t ds b)+  => Dict (Bounded (Backend I t ds b))++inferNum+  :: forall (t :: Type) (ds :: [Nat]) (b :: Type)+   . (Num t, Impl.KnownBackend t ds b)+  => Dict (Num (Backend I t ds b))++inferFractional+  :: forall (t :: Type) (ds :: [Nat]) (b :: Type)+   . (Fractional t, Impl.KnownBackend t ds b)+  => Dict (Fractional (Backend I t ds b))++inferFloating+  :: forall (t :: Type) (ds :: [Nat]) (b :: Type)+   . (Floating t, Impl.KnownBackend t ds b)+  => Dict (Floating (Backend I t ds b))++inferPrimBytes+  :: forall (t :: Type) (ds :: [Nat]) (b :: Type)+   . (PrimBytes t, Dimensions ds, Impl.KnownBackend t ds b)+  => Dict (PrimBytes (Backend I t ds b))++inferPrimArray+  :: forall (t :: Type) (ds :: [Nat]) (b :: Type)+   . (PrimBytes t, Impl.KnownBackend t ds b)+  => Dict (PrimArray t (Backend I t ds b))
+ src/Numeric/DataFrame/Internal/BackendI.hs view
@@ -0,0 +1,197 @@+{-# LANGUAGE CPP                   #-}+{-# LANGUAGE DataKinds             #-}+{-# LANGUAGE FlexibleContexts      #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE PolyKinds             #-}+{-# LANGUAGE ScopedTypeVariables   #-}+{-# LANGUAGE TypeApplications      #-}+#if defined(__HADDOCK__) || defined(__HADDOCK_VERSION__)+{-# LANGUAGE FlexibleInstances     #-}+{-# OPTIONS_GHC -fdefer-type-errors #-}+{-# OPTIONS_GHC -fno-warn-deferred-type-errors #-}+{-# OPTIONS_GHC -fno-warn-missing-methods #-}+{-# OPTIONS_GHC -fno-warn-redundant-constraints #-}+{-# OPTIONS_GHC -fno-warn-simplifiable-class-constraints #-}+#else+{-# OPTIONS_GHC -fplugin Data.Constraint.Deriving #-}+#endif++module Numeric.DataFrame.Internal.BackendI+  ( I+  , inferEq, inferOrd+  , inferProductOrder, inferPONonTransitive, inferPOPartial+  , inferBounded, inferNum+  , inferFractional, inferFloating+  , inferPrimBytes, inferPrimArray+  ) where++++import           Data.Constraint.Deriving             (OverlapMode (..),+                                                       ToInstance (..))+import           Data.Kind                            (Type)+import           Numeric.DataFrame.Internal.PrimArray (PrimArray)+import           Numeric.Dimensions                   (Dict, Dimensions, Nat)+import           Numeric.PrimBytes                    (PrimBytes)+import           Numeric.ProductOrd                   (ProductOrder)+import qualified Numeric.ProductOrd.NonTransitive     as NonTransitive+import qualified Numeric.ProductOrd.Partial           as Partial++import {-# SOURCE #-} Numeric.DataFrame.Internal.Backend        (Backend)+import {-# SOURCE #-} qualified Numeric.DataFrame.Internal.Backend        as Backend+import {-# SOURCE #-} qualified Numeric.DataFrame.Internal.Backend.Family as Impl++++{- | The instance keeper for the `Backend` type.++  Using this data as a tag to the `Backend` type allows to define `Backend` instances+  in two different modules without any orphans.++ -}+data I+++{-# ANN inferEq (ToInstance Incoherent) #-}+inferEq+  :: forall (t :: Type) (ds :: [Nat]) (b :: Type)+   . (Eq t, Impl.KnownBackend t ds b)+  => Dict (Eq (Backend I t ds b))+inferEq = Backend.inferEq @t @ds @b++{-# ANN inferOrd (ToInstance Incoherent) #-}+inferOrd+  :: forall (t :: Type) (ds :: [Nat]) (b :: Type)+   . (Ord t, Impl.KnownBackend t ds b)+  => Dict (Ord (Backend I t ds b))+inferOrd = Backend.inferOrd @t @ds @b++{-# ANN inferProductOrder (ToInstance Incoherent) #-}+inferProductOrder+  :: forall (t :: Type) (ds :: [Nat]) (b :: Type)+   . (Ord t, Impl.KnownBackend t ds b)+  => Dict (ProductOrder (Backend I t ds b))+inferProductOrder = Backend.inferProductOrder @t @ds @b++{-# ANN inferPONonTransitive (ToInstance Incoherent) #-}+inferPONonTransitive+  :: forall (t :: Type) (ds :: [Nat]) (b :: Type)+   . (Ord t, Impl.KnownBackend t ds b)+  => Dict (Ord (NonTransitive.ProductOrd (Backend I t ds b)))+inferPONonTransitive = Backend.inferPONonTransitive @t @ds @b++{-# ANN inferPOPartial (ToInstance Incoherent) #-}+inferPOPartial+  :: forall (t :: Type) (ds :: [Nat]) (b :: Type)+   . (Ord t, Impl.KnownBackend t ds b)+  => Dict (Ord (Partial.ProductOrd (Backend I t ds b)))+inferPOPartial = Backend.inferPOPartial @t @ds @b++{-# ANN inferBounded (ToInstance Incoherent) #-}+inferBounded+  :: forall (t :: Type) (ds :: [Nat]) (b :: Type)+   . (Bounded t, Impl.KnownBackend t ds b)+  => Dict (Bounded (Backend I t ds b))+inferBounded = Backend.inferBounded @t @ds @b++{-# ANN inferNum (ToInstance Incoherent) #-}+inferNum+  :: forall (t :: Type) (ds :: [Nat]) (b :: Type)+   . (Num t, Impl.KnownBackend t ds b)+  => Dict (Num (Backend I t ds b))+inferNum = Backend.inferNum @t @ds @b++{-# ANN inferFractional (ToInstance Incoherent) #-}+inferFractional+  :: forall (t :: Type) (ds :: [Nat]) (b :: Type)+   . (Fractional t, Impl.KnownBackend t ds b)+  => Dict (Fractional (Backend I t ds b))+inferFractional = Backend.inferFractional @t @ds @b++{-# ANN inferFloating (ToInstance Incoherent) #-}+inferFloating+  :: forall (t :: Type) (ds :: [Nat]) (b :: Type)+   . (Floating t, Impl.KnownBackend t ds b)+  => Dict (Floating (Backend I t ds b))+inferFloating = Backend.inferFloating @t @ds @b++{-# ANN inferPrimBytes (ToInstance Incoherent) #-}+inferPrimBytes+  :: forall (t :: Type) (ds :: [Nat]) (b :: Type)+   . (PrimBytes t, Dimensions ds, Impl.KnownBackend t ds b)+  => Dict (PrimBytes (Backend I t ds b))+inferPrimBytes = Backend.inferPrimBytes @t @ds @b++{-# ANN inferPrimArray (ToInstance Incoherent) #-}+inferPrimArray+  :: forall (t :: Type) (ds :: [Nat]) (b :: Type)+   . (PrimBytes t, Impl.KnownBackend t ds b)+  => Dict (PrimArray t (Backend I t ds b))+inferPrimArray = Backend.inferPrimArray @t @ds @b++++-- The instances below are bumb stubs needed only to compile haddock+#if defined(__HADDOCK__) || defined(__HADDOCK_VERSION__)++instance+    forall (t :: Type) (ds :: [Nat]) (b :: Type)+  . (Eq t, Impl.KnownBackend t ds b)+  => Eq (Backend I t ds b)++instance+    forall (t :: Type) (ds :: [Nat]) (b :: Type)+  . (Ord t, Impl.KnownBackend t ds b)+  => Ord (Backend I t ds b)++instance+    forall (t :: Type) (ds :: [Nat]) (b :: Type)+  . (Ord t, Impl.KnownBackend t ds b)+  => ProductOrder (Backend I t ds b)++instance+    forall (t :: Type) (ds :: [Nat]) (b :: Type)+  . (Ord t, Impl.KnownBackend t ds b)+  => Ord (NonTransitive.ProductOrd (Backend I t ds b))++instance+    forall (t :: Type) (ds :: [Nat]) (b :: Type)+  . (Ord t, Impl.KnownBackend t ds b)+  => Ord (Partial.ProductOrd (Backend I t ds b))++instance+    forall (t :: Type) (ds :: [Nat]) (b :: Type)+  . (Bounded t, Impl.KnownBackend t ds b)+  => Bounded (Backend I t ds b)++instance+    forall (t :: Type) (ds :: [Nat]) (b :: Type)+  . (Num t, Impl.KnownBackend t ds b)+  => Num (Backend I t ds b)++instance+    forall (t :: Type) (ds :: [Nat]) (b :: Type)+  . (Fractional t, Impl.KnownBackend t ds b)+  => Fractional (Backend I t ds b)++instance+    forall (t :: Type) (ds :: [Nat]) (b :: Type)+  . (Floating t, Impl.KnownBackend t ds b)+  => Floating (Backend I t ds b)++instance+    forall (t :: Type) (ds :: [Nat]) (b :: Type)+  . ( PrimBytes t+    , Dimensions ds+    , Impl.KnownBackend t ds b+    )+  => PrimBytes (Backend I t ds b)++instance+    forall (t :: Type) (ds :: [Nat]) (b :: Type)+  . ( PrimBytes t+    , Impl.KnownBackend t ds b+    )+  => PrimArray t (Backend I t ds b)++#endif
+ src/Numeric/DataFrame/Internal/BackendI.hs-boot view
@@ -0,0 +1,9 @@+module Numeric.DataFrame.Internal.BackendI (I) where++{- | The instance keeper for the `Backend` type.++  Using this data as a tag to the `Backend` type allows to define `Backend` instances+  in two different modules without any orphans.++ -}+data I
src/Numeric/DataFrame/Internal/Mutable.hs view
@@ -2,7 +2,6 @@ {-# LANGUAGE ExistentialQuantification #-} {-# LANGUAGE FlexibleContexts          #-} {-# LANGUAGE FlexibleInstances         #-}-{-# LANGUAGE KindSignatures            #-} {-# LANGUAGE MagicHash                 #-} {-# LANGUAGE MultiParamTypeClasses     #-} {-# LANGUAGE PolyKinds                 #-}@@ -11,6 +10,7 @@ {-# LANGUAGE TypeFamilies              #-} {-# LANGUAGE TypeOperators             #-} {-# LANGUAGE UnboxedTuples             #-}+{-# OPTIONS_GHC -fno-warn-redundant-constraints #-} ----------------------------------------------------------------------------- -- | -- Module      :  Numeric.DataFrame.Internal.Mutable@@ -27,6 +27,7 @@     ( MDataFrame ()     , newDataFrame#, newPinnedDataFrame#     , copyDataFrame#, copyMDataFrame#+    , copyDataFrame'#, copyMDataFrame'#     , freezeDataFrame#, unsafeFreezeDataFrame#     , thawDataFrame#, thawPinDataFrame#, unsafeThawDataFrame#     , writeDataFrame#, writeDataFrameOff#@@ -35,17 +36,17 @@     ) where  -import           GHC.Base-import           Numeric.DataFrame.Internal.Array.Class-import           Numeric.DataFrame.Type-import           Numeric.Dimensions-import           Numeric.PrimBytes+import GHC.Base+import Numeric.DataFrame.Internal.PrimArray+import Numeric.DataFrame.Type+import Numeric.Dimensions+import Numeric.PrimBytes   -- | Mutable DataFrame type. --   Keeps element offset, number of elements, and a mutable byte storage data MDataFrame s t (ns :: [Nat])-  = MDataFrame# Int# Int# (MutableByteArray# s)+  = MDataFrame# Int# CumulDims (MutableByteArray# s)   -- | Create a new mutable DataFrame.@@ -53,10 +54,10 @@                . ( PrimBytes t, Dimensions ns)               => State# s -> (# State# s, MDataFrame s t ns #) newDataFrame# s0-    | W# nw <- totalDim' @ns-    , n <- word2Int# nw+    | steps <- cumulDims $ dims @ns+    , n <- cdTotalDim# steps     , (# s1, mba #) <- newByteArray# (n *# byteSize @t undefined) s0-    = (# s1,  MDataFrame# 0# n mba #)+    = (# s1,  MDataFrame# 0# steps mba #) {-# INLINE newDataFrame# #-}  -- | Create a new mutable DataFrame.@@ -64,109 +65,163 @@                      . ( PrimBytes t, Dimensions ns)                     => State# s -> (# State# s, MDataFrame s t ns #) newPinnedDataFrame# s0-    | W# nw <- totalDim' @ns-    , n <- word2Int# nw+    | steps <- cumulDims $ dims @ns+    , n <- cdTotalDim# steps     , (# s1, mba #)  <- newAlignedPinnedByteArray#         (n *# byteSize @t undefined)         (byteAlign @t undefined) s0-    = (# s1,  MDataFrame# 0# n mba #)+    = (# s1,  MDataFrame# 0# steps mba #) {-# INLINE newPinnedDataFrame# #-}  -- | Copy one DataFrame into another mutable DataFrame at specified position.-copyDataFrame# :: forall (t :: Type) (as :: [Nat]) (b' :: Nat) (b :: Nat)-                         (bs :: [Nat]) (asbs :: [Nat]) s-                . ( PrimBytes t-                  , PrimBytes (DataFrame t (as +: b'))+--+--   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-                  , Dimensions (b :+ bs)                   )-               => DataFrame t (as +: b') -> Idxs (b :+ bs) -> MDataFrame s t asbs+               => Idxs (as +: bi) -> DataFrame t (bd :+ bs) -> MDataFrame s t asbs                -> State# s -> (# State# s, () #)-copyDataFrame# df ei (MDataFrame# off _ mba) s-    | I# i <- fromEnum ei+copyDataFrame# ei df (MDataFrame# off steps mba) s+    | I# i <- cdIx steps ei     = (# writeBytes mba ((off +# i) *# byteSize @t undefined) df s, () #) {-# INLINE copyDataFrame# #-} ++{-# ANN copyMDataFrame# "HLint: ignore Use camelCase" #-} -- | Copy one mutable DataFrame into another mutable DataFrame at specified position.-copyMDataFrame# :: forall (t :: Type) (as :: [Nat]) (b' :: Nat) (b :: Nat)-                          (bs :: [Nat]) (asbs :: [Nat]) s-                 . ( PrimBytes t+--+--   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-                   , Dimensions (b :+ bs)                    )-                => MDataFrame s t (as +: b') -> Idxs (b :+ bs) -> MDataFrame s t asbs+                => Idxs (as +: bi) -> MDataFrame s t (bd :+ bs) -> MDataFrame s t asbs                 -> State# s -> (# State# s, () #)-copyMDataFrame# (MDataFrame# offA lenA arrA) ei (MDataFrame# offM _ arrM) s+                     -- all information for copying in this case is taken from the inside+                     -- of the data types at the term level;+                     -- steps zips with indices just fine independently of their types+                     -- and length.+                     -- Thus, it's fine here to just unsafeCoerce# an index.+copyMDataFrame# ei df =+  copyMDataFrame'#+     (unsafeCoerce# ei :: Idxs as)+     (unsafeCoerce# df :: MDataFrame s t (b :+ bs))+{-# INLINE copyMDataFrame# #-}++{-# ANN copyDataFrame'# "HLint: ignore Use camelCase" #-}+-- | 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, () #)+copyDataFrame'# ei df (MDataFrame# off steps mba) s+    | I# i <- cdIx steps ei+    = (# writeBytes mba ((off +# i) *# byteSize @t undefined) df s, () #)+{-# INLINE copyDataFrame'# #-}++{-# ANN copyMDataFrame'# "HLint: ignore Use camelCase" #-}+-- | 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, () #)+copyMDataFrame'# ei (MDataFrame# offA stepsA arrA) (MDataFrame# offM stepsM arrM) s     | elS <- byteSize @t undefined-    , I# i <- fromEnum ei+    , lenA <- cdTotalDim# stepsA+    , I# i <- cdIx stepsM ei     = (# copyMutableByteArray# arrA (offA *# elS)                                arrM ((offM +# i) *# elS) (lenA *# elS) s        , () #)-{-# INLINE copyMDataFrame# #-}+{-# INLINE copyMDataFrame'# #-}  -- | 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 #)-unsafeFreezeDataFrame# (MDataFrame# offM lenM arrM) s1+unsafeFreezeDataFrame# (MDataFrame# offM steps arrM) s1     | (# s2, arrA #) <- unsafeFreezeByteArray# arrM s1-    = (# s2, fromElems offM lenM arrA #)+    = (# s2, fromElems steps offM arrA #) {-# INLINE unsafeFreezeDataFrame# #-}  -- | 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 #)-freezeDataFrame# (MDataFrame# offM n arrM) s0+freezeDataFrame# (MDataFrame# offM steps arrM) s0     | elS  <- byteSize @t undefined+    , n <- cdTotalDim# steps     , (# s1, mba #) <- newByteArray# (n *# elS) s0     , s2 <- copyMutableByteArray# arrM (offM *# elS) mba 0# (n *# elS) s1     , (# s3, arrA #) <- unsafeFreezeByteArray# mba s2-    = (# s3, fromElems 0# n arrA #)+    = (# s3, fromElems steps 0# arrA #) {-# INLINE freezeDataFrame# #-}  -- | Create a new mutable DataFrame and copy content of immutable one in there. thawDataFrame# :: forall (t :: Type) (ns :: [Nat]) s-                . (PrimBytes (DataFrame t ns), PrimBytes t)+                . ( Dimensions ns+                  , PrimBytes (DataFrame t ns))                => DataFrame t ns -> State# s -> (# State# s, MDataFrame s t ns #) thawDataFrame# df s0-    | elS  <- byteSize @t undefined-    , arrA  <- getBytes df-    , boff <- byteOffset df+    | arrA  <- getBytes df+    , boff  <- byteOffset df     , bsize <- byteSize df+    , steps <- cumulDims $ dims @ns     , (# s1, arrM #) <- newByteArray# bsize s0     , s2 <- copyByteArray# arrA boff arrM 0# bsize s1-    = (# s2, MDataFrame# 0# (quotInt# bsize elS) arrM #)+    = (# s2, MDataFrame# 0# steps arrM #) {-# INLINE thawDataFrame# #-}  -- | 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-                . (PrimBytes (DataFrame t ns), PrimBytes t)+                . ( Dimensions ns+                  , PrimBytes (DataFrame t ns))                => DataFrame t ns -> State# s -> (# State# s, MDataFrame s t ns #) thawPinDataFrame# df s0-    | elS  <- byteSize @t undefined-    , arrA  <- getBytes df-    , boff <- byteOffset df+    | arrA  <- getBytes df+    , boff  <- byteOffset df     , bsize <- byteSize df+    , steps <- cumulDims $ dims @ns     , (# s1, arrM #) <- newAlignedPinnedByteArray# bsize (byteAlign df) s0     , s2 <- copyByteArray# arrA boff arrM 0# bsize s1-    = (# s2, MDataFrame# 0# (quotInt# bsize elS) arrM #)+    = (# s2, MDataFrame# 0# steps arrM #) {-# INLINE thawPinDataFrame# #-}  -- | UnsafeCoerces an underlying byte array. unsafeThawDataFrame# :: forall (t :: Type) (ns :: [Nat]) s-                      . (PrimBytes (DataFrame t ns), PrimBytes t)+                      . ( Dimensions ns+                        , PrimBytes (DataFrame t ns), PrimBytes t)                      => DataFrame t ns                      -> State# s -> (# State# s, MDataFrame s t ns #) unsafeThawDataFrame# df s0     | elS  <- byteSize @t undefined-    , arrA  <- getBytes df+    , arrA <- getBytes df     , boff <- byteOffset df-    , bsize <- byteSize df+    , steps <- cumulDims $ dims @ns     = (# s0-       , MDataFrame# (quotInt# boff elS) (quotInt# bsize elS) (unsafeCoerce# arrA)+       , MDataFrame# (quotInt# boff elS) steps (unsafeCoerce# arrA)        #) {-# INLINE unsafeThawDataFrame# #-} @@ -181,9 +236,10 @@  -- | Write a single element at the specified index writeDataFrame# :: forall (t :: Type) (ns :: [Nat]) s-                 . ( PrimBytes t, Dimensions ns )+                 . PrimBytes t                 => MDataFrame s t ns -> Idxs ns -> t -> State# s -> (# State# s, () #)-writeDataFrame# mdf ei | I# i <- fromEnum ei = writeDataFrameOff# mdf i+writeDataFrame# mdf@(MDataFrame# _ st _) ei+  | I# i <- cdIx st ei = writeDataFrameOff# mdf i {-# INLINE writeDataFrame# #-}  -- | Read a single element at the specified element offset@@ -195,9 +251,10 @@  -- | Read a single element at the specified index readDataFrame# :: forall (t :: Type) (ns :: [Nat]) s-                . ( PrimBytes t, Dimensions ns )+                . PrimBytes t                => MDataFrame s t ns -> Idxs ns -> State# s -> (# State# s, t #)-readDataFrame# mdf ei | I# i <- fromEnum ei = readDataFrameOff# mdf i+readDataFrame# mdf@(MDataFrame# _ st _) ei+  | I# i <- cdIx st ei = readDataFrameOff# mdf i {-# INLINE readDataFrame# #-}  -- | Allow arbitrary operations on a pointer to the beginning of the data.
+ src/Numeric/DataFrame/Internal/PrimArray.hs view
@@ -0,0 +1,140 @@+{-# LANGUAGE CPP                    #-}+{-# LANGUAGE DataKinds              #-}+{-# LANGUAGE FunctionalDependencies #-}+{-# LANGUAGE MagicHash              #-}+{-# LANGUAGE MultiParamTypeClasses  #-}+{-# LANGUAGE PolyKinds              #-}+{-# LANGUAGE UnboxedTuples          #-}+module Numeric.DataFrame.Internal.PrimArray+  ( PrimArray (..), CumulDims (..)+  , cumulDims, cdTotalDim, cdTotalDim#, cdIx+  , ixOff, unsafeFromFlatList, getSteps, fromSteps+  ) where++import Data.Monoid        as Mon (Monoid (..))+import Data.Semigroup     as Sem (Semigroup (..))+import GHC.Base           (ByteArray#, Int (..), Int#, Word (..), word2Int#)+import Numeric.Dimensions+import Numeric.PrimBytes++-- | 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 { unCumulDims :: [Word] }++instance Sem.Semigroup CumulDims where+    CumulDims as <> CumulDims bs = CumulDims $ map (head bs *) (init as) ++ bs++instance Mon.Monoid CumulDims where+    mempty = CumulDims [1]+#if !(MIN_VERSION_base(4,11,0))+    mappend = (<>)+#endif+++-- | Calculate cumulative dims+cumulDims :: Dims (ns :: [k]) -> CumulDims+cumulDims = CumulDims . uncurry (:)+          . foldr (\d (c, cs) -> (c*d,c:cs)) (1, []) . listDims++-- | Get the total number of elements+cdTotalDim :: CumulDims -> Word+cdTotalDim ~(CumulDims ~(n:_)) = n++cdTotalDim# :: CumulDims -> Int#+cdTotalDim# ~(CumulDims ~(n:_)) = case n of W# w -> word2Int# w++-- | Calculate offset of an Idxs+--+--   Note, you can take offset of subspace with CumulDims of larger space+--     - very convenient!+cdIx :: CumulDims -> Idxs ns -> Int+cdIx ~(CumulDims ~(_:steps))+  = fromIntegral . sum . zipWith (*) steps . listIdxs++-- | Try to get @CumulDims@ from an array,+--   and create it using @Dims@ if failed.+getSteps :: PrimArray t a => Dims (ns :: [k]) -> a -> CumulDims+getSteps dds df = case uniqueOrCumulDims df of+   Left  _  -> cumulDims dds+   Right ds -> ds+{-# INLINE getSteps #-}++-- | Get @Dims@ by "de-accumulating" @CumulDims@.+fromSteps :: CumulDims -> SomeDims+fromSteps = someDimsVal . f . unCumulDims+  where+    -- ignore last value, which is always 1+    f :: [Word] -> [Word]+    f []       = []+    f [_]      = []+    f [n,_]    = [n]+    f (a:b:cs) = a `quot` b : f (b:cs)+{-# INLINE fromSteps #-}++class PrimBytes t => PrimArray t a | a -> t where+    -- | Broadcast element into array+    broadcast :: t -> a+    -- | Index an array given an offset+    ix# :: Int# -> a -> t+    -- | Generate an array using an accumulator funtion+    gen# :: CumulDims+            -- ^ Dimensionality of the result array;+            --   Be careful! @ns@ depends on @a@, but this is not reflected in+            --   types and is not checked at runtime.+         -> (s -> (# s, t #))+         -> s -> (# s, a #)+    -- | update a single element in an array given an offset+    upd# :: CumulDims+            -- ^ Dimensionality of the result array;+            --   Be careful! @ns@ depends on @a@, but this is not reflected in+            --   types and is not checked at runtime.+         -> 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# :: a -> (# t | (# CumulDims, Int#, ByteArray# #) #)++    -- | Offset of an array as a number of elements+    offsetElems :: a -> Int#+    offsetElems a = case arrayContent# a of+      (# _ | #)             -> 0#+      (# | (# _, o, _ #) #) -> o+    {-# INLINE offsetElems #-}++    -- | Normally, this returns a cumulative @totalDim@s.+    --   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 :: a -> Either t CumulDims+    uniqueOrCumulDims a = case arrayContent# a of+      (# x | #)              -> Left x+      (# | (# cd, _, _ #) #) -> Right cd+    {-# INLINE uniqueOrCumulDims #-}++    -- | 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 :: CumulDims -> Int# -> ByteArray# -> a++-- | Index array by an integer offset (starting from 0).+ixOff :: PrimArray t a => Int -> a -> t+ixOff (I# i) = ix# i++-- | 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+unsafeFromFlatList ds x0 vs = case gen# (cumulDims ds) f vs of (# _, r #) -> r+  where+    f []     = (# [], x0 #)+    f (x:xs) = (# xs, x #)
src/Numeric/DataFrame/ST.hs view
@@ -2,7 +2,6 @@ {-# LANGUAGE ExistentialQuantification #-} {-# LANGUAGE FlexibleContexts          #-} {-# LANGUAGE FlexibleInstances         #-}-{-# LANGUAGE KindSignatures            #-} {-# LANGUAGE MagicHash                 #-} {-# LANGUAGE MultiParamTypeClasses     #-} {-# LANGUAGE PolyKinds                 #-}@@ -17,8 +16,6 @@ -- Copyright   :  (c) Artem Chirkin -- License     :  BSD3 ----- Maintainer  :  chirkin@arch.ethz.ch--- -- Mutable DataFrames living in ST. -- -----------------------------------------------------------------------------@@ -27,6 +24,7 @@     ( STDataFrame (XSTFrame), SomeSTDataFrame (..)     , newDataFrame, newPinnedDataFrame     , copyDataFrame, copyMutableDataFrame+    , copyDataFrame', copyMutableDataFrame'     , freezeDataFrame, unsafeFreezeDataFrame     , thawDataFrame, thawPinDataFrame, unsafeThawDataFrame     , writeDataFrame, writeDataFrameOff@@ -35,14 +33,13 @@     ) where  -import           GHC.Base-import           GHC.ST                                 (ST (..))+import GHC.Base+import GHC.ST   (ST (..)) -import           Numeric.DataFrame.Family-import           Numeric.DataFrame.Internal.Array.Class-import           Numeric.DataFrame.Internal.Mutable-import           Numeric.Dimensions-import           Numeric.PrimBytes+import Numeric.DataFrame.Internal.Mutable+import Numeric.DataFrame.Internal.PrimArray+import Numeric.DataFrame.Type+import Numeric.Dimensions   -- | Mutable DataFrame that lives in ST.@@ -79,31 +76,69 @@   -- | Copy one DataFrame into another mutable DataFrame at specified position.-copyDataFrame :: forall (t :: Type) (as :: [Nat]) (b' :: Nat) (b :: Nat)-                                    (bs :: [Nat]) (asbs :: [Nat]) s-               . ( PrimBytes t-                 , PrimBytes (DataFrame t (as +: b'))+--+--   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-                 , Dimensions (b :+ bs)                  )-               => DataFrame t (as +: b') -> Idxs (b :+ bs) -> STDataFrame s t asbs -> ST s ()-copyDataFrame df ei (STDataFrame mdf) = ST (copyDataFrame# df ei mdf)+              => Idxs (as +: bi) -> DataFrame t (bd :+ bs)+              -> STDataFrame s t asbs -> ST s ()+copyDataFrame ei df (STDataFrame mdf) = ST (copyDataFrame# ei df mdf) {-# INLINE copyDataFrame #-}  -- | Copy one mutable DataFrame into another mutable DataFrame at specified position.-copyMutableDataFrame :: forall (t :: Type) (as :: [Nat]) (b' :: Nat) (b :: Nat)-                               (bs :: [Nat]) (asbs :: [Nat]) s-                      . ( PrimBytes t+--+--   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-                        , Dimensions (b :+ bs)                         )-                     => STDataFrame s t (as +: b') -> Idxs (b :+ bs)+                     => Idxs (as +: bi) -> STDataFrame s t (bd :+ bs)                      -> STDataFrame s t asbs -> ST s ()-copyMutableDataFrame (STDataFrame mdfA) ei (STDataFrame mdfB)-    = ST (copyMDataFrame# mdfA ei mdfB)+copyMutableDataFrame ei (STDataFrame mdfA) (STDataFrame mdfB)+    = ST (copyMDataFrame# ei mdfA mdfB) {-# INLINE copyMutableDataFrame #-} +-- | 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 ()+copyDataFrame' ei df (STDataFrame mdf) = ST (copyDataFrame'# ei df mdf)+{-# INLINE copyDataFrame' #-} +-- | 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 ()+copyMutableDataFrame' ei (STDataFrame mdfA) (STDataFrame mdfB)+  = ST (copyMDataFrame'# ei mdfA mdfB)+{-# INLINE copyMutableDataFrame' #-}+ -- | Make a mutable DataFrame immutable, without copying. unsafeFreezeDataFrame :: forall (t :: Type) (ns :: [Nat]) s                        . PrimArray t (DataFrame t ns)@@ -121,7 +156,7 @@  -- | Create a new mutable DataFrame and copy content of immutable one in there. thawDataFrame :: forall (t :: Type) (ns :: [Nat]) s-               . (PrimBytes (DataFrame t ns), PrimBytes t)+               . (Dimensions ns, PrimBytes (DataFrame t ns))               => DataFrame t ns -> ST s (STDataFrame s t ns) thawDataFrame df = STDataFrame <$> ST (thawDataFrame# df) {-# INLINE thawDataFrame #-}@@ -129,14 +164,15 @@ -- | 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-                  . (PrimBytes (DataFrame t ns), PrimBytes t)+                  . (Dimensions ns, PrimBytes (DataFrame t ns))                  => DataFrame t ns -> ST s (STDataFrame s t ns) thawPinDataFrame df = STDataFrame <$> ST (thawPinDataFrame# df) {-# INLINE thawPinDataFrame #-}  -- | UnsafeCoerces an underlying byte array. unsafeThawDataFrame :: forall (t :: Type) (ns :: [Nat]) s-                     . (PrimBytes (DataFrame t ns), PrimBytes t)+                     . ( Dimensions ns+                       , PrimBytes (DataFrame t ns), PrimBytes t)                     => DataFrame t ns -> ST s (STDataFrame s t ns) unsafeThawDataFrame df = STDataFrame <$> ST (unsafeThawDataFrame# df) {-# INLINE unsafeThawDataFrame #-}@@ -144,7 +180,7 @@  -- | Write a single element at the specified index writeDataFrame :: forall t (ns :: [Nat]) s-                . ( PrimBytes t, Dimensions ns )+                . PrimBytes t                => STDataFrame s t ns -> Idxs ns -> DataFrame t ('[] :: [Nat]) -> ST s () writeDataFrame (STDataFrame mdf) ei = ST . writeDataFrame# mdf ei . unsafeCoerce# {-# INLINE writeDataFrame #-}@@ -152,7 +188,7 @@  -- | Read a single element at the specified index readDataFrame :: forall (t :: Type) (ns :: [Nat]) s-               . ( PrimBytes t, Dimensions ns )+               . PrimBytes t               => STDataFrame s t ns -> Idxs ns -> ST s (DataFrame t ('[] :: [Nat])) readDataFrame (STDataFrame mdf) = unsafeCoerce# . ST . readDataFrame# mdf {-# INLINE readDataFrame #-}@@ -178,7 +214,7 @@  -- | Check if the byte array wrapped by this DataFrame is pinned, --   which means cannot be relocated by GC.-isDataFramePinned :: forall (t :: Type) (ns :: [k]) s+isDataFramePinned :: forall (k :: Type) (t :: Type) (ns :: [k]) s                    . KnownDimKind k                   => STDataFrame s t ns -> Bool isDataFramePinned df = case dimKind @k of
− src/Numeric/DataFrame/Shape.hs
@@ -1,238 +0,0 @@-{-# LANGUAGE DataKinds                 #-}-{-# LANGUAGE ExistentialQuantification #-}-{-# LANGUAGE FlexibleContexts          #-}-{-# LANGUAGE FlexibleInstances         #-}-{-# LANGUAGE GADTs                     #-}-{-# LANGUAGE KindSignatures            #-}-{-# LANGUAGE MagicHash                 #-}-{-# LANGUAGE MultiParamTypeClasses     #-}-{-# LANGUAGE PolyKinds                 #-}-{-# LANGUAGE ScopedTypeVariables       #-}-{-# LANGUAGE TypeApplications          #-}-{-# LANGUAGE TypeFamilies              #-}-{-# LANGUAGE TypeOperators             #-}-{-# LANGUAGE UnboxedTuples             #-}-{-# LANGUAGE UndecidableInstances      #-}-{-# OPTIONS_GHC -fno-warn-overlapping-patterns #-}--------------------------------------------------------------------------------- |--- Module      :  Numeric.DataFrame.Shape--- Copyright   :  (c) Artem Chirkin--- License     :  BSD3------ Maintainer  :  chirkin@arch.ethz.ch------ Construct new DataFrames from pieces.-----------------------------------------------------------------------------------module Numeric.DataFrame.Shape-    ( (<:>), (<::>), (<+:>)-    , fromScalar-    , DataFrameToList (..)-    , fromListN, fromList-    ) where--import           GHC.Base--import           Numeric.DataFrame.Internal.Array.Class-import           Numeric.DataFrame.Internal.Array.Family (inferASing, inferPrim,-                                                          inferPrimElem)-import           Numeric.DataFrame.SubSpace-import           Numeric.DataFrame.Type                  (DataFrame (..))-import           Numeric.Dimensions-import           Numeric.PrimBytes-import           Numeric.Scalar                          as Scalar-import           Numeric.TypedList                       (TypedList (..))-import qualified Numeric.TypedList                       as Dims-import           Numeric.Vector----- | Append one DataFrame to another, sum up last dimension-(<:>) :: forall (n :: Nat) (m :: Nat) (npm :: Nat) (ds :: [Nat])-                (t :: Type)-       . ( PrimBytes (DataFrame t (ds +: n))-         , PrimBytes (DataFrame t (ds +: m))-         , PrimBytes (DataFrame t (ds +: npm))-         , npm ~ (n + m)-         , n   ~ (npm - m)-         , m   ~ (npm - n)-         )-        => DataFrame t (ds +: n)-        -> DataFrame t (ds +: m)-        -> DataFrame t (ds +: npm)-(<:>) = appendDF-infixl 5 <:>-{-# INLINE [1] (<:>) #-}---- | Append one DataFrame to another,---   add another @Dim = 2@ to their dimension list.-(<::>) :: forall (ds :: [Nat]) (t :: Type)-       .  ( PrimBytes (DataFrame t ds)-          , PrimBytes (DataFrame t ds)-          , PrimBytes (DataFrame t (ds +: 2 :: [Nat]))-          )-        => DataFrame t ds-        -> DataFrame t ds-        -> DataFrame t (ds +: 2 :: [Nat])-(<::>) = appendDF-infixl 5 <::>-{-# INLINE [1] (<::>) #-}---vec2t :: forall t . SubSpace t '[] '[2] '[2] => Scalar t -> Scalar t -> Vector t 2-vec2t = unsafeCoerce# (vec2 @t)-{-# INLINE vec2t #-}--{-# RULES-"<::>/vec2-Float"  (<::>) = vec2t @Float-"<::>/vec2-Double" (<::>) = vec2t @Double-"<::>/vec2-Int"    (<::>) = vec2t @Int-"<::>/vec2-Word"   (<::>) = vec2t @Word-  #-}---- | Grow the first DataFrame by adding the second one to it---   incrementing the last Dim in the list.-(<+:>) :: forall (ds :: [Nat]) (n :: Nat) (m :: Nat) (t :: Type)-        . ( PrimBytes (DataFrame t (ds +: n))-          , PrimBytes (DataFrame t ds)-          , PrimBytes (DataFrame t (ds +: m))-          , m ~ (n + 1)-          )-        => DataFrame t (ds +: n)-        -> DataFrame t ds-        -> DataFrame t (ds +: m)-(<+:>) = appendDF-infixl 5 <+:>-{-# INLINE [1] (<+:>) #-}----- | Concatenate a list of @DataFrame@s.---   Returns @Nothing@ if the list does not have enough elements.------   Input must be parametrized by @[Nat]@ to make sure every element---   in the input list has the same dimensionality.---   Output is in @[XNat]@, because the last dimension is unknown at compile time.-fromList :: forall m ns t-          . ( Dimensions ns-            , PrimBytes t-            )-         => Dim m-            -- ^ Minimum number of elements in a list-         -> [DataFrame t ns]-            -- ^ List of frames to concatenate-         -> Maybe (DataFrame t (AsXDims ns +: XN m))-fromList d xs = fromListN d (length xs) xs------ | Implement function `toList`.---   We need to create a dedicated type class for this---   to make it polymorphic over kind k (Nat <-> XNat).-class DataFrameToList (t :: Type) (ds :: [k]) (z :: k) where-    -- | Unwrap the last dimension of a DataFrame into a list  of smaller frames-    toList :: DataFrame t (ds +: z) -> [DataFrame t ds]----instance ( Dimensions (ns +: z)-         , PrimBytes t-         )-         => DataFrameToList t (ns :: [Nat]) (z :: Nat) where-    toList df-      | Dims.Snoc (Dims :: Dims ns') dn <- dims @Nat @(ns +: z)-          -- TODO: line below is a workaround and should be avoided.-      , E <- unsafeCoerce# (E @(ns ~ ns)) :: Evidence (ns ~ ns')-      , E <- inferASing @t @ns-      , E <- inferASing @t @(ns +: z)-      , E <- inferPrim @t @(ns +: z)-      , E <- inferPrim @t @ns-      , n <- dimVal dn-      , I# step <- fromIntegral $ totalDim' @ns-      , off0 <- elemOffset df-      , ba <- getBytes df-      = let go 0 _   = []-            go k off = fromElems off step ba : go (k-1) (off +# step)-        in go n off0-      | otherwise = []--instance DataFrameToList t (xns :: [XNat]) (xz :: XNat) where-    toList (XFrame (df :: DataFrame t nsz))-      | nsz <- dims @Nat @nsz-      , xnsz <- xDims @(xns +: xz) nsz-          -- TODO: line below is a workaround and should be avoided.-      , E <- unsafeCoerce# (E @(xns ~ xns)) :: Evidence (xns ~ Init (xns +: xz))-      , xns <- Dims.init xnsz-      , TypeList <- types xnsz-      , EvList <- Dims.init (EvList @_ @KnownXNatType @(xns +: xz))-      , Dims.Snoc (ns@Dims :: Dims ns) _ <- nsz-      , Dims.Cons (_ :: Dim k) (_ :: Dims ks) <- nsz-      , E <- inferPrimElem @t @k @ks-      , XDims ns' <- xns-      , Just E <- sameDims ns ns'-      , E <- inferASing @t @ns-      = map XFrame (toList df)-    toList _ = []---- | Concatenate a list of @DataFrame@s.---   Returns @Nothing@ if the list does not have enough elements---   or if provided length is invalid.-fromListN :: forall (m :: Nat) (ns :: [Nat]) (t :: Type)-           . ( Dimensions ns-             , PrimBytes t-             )-          => Dim m-             -- ^ Minimum number of elements in a list-          -> Int-             -- ^ How many elements of a list to take.-             --   Must be not smaller than @m@ and not greater than @length ns@.-          -> [DataFrame t ns]-             -- ^ List of frames to concatenate-          -> Maybe (DataFrame t (AsXDims ns +: XN m))-fromListN Dim n@(I# n#) xs'-  | n < 0 = Nothing-  | Just dxn@(Dx dn@(D :: Dim n)) <- constrain @m (someDimVal (fromIntegral n))-  , Just xs <- takeMaybe n xs'-  , ns@(AsXDims xns) <- dims @Nat @ns-  , nsn@Dims <- Dims.snoc ns dn-  , xnsn <- Dims.snoc xns dxn-  , EvList <- Dims.snoc (EvList @XNat @KnownXNatType @(AsXDims ns))-                        (toEvidence' (E @(KnownXNatType (XN m))))-  , XDims nsn' <- xnsn-  , Just E <- sameDims nsn nsn'-  , E <- inferASing @t @ns-  , E <- inferASing @t @(ns +: n)-  , E <- inferPrim @t @ns-  , E <- inferPrim @t @(ns +: n)-  , I# partElN <- fromIntegral $ totalDim' @ns-  , totalElN <- partElN *# n#-  , elS <- byteSize @t undefined-  , partBS <- partElN *# elS-  = case runRW#-    ( \s0 -> case newByteArray# (totalElN *# elS) s0 of-        (# s1, mba #) ->-          let go _ [] s = s-              go off (p : ps) s = go (off +# partBS) ps (writeBytes mba off p s)-          in unsafeFreezeByteArray# mba (go 0# xs s1)-    ) of (# _, r #)-            -> Just (XFrame (fromElems 0# totalElN r :: DataFrame t (ns +: n)))-fromListN _ _ _ = Nothing--takeMaybe :: Int -> [a] -> Maybe [a]-takeMaybe 0 _        = Just []-takeMaybe _ []       = Nothing-takeMaybe n (x : xs) = (x:) <$> takeMaybe (n-1) xs----appendDF :: (PrimBytes x, PrimBytes y, PrimBytes z)-         => x -> y -> z-appendDF x y-  | sx <- byteSize x-  = case runRW#-    ( \s0 -> case newByteArray# (sx +# byteSize y) s0 of-        (# s1, mba #) -> unsafeFreezeByteArray# mba-            ( writeBytes mba sx y-            ( writeBytes mba 0# x s1))-    ) of (# _, r #) -> fromBytes 0# r-{-# INLINE appendDF #-}
src/Numeric/DataFrame/SubSpace.hs view
@@ -3,8 +3,6 @@ {-# LANGUAGE FlexibleContexts        #-} {-# LANGUAGE FlexibleInstances       #-} {-# LANGUAGE FunctionalDependencies  #-}-{-# LANGUAGE InstanceSigs            #-}-{-# LANGUAGE KindSignatures          #-} {-# LANGUAGE MagicHash               #-} {-# LANGUAGE MultiParamTypeClasses   #-} {-# LANGUAGE ScopedTypeVariables     #-}@@ -20,31 +18,30 @@ -- Copyright   :  (c) Artem Chirkin -- License     :  BSD3 ----- Maintainer  :  chirkin@arch.ethz.ch ----- -----------------------------------------------------------------------------  module Numeric.DataFrame.SubSpace-  ( SubSpace (..), (!), (!.), element+  ( SubSpace (..), (!), element   , ewfoldMap, iwfoldMap   , ewzip, iwzip   , indexWise_, elementWise_   ) where -import           GHC.Base+import Data.Kind+import GHC.Exts -import           Numeric.DataFrame.Family-import           Numeric.DataFrame.Internal.Array.Class-import           Numeric.DataFrame.Internal.Array.PrimOps-import           Numeric.Dimensions-import           Numeric.PrimBytes+import Numeric.DataFrame.Internal.PrimArray+import Numeric.DataFrame.Type+import Numeric.Dimensions+import Numeric.PrimBytes + -- | Operations on DataFrames ----- @as@ is an element dimensionality+-- @as@ is an indexing dimensionality ----- @bs@ is an indexing dimensionality+-- @bs@ is an element dimensionality -- -- @t@ is an underlying data type (i.e. Float, Int, Double) --@@ -52,92 +49,366 @@       , 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 where+     -- | 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 ("as" element) size (aka `totalDim` of sub dataframe)+    --   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#`:     ---    --   > i !. x = case (# dimVal (dim @as), fromEnum i #) of (# I# n, I# j #) -> indexOffset# (n *# j) n x+    --   > index i = case (# dimVal (dim @bs), fromEnum i #) of (# I# n, I# j #) -> indexOffset# (n *# j)     indexOffset# :: Int# -- ^ Prim element offset-                 -> Int# -- ^ Number of prim elements in the prefix subspace-                 -> DataFrame t asbs -> DataFrame t as+                 -> DataFrame t asbs -> DataFrame t bs+    indexOffset# off df = case uniqueOrCumulDims df of+      Left a      -> broadcast a+      Right steps -> fromElems (dropPref (dims @as) steps) (offsetElems df +# off) (getBytes df)+    {-# INLINE [1] indexOffset# #-}++    -- | 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# :: Int# -- ^ Prim element offset+                  -> DataFrame t bs -> DataFrame t asbs -> DataFrame t asbs+    updateOffset# off x df+      | steps <- getSteps (dims @asbs) df+      , elemBS <- byteSize @t undefined = case runRW#+        ( \s0 -> case newByteArray# (cdTotalDim# steps *# elemBS) s0 of+          (# s1, mba #) -> unsafeFreezeByteArray# mba+            ( writeBytes mba (off *# elemBS) x+              ( writeBytes mba 0# df s1 )+            )+        ) of (# _, r #) -> fromElems steps 0# r+    {-# INLINE [1] updateOffset# #-}++    -- | Get an element by its index in the dataframe+    index :: Idxs as -> DataFrame t asbs -> DataFrame t bs+    index i df = case uniqueOrCumulDims df of+      Left a      -> broadcast a+      Right steps -> case cdIx steps i of+        I# off -> fromElems (dropPref (dims @as) steps) (offsetElems df +# off) (getBytes df)+    {-# INLINE [1] index #-}++    -- | 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])+           . ( b' ~ (bi + bd - 1), bs ~ (b' :+ bs'), KnownDim bd)+          => Idxs (as +: bi) -> DataFrame t asbs -> DataFrame t (bd :+ bs')+    slice  i df+      | _ :* Dims <- dims @bs+      , Dict <- inferKnownBackend @t @(bd ': bs')+        = case uniqueOrCumulDims df of+        Left a      -> broadcast a+        Right steps -> case cdIx steps i of+          I# off+            | bsteps <- repHead (dimVal' @bd) (dropPref (dims @as) steps)+              -> fromElems bsteps (offsetElems df +# off) (getBytes df)+      | otherwise = error "SubSpace/slice: impossible arguments"+      where+        repHead y (CumulDims (_:x:xs)) = CumulDims (y*x:x:xs)+        repHead _ steps                = steps+     -- | Set a new value to an element-    update :: Idxs bs -> DataFrame t as -> DataFrame t asbs -> DataFrame t asbs+    update :: Idxs as -> DataFrame t bs -> DataFrame t asbs -> DataFrame t asbs+    update i x df+      | steps <- getSteps (dims @asbs) df+      , I# off <- cdIx steps i+      , elemBS <- byteSize @t undefined = case runRW#+        ( \s0 -> case newByteArray# (cdTotalDim# steps *# elemBS) s0 of+          (# s1, mba #) -> unsafeFreezeByteArray# mba+            ( writeBytes mba (off *# elemBS) x+              ( writeBytes mba 0# df s1 )+            )+        ) of (# _, r #) -> fromElems steps 0# r+    {-# INLINE [1] update #-}++    -- | 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])+           . ( b' ~ (bi + bd - 1), bs ~ (b' :+ bs'), KnownDim bd)+          => Idxs (as +: bi) -> DataFrame t (bd :+ bs') -> DataFrame t asbs -> DataFrame t asbs+    updateSlice i x df+      | _ :* Dims <- dims @bs+      , Dict <- inferKnownBackend @t @(bd ': bs')+      , steps <- getSteps (dims @asbs) df+      , I# off <- cdIx steps i+      , elemBS <- byteSize @t undefined = case runRW#+        ( \s0 -> case newByteArray# (cdTotalDim# steps *# elemBS) s0 of+          (# s1, mba #) -> unsafeFreezeByteArray# mba+            ( writeBytes mba (off *# elemBS) x+              ( writeBytes mba 0# df s1 )+            )+        ) of (# _, r #) -> fromElems steps 0# r+      | otherwise = error "SubSpace/updateSlice: impossible arguments"+    {-# INLINE [1] updateSlice #-}+     -- | Map a function over each element of DataFrame-    ewmap  :: forall s (as' :: [Nat]) (asbs' :: [Nat])-            . SubSpace s as' bs asbs'-           => (DataFrame s as' -> DataFrame t as)+    ewmap  :: forall s (bs' :: [Nat]) (asbs' :: [Nat])+            . SubSpace s as bs' asbs'+           => (DataFrame s bs' -> DataFrame t bs)            -> DataFrame s asbs' -> DataFrame t asbs+    ewmap f df+      | bsizeT    <- byteSize @t undefined+      , stepsAS   <- cumulDims $ dims @as+      , stepsBS   <- cumulDims $ dims @bs+      , stepsBS'  <- cumulDims $ dims @bs'+      , stepsASBS <- stepsAS <> stepsBS+      , lenAS     <- cdTotalDim# stepsAS+      , lenBS     <- cdTotalDim# stepsBS+      , lenBS'    <- cdTotalDim# stepsBS'+      , lenBSB    <- lenBS *# bsizeT+      , lenASBSB  <- lenAS *# lenBSB+      = let go mba sourceOffE destOffB s+              | isTrue# (destOffB >=# lenASBSB)+                = s+              | otherwise+                = go mba (sourceOffE +# lenBS') (destOffB +# lenBSB)+                     (writeBytes mba destOffB (f (indexOffset# sourceOffE df)) s)+        in  case runRW#+          ( \s0 -> case newByteArray# lenASBSB s0 of+            (# s1, mba #) -> unsafeFreezeByteArray# mba ( go mba 0# 0# s1 )+          ) of (# _, r #) -> fromElems stepsASBS 0# r+    {-# INLINE [1] ewmap #-}+     -- | Map a function over each element with its index of DataFrame-    iwmap  :: forall s (as' :: [Nat]) (asbs' :: [Nat])-            . SubSpace s as' bs asbs'-           => (Idxs bs -> DataFrame s as' -> DataFrame t as)+    iwmap  :: forall s (bs' :: [Nat]) (asbs' :: [Nat])+            . SubSpace s as bs' asbs'+           => (Idxs as -> DataFrame s bs' -> DataFrame t bs)            -> DataFrame s asbs' -> DataFrame t asbs+    iwmap f df+      | bsizeT    <- byteSize @t undefined+      , stepsAS   <- cumulDims $ dims @as+      , stepsBS   <- cumulDims $ dims @bs+      , stepsBS'  <- cumulDims $ dims @bs'+      , stepsASBS <- stepsAS <> stepsBS+      , lenAS     <- cdTotalDim# stepsAS+      , lenBS     <- cdTotalDim# stepsBS+      , lenBS'    <- cdTotalDim# stepsBS'+      , lenBSB    <- lenBS *# bsizeT+      , lenASBSB  <- lenAS *# lenBSB+      = let go _ [] _ _ s = s+            go mba (i:is) sourceOffE destOffB s+                = go mba is (sourceOffE +# lenBS') (destOffB +# lenBSB)+                     (writeBytes mba destOffB (f i (indexOffset# sourceOffE df)) s)+        in  case runRW#+          ( \s0 -> case newByteArray# lenASBSB s0 of+            (# s1, mba #) -> unsafeFreezeByteArray# mba ( go mba [minBound..maxBound] 0# 0# s1 )+          ) of (# _, r #) -> fromElems stepsASBS 0# r+    {-# INLINE [1] iwmap #-}+     -- | Generate a DataFrame by repeating an element-    ewgen :: DataFrame t as -> DataFrame t asbs+    ewgen :: DataFrame t bs -> DataFrame t asbs+    ewgen df = case uniqueOrCumulDims df of+      Left a -> broadcast a+      Right stepsBS+        | stepsAS <- cumulDims $ dims @as+        , stepsASBS <- stepsAS <> stepsBS+        , elS       <- byteSize @t undefined+        , lenBSB    <- cdTotalDim# stepsBS *# elS+        , lenASBSB  <- cdTotalDim# stepsASBS *# elS+          -> let go mba destOffB s+                   | isTrue# (destOffB >=# lenASBSB)+                     = s+                   | otherwise+                     = go mba (destOffB +# lenBSB)+                          (writeBytes mba destOffB df s)+             in  case runRW#+              ( \s0 -> case newByteArray# lenASBSB s0 of+                (# s1, mba #) -> unsafeFreezeByteArray# mba ( go mba 0# s1 )+              ) of (# _, r #) -> fromElems stepsASBS 0# r+    {-# INLINE [1] ewgen #-}+     -- | Generate a DataFrame by iterating a function (index -> element)-    iwgen :: (Idxs bs -> DataFrame t as) -> DataFrame t asbs+    iwgen :: (Idxs as -> DataFrame t bs) -> DataFrame t asbs+    iwgen f+        | stepsAS <- cumulDims $ dims @as+        , stepsBS <- cumulDims $ dims @bs+        , stepsASBS <- stepsAS <> stepsBS+        , elS       <- byteSize @t undefined+        , lenBSB    <- cdTotalDim# stepsBS *# elS+        , lenASBSB  <- cdTotalDim# stepsASBS *# elS+          = let go _ [] _ s = s+                go mba (i:is) destOffB s+                  = go mba is (destOffB +# lenBSB) (writeBytes mba destOffB (f i) s)+            in  case runRW#+              ( \s0 -> case newByteArray# lenASBSB s0 of+                (# s1, mba #) -> unsafeFreezeByteArray# mba ( go mba [minBound..maxBound] 0# s1 )+              ) of (# _, r #) -> fromElems stepsASBS 0# r+    {-# INLINE [1] iwgen #-}+     -- | 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 :: (b -> DataFrame t as -> b) -> b -> DataFrame t asbs -> b+    ewfoldl :: (b -> DataFrame t bs -> b) -> b -> DataFrame t asbs -> b+    ewfoldl f x0 df = case uniqueOrCumulDims df of+      Left a ->+        let b = broadcast a+            go 0 x = x+            go n x = go (n-1) $! f x b+        in  go (totalDim' @as) x0+      Right stepsASBS+        | stepsBS <- dropPref (dims @as) stepsASBS+        , lenBS   <- cdTotalDim# stepsBS+        , lenASBS <- cdTotalDim# stepsASBS+          -> let go sourceOffE x+                  | isTrue# (sourceOffE >=# lenASBS)+                    = x+                  | otherwise+                    = go (sourceOffE +# lenBS) $! f x (indexOffset# sourceOffE df)+             in  go 0# x0+     -- | 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 :: (Idxs bs -> b -> DataFrame t as -> b) -> b -> DataFrame t asbs -> b+    iwfoldl :: (Idxs as -> b -> DataFrame t bs -> b) -> b -> DataFrame t asbs -> b+    iwfoldl f x0 df = case uniqueOrCumulDims df of+      Left a ->+        let b = broadcast a+            go [] x     = x+            go (i:is) x = go is $! f i x b+        in  go [minBound..maxBound] x0+      Right stepsASBS+        | stepsBS <- dropPref (dims @as) stepsASBS+        , lenBS   <- cdTotalDim# stepsBS+          -> let go [] _ x = x+                 go (i:is) sourceOffE x+                    = go is (sourceOffE +# lenBS) $! f i x (indexOffset# sourceOffE df)+             in  go [minBound..maxBound] 0# x0+     -- | 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 :: (DataFrame t as -> b -> b) -> b -> DataFrame t asbs -> b+    ewfoldr :: (DataFrame t bs -> b -> b) -> b -> DataFrame t asbs -> b+    ewfoldr f x0 df = case uniqueOrCumulDims df of+      Left a ->+        let b = broadcast a+            go 0 x = x+            go n x = go (n-1) $! f b x+        in  go (totalDim' @as) x0+      Right stepsASBS+        | stepsBS <- dropPref (dims @as) stepsASBS+        , lenBS   <- cdTotalDim# stepsBS+        , lenASBS <- cdTotalDim# stepsASBS+          -> let go sourceOffE x+                  | isTrue# (sourceOffE <# 0#)+                    = x+                  | otherwise+                    = go (sourceOffE -# lenBS) $! f (indexOffset# sourceOffE df) x+             in  go (lenASBS -# lenBS) x0+     -- | 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 :: (Idxs bs -> DataFrame t as -> b -> b) -> b -> DataFrame t asbs -> b+    iwfoldr :: (Idxs as -> DataFrame t bs -> b -> b) -> b -> DataFrame t asbs -> b+    iwfoldr f x0 df = case uniqueOrCumulDims df of+      Left a ->+        let b = broadcast a+            go [] x     = x+            go (i:is) x = go is $! f i b x+        in  go [maxBound, pred maxBound .. minBound] x0+      Right stepsASBS+        | stepsBS <- dropPref (dims @as) stepsASBS+        , lenBS   <- cdTotalDim# stepsBS+        , lenASBS <- cdTotalDim# stepsASBS+          -> let go [] _ x = x+                 go (i:is) sourceOffE x+                    = go is (sourceOffE -# lenBS) $! f i (indexOffset# sourceOffE df) x+             in  go [maxBound, pred maxBound .. minBound] (lenASBS -# lenBS) x0+     -- | Apply an applicative functor on each element (Lens-like traversal)-    elementWise :: forall s (as' :: [Nat]) (asbs' :: [Nat]) f+    elementWise :: forall (s :: Type) (bs' :: [Nat]) (asbs' :: [Nat]) (f :: Type -> Type)                  . ( Applicative f-                   , SubSpace s as' bs asbs'+                   , SubSpace s as bs' asbs'                    )-                => (DataFrame s as' -> f (DataFrame t as))+                => (DataFrame s bs' -> f (DataFrame t bs))                 -> DataFrame s asbs' -> f (DataFrame t asbs)+    elementWise = indexWise . const+    {-# INLINE [1] elementWise #-}+     -- | Apply an applicative functor on each element with its index     --     (Lens-like indexed traversal)-    indexWise :: forall s (as' :: [Nat]) (asbs' :: [Nat]) f+    indexWise :: forall (s :: Type) (bs' :: [Nat]) (asbs' :: [Nat]) (f :: Type -> Type)                . ( Applicative f-                 , SubSpace s as' bs asbs'+                 , SubSpace s as bs' asbs'                  )-              => (Idxs bs -> DataFrame s as' -> f (DataFrame t as))+              => (Idxs as -> DataFrame s bs' -> f (DataFrame t bs))               -> DataFrame s asbs' -> f (DataFrame t asbs)+    indexWise f df = runWithState <$> iwfoldl applyF (pure initialState) df+      where+        steps = cumulDims $ dims @asbs+        -- run a state-based continuation within RW+        runWithState :: ( State# RealWorld -> (# State# RealWorld, (# MutableByteArray# RealWorld, Int# #) #))+                     -> DataFrame t asbs+        runWithState g = case runRW#+                           ( \s0 -> case g s0 of+                                (# s1, (# marr, _ #) #) -> unsafeFreezeByteArray# marr s1+                           ) of (# _, arr #) -> fromElems steps 0# arr --- | Get an element by its index in the dataframe-(!.) :: forall t as bs asbs-      . SubSpace t as bs asbs-     => Idxs bs -> DataFrame t asbs -> DataFrame t as-(!.) i = case (# totalDim (dims @_ @as), fromEnum i #) of-   (# W# n, I# j #) -> indexOffset# (word2Int# n *# j) (word2Int# n)-{-# INLINE [1] (!.) #-}-infixr 4 !.+        -- Prepare empty byte array for the result DataFrame and keep a current position counter+        -- Input: state+        -- Output: state ++        --     ( current mutable byte array + current write position )+        initialState :: State# RealWorld -> (# State# RealWorld, (# MutableByteArray# RealWorld, Int# #) #)+        initialState s0 = case newByteArray# (rezLength# *# rezElBSize#) s0 of+                            (# s1, marr #) -> (# s1, (# marr, 0# #) #) +        -- Given the result chunk, write it into a mutable array+        updateChunk :: (State# RealWorld -> (# State# RealWorld, (# MutableByteArray# RealWorld, Int# #) #))+                    -> DataFrame t bs+                    -> (State# RealWorld -> (# State# RealWorld, (# MutableByteArray# RealWorld, Int# #) #))+        updateChunk g dfChunk = case (# byteOffset dfChunk, getBytes dfChunk #) of+            (# off#, arr#  #) -> \s -> case g s of+                                        (# s1, (# marr#, pos# #) #) -> case+                                            copyByteArray# arr# (off# *# rezElBSize#)+                                                           marr# (pos# *# rezElBSize#)+                                                           (rezStepN# *# rezElBSize#) s1 of+                                          s2 -> (# s2, (# marr#, pos# +# rezStepN# #) #)++        -- Apply applicative functor on each chunk and update a state.+        applyF :: Idxs as+               -> f (State# RealWorld -> (# State# RealWorld, (# MutableByteArray# RealWorld, Int# #) #))+               -> DataFrame s bs'+               -> f (State# RealWorld -> (# State# RealWorld, (# MutableByteArray# RealWorld, Int# #) #))+        applyF idx s dfChunk = idx `seq` dfChunk `seq` updateChunk <$> s <*> f idx dfChunk++        -- Element byte size of the result DataFrame (byte size of s)+        rezElBSize# = byteSize @t undefined+        -- Number of primitive elements in the result DataFrame chunk+        !(I# rezStepN#) = fromIntegral $ totalDim' @bs+        -- Number of primitive elements in the result DataFrame+        rezLength# = cdTotalDim# steps+++ -- | 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 bs -> DataFrame t as -> f b)+           => (Idxs as -> DataFrame t bs -> f b)            -> DataFrame t asbs -> f () indexWise_ f = iwfoldr (\i -> (*>) . f i) (pure ())  -- | 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 as -> f b)+             => (DataFrame t bs -> f b)              -> DataFrame t asbs -> f () elementWise_ f = ewfoldr ((*>) . f) (pure ()) @@ -145,29 +416,30 @@ -- | 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 bs-        -> (DataFrame t as -> f (DataFrame t as))+        => Idxs as+        -> (DataFrame t bs -> f (DataFrame t bs))         -> DataFrame t asbs -> f (DataFrame t asbs)-element i f df = flip (update i) df <$> f (i !. df)+element i f df = flip (update i) df <$> f (index i df) {-# INLINE element #-} --- | Index an element (reverse of !.)+-- | Index an element (reverse arguments of `index`) (!) :: SubSpace t (as :: [Nat]) (bs :: [Nat]) (asbs :: [Nat])-    => DataFrame t asbs -> Idxs bs -> DataFrame t as-(!) = flip (!.)-infixl 4 !+    => DataFrame t asbs -> Idxs as -> DataFrame t bs+(!) = flip index {-# INLINE (!) #-}+infixl 4 !  + ewfoldMap :: forall t (as :: [Nat]) (bs :: [Nat]) (asbs :: [Nat]) m            . (Monoid m, SubSpace t as bs asbs)-          => (DataFrame t as -> m) -> DataFrame t asbs -> m+          => (DataFrame t bs -> m) -> DataFrame t asbs -> m ewfoldMap f = ewfoldl (\m b -> m `seq` (mappend m $! f b)) mempty {-# INLINE ewfoldMap #-}  iwfoldMap :: forall t (as :: [Nat]) (bs :: [Nat]) (asbs :: [Nat]) m            . ( Monoid m, SubSpace t as bs asbs)-          => (Idxs bs -> DataFrame t as -> m) -> DataFrame t asbs -> m+          => (Idxs as -> DataFrame t bs -> m) -> DataFrame t asbs -> m iwfoldMap f = iwfoldl (\i m b -> m `seq` (mappend m $! f i b)) mempty {-# INLINE iwfoldMap #-} @@ -175,30 +447,30 @@  -- | Zip two spaces on a specified subspace index-wise (with index) iwzip :: forall t (as :: [Nat]) (bs :: [Nat]) (asbs :: [Nat])-                s (as' :: [Nat]) (asbs' :: [Nat])-                r (as'' :: [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''+         , SubSpace s as bs' asbs'+         , SubSpace r as bs'' asbs''          )-      => (Idxs bs -> DataFrame t as -> DataFrame s as' -> DataFrame r as'')+      => (Idxs as -> DataFrame t bs -> DataFrame s bs' -> DataFrame r bs'')       -> DataFrame t asbs       -> DataFrame s asbs'       -> DataFrame r asbs'' iwzip f dft dfs = iwmap g dft   where-    g i dft' = f i dft' (i !. dfs)+    g i dft' = f i dft' (index i dfs) {-# INLINE iwzip #-}  -- | Zip two spaces on a specified subspace element-wise (without index) ewzip :: forall t (as :: [Nat]) (bs :: [Nat]) (asbs :: [Nat])-                s (as' :: [Nat]) (asbs' :: [Nat])-                r (as'' :: [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''+         , SubSpace s as bs' asbs'+         , SubSpace r as bs'' asbs''          )-      => (DataFrame t as -> DataFrame s as' -> DataFrame r as'')+      => (DataFrame t bs -> DataFrame s bs' -> DataFrame r bs'')       -> DataFrame t asbs       -> DataFrame s asbs'       -> DataFrame r asbs''@@ -210,194 +482,16 @@          , Dimensions as          , Dimensions bs          , Dimensions asbs-         , PrimArray t (DataFrame t as)+         , PrimArray t (DataFrame t bs)          , PrimArray t (DataFrame t asbs)-         , PrimBytes   (DataFrame t as)+         , PrimBytes   (DataFrame t bs)          , PrimBytes   (DataFrame t asbs)          ) => SubSpace t (as :: [Nat]) (bs :: [Nat]) (asbs :: [Nat]) where -    indexOffset# i l d = case elemSize0 d of-      -- if elemSize0 returns 0, then this is a fromScalar-like constructor-      0# -> broadcast (ix# 0# d)-      _  -> fromElems (elemOffset d +# i) l (getBytes d)  -    update ei x df-      | I# i <- fromEnum ei-      , I# len <- fromIntegral $ totalDim' @asbs-      = case runRW#-          ( \s0 -> case newByteArray# (len *# byteSize @t undefined) s0 of-            (# s1, mba #) -> unsafeFreezeByteArray# mba-              ( writeArray mba i x-                ( writeBytes mba 0# df s1 )-              )-          ) of (# _, r #) -> fromElems 0# len r--    ewmap  :: forall s (as' :: [Nat]) (asbs' :: [Nat])-            . SubSpace s as' bs asbs'-           => (DataFrame s as' -> DataFrame t as)-           -> DataFrame s asbs' -> DataFrame t asbs-    ewmap f df-      | elS <- byteSize @t undefined-      , W# lenBSW <- totalDim' @bs-      , W# lenASW <- totalDim' @as-      , W# lenAS'W <- totalDim' @as'-      , lenBS <- word2Int# lenBSW-      , lenAS <- word2Int# lenASW-      , lenAS' <- word2Int# lenAS'W-      , lenASBS <- lenAS *# lenBS-      , lenAS'BS <- lenAS' *# lenBS-      = case runRW#-          ( \s0 -> case newByteArray# (lenASBS *# elS) s0 of-            (# s1, mba #) -> unsafeFreezeByteArray# mba-              ( loopWithI# 0# lenAS' lenAS'BS-                (\i off -> writeArray mba i (f (indexOffset# off lenAS' df)))-                s1-              )-          ) of (# _, r #) -> fromElems 0# lenASBS r-    {-# INLINE ewmap #-}---    iwmap  :: forall s (as' :: [Nat]) (asbs' :: [Nat])-            . SubSpace s as' bs asbs'-           => (Idxs bs -> DataFrame s as' -> DataFrame t as)-           -> DataFrame s asbs' -> DataFrame t asbs-    iwmap f df-      | elS <- byteSize @t undefined-      , dbs <- dims @_ @bs-      , W# lenBSW <- totalDim dbs-      , W# lenASW <- totalDim' @as-      , W# lenAS'W <- totalDim' @as'-      , lenBS <- word2Int# lenBSW-      , lenAS <- word2Int# lenASW-      , lenAS' <- word2Int# lenAS'W-      , lenASBS <- lenAS *# lenBS-      = case runRW#-          ( \s0 -> case newByteArray# (lenASBS *# elS) s0 of-            (# s1, mba #) -> unsafeFreezeByteArray# mba-              ( overDim_# dbs-                ( \i pos ->-                    writeArray mba pos (f i (indexOffset# (pos *# lenAS') lenAS' df))-                ) 0# 1# s1-              )-          ) of (# _, r #) -> fromElems 0# lenASBS r--    ewgen x = case elemSize0 x of-      0# -> broadcast (ix# 0# x)-      1# -> broadcast (ix# 0# x)-      lenAS-        | elS <- byteSize @t undefined-        , W# lenBSW <- totalDim' @bs-        , lenBS <- word2Int# lenBSW-        , lenASBS <- lenAS *# lenBS-        , bsize <- lenASBS *# elS-        -> case runRW#-            ( \s0 -> case newByteArray# bsize s0 of-              (# s1, mba #) -> unsafeFreezeByteArray# mba-                ( loop# 0# (lenAS *# elS) bsize-                  (\off -> writeBytes mba off x)-                  s1-                )-            ) of (# _, r #) -> fromElems 0# lenASBS r-    {-# INLINE [1] ewgen #-}--    iwgen f-      | elS <- byteSize @t undefined-      , dbs <- dims @_ @bs-      , W# lenBSW <- totalDim dbs-      , W# lenASW <- totalDim' @as-      , lenBS <- word2Int# lenBSW-      , lenAS <- word2Int# lenASW-      , lenASBS <- lenAS *# lenBS-      = case runRW#-          ( \s0 -> case newByteArray# (lenASBS *# elS) s0 of-            (# s1, mba #) -> unsafeFreezeByteArray# mba-              ( overDim_# dbs-                ( \i pos -> writeArray mba pos (f i)-                ) 0# 1# s1-              )-          ) of (# _, r #) -> fromElems 0# lenASBS r--    ewfoldl f x0 df-      | ba <- getBytes df-      = foldDimOff (dims @_ @bs) (\(I# o) acc -> f acc (fromBytes o ba))-          (I# (byteOffset df))-          (I# (byteSize @t undefined) * fromIntegral (totalDim' @as)) x0--    iwfoldl f x0 df-      | ba <- getBytes df-      = foldDim (dims @_ @bs) (\i (I# o) acc -> f i acc (fromBytes o ba))-          (I# (byteOffset df))-          (I# (byteSize @t undefined) * fromIntegral (totalDim' @as)) x0--    ewfoldr f x0 df-      | step <- I# (byteSize @t undefined) * fromIntegral (totalDim' @as)-      , ba <- getBytes df-      = foldDimOff (dims @_ @bs) (\(I# o) -> f (fromBytes o ba))-          (I# (byteOffset df +# byteSize df) - step)-          (negate step) x0--    iwfoldr f x0 df-      | step <- I# (byteSize @t undefined) * fromIntegral (totalDim' @as)-      , ba <- getBytes df-      = foldDimReverse (dims @_ @bs) (\i (I# o) -> f i (fromBytes o ba))-          (I# (byteOffset df +# byteSize df) - step)-          step x0---    -- implement elementWise in terms of indexWise-    elementWise = indexWise . const-    {-# INLINE elementWise #-}--    indexWise :: forall (s :: Type) (f :: Type -> Type) (as' :: [Nat]) (asbs' :: [Nat])-               . ( Applicative f-                 , SubSpace s as' bs asbs'-                 )-              => (Idxs bs -> DataFrame s as' -> f (DataFrame t as))-              -> DataFrame s asbs' -> f (DataFrame t asbs)-    indexWise f df = runWithState <$> iwfoldl applyF (pure initialState) df-      where-        -- run a state-based continuation within RW-        runWithState :: ( State# RealWorld -> (# State# RealWorld, (# MutableByteArray# RealWorld, Int# #) #))-                     -> DataFrame t asbs-        runWithState g = case runRW#-                           ( \s0 -> case g s0 of-                                (# s1, (# marr, _ #) #) -> unsafeFreezeByteArray# marr s1-                           ) of (# _, arr #) -> fromElems 0# rezLength# arr--        -- Prepare empty byte array for the result DataFrame and keep a current position counter-        -- Input: state-        -- Output: state +-        --     ( current mutable byte array + current write position )-        initialState :: State# RealWorld -> (# State# RealWorld, (# MutableByteArray# RealWorld, Int# #) #)-        initialState s0 = case newByteArray# (rezLength# *# rezElBSize#) s0 of-                            (# s1, marr #) -> (# s1, (# marr, 0# #) #)--        -- Given the result chunk, write it into a mutable array-        updateChunk :: (State# RealWorld -> (# State# RealWorld, (# MutableByteArray# RealWorld, Int# #) #))-                    -> DataFrame t as-                    -> (State# RealWorld -> (# State# RealWorld, (# MutableByteArray# RealWorld, Int# #) #))-        updateChunk g dfChunk = case (# byteOffset dfChunk, getBytes dfChunk #) of-            (# off#, arr#  #) -> \s -> case g s of-                                        (# s1, (# marr#, pos# #) #) -> case-                                            copyByteArray# arr# (off# *# rezElBSize#)-                                                           marr# (pos# *# rezElBSize#)-                                                           (rezStepN# *# rezElBSize#) s1 of-                                          s2 -> (# s2, (# marr#, pos# +# rezStepN# #) #)--        -- Apply applicative functor on each chunk and update a state.-        applyF :: Idxs bs-               -> f (State# RealWorld -> (# State# RealWorld, (# MutableByteArray# RealWorld, Int# #) #))-               -> DataFrame s as'-               -> f (State# RealWorld -> (# State# RealWorld, (# MutableByteArray# RealWorld, Int# #) #))-        applyF idx s dfChunk = idx `seq` dfChunk `seq` updateChunk <$> s <*> f idx dfChunk--        -- Element byte size of the result DataFrame (byte size of s)-        rezElBSize# = byteSize @t undefined-        -- Number of primitive elements in the result DataFrame chunk-        !(I# rezStepN#) = fromIntegral $ totalDim' @as-        -- Number of primitive elements in the result DataFrame-        !(I# rezLength#) = fromIntegral $ totalDim' @asbs+dropPref :: Dims (ns :: [Nat]) -> CumulDims -> CumulDims+dropPref ds = CumulDims . drop (length $ listDims ds) . unCumulDims   unSc :: DataFrame (t :: Type) ('[] :: [Nat]) -> t
src/Numeric/DataFrame/Type.hs view
@@ -1,464 +1,1140 @@-{-# LANGUAGE ConstraintKinds            #-}-{-# LANGUAGE DataKinds                  #-}-{-# LANGUAGE ExistentialQuantification  #-}-{-# LANGUAGE FlexibleContexts           #-}-{-# LANGUAGE FlexibleInstances          #-}-{-# LANGUAGE GADTs                      #-}-{-# LANGUAGE GeneralizedNewtypeDeriving #-}-{-# LANGUAGE KindSignatures             #-}-{-# LANGUAGE MagicHash                  #-}-{-# LANGUAGE MultiParamTypeClasses      #-}-{-# LANGUAGE PatternSynonyms            #-}-{-# LANGUAGE PolyKinds                  #-}-{-# LANGUAGE ScopedTypeVariables        #-}-{-# LANGUAGE StandaloneDeriving         #-}-{-# LANGUAGE TypeApplications           #-}-{-# LANGUAGE TypeFamilies               #-}-{-# LANGUAGE TypeInType                 #-}-{-# LANGUAGE TypeOperators              #-}-{-# LANGUAGE UnboxedTuples              #-}-{-# LANGUAGE UndecidableInstances       #-}-{-# LANGUAGE ViewPatterns               #-}-{-# LANGUAGE AllowAmbiguousTypes        #-}-{-# OPTIONS_GHC -fno-warn-orphans       #-}--module Numeric.DataFrame.Type-  ( -- * Data types-    DataFrame (..)-  , SomeDataFrame (..), DataFrame'-  , pattern (:*:), pattern Z-    -- * Infer type class instances-  , AllTypes, ImplAllows, ArraySingletons, PrimFrames-  , DataFrameInference (..)-  , inferOrd, inferNum, inferFractional, inferFloating-  , inferOrd', inferNum', inferFractional', inferFloating'-  , inferASing', inferEq', inferShow', inferPrim', inferPrimElem'-    -- * Misc-  , ixOff, unsafeFromFlatList-  , Dim1 (..), Dim2 (..), Dim3 (..)-  , dimSize1, dimSize2, dimSize3-  , bSizeOf, bAlignOf-    -- * Re-exports from dimensions-  , Dim (..), Idx (..), XNat (..), Dims, Idxs, TypedList (..)-  ) where---import           Data.Proxy (Proxy)-import           Foreign.Storable                        (Storable (..))-import           GHC.Base-import           GHC.Ptr (Ptr (..))--import           Numeric.DataFrame.Family-import           Numeric.DataFrame.Internal.Array.Class-import           Numeric.DataFrame.Internal.Array.Family (Array, ArraySingleton (..))-import qualified Numeric.DataFrame.Internal.Array.Family as AFam-import           Numeric.Dimensions-import           Numeric.PrimBytes---- | Single frame-newtype instance DataFrame (t :: Type) (ns :: [Nat])-  = SingleFrame { _getDF :: Array t ns }---- | Multiple "columns" of data frames of the same shape-newtype instance DataFrame (ts :: [Type]) (ns :: [Nat])-  = MultiFrame { _getDFS ::  TypedList (DataFrame' ns) ts }---- | Data frame with some dimensions missing at compile time.---   Pattern-match against its constructor to get a Nat-indexed data frame.-data instance DataFrame (ts :: l) (xns :: [XNat])-  = forall (ns :: [Nat])-  . (KnownXNatTypes xns, FixedDims xns ns, Dimensions ns, ArraySingletons ts ns)-  => XFrame (DataFrame ts ns)---- | 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)-  = forall (ns :: [Nat]) . (Dimensions ns, ArraySingletons t ns)-  => SomeDataFrame (DataFrame t ns)---- | DataFrame with its type arguments swapped.-newtype DataFrame' (xs :: [k]) (t :: l) = DataFrame' (DataFrame t xs)--{-# COMPLETE Z, (:*:) #-}----- | 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-pattern (:*:) x xs <- (MultiFrame (DataFrame' x :* (MultiFrame -> xs)))-  where-    (:*:) x (MultiFrame xs) = MultiFrame (DataFrame' x :* xs)-infixr 6 :*:---- | Empty MultiFrame-pattern Z :: forall (xs :: [Type]) (ns :: [Nat])-           . () => (xs ~ '[]) => DataFrame xs ns-pattern Z = MultiFrame U-------------------------------------------------------------------------------------- All Eq instances-----------------------------------------------------------------------------------deriving instance Eq (Array t ds) => Eq (DataFrame (t :: Type) (ds :: [Nat]))--instance ImplAllows Eq ts ds => Eq (DataFrame (ts :: [Type]) ds) where-    Z == Z = True-    (a :*: as) == (b :*: bs) = a == b && as == bs--instance (AllTypes Eq t, DataFrameInference t)-      => Eq (DataFrame (t :: l) (ds :: [XNat])) where-    (XFrame dfa) == (XFrame dfb)-      | Just E <- sameDims' dfa dfb-      , E <- inferEq dfa = dfa == dfb-    _ == _ = False--instance (AllTypes Eq t, DataFrameInference t)-      => Eq (SomeDataFrame (t :: l)) where-    (SomeDataFrame dfa) == (SomeDataFrame dfb)-      | Just E <- sameDims' dfa dfb-      , E <- inferEq dfa = dfa == dfb-    _ == _ = False-------------------------------------------------------------------------------------- All Show instances-----------------------------------------------------------------------------------instance ( Show (Array t ds)-         , Dimensions ds-         ) => Show (DataFrame (t :: Type) (ds :: [Nat])) where-  show (SingleFrame arr) = unlines-                            [ "DF " ++ drop 5 (show $ dims @_ @ds) ++ ":"-                            , show arr-                            ]--instance ( Dimensions ds-         , ImplAllows Show ts ds-         ) => Show (DataFrame (ts :: [Type]) (ds :: [Nat])) where-  show dfs = unlines $-      ("DF " ++ show (order dds) ++ " x "  ++ drop 5 (show dds) ++ ":")-      : showAll 1 dfs-    where-      dds = dims @_ @ds-      showAll :: ImplAllows Show xs ds-              => Word -> DataFrame (xs :: [Type]) ds -> [String]-      showAll _ Z = []-      showAll n (SingleFrame arr :*: fs)-        = ("Var " ++ show n) : show arr : showAll (n+1) fs---instance (AllTypes Show t, DataFrameInference t)-      => Show (DataFrame (t :: l) (xns :: [XNat])) where-  show (XFrame df)-    | E <- inferShow df = 'X': show df--instance (AllTypes Show t, DataFrameInference t)-      => Show (SomeDataFrame (t :: l)) where-  show (SomeDataFrame df)-    | E <- inferShow df = "Some" ++ show df--------------------------------------------------------------------------------------type family AllTypes (f :: Type -> Constraint) (ts :: l) :: Constraint where-    AllTypes f (t :: Type) = f t-    AllTypes f (ts :: [Type]) = All f ts--type family ImplAllows (f :: Type -> Constraint) (ts :: l) (ds :: [Nat])-                                                             :: Constraint where-    ImplAllows f (t :: Type) ds = f (Array t ds)-    ImplAllows _ ('[] :: [Type]) _ = ()-    ImplAllows f (t ': ts :: [Type]) ds = (f (Array t ds), ImplAllows f ts ds)--type family ArraySingletons (ts :: l) (ns :: [Nat]) :: Constraint where-    ArraySingletons (t :: Type) ns = ArraySingleton t ns-    ArraySingletons ('[] :: [Type]) _ = ()-    ArraySingletons (t ': ts :: [Type]) ns-      = (ArraySingleton t ns, ArraySingletons ts ns)--type family PrimFrames (ts :: l) (ns :: [Nat]) :: Constraint where-    PrimFrames (t :: Type) ns-      = (PrimBytes (DataFrame t ns), PrimArray t (DataFrame t ns))-    PrimFrames ('[] :: [Type]) _ = ()-    PrimFrames (t ': ts :: [Type]) ns-      = ( PrimBytes (DataFrame t ns), PrimArray t (DataFrame t ns)-        , PrimFrames ts ns)---deriving instance Bounded (Array t ds) => Bounded (DataFrame t ds)-deriving instance Enum (Array t ds) => Enum (DataFrame t ds)-deriving instance Integral (Array t ds)-               => Integral (DataFrame t ds)-deriving instance Num (Array t ds)-               => Num (DataFrame t ds)-deriving instance Fractional (Array t ds)-               => Fractional (DataFrame t ds)-deriving instance Floating (Array t ds)-               => Floating (DataFrame t ds)-deriving instance Ord (Array t ds)-               => Ord (DataFrame t ds)-deriving instance ( Read (Array t ds), Dimensions ds )-               => Read (DataFrame t ds)-deriving instance Real (Array t ds)-               => Real (DataFrame t ds)-deriving instance RealFrac (Array t ds)-               => RealFrac (DataFrame t ds)-deriving instance RealFloat (Array t ds)-               => RealFloat (DataFrame t ds)-deriving instance (PrimArray t (Array t ds), PrimBytes t)-               => PrimArray t (DataFrame t ds)-deriving instance PrimBytes (Array t ds)-               => PrimBytes (DataFrame t ds)----instance PrimBytes (DataFrame t ds) => Storable (DataFrame t ds) where-    sizeOf x = I# (byteSize x)-    alignment x = I# (byteAlign x)-    peek (Ptr addr) = IO (readAddr addr)-    poke (Ptr addr) a = IO (\s -> (# writeAddr a addr s, () #))----class DataFrameInference (t :: l) where-    -- | Bring an evidence of `ArraySingleton` instance into-    --   a scope at runtime.-    --   This is often used to let GHC infer other complex type class instances,-    --   such as `SubSpace`.-    inferASing-        :: (AllTypes PrimBytes t, Dimensions ds)-        => DataFrame t ds -> Evidence (ArraySingletons t ds)-    inferEq-        :: (AllTypes Eq t, ArraySingletons t ds)-        => DataFrame t ds -> Evidence (Eq (DataFrame t ds))-    inferShow-        :: (AllTypes Show t, ArraySingletons t ds, Dimensions ds)-        => DataFrame t ds -> Evidence (Show (DataFrame t ds))-    inferPrim-        :: (AllTypes PrimBytes t, ArraySingletons t ds, Dimensions ds)-        => DataFrame t ds -> Evidence (PrimFrames t ds)-    -- | This is a special function, because Scalar does not require PrimBytes.-    --   That is why the dimension list in the argument nust not be empty.-    inferPrimElem-        :: (ArraySingletons t ds, ds ~ (Head ds ': Tail ds))-        => DataFrame t ds -> Evidence (AllTypes PrimBytes t)----instance DataFrameInference (t :: Type) where-    inferASing    (_ :: DataFrame t ds)-      = AFam.inferASing @t @ds-    inferEq       (_ :: DataFrame t ds)-      = case AFam.inferEq @t @ds of E -> E-    inferShow     (_ :: DataFrame t ds)-      = case AFam.inferShow @t @ds of E -> E-    inferPrim     (_ :: DataFrame t ds)-      = case AFam.inferPrim @t @ds of E -> E-    inferPrimElem (_ :: DataFrame t ds)-      = case AFam.inferPrimElem @t @(Head ds) @(Tail ds) of E -> E--inferOrd' :: forall t ds-           . (Ord t, ArraySingleton t ds)-          => Evidence (Ord (DataFrame t ds))-inferOrd' = case AFam.inferOrd @t @ds of E -> E--inferNum' :: forall t ds-           . (Num t, ArraySingletons t ds)-          => Evidence (Num (DataFrame t ds))-inferNum' = case AFam.inferNum @t @ds of E -> E--inferFractional' :: forall t ds-                  . (Fractional t, ArraySingleton t ds)-                 => Evidence (Fractional (DataFrame t ds))-inferFractional' = case AFam.inferFractional @t @ds of E -> E--inferFloating' :: forall t ds-                . (Floating t, ArraySingleton t ds)-               => Evidence (Floating (DataFrame t ds))-inferFloating' = case AFam.inferFloating @t @ds of E -> E---instance RepresentableList ts => DataFrameInference (ts :: [Type]) where-    inferASing    (_ :: DataFrame t ds)-      = inferASings @ts @ds (tList @_ @ts)-    inferEq       (_ :: DataFrame t ds)-      = case inferEqs @ts @ds (tList @_ @ts) of E -> E-    inferShow     (_ :: DataFrame t ds)-      = case inferShows @ts @ds (tList @_ @ts) of E -> E-    inferPrim     (_ :: DataFrame t ds)-      = case inferPrims @ts @ds (tList @_ @ts) of E -> E-    inferPrimElem (_ :: DataFrame t ds)-      = case inferPrimElems @ts @(Head ds) @(Tail ds) (tList @_ @ts) of E -> E----inferASings :: forall ts ds-             . (All PrimBytes ts, Dimensions ds)-            => TypeList ts -> Evidence (ArraySingletons ts ds)-inferASings U = E-inferASings ((_ :: Proxy t) :* ts)-  = case (inferASing' @t @ds, inferASings @_ @ds ts) of (E, E) -> E----inferEqs :: forall ts ds-          . (All Eq ts, ArraySingletons ts ds)-         => TypeList ts -> Evidence (ImplAllows Eq ts ds)-inferEqs U = E-inferEqs ((_ :: Proxy t) :* ts)-  = case (AFam.inferEq @t @ds, inferEqs @_ @ds ts) of (E, E) -> E--inferShows :: forall ts ds-            . (All Show ts, ArraySingletons ts ds, Dimensions ds)-           => TypeList ts -> Evidence (ImplAllows Show ts ds)-inferShows U = E-inferShows ((_ :: Proxy t) :* ts)-  = case (AFam.inferShow @t @ds, inferShows @_ @ds ts) of (E, E) -> E--inferPrims :: forall ts ds-            . (All PrimBytes ts, ArraySingletons ts ds, Dimensions ds)-           => TypeList ts -> Evidence (PrimFrames ts ds)-inferPrims U = E-inferPrims ((_ :: Proxy t) :* ts)-  = case (AFam.inferPrim @t @ds, inferPrims @_ @ds ts) of (E, E) -> E--inferPrimElems :: forall ts d ds-             . (ArraySingletons ts (d ': ds))-            => TypeList ts -> Evidence (All PrimBytes ts)-inferPrimElems U = E-inferPrimElems ((_ :: Proxy t) :* ts)-  = case (AFam.inferPrimElem @t @d @ds, inferPrimElems @_ @d @ds ts) of (E, E) -> E---inferASing' :: forall t ds-            . (DataFrameInference t, AllTypes PrimBytes t, Dimensions ds)-           => Evidence (ArraySingletons t ds)-inferASing' = inferASing (undefined :: DataFrame t ds)--inferEq' :: forall t ds-         . (DataFrameInference t, AllTypes Eq t, ArraySingletons t ds)-        => Evidence (Eq (DataFrame t ds))-inferEq' = inferEq (undefined :: DataFrame t ds)--inferShow' :: forall t ds-           . ( DataFrameInference t, AllTypes Show t-             , ArraySingletons t ds, Dimensions ds)-          => Evidence (Show (DataFrame t ds))-inferShow' = inferShow (undefined :: DataFrame t ds)---inferPrim' :: forall t ds-           . ( DataFrameInference t, AllTypes PrimBytes t-             , ArraySingletons t ds, Dimensions ds)-          => Evidence (PrimFrames t ds)-inferPrim' = inferPrim (undefined :: DataFrame t ds)---inferPrimElem' :: forall t ds-               . ( DataFrameInference t, ArraySingletons t ds-                 , ds ~ (Head ds ': Tail ds))-              => Evidence (AllTypes PrimBytes t)-inferPrimElem' = inferPrimElem (undefined :: DataFrame t ds)--inferOrd :: forall t ds-          . (Ord t, ArraySingleton t ds)-         => DataFrame t ds -> Evidence (Ord (DataFrame t ds))-inferOrd = const (inferOrd' @t @ds)--inferNum :: forall t ds-          . (Num t, ArraySingletons t ds)-         => DataFrame t ds -> Evidence (Num (DataFrame t ds))-inferNum = const (inferNum' @t @ds)--inferFractional :: forall t ds-                 . (Fractional t, ArraySingleton t ds)-                => DataFrame t ds -> Evidence (Fractional (DataFrame t ds))-inferFractional = const (inferFractional' @t @ds)--inferFloating :: forall t ds-               . (Floating t, ArraySingleton t ds)-              => DataFrame t ds -> Evidence (Floating (DataFrame t ds))-inferFloating = const (inferFloating' @t @ds)-------------------------------------------------------------------------------------- * Misc------------------------------------------------------------------------------------- | A wrapper on `byteSize`-bSizeOf :: PrimBytes a => a -> Int-bSizeOf a = I# (byteSize a)---- | A wrapper on `byteAlign`-bAlignOf :: PrimBytes a => a -> Int-bAlignOf a = I# (byteAlign a)---- | Number of elements along the 1st dimension.-dimSize1 :: Dim1 t ds => t ds -> Word-dimSize1 = dimVal . dim1---- | Number of elements along the 2nd dimension.-dimSize2 :: Dim2 t ds => t ds -> Word-dimSize2 = dimVal . dim2---- | Number of elements along the 3rd dimension.-dimSize3 :: Dim3 t ds => t ds -> Word-dimSize3 = dimVal . dim3--class Dim1 (t :: [k] -> Type) (ds :: [k]) where-    dim1 :: t ds -> Dim (Head ds)--class Dim2 (t :: [k] -> Type) (ds :: [k]) where-    dim2 :: t ds -> Dim (Head (Tail ds))--class Dim3 (t :: [k] -> Type) (ds :: [k]) where-    dim3 :: t ds -> Dim (Head (Tail (Tail ds)))---instance {-# OVERLAPPABLE #-}-         Dimensions (d ': ds)-         => Dim1 t (d ': ds :: [k]) where-    dim1 _ = case dims @k @(d ': ds) of d :* _ -> d--instance {-# OVERLAPPING #-}-         Dim1 (TypedList Dim) (d ': ds) where-    dim1 (d :* _) = d--instance {-# OVERLAPPING #-}-         Dim1 (DataFrame l) (d ': ds :: [XNat]) where-    dim1 (XFrame (_ :: DataFrame l ns))-      = case xDims' @(d ': ds) @ns of d :* _  -> d--instance {-# OVERLAPPABLE #-}-         Dimensions (d1 ': d2 ': ds)-         => Dim2 t (d1 ': d2 ': ds :: [k]) where-    dim2 _ = case dims @k @(d1 ': d2 ': ds) of _ :* d :* _ -> d--instance {-# OVERLAPPING #-}-         Dim2 (TypedList Dim) (d1 ': d2 ': ds) where-    dim2 (_ :* d :* _) = d--instance {-# OVERLAPPING #-}-         Dim2 (DataFrame l) (d1 ': d2 ': ds :: [XNat]) where-    dim2 (XFrame (_ :: DataFrame l ns))-      = case xDims' @(d1 ': d2 ': ds) @ns of _ :* d :* _  -> d--instance {-# OVERLAPPABLE #-}-         Dimensions (d1 ': d2 ': d3 ': ds)-         => Dim3 t (d1 ': d2 ': d3 ': ds :: [k]) where-    dim3 _ = case dims @k @(d1 ': d2 ': d3 ': ds) of _ :* _ :* d :* _ -> d--instance {-# OVERLAPPING #-}-         Dim3 (TypedList Dim) (d1 ': d2 ': d3 ': ds) where-    dim3 (_ :* _ :* d :* _) = d--instance {-# OVERLAPPING #-}-         Dim3 (DataFrame l) (d1 ': d2 ': d3 ': ds :: [XNat]) where-    dim3 (XFrame (_ :: DataFrame l ns))-      = case xDims' @(d1 ': d2 ': d3 ': ds) @ns of _ :* _ :* d :* _  -> d+{-# LANGUAGE AllowAmbiguousTypes        #-}+{-# LANGUAGE CPP                        #-}+{-# LANGUAGE ConstraintKinds            #-}+{-# LANGUAGE DataKinds                  #-}+{-# LANGUAGE DeriveDataTypeable         #-}+{-# LANGUAGE ExistentialQuantification  #-}+{-# LANGUAGE FlexibleContexts           #-}+{-# LANGUAGE FlexibleInstances          #-}+{-# LANGUAGE GADTs                      #-}+{-# LANGUAGE GeneralizedNewtypeDeriving #-}+{-# LANGUAGE LambdaCase                 #-}+{-# LANGUAGE MagicHash                  #-}+{-# LANGUAGE MultiParamTypeClasses      #-}+{-# LANGUAGE PatternSynonyms            #-}+{-# LANGUAGE RankNTypes                 #-}+{-# LANGUAGE ScopedTypeVariables        #-}+{-# LANGUAGE StandaloneDeriving         #-}+{-# LANGUAGE TypeApplications           #-}+{-# LANGUAGE TypeFamilies               #-}+{-# LANGUAGE TypeInType                 #-}+{-# LANGUAGE TypeOperators              #-}+{-# LANGUAGE UnboxedTuples              #-}+{-# LANGUAGE UndecidableInstances       #-}+{-# LANGUAGE ViewPatterns               #-}++{- |+  The core @easytensor@ types.+ -}+module Numeric.DataFrame.Type+  ( -- * Data types+    SomeDataFrame (..), DataFrame'+#if defined(__HADDOCK__) || defined(__HADDOCK_VERSION__)+  , DataFrame (SingleFrame, MultiFrame, XFrame)+  , pattern Z, pattern (:*:)+  , pattern S, pattern DF2, pattern DF3, pattern DF4, pattern DF5+  , pattern DF6, pattern DF7, pattern DF8, pattern DF9+#else+  , DataFrame ( SingleFrame, MultiFrame, XFrame, (:*:), Z+              , S, DF2, DF3, DF4, DF5, DF6, DF7, DF8, DF9)+#endif+    -- * Flexible assembling and disassembling+  , PackDF, packDF, unpackDF+  , appendDF, consDF, snocDF+  , fromFlatList, fromListWithDefault, fromList+  , constrainDF+    -- * Infer type class instances+  , KnownBackend (), DFBackend, KnownBackends+  , InferKnownBackend (..), inferPrimElem+    -- * Re-exports+  , Dim (..), Idx (), XNat (..), N, XN, Dims, Idxs, TypedList (..)+  , PrimBytes (), bSizeOf, bAlignOf, bFieldOffsetOf+  , PrimArray (), ixOff+  ) where+++import           Data.Data+import           Data.Proxy                      (Proxy)+import           Data.Semigroup                  hiding (All)+import           Data.Type.Lits+import           Data.Void+import           Foreign.Storable                (Storable (..))+import           GHC.Base+import           GHC.Exts                        (TYPE)+import qualified GHC.Generics                    as G+import           GHC.Ptr                         (Ptr (..))+import qualified Text.ParserCombinators.ReadPrec as Read+import qualified Text.Read                       as Read+import qualified Text.Read.Lex                   as Read++import           Numeric.DataFrame.Internal.PrimArray+import           Numeric.Dimensions+import           Numeric.PrimBytes+import           Numeric.ProductOrd+import qualified Numeric.ProductOrd.NonTransitive     as NonTransitive+import qualified Numeric.ProductOrd.Partial           as Partial+import           Numeric.TypedList                    (typeables)++import {-# SOURCE #-} Numeric.DataFrame.Internal.Backend  (DFBackend,+                                                           KnownBackend)+import {-# SOURCE #-} qualified Numeric.DataFrame.Internal.Backend  as Backend+import           Numeric.DataFrame.Internal.BackendI ()+++-- | Keep data in a primitive data frame+--    and maintain information about Dimensions in the type system+data family DataFrame (t :: l) (xs :: [k])++-- | Single frame+newtype instance DataFrame (t :: Type) (ns :: [Nat])+  = SingleFrame { getSingleFrame :: DFBackend t ns }++-- | Multiple "columns" of data frames of the same shape+newtype instance DataFrame (ts :: [Type]) (ns :: [Nat])+  = MultiFrame ( TypedList (DataFrame' ns) ts )++-- | Data frame with some dimensions missing at compile time.+--   Pattern-match against its constructor to get a Nat-indexed data frame.+data instance DataFrame (ts :: l) (xns :: [XNat])+  = forall (ns :: [Nat])+  . (KnownXNatTypes xns, FixedDims xns ns, Dimensions ns, KnownBackends ts ns)+  => XFrame (DataFrame ts ns)++-- | 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)+  = forall (ns :: [Nat]) . (Dimensions ns, KnownBackends t ns)+  => SomeDataFrame (DataFrame t ns)+  deriving Typeable++-- | DataFrame with its type arguments swapped.+newtype DataFrame' (xs :: [k]) (t :: l) = DataFrame' (DataFrame t xs)+  deriving Typeable++{-# COMPLETE Z, (:*:) #-}+++-- | 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+pattern (:*:) x xs <- (MultiFrame (DataFrame' x :* (MultiFrame -> xs)))+  where+    (:*:) x (MultiFrame xs) = MultiFrame (DataFrame' x :* xs)+infixr 6 :*:++-- | Empty MultiFrame+pattern Z :: forall (xs :: [Type]) (ns :: [Nat])+           . () => (xs ~ '[]) => DataFrame xs ns+pattern Z = MultiFrame U++-- | I use this kind-polymorphic constraint to generalize @XFrame@ and @SomeDataFrame@+--   over @SingleFrame@ and @MultiFrame@.+type family KnownBackends (ts :: l) (ns :: [Nat]) :: Constraint where+    KnownBackends ( t      ::  Type ) ns = KnownBackend t ns+    KnownBackends ('[]     :: [Type]) _  = ()+    KnownBackends (t ': ts :: [Type]) ns =+      (KnownBackend t ns, KnownBackends ts ns)++-- | Allow inferring @KnownBackends@ if you know the dimensions and the element types.+class InferKnownBackend (t :: k) ds where+    -- Infer @KnownBackends@ if you know the dimensions and the element types.+    inferKnownBackend :: Dict (KnownBackends t ds)++instance (PrimBytes t, Dimensions ds) => InferKnownBackend (t :: Type) ds where+    inferKnownBackend = Backend.inferKnownBackend @t @ds++instance (RepresentableList ts, All PrimBytes ts, Dimensions ds)+      => InferKnownBackend (ts :: [Type]) ds where+    inferKnownBackend = go (tList @_ @ts)+      where+        go :: forall ss . All PrimBytes ss => TypeList ss -> Dict (KnownBackends ss ds)+        go U = Dict+        go ((_ :: Proxy t) :* ts)+             = case Backend.inferKnownBackend @t @ds of+                 Dict -> case go ts of+                   Dict -> Dict++-- | All component data frames must satisfy a given constraint.+type family AllFrames (f :: Type -> Constraint) (ts :: [Type]) (ds :: [Nat])+                                                             :: Constraint where+    AllFrames _ '[] _ = ()+    AllFrames f (t ': ts) ds = (f (DataFrame t ds), AllFrames f ts ds)+++deriving instance Typeable (DataFrame (t :: l) (xs :: [k]))+deriving instance ( Data (DataFrame t xs)+                  , Typeable t, Typeable xs, Typeable k, Typeable l)+               => Data (DataFrame' (xs :: [k]) (t :: l))+deriving instance Eq (DFBackend t ds)+               => Eq (DataFrame t ds)+deriving instance Ord (DFBackend t ds)+               => Ord (DataFrame t ds)+deriving instance ProductOrder (DFBackend t ds)+               => ProductOrder (DataFrame t ds)+deriving instance Bounded (DFBackend t ds)+               => Bounded (DataFrame t ds)+deriving instance Enum (DFBackend t ds)+               => Enum (DataFrame t ds)+deriving instance Integral (DFBackend t ds)+               => Integral (DataFrame t ds)+deriving instance Num (DFBackend t ds)+               => Num (DataFrame t ds)+deriving instance Fractional (DFBackend t ds)+               => Fractional (DataFrame t ds)+deriving instance Floating (DFBackend t ds)+               => Floating (DataFrame t ds)+deriving instance Real (DFBackend t ds)+               => Real (DataFrame t ds)+deriving instance RealFrac (DFBackend t ds)+               => RealFrac (DataFrame t ds)+deriving instance RealFloat (DFBackend t ds)+               => RealFloat (DataFrame t ds)+deriving instance PrimBytes (DFBackend t ds)+               => PrimBytes (DataFrame t ds)+deriving instance (PrimArray t (DFBackend t ds), PrimBytes t)+               => PrimArray t (DataFrame t ds)++instance Ord (NonTransitive.ProductOrd (DFBackend t ds))+      => Ord (NonTransitive.ProductOrd (DataFrame t ds)) where+    (>) = coerce ((>) @(NonTransitive.ProductOrd (DFBackend t ds)))+    (<) = coerce ((<) @(NonTransitive.ProductOrd (DFBackend t ds)))+    (>=) = coerce ((>=) @(NonTransitive.ProductOrd (DFBackend t ds)))+    (<=) = coerce ((<=) @(NonTransitive.ProductOrd (DFBackend t ds)))+    compare = coerce (compare @(NonTransitive.ProductOrd (DFBackend t ds)))+    min = coerce (min @(NonTransitive.ProductOrd (DFBackend t ds)))+    max = coerce (max @(NonTransitive.ProductOrd (DFBackend t ds)))++instance (Ord (Partial.ProductOrd (DFBackend t ds)), Eq (DFBackend t ds))+      => Ord (Partial.ProductOrd (DataFrame t ds)) where+    (>) = coerce ((>) @(Partial.ProductOrd (DFBackend t ds)))+    (<) = coerce ((<) @(Partial.ProductOrd (DFBackend t ds)))+    (>=) = coerce ((>=) @(Partial.ProductOrd (DFBackend t ds)))+    (<=) = coerce ((<=) @(Partial.ProductOrd (DFBackend t ds)))+    compare = coerce (compare @(Partial.ProductOrd (DFBackend t ds)))+    min = coerce (min @(Partial.ProductOrd (DFBackend t ds)))+    max = coerce (max @(Partial.ProductOrd (DFBackend t ds)))++++instance PrimBytes (DataFrame t ds) => Storable (DataFrame t ds) where+    sizeOf x = I# (byteSize x)+    alignment x = I# (byteAlign x)+    peek (Ptr addr) = IO (readAddr addr)+    poke (Ptr addr) a = IO (\s -> (# writeAddr a addr s, () #))+++instance AllFrames Eq ts ds => Eq (DataFrame (ts :: [Type]) ds) where+    Z == Z = True+    (a :*: as) == (b :*: bs) = a == b && as == bs++instance Eq t => Eq (DataFrame (t :: Type) (ds :: [XNat])) where+    XFrame dfa == XFrame dfb+      | Just Dict <- sameDims' dfa dfb = dfa == dfb+      | otherwise                      = False++instance All Eq ts => Eq (DataFrame (ts :: [Type]) (ds :: [XNat])) where+    XFrame dfa == XFrame dfb+      | Just Dict <- sameDims' dfa dfb = eqFrames dfa dfb+      | otherwise                      = False++instance Eq t => Eq (SomeDataFrame (t :: Type)) where+    SomeDataFrame dfa == SomeDataFrame dfb+      | Just Dict <- sameDims' dfa dfb = dfa == dfb+      | otherwise                      = False++instance All Eq ts => Eq (SomeDataFrame (ts :: [Type])) where+    SomeDataFrame dfa == SomeDataFrame dfb+      | Just Dict <- sameDims' dfa dfb = eqFrames dfa dfb+      | otherwise                      = False+++eqFrames :: forall (xs :: [Type]) (ns :: [Nat])+          . (KnownBackends xs ns, All Eq xs)+         => DataFrame xs ns -> DataFrame xs ns -> Bool+eqFrames Z Z                   = True+eqFrames (a :*: as) (b :*: bs) = a == b && eqFrames as bs++++instance ( Show t+         , PrimBytes t+         , Dimensions ds+         ) => Show (DataFrame (t :: Type) (ds :: [Nat])) where+    showsPrec p x = case dims @ds of+      U       -> showParen (p >= 10)+        $ showString "S " . showsPrec 10 (unsafeCoerce# x :: t)+      D0 :* _ -> showString "DF0"+      d  :* _ -> showParen (p >= 10)+        $ unpackDF' ( \Dict f ->+            let g :: Endo (Int -> ShowS)+                g = Endo $ \k -> f (\o e -> k o . showChar ' ' . showsPrec 11 e)+                n = dimVal d+            in  appEndo (stimes n g) (const $ showString "DF" . shows n)+          ) x++instance ( All Show ts+         , All PrimBytes ts+         , Dimensions ds+         ) => Show (DataFrame (ts :: [Type]) (ds :: [Nat])) where+    showsPrec _ Z = showChar 'Z'+    showsPrec p (x :*: xs) = showParen (p >= 7) $+        showsPrec 7 x . showString " :*: " . showsPrec 6 xs++instance (Show t, PrimBytes t)+      => Show (DataFrame (t :: Type) (xns :: [XNat])) where+    showsPrec p (XFrame x)+      = showParen (p >= 10) $ showString "XFrame " . showsPrec 11 x++instance (All Show ts, All PrimBytes ts)+      => Show (DataFrame (ts :: [Type]) (xns :: [XNat])) where+    showsPrec p (XFrame x)+      = showParen (p >= 10) $ showString "XFrame " . showsPrec 11 x++instance (Show t, PrimBytes t)+      => Show (SomeDataFrame (t :: Type)) where+    showsPrec p (SomeDataFrame x)+      = showParen (p >= 10) $ showString "SomeDataFrame " . showsPrec 11 x++instance (All Show ts, All PrimBytes ts)+      => Show (SomeDataFrame (ts :: [Type])) where+    showsPrec p (SomeDataFrame x)+      = showParen (p >= 10) $ showString "SomeDataFrame " . showsPrec 11 x+++instance (Read t, PrimBytes t, Dimensions ds)+      => Read (DataFrame (t :: Type) (ds :: [Nat])) where+    readPrec = readPrecFixedDF (dims @ds)+    readList = Read.readListDefault+    readListPrec = Read.readListPrecDefault++instance (All Read ts, All PrimBytes ts, RepresentableList ts, Dimensions ds)+      => Read (DataFrame (ts :: [Type]) (ds :: [Nat])) where+    readPrec = readFixedMultiDF (tList @Type @ts) (dims @ds)+    readList = Read.readListDefault+    readListPrec = Read.readListPrecDefault++instance (Read t, PrimBytes t, BoundedDims ds, All KnownXNatType ds)+      => Read (DataFrame (t :: Type) (ds :: [XNat])) where+    readPrec = Read.parens . Read.prec 10 $ do+      Read.lift . Read.expect $ Read.Ident "XFrame"+      Read.step $ readPrecBoundedDF (minDims @XNat @ds)+    readList = Read.readListDefault+    readListPrec = Read.readListPrecDefault++instance ( All Read ts, All PrimBytes ts, RepresentableList ts+         , BoundedDims ds, All KnownXNatType ds)+      => Read (DataFrame (ts :: [Type]) (ds :: [XNat])) where+    readPrec = Read.parens . Read.prec 10 $ do+      Read.lift . Read.expect $ Read.Ident "XFrame"+      Read.step $ readBoundedMultiDF (tList @Type @ts) (minDims @XNat @ds)+    readList = Read.readListDefault+    readListPrec = Read.readListPrecDefault++instance (Read t, PrimBytes t)+      => Read (SomeDataFrame (t :: Type)) where+    readPrec = Read.parens . Read.prec 10 $ do+      Read.lift . Read.expect $ Read.Ident "SomeDataFrame"+      Read.step readPrecSomeDF+    readList = Read.readListDefault+    readListPrec = Read.readListPrecDefault++instance ( All Read ts, All PrimBytes ts, RepresentableList ts )+      => Read (SomeDataFrame (ts :: [Type])) where+    readPrec = Read.parens . Read.prec 10 $ do+      Read.lift . Read.expect $ Read.Ident "SomeDataFrame"+      Read.step $ readSomeMultiDF (tList @Type @ts)+    readList = Read.readListDefault+    readListPrec = Read.readListPrecDefault++readPrecFixedDF :: forall (t :: Type) (ds :: [Nat])+                 . (Read t, PrimBytes t)+                => Dims ds -> Read.ReadPrec (DataFrame t ds)+readPrecFixedDF U+  = Read.parens . Read.prec 10 $ do+    Read.lift . Read.expect $ Read.Ident "S"+    S <$> Read.step Read.readPrec+readPrecFixedDF (D0 :* Dims)+  = Read.parens $ do+    Read.lift . Read.expect . Read.Ident $ "DF0"+    return (packDF @t @0)+readPrecFixedDF (d@D :* ds@Dims)+  = Read.parens . Read.prec 10 $ do+    Read.lift . Read.expect . Read.Ident $ "DF" ++ show (dimVal d)+    packDF' (<*> Read.step (readPrecFixedDF ds)) pure++{-+The first argument is, in fact, a @dimsBound@, but covered in the same @[XNat]@+  form. That is, XN values are lower bounds rather than actual runtime dimensions.++The interesting bit about this function is that it is very particular in specifying+what is enforced and what is unknown.+At the very least, the call site must know the order of the Dims (unless DF0 is present)+  -- and specify all dims as @XN 0@.+It allows a fine-grained control over the shape of a DataFrame.++For example,++>>> readPrecBoundedDF (Dx @5 DF5 :* Dn DF4 :* Dn DF4 :* U)++  reads an array of 4x4 matrices of length at least 5.++ -}+readPrecBoundedDF :: forall (t :: Type) (ds :: [XNat])+                   . (Read t, PrimBytes t, KnownXNatTypes ds)+                  => Dims ds -> Read.ReadPrec (DataFrame t ds)+-- reading scalar+readPrecBoundedDF U+  = Read.parens . Read.prec 10 $ do+    Read.lift . Read.expect $ Read.Ident "S"+    case inferKnownBackend @t @'[] of+      Dict -> XFrame . S <$> Read.step Read.readPrec+-- DF0 is funny because it will succesfully parse any dimension to the right of it.+readPrecBoundedDF (Dn D0 :* XDims (Dims :: Dims ns))+  = Read.parens $ do+    Read.lift . Read.expect . Read.Ident $ "DF0"+    return $ case inferKnownBackend @t @(0 ': ns) of+      Dict -> XFrame @Type @t @ds @(0 ': ns) (packDF @t @0 @ns)+-- Fixed dimension:+--  The number of component frames is exactly n+--  the first component frame fixes the shape of the rest n-1+readPrecBoundedDF (Dn d@(D :: Dim n) :* xns)+  = Read.parens . Read.prec 10 $ do+    Read.lift . Read.expect . Read.Ident $ "DF" ++ show (dimVal d)+    XFrame (x :: DataFrame t ns) <- Read.step $ readPrecBoundedDF @t xns+    case inferKnownBackend @t @(n ': ns) of+      Dict -> fmap XFrame . snd . runDelay $ packDF' @t @n @ns+        (readDelayed $ Read.prec 10 (readPrecFixedDF @t @ns dims))+        (followedBy x)+-- Bounded dimension:+--   The number of component frames is at least m+--   the first component frame fixes the shape of the rest n-1+readPrecBoundedDF ((Dx (m :: Dim m) :: Dim xm) :* xns)+  | Dict <- unsafeEqTypes @XNat @('XN m) @xm -- by user contract the argument is dimBound+  = Read.parens $ lookLex >>= \case+    Read.Ident ('D':'F':s)+      | Just (Dx (n :: Dim n)) <- (Read.readMaybe ('D':s) :: Maybe SomeDim)+      , Just Dict <- indeedLE m n -- check if the DF dim is not less than m+        -> case n of+          D0 -> do -- need to repack it under different constraint dims+            XFrame x <- readPrecBoundedDF @t (Dn D0 :* xns)+            return (XFrame x)+          D  -> do+            Read.lift . Read.expect . Read.Ident $ "DF" ++ show (dimVal n)+            XFrame (x :: DataFrame t ns) <- Read.prec 10 $ readPrecBoundedDF @t xns+            case inferKnownBackend @t @(n ': ns) of+              Dict -> fmap XFrame . snd . runDelay $ packDF' @t @n @ns+                (readDelayed $ Read.prec 10 (readPrecFixedDF @t @ns dims))+                (followedBy x)++    _ -> Read.pfail+  where+    indeedLE :: forall (a ::Nat) (b :: Nat) . Dim a -> Dim b -> Maybe (Dict (a <= b))+    indeedLE a b = case compareDim a b of+      SLT -> Just Dict+      SEQ -> Just Dict+      SGT -> Nothing++{-+In this case we know Nothing about the dimensionality of a DataFrame.+The logic is similar to readPrecBoundedDF, but a bit simpler:+the first dimension is flexible, but fixes the rest dimensions.+ -}+readPrecSomeDF :: forall (t :: Type) . (Read t, PrimBytes t)+               => Read.ReadPrec (SomeDataFrame t)+readPrecSomeDF = Read.parens $+    Read.prec 10 (do+      Read.lift . Read.expect $ Read.Ident "S"+      case inferKnownBackend @t @'[] of+        Dict -> SomeDataFrame . S <$> Read.readPrec+    )+    Read.++++    (lookLex >>= \case+       Read.Ident ('D':'F':s)+         | Just (Dx (d :: Dim d)) <- (Read.readMaybe ('D':s) :: Maybe SomeDim)+           -> case d of+             D0 | Dict <- inferKnownBackend @t @'[0]+                 -> SomeDataFrame <$> readPrecFixedDF @t (D0 :* U)+             _ -> do+               Read.lift . Read.expect . Read.Ident $ "DF" ++ show (dimVal d)+               SomeDataFrame (x :: DataFrame t ds) <- Read.prec 10 $ readPrecSomeDF @t+               case inferKnownBackend @t @(d ': ds) of+                 Dict -> fmap SomeDataFrame . snd . runDelay $ packDF' @t @d @ds+                   (readDelayed $ Read.prec 10 (readPrecFixedDF @t @ds dims))+                   (followedBy x)+       _ -> Read.pfail+    )++readFixedMultiDF :: forall (ts :: [Type]) (ds :: [Nat])+                  . (All Read ts, All PrimBytes ts)+                 => TypeList ts+                 -> Dims ds+                 -> Read.ReadPrec (DataFrame ts ds)+readFixedMultiDF U _ = Read.parens $+    Z <$ Read.lift (Read.expect $ Read.Ident "Z")+readFixedMultiDF (_ :* ts) ds = Read.parens . Read.prec 6 $ do+    x <- Read.step $ readPrecFixedDF ds+    Read.lift . Read.expect $ Read.Symbol ":*:"+    xs <- readFixedMultiDF ts ds+    return (x :*: xs)++readBoundedMultiDF :: forall (ts :: [Type]) (ds :: [XNat])+                    . (All Read ts, All PrimBytes ts, KnownXNatTypes ds)+                   => TypeList ts+                   -> Dims ds+                   -> Read.ReadPrec (DataFrame ts ds)+readBoundedMultiDF U (XDims (Dims :: Dims ns))+  = Read.parens $+    XFrame @[Type] @'[] @ds @ns Z <$ Read.lift (Read.expect $ Read.Ident "Z")+readBoundedMultiDF ((_ :: Proxy t) :* ts@TypeList) ds+  = Read.parens . Read.prec 6 $ do+    XFrame (x :: DataFrame t ns) <- Read.step $ readPrecBoundedDF @t ds+    Read.lift . Read.expect $ Read.Symbol ":*:"+    xs <- readFixedMultiDF ts (dims @ns)+    case inferKnownBackend @ts @ns of+      Dict -> return $ XFrame (x :*: xs)++readSomeMultiDF :: forall (ts :: [Type])+                 . (All Read ts, All PrimBytes ts)+                => TypeList ts+                -> Read.ReadPrec (SomeDataFrame ts)+readSomeMultiDF U+  = Read.parens $+    SomeDataFrame @[Type] @ts @'[] Z <$ Read.lift (Read.expect $ Read.Ident "Z")+readSomeMultiDF ((_ :: Proxy t) :* ts@TypeList)+  = Read.parens . Read.prec 6 $ do+    SomeDataFrame (x :: DataFrame t ns) <- Read.step $ readPrecSomeDF @t+    Read.lift . Read.expect $ Read.Symbol ":*:"+    xs <- readFixedMultiDF ts (dims @ns)+    case inferKnownBackend @ts @ns of+      Dict -> return $ SomeDataFrame (x :*: xs)++-- First element is read separately, enforcing the structure of the rest.+newtype Delayed t ds c a = Delayed { runDelay :: (c (DataFrame t ds), c a) }++followedBy :: Applicative c => DataFrame t ds -> a -> Delayed t ds c a+followedBy x = Delayed . (,) (pure x) . pure++readDelayed :: forall (t :: Type) (ds :: [Nat]) (c :: Type -> Type) (r :: Type)+             . Applicative c+            => c (DataFrame t ds)+            -> Delayed t ds c (DataFrame t ds -> r) -> Delayed t ds c r+readDelayed readF (Delayed (cprev, cf)) = Delayed (readF, cf <*> cprev)+++-- | Check the next lexeme without consuming it+lookLex :: Read.ReadPrec Read.Lexeme+lookLex = Read.look >>=+  Read.choice . map (pure . fst) . Read.readPrec_to_S Read.lexP 10+++++-- | 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)+inferPrimElem = Backend.inferPrimElem . getSingleFrame++-- | 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+fromFlatList = unsafeFromFlatList++++-- | A scalar DataFrame is just a newtype wrapper on a value.+pattern S :: forall (t :: Type) . t -> DataFrame t ('[] :: [Nat])+-- rely on that Scalar is just two times newtype alias to t+pattern S x <- (unsafeCoerce# -> x)+  where+    S = unsafeCoerce#+{-# COMPLETE S #-}+++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 DF2 a1 a2+    <- (unpackDF @t @2 @ds (#,,#) -> (# a1,a2,Dict #))+  where DF2 = packDF @t @2 @ds+{-# COMPLETE DF2 #-}++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 DF3 a1 a2 a3+    <- (unpackDF @t @3 @ds (#,,,#) -> (# a1,a2,a3,Dict #))+  where DF3 = packDF @t @3 @ds+{-# COMPLETE DF3 #-}++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 DF4 a1 a2 a3 a4+    <- (unpackDF @t @4 @ds (#,,,,#) -> (# a1,a2,a3,a4,Dict #))+  where DF4 = packDF @t @4 @ds+{-# COMPLETE DF4 #-}++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 DF5 a1 a2 a3 a4 a5+    <- (unpackDF @t @5 @ds (#,,,,,#) -> (# a1,a2,a3,a4,a5,Dict #))+  where DF5 = packDF @t @5 @ds+{-# COMPLETE DF5 #-}++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 DF6 a1 a2 a3 a4 a5 a6+    <- (unpackDF @t @6 @ds (#,,,,,,#) -> (# a1,a2,a3,a4,a5,a6,Dict #))+  where DF6 = packDF @t @6 @ds+{-# COMPLETE DF6 #-}++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 DF7 a1 a2 a3 a4 a5 a6 a7+    <- (unpackDF @t @7 @ds (#,,,,,,,#) -> (# a1,a2,a3,a4,a5,a6,a7,Dict #))+  where DF7 = packDF @t @7 @ds+{-# COMPLETE DF7 #-}++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 DF8 a1 a2 a3 a4 a5 a6 a7 a8+    <- (unpackDF @t @8 @ds (#,,,,,,,,#) -> (# a1,a2,a3,a4,a5,a6,a7,a8,Dict #))+  where DF8 = packDF @t @8 @ds+{-# COMPLETE DF8 #-}++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)+pattern DF9 a1 a2 a3 a4 a5 a6 a7 a8 a9+    <- (unpackDF @t @9 @ds (#,,,,,,,,,#) -> (# a1,a2,a3,a4,a5,a6,a7,a8,a9,Dict #))+  where DF9 = packDF @t @9 @ds+{-# COMPLETE DF9 #-}+++-- | Represent smart constructor functions `packDF` and `unpackDF`.+type family PackDF (t :: Type) (ds :: [Nat]) (d :: Nat) (r :: Type) :: Type where+    PackDF _ _  0 r = r+    PackDF t ds d r = DataFrame t ds -> PackDF t ds (d - 1) r++{- |+   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))+packDF+  | d :* Dims <- dims @(d ': ds)+  , Dict <- inferKnownBackend @t @(d ': ds)+  , Dict <- inferKnownBackend @t @ds+    = go d+  | otherwise = error "Numeric.DataFrame.Type.packDF: impossible args"+  where+    go :: (Dimensions ds, KnownBackend t ds, KnownBackend t (d ': ds))+       => Dim d+       -> PackDF t ds d (DataFrame t (d ': ds))+    go d = recur d getResult+      where+        -- number of elements in the frame as Int#+        els = case dimVal d of W# w -> word2Int# w+        -- size of a single element in bytes+        asize = byteSize @(DataFrame t ds) undefined++        getResult :: forall rRep (r :: TYPE rRep)+                  . (forall s. Int# -> MutableByteArray# s -> State# s -> r)+                  -> r+        getResult f = runRW#+          ( \s0 -> case newByteArray# (asize *# els) s0 of+               (# s1, mba #) -> f 0# mba s1+          )++        recur :: forall n . Dim n+              -> (forall rRep (r :: TYPE rRep)+                    . (forall s. Int# -> MutableByteArray# s -> State# s -> r ) -> r)+              -> PackDF t ds n (DataFrame t (d ': ds))+        recur n f = case minusDimM n (D :: Dim 1) of+          Nothing -> case unsafeEqTypes @Nat @n @0 of+            Dict -> f (\_ mba s -> case unsafeFreezeByteArray# mba s of+                                     (# _, ba #) -> fromBytes 0# ba )+          Just n' -> case unsafeEqTypes @_+                           @(PackDF t ds n (DataFrame t (d ': ds)))+                           @(DataFrame t ds -> PackDF t ds (n - 1) (DataFrame t (d ': ds))) of+            Dict -> \x -> recur n'+              ( \c -> f (\off mba s -> c (off +# asize) mba (writeBytes mba off x s)) )++++{- |+  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+unpackDF c+  | d :* Dims <- dims @(d ': ds)+    = unpackDF' (go d)+  | otherwise = error "Numeric.DataFrame.Type.unpackDF: impossible args"+  where+    go :: forall a . (a ~ Dict (Dimensions ds, KnownBackend t ds))+       => Dim d -> a+       -> (forall (zRep :: RuntimeRep) (z :: TYPE zRep)+                  . (Int -> DataFrame t ds -> z) -> Int -> z)+       -> Int -> r+    go d a k = recur d (const c)+      where+        recur :: forall n+               . Dim n+              -> (Int -> PackDF t ds n (a -> r))+              -> Int -> r+        recur n f = case minusDimM n (D :: Dim 1) of+          Nothing -> case unsafeEqTypes @Nat @n @0 of+            Dict -> (`f` a)+          Just n' -> case unsafeEqTypes @_+                           @(PackDF t ds n (a -> r))+                           @(DataFrame t ds -> PackDF t ds (n - 1) (a -> r)) of+            Dict -> recur n' (k f)+++packDF' :: forall (t :: Type) (d :: Nat) (ds :: [Nat]) c+         . (PrimBytes t, Dimensions (d ': ds))+        => (forall r. c (DataFrame t ds -> r) -> c r)+        -> (forall r. r -> c r)+        -> c (DataFrame t (d ': ds))+packDF' k z+  | d :* _ <- dims @(d ': ds)+    = go d (z (packDF @t @d @ds))+  | otherwise = error "Numeric.DataFrame.Type.packDF': impossible args"+  where+    go :: forall n . Dim n+       -> c (PackDF t ds n (DataFrame t (d ': ds))) -> c (DataFrame t (d ': ds))+    go n = case minusDimM n (D :: Dim 1) of+      Nothing -> case unsafeEqTypes @Nat @n @0 of Dict -> id+      Just n' -> case unsafeEqTypes @_+                       @(PackDF t ds n (DataFrame t (d ': ds)))+                       @(DataFrame t ds -> PackDF t ds (n - 1) (DataFrame t (d ': ds))) of+        Dict -> go n' . k+++-- Parameter Int# here is an element offset, it should not be used at the call site.+unpackDF' :: forall (rep :: RuntimeRep)+                    (t :: Type) (d :: Nat) (ds :: [Nat]) (r :: TYPE rep)+           . (PrimBytes t, Dimensions (d ': ds))+          => ( Dict (Dimensions ds, KnownBackend t ds)+               -> (forall (zRep :: RuntimeRep) (z :: TYPE zRep)+                          . (Int -> DataFrame t ds -> z) -> Int -> z)+               -> Int -> r)+          -> DataFrame t (d ': ds)+          -> r+unpackDF' k df+  | d :* Dims <- dims @(d ': ds)+  , Dict <- inferKnownBackend @t @(d ': ds)+  , Dict <- inferKnownBackend @t @ds+    = case arrayContent# df of+        (# x | #)+          | e <- broadcast x+            -> let f :: forall (zr :: RuntimeRep) (z :: TYPE zr)+                      . (Int -> DataFrame t ds -> z) -> Int -> z+                   f consume = (`consume` e)+               in k Dict f 0+        (# | (# cdims, off, arr #) #)+          | cd <- CumulDims . tail $ unCumulDims cdims+          , td <- cdTotalDim# cd+          , n <- case dimVal d of W# w -> word2Int# w+            -> let f :: forall (zr :: RuntimeRep) (z :: TYPE zr)+                      . (Int -> DataFrame t ds -> z) -> Int -> z+                   f consume (I# o) = consume (I# (o -# td)) (fromElems cd o arr)+               in k Dict f (I# (off +# td *# (n -# 1#)))+  | otherwise = error "Numeric.DataFrame.Type.unpackDF: impossible args"+++-- | Append one DataFrame to another, sum up the first dimension.+--+--   If you want to deconstruct a DataFrame, use+--       `Numeric.DataFrame.SubSpace.index`+--    or `Numeric.DataFrame.SubSpace.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)+appendDF+  | D <- D @n `plusDim` D @m+  , Dict <- inferKnownBackend @t @(n :+ ds)+  , Dict <- inferKnownBackend @t @(m :+ ds)+  , Dict <- inferKnownBackend @t @((n + m) :+ ds)+              = unsafeAppendPB+  | otherwise = error "Numeri.DataFrame.Type/appendDF: impossible arguments"++-- | Append a small DataFrame to a big DataFrame on the left.+--+--   If you want to deconstruct a DataFrame, use+--       `Numeric.DataFrame.SubSpace.index`+--    or `Numeric.DataFrame.SubSpace.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)+consDF+  | D <- D @n `plusDim` D1+  , Dict <- inferKnownBackend @t @(n :+ ds)+  , Dict <- inferKnownBackend @t @ds+  , Dict <- inferKnownBackend @t @((n + 1) :+ ds)+              = unsafeAppendPB+  | otherwise = error "Numeri.DataFrame.Type/consDF: impossible arguments"++-- | Append a small DataFrame to a big DataFrame on the right.+--+--   If you want to deconstruct a DataFrame, use+--       `Numeric.DataFrame.SubSpace.index`+--    or `Numeric.DataFrame.SubSpace.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)+snocDF+  | D <- D @n `plusDim` D1+  , Dict <- inferKnownBackend @t @(n :+ ds)+  , Dict <- inferKnownBackend @t @ds+  , Dict <- inferKnownBackend @t @((n + 1) :+ ds)+              = unsafeAppendPB+  | otherwise = error "Numeri.DataFrame.Type/snocDF: impossible arguments"+++-- | Unsafely copy two PrimBytes values into a third one.+unsafeAppendPB :: (PrimBytes x, PrimBytes y, PrimBytes z)+               => x -> y -> z+unsafeAppendPB x y+  | sx <- byteSize x+  = case runRW#+    ( \s0 -> case newByteArray# (sx +# byteSize y) s0 of+        (# s1, mba #) -> unsafeFreezeByteArray# mba+            ( writeBytes mba sx y+            ( writeBytes mba 0# x s1))+    ) of (# _, r #) -> fromBytes 0# r+++-- | 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)+fromListWithDefault d ds = snd $ packDF' f ((,) ds)+  where+    f :: forall r . ([DataFrame t ds], DataFrame t ds -> r) -> ([DataFrame t ds], r)+    f ([] ,  k) = ([], k d)+    f (x:xs, k) = (xs, k x)++-- | 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)+fromList xs+    | Dx (D :: Dim n) <- someDimVal . fromIntegral $ length xs+    , Dict <- inferKnownBackend @t @(n ': ds)+    , ds@(AsXDims (XDims ds')) <- dims @ds+    , Just Dict <- sameDims ds ds'+      = XFrame (fromListWithDefault @t @n @ds undefined xs)+    | otherwise+      = error "Numeri.DataFrame.Type/fromList: impossible arguments"+++-- | 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)+constrainDF (XFrame (df :: DataFrame ts ns))+  | ns <- dims @ns+  = case constrainDims @XNat @ds ns of+      Just (XDims (Dims :: Dims ms))+        | Dict <- unsafeEqTypes @[Nat] @ns @ms+          -> Just $ XFrame df+      _   -> Nothing++++-- Need this for @packDF'@ to make @Int -> c z@ a proper second-order type+-- parameterized by the result type.+newtype Off c z = Off { runOff :: Int -> c z }++-- | Term-level structure of a @SingleFrame t ds@ is fully determined by its+--   type dimensionality @Typeable ds@.+--   Thus, @gunfold@ does not use its last argument (@Constr@) at all,+--   relying on the structure of the type parameter.+instance (Data t, PrimBytes t, Typeable ds)+      => Data (DataFrame (t :: Type) (ds :: [Nat])) where+    gfoldl k z v = case typeableDims @ds of+      U | S x <- v+        -> z S `k` x+      D :* (Dims :: Dims ns)+        -> case inferTypeableCons @_ @ds of+          Dict ->+            -- PLZ don't ask me how does this work+            unpackDF' (\_ f -> runOff $ packDF'+                           (\g -> Off . f $ k . runOff g)+                           (Off . const . z)+                       ) v+    gunfold k z _ = case typeableDims @ds of+      U      -> k (z S)+      D :* (Dims :: Dims ns)+        -> case inferTypeableCons @_ @ds of Dict -> packDF' k z+    toConstr _ = case typeableDims @ds of+      U      -> scalarFrameConstr+      d :* _ -> singleFrameConstr $ dimVal d+    dataTypeOf _ = case typeableDims @ds of+      U      -> dataFrameDataType [scalarFrameConstr]+      d :* _ -> dataFrameDataType . (:[]). singleFrameConstr $ dimVal d++-- | Term-level structure of a @MultiFrame ts@ is fully determined by its+--   type @Typeable ts@.+--   Thus, @gunfold@ does not use its last argument (@Constr@) at all,+--   relying on the structure of the type parameter.+instance (AllFrames Data ts ds, Typeable ts, Typeable ds)+      => Data (DataFrame (ts :: [Type]) (ds :: [Nat])) where+    gfoldl _ z Z = z Z+    gfoldl k z (x :*: xs) = case inferTypeableCons @Type @ts of+      Dict -> z (:*:) `k` x `k` xs+    gunfold k z _ = case typeables @Type @ts of+      U      -> z Z+      _ :* _ -> case inferTypeableCons @_ @ts of Dict -> k (k (z (:*:)))+    toConstr Z         = multiFrameZConstr+    toConstr (_ :*: _) = multiFrameConsConstr+    dataTypeOf _ = dataFrameDataType [multiFrameZConstr, multiFrameConsConstr]+++dataFrameDataType :: [Constr] -> DataType+dataFrameDataType = mkDataType "Numeric.DataFrame.Type.DataFrame"++scalarFrameConstr :: Constr+scalarFrameConstr+  = mkConstr (dataFrameDataType [scalarFrameConstr]) "S" [] Prefix++singleFrameConstr :: Word -> Constr+singleFrameConstr d+  = mkConstr (dataFrameDataType [singleFrameConstr d]) ("DF" ++ show d) [] Prefix++multiFrameZConstr :: Constr+multiFrameZConstr = mkConstr+     (dataFrameDataType [multiFrameZConstr, multiFrameConsConstr])+     "Z" [] Prefix++multiFrameConsConstr :: Constr+multiFrameConsConstr = mkConstr+     (dataFrameDataType [multiFrameZConstr, multiFrameConsConstr])+     ":*:" [] Infix+++type DFMetaSel = 'G.MetaSel+  'Nothing 'G.NoSourceUnpackedness 'G.NoSourceStrictness 'G.DecidedLazy++type family DFTree (t :: Type) (ds :: [Nat]) (d :: Nat) where+  DFTree t ds 0 = G.U1+  DFTree t ds 1 = G.S1 DFMetaSel (G.Rec0 (DataFrame t ds))+  DFTree t ds n = DFTree t ds (Div n 2) G.:*: DFTree t ds (Div n 2 + Mod n 2)++type family SingleFrameRep (t :: Type) (ds :: [Nat]) :: (Type -> Type) where+  SingleFrameRep t '[]+    = G.C1 ('G.MetaCons "S" 'G.PrefixI 'False) (G.S1 DFMetaSel (G.Rec0 t))+  SingleFrameRep t (d ': ds)+    = G.C1 ('G.MetaCons (AppendSymbol "DF" (ShowNat d)) 'G.PrefixI 'False) (DFTree t ds d)++instance (PrimBytes t, Dimensions ds)+      => G.Generic (DataFrame (t :: Type) (ds :: [Nat])) where+    type Rep (DataFrame t ds) = G.D1+          ('G.MetaData "DataFrame" "Numeric.DataFrame.Type" "easytensor" 'False)+          ( SingleFrameRep t ds )+    from = G.M1 . fromSingleFrame (dims @ds)+    to (G.M1 rep) = toSingleFrame (dims @ds) rep++fromSingleFrame :: forall (t :: Type) (ds :: [Nat]) (x :: Type)+                 . PrimBytes t+                => Dims ds+                -> DataFrame t ds+                -> SingleFrameRep t ds x+fromSingleFrame U (S x) = G.M1 . G.M1 $ G.K1 x+fromSingleFrame (dd@D :* (Dims :: Dims ds')) x+  | Dict <- inferKnownBackend @t @ds+  , Dict <- inferKnownBackend @t @ds'+    = G.M1 $ case arrayContent# x of+      (# e | #) -> fillRep @_ @ds' (const $ broadcast e) 0 dd+      (# | (# cdims, off, arr #) #)+       | cd <- CumulDims . tail $ unCumulDims cdims+       , td <- cdTotalDim# cd+                -> fillRep @_ @ds'+                   (\(W# i) -> fromElems cd (off +# td *# word2Int# i) arr) 0 dd+  where+    fillRep :: forall (n :: Nat) (ns :: [Nat])+             . (Word -> DataFrame t ns)+            -> Word+            -> Dim n+            -> DFTree t ns n x+    fillRep _ _ D0 = G.U1+    fillRep f i D1 = G.M1 . G.K1 $ f i+    fillRep f i d+        | Dict <- unsafeEqTypes @(Type -> Type)+            @(DFTree t ns n)+            @(DFTree t ns (Div n 2) G.:*: DFTree t ns (Div n 2 + Mod n 2))+          = fillRep f i d2 G.:*: fillRep f (i + dimVal d2) d2'+      where+        d2  = divDim d D2+        d2' = d2 `plusDim` modDim d D2++toSingleFrame :: forall (t :: Type) (ds :: [Nat]) (x :: Type)+               . PrimBytes t+              => Dims ds+              -> SingleFrameRep t ds x+              -> DataFrame t ds+toSingleFrame U (G.M1 (G.M1 (G.K1 x))) = S x+toSingleFrame (dd@D :* (Dims :: Dims ds')) (G.M1 rep)+  | Dict  <- inferKnownBackend @t @ds+  , Dict  <- inferKnownBackend @t @ds'+  , els   <- case dimVal dd of W# w -> word2Int# w+  , asize <- byteSize @(DataFrame t ds') undefined+    = runRW#+    ( \s0 -> case newByteArray# (asize *# els) s0 of+       (# s1, mba #)+         | s2 <- fillDF @_ @ds'+                  (\(W# i) df -> writeBytes mba (asize *# word2Int# i) df)+                  0 dd rep s1+         , (# _, ba #) <- unsafeFreezeByteArray# mba s2+           -> fromBytes 0# ba+    )+  where+    fillDF :: forall (n :: Nat) (ns :: [Nat]) s+            . (Word -> DataFrame t ns -> State# s -> State# s)+           -> Word+           -> Dim n+           -> DFTree t ns n x+           -> State# s -> State# s+    fillDF _ _ D0 _ s               = s+    fillDF f i D1 (G.M1 (G.K1 e)) s = f i e s+    fillDF f i d    xy             s+      | Dict <- unsafeEqTypes @(Type -> Type)+          @(DFTree t ns n)+          @(DFTree t ns (Div n 2) G.:*: DFTree t ns (Div n 2 + Mod n 2))+      , x G.:*: y <- xy+        = fillDF f (i + dimVal d2) d2' y (fillDF f i d2 x s)+      where+        d2  = divDim d D2+        d2' = d2 `plusDim` modDim d D2+++type family MultiFrameRepNil (ts :: [Type]) :: (Type -> Type) where+    MultiFrameRepNil '[]      = G.C1 ('G.MetaCons "Z" 'G.PrefixI 'False) G.U1+    MultiFrameRepNil (_ ': _) = G.Rec0 Void++type family MultiFrameRepCons (ts :: [Type]) (ds :: [Nat]) :: (Type -> Type) where+    MultiFrameRepCons '[]       _  = G.Rec0 Void+    MultiFrameRepCons (t ': ts) ds = G.C1+      ('G.MetaCons ":*:" ('G.InfixI 'G.RightAssociative 6) 'False)+      ( G.S1 DFMetaSel+           (G.Rec0 (DataFrame t ds))+       G.:*:+        G.S1 DFMetaSel+           (G.Rec0 (DataFrame ts ds))+      )++instance G.Generic (DataFrame (ts :: [Type]) (ds :: [Nat])) where+    type Rep (DataFrame ts ds) = G.D1+          ('G.MetaData "DataFrame" "Numeric.DataFrame.Type" "easytensor" 'False)+          ( MultiFrameRepNil ts G.:+: MultiFrameRepCons ts ds )+    from  Z         = G.M1 (G.L1 (G.M1 G.U1))+    from (x :*: xs) = G.M1 (G.R1 (G.M1 (G.M1 (G.K1 x) G.:*: G.M1 (G.K1 xs))))+    to (G.M1 (G.L1 _))+      | Dict <- unsafeEqTypes @[Type] @ts @'[] = Z+    to (G.M1 (G.R1 xxs))+      | Dict <- unsafeEqTypes @[Type] @ts @(Head ts ': Tail ts)+      , G.M1 (G.M1 (G.K1 x) G.:*: G.M1 (G.K1 xs)) <- xxs = x :*: xs++++unsafeEqTypes :: forall k (a :: k) (b :: k) . Dict (a ~ b)+unsafeEqTypes = unsafeCoerce# (Dict :: Dict (a ~ a))
src/Numeric/Matrix.hs view
@@ -1,32 +1,3 @@-{-# LANGUAGE BangPatterns              #-}-{-# LANGUAGE CPP                       #-}-{-# LANGUAGE DataKinds                 #-}-{-# LANGUAGE ExistentialQuantification #-}-{-# LANGUAGE FlexibleContexts          #-}-{-# LANGUAGE FlexibleInstances         #-}-{-# LANGUAGE KindSignatures            #-}-{-# LANGUAGE MagicHash                 #-}-{-# LANGUAGE MultiParamTypeClasses     #-}-{-# LANGUAGE PolyKinds                 #-}-{-# LANGUAGE RecordWildCards           #-}-{-# LANGUAGE ScopedTypeVariables       #-}-{-# LANGUAGE TypeApplications          #-}-{-# LANGUAGE TypeFamilies              #-}-{-# LANGUAGE UnboxedSums               #-}-{-# LANGUAGE UnboxedTuples             #-}-{-# LANGUAGE UndecidableInstances      #-}-{-# OPTIONS_GHC -fno-warn-orphans  #-}--------------------------------------------------------------------------------- |--- Module      :  Numeric.Matrix--- Copyright   :  (c) Artem Chirkin--- License     :  BSD3------ Maintainer  :  chirkin@arch.ethz.ch------------------------------------------------------------------------------------- module Numeric.Matrix   ( MatrixTranspose (..)   , SquareMatrix (..)@@ -46,300 +17,7 @@   , pivotMat, luSolve   ) where --import           Control.Monad                           (foldM)-import           Data.Foldable                           (forM_, foldl')-import           Data.List                               (delete)-import           GHC.Base-import           Numeric.DataFrame.Contraction           ((%*))-import           Numeric.DataFrame.Internal.Array.Class-import           Numeric.DataFrame.Internal.Array.Family as AFam-import           Numeric.DataFrame.Shape-import           Numeric.DataFrame.SubSpace-import           Numeric.DataFrame.Type-import           Numeric.Dimensions-import           Numeric.Matrix.Class-import           Numeric.Matrix.Mat44d ()-import           Numeric.Matrix.Mat44f ()-import           Numeric.PrimBytes-import           Numeric.Scalar-import           Numeric.Vector--import           Control.Monad.ST-import           Numeric.DataFrame.ST------ | Compose a 2x2D matrix-mat22 :: ( PrimBytes (Vector (t :: Type) 2)-         , PrimBytes (Matrix t 2 2)-         )-      => Vector t 2 -> Vector t 2 -> Matrix t 2 2-mat22 = (<::>)---- | Compose a 3x3D matrix-mat33 :: ( PrimBytes (t :: Type)-         , PrimBytes (Vector t 3)-         , PrimBytes (Matrix t 3 3)-         )-      => Vector t 3 -> Vector t 3 -> Vector t 3 -> Matrix t 3 3-mat33 a b c = runST $ do-  mmat <- newDataFrame-  copyDataFrame a (1:*1:*U) mmat-  copyDataFrame b (1:*2:*U) mmat-  copyDataFrame c (1:*3:*U) mmat-  unsafeFreezeDataFrame mmat---- | Compose a 4x4D matrix-mat44 :: forall (t :: Type)-       . ( PrimBytes t-         , PrimBytes (Vector t (4 :: Nat))-         , PrimBytes (Matrix t (4 :: Nat) (4 :: Nat))-         )-      => Vector t (4 :: Nat)-      -> Vector t (4 :: Nat)-      -> Vector t (4 :: Nat)-      -> Vector t (4 :: Nat)-      -> Matrix t (4 :: Nat) (4 :: Nat)-mat44 a b c d = runST $ do-  mmat <- newDataFrame-  copyDataFrame a (1:*1:*U) mmat-  copyDataFrame b (1:*2:*U) mmat-  copyDataFrame c (1:*3:*U) mmat-  copyDataFrame d (1:*4:*U) mmat-  unsafeFreezeDataFrame mmat----instance ( KnownDim n, KnownDim m-         , PrimArray t (Matrix t n m)-         , PrimArray t (Matrix t m n)-         ) => MatrixTranspose t (n :: Nat) (m :: Nat) where-    transpose df = case elemSize0 df of-      0# -> broadcast (ix# 0# df)-      nm | I# m <- fromIntegral $ dimVal' @m-         , I# n <- fromIntegral $ dimVal' @n-         -> let f ( I# j,  I# i )-                  | isTrue# (j ==# m) = f ( 0 , I# (i +# 1#) )-                  | otherwise         = (# ( I# (j +# 1#), I# i )-                                         , ix# (j *# n +# i) df-                                         #)-            in case gen# nm f (0,0) of-              (# _, r #) -> r--instance MatrixTranspose (t :: Type) (xn :: XNat) (xm :: XNat) where-    transpose (XFrame (df :: DataFrame t ns))-      | ((D :: Dim n) :* (D :: Dim m) :* U) <- dims @Nat @ns-      , E <- AFam.inferPrimElem @t @n @'[m]-      = XFrame (transpose df :: Matrix t m n)-    transpose _ = error "MatrixTranspose/transpose: impossible argument"--instance (KnownDim n, PrimArray t (Matrix t n n), Num t)-      => SquareMatrix t n where-    eye-      | n@(I# n#) <- fromIntegral $ dimVal' @n-      = let f 0 = (# n, 1 #)-            f k = (# k - 1, 0 #)-        in case gen# (n# *# n#) f 0 of-            (# _, r #) -> r-    diag se-      | n@(I# n#) <- fromIntegral $ dimVal' @n-      , e <- unScalar se-      = let f 0 = (# n, e #)-            f k = (# k - 1, 0 #)-        in case gen# (n# *# n#) f 0 of-            (# _, r #) -> r-    trace df-      | I# n <- fromIntegral $ dimVal' @n-      , n1 <- n +# 1#-      = let f 0# = ix# 0# df-            f k  = ix# k  df + f (k -# n1)-        in scalar $ f (n *# n -# 1#)---instance ( KnownDim n, Ord t, Fractional t-         , PrimBytes t-         , PrimArray t (Matrix t n n)-         , PrimArray t (Vector t n)-         , PrimBytes (Vector t n)-         , PrimBytes (Matrix t n n)-         )-         => MatrixInverse t n where-  inverse m = ewmap (luSolve (lu m)) eye---instance ( KnownDim n, Ord t, Fractional t-         , PrimBytes t, PrimArray t (Matrix t n n))-         => MatrixDeterminant t n where-  det m = prodF (luUpper f) * prodF (luLower f) * luPermSign f-    where-      f = lu m-      !(I# n) = fromIntegral $ dimVal' @n-      n1 = n +# 1#-      nn1 = n *# n -# 1#-      prodF a = scalar $ prodF' nn1 a-      prodF' 0# a = ix# 0# a-      prodF' k  a = ix# k a * prodF' (k -# n1) a---instance ( KnownDim n, Ord t, Fractional t-         , PrimBytes t, PrimArray t (Matrix t n n))-         => MatrixLU t n where-    lu m' = case runRW# go of-        (# _, (# bu, bl #) #) -> LUFact-            { luLower    = fromElems 0# nn bl-            , luUpper    = fromElems 0# nn bu-            , luPerm     = p-            , luPermSign = si-            }-      where-        (m, p, si) = pivotMat m'-        !(I# n) = fromIntegral $ dimVal' @n-        nn = n *# n-        tbs = byteSize @t undefined-        bsize = nn *# tbs-        ixm i j = ix# (i +# n *# j) m-        loop :: (Int# -> a -> State# s -> (# State# s, a #))-             -> Int# -> Int# -> a -> State# s -> (# State# s, a #)-        loop f i k x s-          | isTrue# (i ==# k) = (# s, x #)-          | otherwise = case f i x s of-              (# s', y #) -> loop f ( i +# 1# ) k y s'-        go s0-          | (# s1, mbl #) <- newByteArray# bsize s0-          , (# s2, mbu #) <- newByteArray# bsize s1-          , s3 <- setByteArray# mbl 0# bsize 0# s2-          , s4 <- setByteArray# mbu 0# bsize 0# s3-          , readL <- \i j -> readArray @t mbl (i +# n *# j)-          , readU <- \i j -> readArray @t mbu (i +# n *# j)-          , writeL <- \i j -> writeArray @t mbl (i +# n *# j)-          , writeU <- \i j -> writeArray @t mbu (i +# n *# j)-          , computeU <- \i j ->-              let f k x s-                    | (# s' , ukj #) <- readU k j s-                    , (# s'', lik #) <- readL i k s'-                    = (# s'', x - ukj * lik #)-              in loop f 0# i (ixm i j)-          , computeL' <- \i j ->-              let f k x s-                    | (# s' , ukj #) <- readU k j s-                    , (# s'', lik #) <- readL i k s'-                    = (# s'', x - ukj * lik #)-              in loop f 0# j (ixm i j)-          , (# sr, () #) <--              loop-                ( \j _ sj -> case sj of-                    sj0-                      | sj1 <- writeL j j 1 sj0-                      , (# sj2, () #) <- loop-                          ( \i _ sij0 -> case computeU i j sij0 of-                               (# sij1, uij #) -> (# writeU i j uij sij1, () #)-                          ) 0# j () sj1-                      , (# sj3, ujj #) <- computeU j j sj2-                      , sj4 <- writeU j j ujj sj3-                        -> case ujj of-                          0 -> loop-                            ( \i _ sij -> (# writeL i j 0 sij, () #)-                            ) (j +# 1#) n () sj4-                          x -> loop-                            ( \i _ sij0 -> case computeL' i j sij0 of-                                (# sij1, lij #) -> (# writeL i j (lij / x) sij1, () #)-                            ) (j +# 1#) n () sj4-                ) 0# n () s4-          , (# sf0, bl #) <- unsafeFreezeByteArray# mbl sr-          , (# sf1, bu #) <- unsafeFreezeByteArray# mbu sf0-          = (# sf1, (# bu, bl #) #)----- | Solve @Ax = b@ problem given LU decomposition of A.-luSolve :: forall (t :: Type) (n :: Nat)-         . ( KnownDim n, Ord t, Fractional t-           , PrimBytes t, PrimArray t (Matrix t n n), PrimArray t (Vector t n))-        => LUFact t n -> Vector t n -> Vector t n-luSolve LUFact {..} b = x-  where-    -- Pb = LUx-    pb = luPerm %* b-    !n@(I# n#) = fromIntegral $ dimVal' @n-    -- Ly = Pb-    y :: Vector t n-    y = runST $ do-      my <- newDataFrame-      let ixA (I# i) (I# j) = scalar $ ix# (i +# n# *# j) luLower-          ixB (I# i) = scalar $ ix# i pb-      forM_ [0..n-1] $ \i -> do-        v <- foldM ( \v j -> do-                      dj <- readDataFrameOff my j-                      return $ v - dj * ixA i j-                   ) (ixB i) [0..i-1]-        writeDataFrameOff my i v-      unsafeFreezeDataFrame my-    -- Ux = y-    x = runST $ do-      mx <- newDataFrame-      let ixA (I# i) (I# j) = scalar $ ix# (i +# n# *# j) luUpper-          ixB (I# i) = scalar $ ix# i y-      forM_ [n-1, n-2 .. 0] $ \i -> do-        v <- foldM ( \v j -> do-                      dj <- readDataFrameOff mx j-                      return $ v - dj * ixA i j-                   ) (ixB i) [i+1..n-1]-        writeDataFrameOff mx i (v / ixA i i)-      unsafeFreezeDataFrame mx----- | 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 :: k)-          . (KnownDim n, PrimArray t (Matrix t n n), Ord t, Num t)-         => Matrix t n n -> ( Matrix t n n -- permutated matrix-                            , Matrix t n n -- permutation matrix-                            , Scalar t -- sign of permutation matrix-                            )-pivotMat m-    = ( let f ( j, [] )   = f (j+1, rowOrder)-            f ( j, i:is ) = (# (j, is), ix i j #)-        in case gen# nn f (0,rowOrder) of-            (# _, r #) -> r-      , let f ( j, [] ) = f (j+1, rowOrder)-            f ( j, x:xs )-               | j == x    = (# ( j, xs), 1 #)-               | otherwise = (# ( j, xs), 0 #)-        in case gen# nn f (0,rowOrder) of-            (# _, r #) -> r-      , if countMisordered rowOrder `rem` 2 == 1-        then -1 else 1-      )-  where-    -- permuted row ordering-    rowOrder = uncurry fillPass $ searchPass 0 [0..n-1]-    -- matrix size-    !n@(I# n#) = fromIntegral $ dimVal' @n-    -- sign of permutations-    countMisordered :: [Int] -> Int-    countMisordered [] = 0-    countMisordered (i:is) = foldl' (\c j -> if i > j then succ c else c) 0 is-                           + countMisordered is-    nn = n# *# n#-    ix (I# i) (I# j) = ix# (i +# j *# n#) m-    findMax :: Int -> [Int] -> (t, Int)-    findMax j = foldl' (\(ox, oi) i -> let x = abs (ix i j)-                                       in if x > ox then (x, i)-                                                    else (ox, oi)-                      ) (0, 0)-    -- search maximums, leaving Nothing where all rows are 0-    searchPass :: Int -> [Int] -> ([Int], [Maybe Int])-    searchPass j is-      | j == n    = (is, [])-      | otherwise = case findMax j is of-          (0, _) -> (Nothing:) <$> searchPass (j+1) is-          (_, i) -> (Just i:) <$> searchPass (j+1) (delete i is)-    -- replace Nothings with remaining row numbers-    fillPass :: [Int] -> [Maybe Int] -> [Int]-    fillPass _ []                  = []-    fillPass js (Just i : is)      = i : fillPass js is-    fillPass (j:js) (Nothing : is) = j : fillPass js is-    fillPass [] (Nothing : is)     = 0 : fillPass [] is+import Numeric.DataFrame.Internal.Backend ()+import Numeric.Matrix.Internal+import Numeric.Matrix.Internal.Mat44d     ()+import Numeric.Matrix.Internal.Mat44f     ()
− src/Numeric/Matrix/Class.hs
@@ -1,151 +0,0 @@-{-# LANGUAGE DataKinds             #-}-{-# LANGUAGE FlexibleContexts      #-}-{-# LANGUAGE KindSignatures        #-}-{-# LANGUAGE MultiParamTypeClasses #-}-{-# LANGUAGE PolyKinds             #-}-{-# LANGUAGE StandaloneDeriving    #-}-{-# LANGUAGE TypeFamilies          #-}-{-# LANGUAGE UndecidableInstances  #-}-module Numeric.Matrix.Class-  ( MatrixTranspose (..)-  , SquareMatrix (..)-  , MatrixDeterminant (..)-  , MatrixInverse (..)-  , MatrixLU (..), LUFact (..)-  , Matrix-  , HomTransform4 (..)-  , Mat22f, Mat23f, Mat24f-  , Mat32f, Mat33f, Mat34f-  , Mat42f, Mat43f, Mat44f-  , Mat22d, Mat23d, Mat24d-  , Mat32d, Mat33d, Mat34d-  , Mat42d, Mat43d, Mat44d-  ) where--import           Numeric.DataFrame.Family-import           Numeric.Dimensions       (Nat)-import           Numeric.Scalar-import           Numeric.Vector---- | Alias for DataFrames of rank 2-type Matrix (t :: l) (n :: k) (m :: k) = DataFrame t '[n,m]--class MatrixTranspose t (n :: k) (m :: k) where-    -- | Transpose Mat-    transpose :: Matrix t n m -> Matrix t m n-  -- (MatrixTranspose t m n, PrimBytes (Matrix t m n)) =>--class SquareMatrix t (n :: Nat) where-    -- | Mat with 1 on diagonal and 0 elsewhere-    eye :: Matrix t n n-    -- | Put the same value on the Mat diagonal, 0 otherwise-    diag :: Scalar t -> Matrix t n n-    -- | Sum of diagonal elements-    trace :: Matrix t n n -> Scalar t--class MatrixDeterminant t (n :: Nat) where-    -- | Determinant of  Mat-    det :: Matrix t n n -> Scalar t--class MatrixInverse t (n :: Nat) where-    -- | Matrix inverse-    inverse :: Matrix t n n -> Matrix t n n----- | Result of LU factorization with Partial Pivoting---   @ PA = LU @.-data LUFact t n-  = LUFact-  { luLower    :: Matrix t n n-    -- ^ Lower triangular matrix @L@.-    --   All elements on the diagonal of @L@ equal @1@.-  , luUpper    :: Matrix t n n-    -- ^ Upper triangular matrix @U@-  , luPerm     :: Matrix t n n-    -- ^ Row permutation matrix @P@-  , luPermSign :: Scalar t-    -- ^ Sign of permutation @luPermSign == det . luPerm@-  }--deriving instance (Show (Matrix t n n), Show t) => Show (LUFact t n)-deriving instance (Eq (Matrix t n n), Eq t) => Eq (LUFact t n)--class MatrixLU t (n :: Nat) where-    -- | Compute LU factorization with Partial Pivoting-    lu :: Matrix t n n -> LUFact t n----- | Operations on 4x4 transformation matrices and vectors in homogeneous coordinates.---   All angles are specified in radians.-class HomTransform4 t where-    -- | Create a translation matrix from a vector.  The 4th coordinate is ignored.-    translate4  :: Vector t 4 -> Matrix t 4 4-    -- | Create a translation matrix from a vector.-    translate3  :: Vector t 3 -> Matrix t 4 4-    -- | Rotation matrix for a rotation around the X axis, angle is given in radians.-    rotateX     :: t -> Matrix t 4 4-    -- | Rotation matrix for a rotation around the Y axis, angle is given in radians.-    rotateY     :: t -> Matrix t 4 4-    -- | Rotation matrix for a rotation around the Z axis, angle is given in radians.-    rotateZ     :: t -> Matrix t 4 4-    -- | Rotation matrix for a rotation around an arbitrary normalized vector-    rotate      :: 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 == rotateX pitch %* rotateY yaw %* rotateZ roll-    ---    --   https://en.wikipedia.org/wiki/Euler_angles#Conventions_2-    rotateEuler :: t -- ^ pitch (axis @X''@)-                -> t -- ^ yaw (axis @Y'@)-                -> t -- ^ roll (axis @Z@)-                -> 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      :: Vector t 3 -- ^ The up direction, not necessary unit length or perpendicular to the view vector-                -> Vector t 3 -- ^ The viewers position-                -> Vector t 3 -- ^ The point to look at-                -> 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 :: t -- ^ Near plane clipping distance (always positive)-                -> t -- ^ Far plane clipping distance (always positive)-                -> t -- ^ Field of view of the y axis, in radians-                -> t -- ^ Aspect ratio, i.e. screen's width\/height-                -> 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  :: t -- ^ Near plane clipping distance-                -> t -- ^ Far plane clipping distance-                -> t -- ^ width-                -> t -- ^ height-                -> Matrix t 4 4-    -- | Add one more dimension and set it to 1.-    toHomPoint  :: Vector t 3 -> Vector t 4-    -- | Add one more dimension and set it to 0.-    toHomVector :: 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     :: Vector t 4 -> Vector t 3---- Type abbreviations--type Mat22f = Matrix Float 2 2-type Mat32f = Matrix Float 3 2-type Mat42f = Matrix Float 4 2-type Mat23f = Matrix Float 2 3-type Mat33f = Matrix Float 3 3-type Mat43f = Matrix Float 4 3-type Mat24f = Matrix Float 2 4-type Mat34f = Matrix Float 3 4-type Mat44f = Matrix Float 4 4--type Mat22d = Matrix Double 2 2-type Mat32d = Matrix Double 3 2-type Mat42d = Matrix Double 4 2-type Mat23d = Matrix Double 2 3-type Mat33d = Matrix Double 3 3-type Mat43d = Matrix Double 4 3-type Mat24d = Matrix Double 2 4-type Mat34d = Matrix Double 3 4-type Mat44d = Matrix Double 4 4
+ src/Numeric/Matrix/Internal.hs view
@@ -0,0 +1,473 @@+{-# LANGUAGE DataKinds             #-}+{-# LANGUAGE FlexibleContexts      #-}+{-# LANGUAGE FlexibleInstances     #-}+{-# LANGUAGE MagicHash             #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE PolyKinds             #-}+{-# LANGUAGE RecordWildCards       #-}+{-# LANGUAGE ScopedTypeVariables   #-}+{-# LANGUAGE StandaloneDeriving    #-}+{-# LANGUAGE TypeApplications      #-}+{-# LANGUAGE TypeFamilies          #-}+{-# LANGUAGE TypeOperators         #-}+{-# LANGUAGE UnboxedTuples         #-}+{-# LANGUAGE UndecidableInstances  #-}+module Numeric.Matrix.Internal+  ( MatrixTranspose (..)+  , SquareMatrix (..)+  , MatrixDeterminant (..)+  , MatrixInverse (..)+  , MatrixLU (..), LUFact (..)+  , Matrix+  , HomTransform4 (..)+  , Mat22f, Mat23f, Mat24f+  , Mat32f, Mat33f, Mat34f+  , Mat42f, Mat43f, Mat44f+  , Mat22d, Mat23d, Mat24d+  , Mat32d, Mat33d, Mat34d+  , Mat42d, Mat43d, Mat44d+  , mat22, mat33, mat44+  , (%*)+  , pivotMat, luSolve+  ) where++import Control.Monad                        (foldM)+import Control.Monad.ST+import Data.Foldable                        (foldl', forM_)+import Data.List                            (delete)+import GHC.Base+import Numeric.DataFrame.Contraction        ((%*))+import Numeric.DataFrame.Internal.PrimArray+import Numeric.DataFrame.ST+import Numeric.DataFrame.SubSpace+import Numeric.DataFrame.Type+import Numeric.Dimensions+import Numeric.PrimBytes+import Numeric.Scalar.Internal+import Numeric.Vector.Internal++-- | Alias for DataFrames of rank 2+type Matrix (t :: l) (n :: k) (m :: k) = DataFrame t '[n,m]++class MatrixTranspose t (n :: k) (m :: k) where+    -- | Transpose Mat+    transpose :: Matrix t n m -> Matrix t m n++class SquareMatrix t (n :: Nat) where+    -- | Mat with 1 on diagonal and 0 elsewhere+    eye :: Matrix t n n+    -- | Put the same value on the Mat diagonal, 0 otherwise+    diag :: Scalar t -> Matrix t n n+    -- | Sum of diagonal elements+    trace :: Matrix t n n -> Scalar t++class MatrixDeterminant t (n :: Nat) where+    -- | Determinant of  Mat+    det :: Matrix t n n -> Scalar t++class MatrixInverse t (n :: Nat) where+    -- | Matrix inverse+    inverse :: Matrix t n n -> Matrix t n n+++-- | Result of LU factorization with Partial Pivoting+--   @ PA = LU @.+data LUFact t n+  = LUFact+  { luLower    :: Matrix t n n+    -- ^ Lower triangular matrix @L@.+    --   All elements on the diagonal of @L@ equal @1@.+  , luUpper    :: Matrix t n n+    -- ^ Upper triangular matrix @U@+  , luPerm     :: Matrix t n n+    -- ^ Row permutation matrix @P@+  , luPermSign :: Scalar t+    -- ^ Sign of permutation @luPermSign == det . luPerm@+  }++deriving instance (Show t, PrimBytes t, KnownDim n) => Show (LUFact t n)+deriving instance (Eq (Matrix t n n), Eq t) => Eq (LUFact t n)++class MatrixLU t (n :: Nat) where+    -- | Compute LU factorization with Partial Pivoting+    lu :: Matrix t n n -> LUFact t n+++-- | 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 where+    -- | 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  :: 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  :: 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     :: 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     :: 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     :: 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      :: 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 :: t -- ^ pitch (axis @X''@)+                -> t -- ^ yaw (axis @Y'@)+                -> t -- ^ roll (axis @Z@)+                -> 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      :: Vector t 3 -- ^ The up direction, not necessary unit length or perpendicular to the view vector+                -> Vector t 3 -- ^ The viewers position+                -> Vector t 3 -- ^ The point to look at+                -> 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 :: t -- ^ Near plane clipping distance (always positive)+                -> t -- ^ Far plane clipping distance (always positive)+                -> t -- ^ Field of view of the y axis, in radians+                -> t -- ^ Aspect ratio, i.e. screen's width\/height+                -> 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  :: t -- ^ Near plane clipping distance+                -> t -- ^ Far plane clipping distance+                -> t -- ^ width+                -> t -- ^ height+                -> Matrix t 4 4+    -- | Add one more dimension and set it to 1.+    toHomPoint  :: Vector t 3 -> Vector t 4+    -- | Add one more dimension and set it to 0.+    toHomVector :: 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     :: Vector t 4 -> Vector t 3++-- Type abbreviations++type Mat22f = Matrix Float 2 2+type Mat32f = Matrix Float 3 2+type Mat42f = Matrix Float 4 2+type Mat23f = Matrix Float 2 3+type Mat33f = Matrix Float 3 3+type Mat43f = Matrix Float 4 3+type Mat24f = Matrix Float 2 4+type Mat34f = Matrix Float 3 4+type Mat44f = Matrix Float 4 4++type Mat22d = Matrix Double 2 2+type Mat32d = Matrix Double 3 2+type Mat42d = Matrix Double 4 2+type Mat23d = Matrix Double 2 3+type Mat33d = Matrix Double 3 3+type Mat43d = Matrix Double 4 3+type Mat24d = Matrix Double 2 4+type Mat34d = Matrix Double 3 4+type Mat44d = Matrix Double 4 4+++-- | Compose a 2x2D matrix+mat22 :: PrimBytes (t :: Type)+      => Vector t 2 -> Vector t 2 -> Matrix t 2 2+mat22 = packDF @_ @2 @'[2]+{-# INLINE mat22 #-}++-- | Compose a 3x3D matrix+mat33 :: PrimBytes (t :: Type)+      => Vector t 3 -> Vector t 3 -> Vector t 3 -> Matrix t 3 3+mat33 = packDF @_ @3 @'[3]+{-# INLINE mat33 #-}++-- | Compose a 4x4D matrix+mat44 :: PrimBytes (t :: Type)+      => Vector t 4+      -> Vector t 4+      -> Vector t 4+      -> Vector t 4+      -> Matrix t 4 4+mat44 = packDF @_ @4 @'[4]+{-# INLINE mat44 #-}++++instance ( KnownDim n, KnownDim m+         , PrimArray t (Matrix t n m)+         , PrimArray t (Matrix t m n)+         ) => MatrixTranspose t (n :: Nat) (m :: Nat) where+    transpose df = case uniqueOrCumulDims df of+      Left a -> broadcast a+      Right _+         | wm <- dimVal' @m+         , wn <- dimVal' @n+         , m <- case wm of W# w -> word2Int# w+         , n <- case wn of W# w -> word2Int# w+         -> let f ( I# i,  I# j )+                  | isTrue# (i ==# n) = f ( 0, I# (j +# 1#) )+                  | otherwise         = (# ( I# (i +# 1#), I# j )+                                         , ix# (i *# m +# j) df+                                         #)+            in case gen# (CumulDims [wm*wn, wn, 1]) f (0,0) of (# _, r #) -> r++instance MatrixTranspose (t :: Type) (xn :: XNat) (xm :: XNat) where+    transpose (XFrame (df :: DataFrame t ns))+      | ((D :: Dim n) :* (D :: Dim m) :* U) <- dims @ns+      , Dict <- inferPrimElem df+      = XFrame (transpose df :: Matrix t m n)+    transpose _ = error "MatrixTranspose/transpose: impossible argument"++instance (KnownDim n, PrimArray t (Matrix t n n), Num t)+      => SquareMatrix t n where+    eye+      | n <- dimVal' @n+      = let f 0 = (# n    , 1 #)+            f k = (# k - 1, 0 #)+        in case gen# (CumulDims [n*n, n, 1]) f 0 of+            (# _, r #) -> r+    diag se+      | n <- dimVal' @n+      , e <- unScalar se+      = let f 0 = (# n    , e #)+            f k = (# k - 1, 0 #)+        in case gen# (CumulDims [n*n, n, 1]) f 0 of+            (# _, r #) -> r+    trace df+      | I# n <- fromIntegral $ dimVal' @n+      , n1 <- n +# 1#+      = let f 0# = ix# 0# df+            f k  = ix# k  df + f (k -# n1)+        in scalar $ f (n *# n -# 1#)+++instance ( KnownDim n, Ord t, Fractional t+         , PrimBytes t+         , PrimArray t (Matrix t n n)+         , PrimArray t (Vector t n)+         , PrimBytes (Vector t n)+         , PrimBytes (Matrix t n n)+         )+         => MatrixInverse t n where+  inverse m = runST $ do+      m' <- newDataFrame+      indexWise_ @t @'[n] @'[n] @'[n, n] @_ @()+        (\is ->+          indexWise_ @t @'[n] @'[] @'[n] @_ @()+            (\(j:*U) -> writeDataFrame m' (j:*is)) . luSolve luM+        ) eye+      unsafeFreezeDataFrame m'+    where+      luM = lu m++    -- much nicer, but probably slower version:+    --   (it is not particularly fast to do an extra transpose+    --       before calculating the inverse)+    -- ewmap (luSolve . lu $ transpose m) eye++++instance ( KnownDim n, Ord t, Fractional t+         , PrimBytes t, PrimArray t (Matrix t n n))+         => MatrixDeterminant t n where+  det m = prodF (luUpper f) * prodF (luLower f) * luPermSign f+    where+      f = lu m+      n = case dimVal' @n of W# w -> word2Int# w+      n1 = n +# 1#+      nn1 = n *# n -# 1#+      prodF a = scalar $ prodF' nn1 a+      prodF' 0# a = ix# 0# a+      prodF' k  a = ix# k a * prodF' (k -# n1) a+++instance ( KnownDim n, Ord t, Fractional t+         , PrimBytes t, PrimArray t (Matrix t n n))+         => MatrixLU t n where+    lu m' = case runRW# go of+        (# _, (# bu, bl #) #) -> LUFact+            { luLower    = fromElems steps 0# bl+            , luUpper    = fromElems steps 0# bu+            , luPerm     = p+            , luPermSign = si+            }+      where+        dn = dimVal' @n+        dnn = dn * dn+        steps = CumulDims [dnn, dn, 1]+        (m, p, si) = pivotMat m'+        n  = case dn of W# w -> word2Int# w+        nn = case dnn of W# w -> word2Int# w+        tbs = byteSize @t undefined+        bsize = nn *# tbs+        ixm i j = ix# (i *# n +# j) m+        loop :: (Int# -> a -> State# s -> (# State# s, a #))+             -> Int# -> Int# -> a -> State# s -> (# State# s, a #)+        loop f i k x s+          | isTrue# (i ==# k) = (# s, x #)+          | otherwise = case f i x s of+              (# s', y #) -> loop f ( i +# 1# ) k y s'+        go s0+          | (# s1, mbl #) <- newByteArray# bsize s0+          , (# s2, mbu #) <- newByteArray# bsize s1+          , s3 <- setByteArray# mbl 0# bsize 0# s2+          , s4 <- setByteArray# mbu 0# bsize 0# s3+          , readL <- \i j -> readArray @t mbl (i *# n +# j)+          , readU <- \i j -> readArray @t mbu (i *# n +# j)+          , writeL <- \i j -> writeArray @t mbl (i *# n +# j)+          , writeU <- \i j -> writeArray @t mbu (i *# n +# j)+          , computeU <- \i j ->+              let f k x s+                    | (# s' , ukj #) <- readU k j s+                    , (# s'', lik #) <- readL i k s'+                    = (# s'', x - ukj * lik #)+              in loop f 0# i (ixm i j)+          , computeL' <- \i j ->+              let f k x s+                    | (# s' , ukj #) <- readU k j s+                    , (# s'', lik #) <- readL i k s'+                    = (# s'', x - ukj * lik #)+              in loop f 0# j (ixm i j)+          , (# sr, () #) <-+              loop+                ( \j _ sj -> case sj of+                    sj0+                      | sj1 <- writeL j j 1 sj0+                      , (# sj2, () #) <- loop+                          ( \i _ sij0 -> case computeU i j sij0 of+                               (# sij1, uij #) -> (# writeU i j uij sij1, () #)+                          ) 0# j () sj1+                      , (# sj3, ujj #) <- computeU j j sj2+                      , sj4 <- writeU j j ujj sj3+                        -> case ujj of+                          0 -> loop+                            ( \i _ sij -> (# writeL i j 0 sij, () #)+                            ) (j +# 1#) n () sj4+                          x -> loop+                            ( \i _ sij0 -> case computeL' i j sij0 of+                                (# sij1, lij #) -> (# writeL i j (lij / x) sij1, () #)+                            ) (j +# 1#) n () sj4+                ) 0# n () s4+          , (# sf0, bl #) <- unsafeFreezeByteArray# mbl sr+          , (# sf1, bu #) <- unsafeFreezeByteArray# mbu sf0+          = (# sf1, (# bu, bl #) #)+++-- | 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+luSolve LUFact {..} b = x+  where+    -- Pb = LUx+    pb = luPerm %* b+    n# = case dimVal' @n of W# w -> word2Int# w+    n = I# n#+    -- Ly = Pb+    y :: Vector t n+    y = runST $ do+      my <- newDataFrame+      let ixA (I# i) (I# j) = scalar $ ix# (i *# n# +# j) luLower+          ixB (I# i) = scalar $ ix# i pb+      forM_ [0..n-1] $ \i -> do+        v <- foldM ( \v j -> do+                      dj <- readDataFrameOff my j+                      return $ v - dj * ixA i j+                   ) (ixB i) [0..i-1]+        writeDataFrameOff my i v+      unsafeFreezeDataFrame my+    -- Ux = y+    x = runST $ do+      mx <- newDataFrame+      let ixA (I# i) (I# j) = scalar $ ix# (i *# n# +# j) luUpper+          ixB (I# i) = scalar $ ix# i y+      forM_ [n-1, n-2 .. 0] $ \i -> do+        v <- foldM ( \v j -> do+                      dj <- readDataFrameOff mx j+                      return $ v - dj * ixA i j+                   ) (ixB i) [i+1..n-1]+        writeDataFrameOff mx i (v / ixA i i)+      unsafeFreezeDataFrame mx+++-- | 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 -- permutated matrix+                            , Matrix t n n -- permutation matrix+                            , Scalar t -- sign of permutation matrix+                            )+pivotMat mat+    = ( let f ( _, [] )   = undefined+            f ( j, i:is )+              | j == n    = f (0, is)+              | otherwise = (# (j+1, i:is), ix i j #)+        in case gen# steps f (0,rowOrder) of+            (# _, r #) -> r+      , let f ( _, [] ) = undefined+            f ( j, x:xs )+               | j == n    = f (0, xs)+               | otherwise = (# ( j + 1, x:xs), if j == x then 1 else 0 #)+        in case gen# steps f (0,rowOrder) of+            (# _, r #) -> r+      , if countMisordered rowOrder `rem` 2 == 1+        then -1 else 1+      )+  where+    dn = dimVal' @n+    steps = CumulDims [dn * dn, dn, 1]+    -- permuted row ordering+    rowOrder = uncurry fillPass $ searchPass 0 [0..n-1]+    -- matrix size+    n = fromIntegral dn+    n# = case n of I# x -> x+    -- sign of permutations+    countMisordered :: [Int] -> Int+    countMisordered [] = 0+    countMisordered (i:is) = foldl' (\c j -> if i > j then succ c else c) 0 is+                           + countMisordered is+    ix (I# i) (I# j) = ix# (i *# n# +# j) mat+    findMax :: Int -> [Int] -> (t, Int)+    findMax j = foldl' (\(ox, oi) i -> let x = abs (ix i j)+                                       in if x > ox then (x, i)+                                                    else (ox, oi)+                      ) (0, 0)+    -- search maximums, leaving Nothing where all rows are 0+    searchPass :: Int -> [Int] -> ([Int], [Maybe Int])+    searchPass j is+      | j == n    = (is, [])+      | otherwise = case findMax j is of+          (0, _) -> (Nothing:) <$> searchPass (j+1) is+          (_, i) -> (Just i:) <$> searchPass (j+1) (delete i is)+    -- replace Nothings with remaining row numbers+    fillPass :: [Int] -> [Maybe Int] -> [Int]+    fillPass _ []                  = []+    fillPass js (Just i : is)      = i : fillPass js is+    fillPass (j:js) (Nothing : is) = j : fillPass js is+    fillPass [] (Nothing : is)     = 0 : fillPass [] is
+ src/Numeric/Matrix/Internal/Mat44d.hs view
@@ -0,0 +1,186 @@+{-# LANGUAGE MagicHash     #-}+{-# LANGUAGE UnboxedTuples #-}+{-# LANGUAGE ViewPatterns  #-}+{-# OPTIONS_GHC -fno-warn-orphans #-}++module Numeric.Matrix.Internal.Mat44d () where++import qualified Control.Monad.ST        as ST+import qualified Numeric.DataFrame.ST    as ST+import           Numeric.Matrix.Internal+import           Numeric.Scalar.Internal+import           Numeric.Vector.Internal++{-# INLINE mkMat #-}+mkMat ::+  Double -> Double -> Double -> Double ->+  Double -> Double -> Double -> Double ->+  Double -> Double -> Double -> Double ->+  Double -> Double -> Double -> Double ->+  Mat44d+mkMat+  _11 _12 _13 _14+  _21 _22 _23 _24+  _31 _32 _33 _34+  _41 _42 _43 _44+  = ST.runST $ do+    df <- ST.newDataFrame+    ST.writeDataFrameOff df 0  $ scalar _11+    ST.writeDataFrameOff df 1  $ scalar _12+    ST.writeDataFrameOff df 2  $ scalar _13+    ST.writeDataFrameOff df 3  $ scalar _14+    ST.writeDataFrameOff df 4  $ scalar _21+    ST.writeDataFrameOff df 5  $ scalar _22+    ST.writeDataFrameOff df 6  $ scalar _23+    ST.writeDataFrameOff df 7  $ scalar _24+    ST.writeDataFrameOff df 8  $ scalar _31+    ST.writeDataFrameOff df 9  $ scalar _32+    ST.writeDataFrameOff df 10 $ scalar _33+    ST.writeDataFrameOff df 11 $ scalar _34+    ST.writeDataFrameOff df 12 $ scalar _41+    ST.writeDataFrameOff df 13 $ scalar _42+    ST.writeDataFrameOff df 14 $ scalar _43+    ST.writeDataFrameOff df 15 $ scalar _44+    ST.unsafeFreezeDataFrame df++instance HomTransform4 Double where+  {-# INLINE translate4 #-}+  translate4 (unpackV4# -> (# x, y, z, _ #)) = mkMat+    1 0 0 0+    0 1 0 0+    0 0 1 0+    x y z 1++  {-# INLINE translate3 #-}+  translate3 (unpackV3# -> (# x, y, z #)) = mkMat+    1 0 0 0+    0 1 0 0+    0 0 1 0+    x y z 1++  {-# INLINE rotateX #-}+  rotateX a = mkMat+    1 0 0 0+    0 c s 0+    0 n c 0+    0 0 0 1+    where+      c = cos a+      s = sin a+      n = -s++  {-# INLINE rotateY #-}+  rotateY a = mkMat+    c 0 n 0+    0 1 0 0+    s 0 c 0+    0 0 0 1+    where+      c = cos a+      s = sin a+      n = -s++  {-# INLINE rotateZ #-}+  rotateZ a = mkMat+    c s 0 0+    n c 0 0+    0 0 1 0+    0 0 0 1+    where+      c = cos a+      s = sin a+      n = -s++  {-# INLINE rotate #-}+  rotate (unpackV3# -> (# x, y, z #)) a = mkMat+    (c+xxv)  (yxv+zs) (zxv-ys) 0+    (xyv-zs) (c+yyv)  (zyv+xs) 0+    (xzv+ys) (yzv-xs) (c+zzv)  0+     0        0        0       1+    where+      c = cos a+      v = 1 - c -- v for versine+      s = sin a+      xxv = x * x * v+      xyv = x * y * v+      xzv = x * z * v+      yxv = xyv+      yyv = y * y * v+      yzv = y * z * v+      zxv = xzv+      zyv = yzv+      zzv = z * z * v+      xs = x * s+      ys = y * s+      zs = z * s++  {-# INLINE rotateEuler #-}+  rotateEuler x y z = mkMat+    (cy*cz)  (cx*sz+sx*sy*cz) (sx*sz-cx*sy*cz) 0+    (-cy*sz) (cx*cz-sx*sy*sz) (sx*cz+cx*sy*sz) 0+     sy      (-sx*cy)         (cx*cy)          0+     0        0                0               1+    where+      cx = cos x+      sx = sin x+      cy = cos y+      sy = sin y+      cz = cos z+      sz = sin z++  {-# INLINE lookAt #-}+  lookAt up cam foc = mkMat+    xb1 yb1 zb1 0+    xb2 yb2 zb2 0+    xb3 yb3 zb3 0+    tx  ty  tz  1+    where+      (# xb1, xb2, xb3 #) = unpackV3# xb+      (# yb1, yb2, yb3 #) = unpackV3# yb+      (# zb1, zb2, zb3 #) = unpackV3# zb+      zb = normalized $ cam - foc -- Basis vector for "backward", since +Z is behind the camera+      xb = normalized $ up `cross` zb -- Basis vector for "right"+      yb = zb `cross` xb -- Basis vector for "up"+      ncam = -cam+      tx = unScalar $ xb `dot` ncam+      ty = unScalar $ yb `dot` ncam+      tz = unScalar $ zb `dot` ncam++  {-# INLINE perspective #-}+  perspective n f fovy aspect = mkMat+    dpw 0   0   0+    0   dph 0   0+    0   0   a (-1)+    0   0   b   0+    where+      hpd = tan (fovy * 0.5) -- height/distance+      wpd = aspect * hpd; -- width/distance+      dph = recip hpd -- distance/height+      dpw = recip wpd -- distance/width+      nmf = n - f+      a = (n + f) / nmf+      b = 2 * n * f / nmf++  {-# INLINE orthogonal #-}+  orthogonal n f w h = mkMat+    iw 0  0 0+    0  ih 0 0+    0  0  a 0+    0  0  b 1+    where+      ih = 2 / h+      iw = 2 / w+      nmf = n - f+      a = 2 / nmf+      b = (n + f) / nmf++  {-# INLINE toHomPoint #-}+  toHomPoint (unpackV3# -> (# x, y, z #)) = vec4 x y z 1++  {-# INLINE toHomVector #-}+  toHomVector (unpackV3# -> (# x, y, z #)) = vec4 x y z 0++  {-# INLINE fromHom #-}+  fromHom (unpackV4# -> (# x, y, z, w #))+    | w == 0    = vec3 x y z+    | otherwise = vec3 (x/w) (y/w) (z/w)
+ src/Numeric/Matrix/Internal/Mat44f.hs view
@@ -0,0 +1,186 @@+{-# LANGUAGE MagicHash     #-}+{-# LANGUAGE UnboxedTuples #-}+{-# LANGUAGE ViewPatterns  #-}+{-# OPTIONS_GHC -fno-warn-orphans #-}++module Numeric.Matrix.Internal.Mat44f () where++import qualified Control.Monad.ST        as ST+import qualified Numeric.DataFrame.ST    as ST+import           Numeric.Matrix.Internal+import           Numeric.Scalar.Internal+import           Numeric.Vector.Internal++{-# INLINE mkMat #-}+mkMat ::+  Float -> Float -> Float -> Float ->+  Float -> Float -> Float -> Float ->+  Float -> Float -> Float -> Float ->+  Float -> Float -> Float -> Float ->+  Mat44f+mkMat+  _11 _12 _13 _14+  _21 _22 _23 _24+  _31 _32 _33 _34+  _41 _42 _43 _44+  = ST.runST $ do+    df <- ST.newDataFrame+    ST.writeDataFrameOff df 0  $ scalar _11+    ST.writeDataFrameOff df 1  $ scalar _12+    ST.writeDataFrameOff df 2  $ scalar _13+    ST.writeDataFrameOff df 3  $ scalar _14+    ST.writeDataFrameOff df 4  $ scalar _21+    ST.writeDataFrameOff df 5  $ scalar _22+    ST.writeDataFrameOff df 6  $ scalar _23+    ST.writeDataFrameOff df 7  $ scalar _24+    ST.writeDataFrameOff df 8  $ scalar _31+    ST.writeDataFrameOff df 9  $ scalar _32+    ST.writeDataFrameOff df 10 $ scalar _33+    ST.writeDataFrameOff df 11 $ scalar _34+    ST.writeDataFrameOff df 12 $ scalar _41+    ST.writeDataFrameOff df 13 $ scalar _42+    ST.writeDataFrameOff df 14 $ scalar _43+    ST.writeDataFrameOff df 15 $ scalar _44+    ST.unsafeFreezeDataFrame df++instance HomTransform4 Float where+  {-# INLINE translate4 #-}+  translate4 (unpackV4# -> (# x, y, z, _ #)) = mkMat+    1 0 0 0+    0 1 0 0+    0 0 1 0+    x y z 1++  {-# INLINE translate3 #-}+  translate3 (unpackV3# -> (# x, y, z #)) = mkMat+    1 0 0 0+    0 1 0 0+    0 0 1 0+    x y z 1++  {-# INLINE rotateX #-}+  rotateX a = mkMat+    1 0 0 0+    0 c s 0+    0 n c 0+    0 0 0 1+    where+      c = cos a+      s = sin a+      n = -s++  {-# INLINE rotateY #-}+  rotateY a = mkMat+    c 0 n 0+    0 1 0 0+    s 0 c 0+    0 0 0 1+    where+      c = cos a+      s = sin a+      n = -s++  {-# INLINE rotateZ #-}+  rotateZ a = mkMat+    c s 0 0+    n c 0 0+    0 0 1 0+    0 0 0 1+    where+      c = cos a+      s = sin a+      n = -s++  {-# INLINE rotate #-}+  rotate (unpackV3# -> (# x, y, z #)) a = mkMat+    (c+xxv)  (yxv+zs) (zxv-ys) 0+    (xyv-zs) (c+yyv)  (zyv+xs) 0+    (xzv+ys) (yzv-xs) (c+zzv)  0+     0        0        0       1+    where+      c = cos a+      v = 1 - c -- v for versine+      s = sin a+      xxv = x * x * v+      xyv = x * y * v+      xzv = x * z * v+      yxv = xyv+      yyv = y * y * v+      yzv = y * z * v+      zxv = xzv+      zyv = yzv+      zzv = z * z * v+      xs = x * s+      ys = y * s+      zs = z * s++  {-# INLINE rotateEuler #-}+  rotateEuler x y z = mkMat+    (cy*cz)  (cx*sz+sx*sy*cz) (sx*sz-cx*sy*cz) 0+    (-cy*sz) (cx*cz-sx*sy*sz) (sx*cz+cx*sy*sz) 0+     sy      (-sx*cy)         (cx*cy)          0+     0        0                0               1+    where+      cx = cos x+      sx = sin x+      cy = cos y+      sy = sin y+      cz = cos z+      sz = sin z++  {-# INLINE lookAt #-}+  lookAt up cam foc = mkMat+    xb1 yb1 zb1 0+    xb2 yb2 zb2 0+    xb3 yb3 zb3 0+    tx  ty  tz  1+    where+      (# xb1, xb2, xb3 #) = unpackV3# xb+      (# yb1, yb2, yb3 #) = unpackV3# yb+      (# zb1, zb2, zb3 #) = unpackV3# zb+      zb = normalized $ cam - foc -- Basis vector for "backward", since +Z is behind the camera+      xb = normalized $ up `cross` zb -- Basis vector for "right"+      yb = zb `cross` xb -- Basis vector for "up"+      ncam = -cam+      tx = unScalar $ xb `dot` ncam+      ty = unScalar $ yb `dot` ncam+      tz = unScalar $ zb `dot` ncam++  {-# INLINE perspective #-}+  perspective n f fovy aspect = mkMat+    dpw 0   0   0+    0   dph 0   0+    0   0   a (-1)+    0   0   b   0+    where+      hpd = tan (fovy * 0.5) -- height/distance+      wpd = aspect * hpd; -- width/distance+      dph = recip hpd -- distance/height+      dpw = recip wpd -- distance/width+      nmf = n - f+      a = (n + f) / nmf+      b = 2 * n * f / nmf++  {-# INLINE orthogonal #-}+  orthogonal n f w h = mkMat+    iw 0  0 0+    0  ih 0 0+    0  0  a 0+    0  0  b 1+    where+      ih = 2 / h+      iw = 2 / w+      nmf = n - f+      a = 2 / nmf+      b = (n + f) / nmf++  {-# INLINE toHomPoint #-}+  toHomPoint (unpackV3# -> (# x, y, z #)) = vec4 x y z 1++  {-# INLINE toHomVector #-}+  toHomVector (unpackV3# -> (# x, y, z #)) = vec4 x y z 0++  {-# INLINE fromHom #-}+  fromHom (unpackV4# -> (# x, y, z, w #))+    | w == 0    = vec3 x y z+    | otherwise = vec3 (x/w) (y/w) (z/w)
− src/Numeric/Matrix/Mat44d.hs
@@ -1,196 +0,0 @@-{-# LANGUAGE MagicHash #-}-{-# OPTIONS_GHC -fno-warn-orphans #-}--module Numeric.Matrix.Mat44d () where--import qualified Control.Monad.ST as ST-import GHC.Exts-import Numeric.DataFrame.Internal.Array.Family.DoubleX3-import Numeric.DataFrame.Internal.Array.Family.DoubleX4-import qualified Numeric.DataFrame.ST as ST-import Numeric.DataFrame.SubSpace-import Numeric.DataFrame.Type-import Numeric.Matrix.Class-import Numeric.Scalar-import Numeric.Vector--{-# INLINE mat44d #-}-mat44d ::-  Scd -> Scd -> Scd -> Scd ->-  Scd -> Scd -> Scd -> Scd ->-  Scd -> Scd -> Scd -> Scd ->-  Scd -> Scd -> Scd -> Scd ->-  Mat44d-mat44d-  _11 _12 _13 _14-  _21 _22 _23 _24-  _31 _32 _33 _34-  _41 _42 _43 _44-  = ST.runST $ do-    df <- ST.newDataFrame-    ST.writeDataFrameOff df 0 _11-    ST.writeDataFrameOff df 1 _21-    ST.writeDataFrameOff df 2 _31-    ST.writeDataFrameOff df 3 _41-    ST.writeDataFrameOff df 4 _12-    ST.writeDataFrameOff df 5 _22-    ST.writeDataFrameOff df 6 _32-    ST.writeDataFrameOff df 7 _42-    ST.writeDataFrameOff df 8 _13-    ST.writeDataFrameOff df 9 _23-    ST.writeDataFrameOff df 10 _33-    ST.writeDataFrameOff df 11 _43-    ST.writeDataFrameOff df 12 _14-    ST.writeDataFrameOff df 13 _24-    ST.writeDataFrameOff df 14 _34-    ST.writeDataFrameOff df 15 _44-    ST.unsafeFreezeDataFrame df- -instance HomTransform4 Double where-  {-# INLINE translate4 #-}-  translate4 (SingleFrame (DoubleX4# x# y# z# _)) = mat44d-    1 0 0 x-    0 1 0 y-    0 0 1 z-    0 0 0 1-    where-      x = scalar $ D# x#-      y = scalar $ D# y#-      z = scalar $ D# z#--  {-# INLINE translate3 #-}-  translate3 (SingleFrame (DoubleX3# x# y# z#)) = mat44d-    1 0 0 x-    0 1 0 y-    0 0 1 z-    0 0 0 1-    where-      x = scalar $ D# x#-      y = scalar $ D# y#-      z = scalar $ D# z#--  {-# INLINE rotateX #-}-  rotateX a = mat44d-    1 0 0 0-    0 c n 0-    0 s c 0-    0 0 0 1-    where-      c = scalar $ cos a-      s = scalar $ sin a-      n = -s--  {-# INLINE rotateY #-}-  rotateY a = mat44d-    c 0 s 0-    0 1 0 0-    n 0 c 0-    0 0 0 1-    where-      c = scalar $ cos a-      s = scalar $ sin a-      n = -s--  {-# INLINE rotateZ #-}-  rotateZ a = mat44d-    c n 0 0-    s c 0 0-    0 0 1 0-    0 0 0 1-    where-      c = scalar $ cos a-      s = scalar $ sin a-      n = -s--  {-# INLINE rotate #-}-  rotate (SingleFrame (DoubleX3# x# y# z#)) a = mat44d-    (c+xxv)  (xyv-zs) (xzv+ys) 0-    (yxv+zs) (c+yyv)  (yzv-xs) 0-    (zxv-ys) (zyv+xs) (c+zzv)  0-    0        0        0        1-    where-      c = scalar $ cos a-      v = 1 - c -- v for versine-      s = scalar $ sin a-      x = scalar $ D# x#-      y = scalar $ D# y#-      z = scalar $ D# z#-      xxv = x * x * v-      xyv = x * y * v-      xzv = x * z * v-      yxv = xyv-      yyv = y * y * v-      yzv = y * z * v-      zxv = xzv-      zyv = yzv-      zzv = z * z * v-      xs = x * s-      ys = y * s-      zs = z * s--  {-# INLINE rotateEuler #-}-  rotateEuler x y z = mat44d-    (cy*cz)          (-cy*sz)         sy       0-    (cx*sz+sx*sy*cz) (cx*cz-sx*sy*sz) (-sx*cy) 0-    (sx*sz-cx*sy*cz) (sx*cz+cx*sy*sz) (cx*cy)  0-    0                0                0        1-    where-      cx = scalar $ cos x-      sx = scalar $ sin x-      cy = scalar $ cos y-      sy = scalar $ sin y-      cz = scalar $ cos z-      sz = scalar $ sin z--  {-# INLINE lookAt #-}-  lookAt up cam foc = mat44d-    (xb!1) (xb!2) (xb!3) tx-    (yb!1) (yb!2) (yb!3) ty-    (zb!1) (zb!2) (zb!3) tz-    0      0      0      1-    where-      zb = normalized $ cam - foc -- Basis vector for "backward", since +Z is behind the camera-      xb = normalized $ up `cross` zb -- Basis vector for "right"-      yb = zb `cross` xb -- Basis vector for "up"-      ncam = -cam-      tx = xb `dot` ncam-      ty = yb `dot` ncam-      tz = zb `dot` ncam--  {-# INLINE perspective #-}-  perspective n f fovy aspect = mat44d-    dpw 0   0    0-    0   dph 0    0-    0   0   a    b-    0   0   (-1) 0-    where-      hpd = tan (fovy * 0.5) -- height/distance-      wpd = aspect * hpd; -- width/distance-      dph = scalar $ 1 / hpd -- distance/height-      dpw = scalar $ 1 / wpd -- distance/width-      nmf = n - f-      a = scalar $ (n + f) / nmf-      b = scalar $ 2 * n * f / nmf--  {-# INLINE orthogonal #-}-  orthogonal n f w h = mat44d-    iw 0  0 0-    0  ih 0 0-    0  0  a b-    0  0  0 1-    where-      ih = scalar $ 2 / h-      iw = scalar $ 2 / w-      nmf = n - f-      a = scalar $ 2 / nmf-      b = scalar $ (n + f) / nmf--  {-# INLINE toHomPoint #-}-  toHomPoint (SingleFrame (DoubleX3# x# y# z#)) = SingleFrame (DoubleX4# x# y# z# 1.0##)--  {-# INLINE toHomVector #-}-  toHomVector (SingleFrame (DoubleX3# x# y# z#)) = SingleFrame (DoubleX4# x# y# z# 0.0##)--  {-# INLINE fromHom #-}-  fromHom (SingleFrame (DoubleX4# x# y# z# 0.0##)) = SingleFrame (DoubleX3# x# y# z#)-  fromHom (SingleFrame (DoubleX4# x# y# z# w#)) = SingleFrame (DoubleX3# (x# /## w#) (y# /## w#) (z# /## w#))
− src/Numeric/Matrix/Mat44f.hs
@@ -1,196 +0,0 @@-{-# LANGUAGE MagicHash #-}-{-# OPTIONS_GHC -fno-warn-orphans #-}--module Numeric.Matrix.Mat44f () where--import qualified Control.Monad.ST as ST-import GHC.Exts-import Numeric.DataFrame.Internal.Array.Family.FloatX3-import Numeric.DataFrame.Internal.Array.Family.FloatX4-import qualified Numeric.DataFrame.ST as ST-import Numeric.DataFrame.SubSpace-import Numeric.DataFrame.Type-import Numeric.Matrix.Class-import Numeric.Scalar-import Numeric.Vector--{-# INLINE mat44f #-}-mat44f ::-  Scf -> Scf -> Scf -> Scf ->-  Scf -> Scf -> Scf -> Scf ->-  Scf -> Scf -> Scf -> Scf ->-  Scf -> Scf -> Scf -> Scf ->-  Mat44f-mat44f-  _11 _12 _13 _14-  _21 _22 _23 _24-  _31 _32 _33 _34-  _41 _42 _43 _44-  = ST.runST $ do-    df <- ST.newDataFrame-    ST.writeDataFrameOff df 0 _11-    ST.writeDataFrameOff df 1 _21-    ST.writeDataFrameOff df 2 _31-    ST.writeDataFrameOff df 3 _41-    ST.writeDataFrameOff df 4 _12-    ST.writeDataFrameOff df 5 _22-    ST.writeDataFrameOff df 6 _32-    ST.writeDataFrameOff df 7 _42-    ST.writeDataFrameOff df 8 _13-    ST.writeDataFrameOff df 9 _23-    ST.writeDataFrameOff df 10 _33-    ST.writeDataFrameOff df 11 _43-    ST.writeDataFrameOff df 12 _14-    ST.writeDataFrameOff df 13 _24-    ST.writeDataFrameOff df 14 _34-    ST.writeDataFrameOff df 15 _44-    ST.unsafeFreezeDataFrame df- -instance HomTransform4 Float where-  {-# INLINE translate4 #-}-  translate4 (SingleFrame (FloatX4# x# y# z# _)) = mat44f-    1 0 0 x-    0 1 0 y-    0 0 1 z-    0 0 0 1-    where-      x = scalar $ F# x#-      y = scalar $ F# y#-      z = scalar $ F# z#--  {-# INLINE translate3 #-}-  translate3 (SingleFrame (FloatX3# x# y# z#)) = mat44f-    1 0 0 x-    0 1 0 y-    0 0 1 z-    0 0 0 1-    where-      x = scalar $ F# x#-      y = scalar $ F# y#-      z = scalar $ F# z#--  {-# INLINE rotateX #-}-  rotateX a = mat44f-    1 0 0 0-    0 c n 0-    0 s c 0-    0 0 0 1-    where-      c = scalar $ cos a-      s = scalar $ sin a-      n = -s--  {-# INLINE rotateY #-}-  rotateY a = mat44f-    c 0 s 0-    0 1 0 0-    n 0 c 0-    0 0 0 1-    where-      c = scalar $ cos a-      s = scalar $ sin a-      n = -s--  {-# INLINE rotateZ #-}-  rotateZ a = mat44f-    c n 0 0-    s c 0 0-    0 0 1 0-    0 0 0 1-    where-      c = scalar $ cos a-      s = scalar $ sin a-      n = -s--  {-# INLINE rotate #-}-  rotate (SingleFrame (FloatX3# x# y# z#)) a = mat44f-    (c+xxv)  (xyv-zs) (xzv+ys) 0-    (yxv+zs) (c+yyv)  (yzv-xs) 0-    (zxv-ys) (zyv+xs) (c+zzv)  0-    0        0        0        1-    where-      c = scalar $ cos a-      v = 1 - c -- v for versine-      s = scalar $ sin a-      x = scalar $ F# x#-      y = scalar $ F# y#-      z = scalar $ F# z#-      xxv = x * x * v-      xyv = x * y * v-      xzv = x * z * v-      yxv = xyv-      yyv = y * y * v-      yzv = y * z * v-      zxv = xzv-      zyv = yzv-      zzv = z * z * v-      xs = x * s-      ys = y * s-      zs = z * s--  {-# INLINE rotateEuler #-}-  rotateEuler x y z = mat44f-    (cy*cz)          (-cy*sz)         sy       0-    (cx*sz+sx*sy*cz) (cx*cz-sx*sy*sz) (-sx*cy) 0-    (sx*sz-cx*sy*cz) (sx*cz+cx*sy*sz) (cx*cy)  0-    0                0                0        1-    where-      cx = scalar $ cos x-      sx = scalar $ sin x-      cy = scalar $ cos y-      sy = scalar $ sin y-      cz = scalar $ cos z-      sz = scalar $ sin z--  {-# INLINE lookAt #-}-  lookAt up cam foc = mat44f-    (xb!1) (xb!2) (xb!3) tx-    (yb!1) (yb!2) (yb!3) ty-    (zb!1) (zb!2) (zb!3) tz-    0      0      0      1-    where-      zb = normalized $ cam - foc -- Basis vector for "backward", since +Z is behind the camera-      xb = normalized $ up `cross` zb -- Basis vector for "right"-      yb = zb `cross` xb -- Basis vector for "up"-      ncam = -cam-      tx = xb `dot` ncam-      ty = yb `dot` ncam-      tz = zb `dot` ncam--  {-# INLINE perspective #-}-  perspective n f fovy aspect = mat44f-    dpw 0   0    0-    0   dph 0    0-    0   0   a    b-    0   0   (-1) 0-    where-      hpd = tan (fovy * 0.5) -- height/distance-      wpd = aspect * hpd; -- width/distance-      dph = scalar $ 1 / hpd -- distance/height-      dpw = scalar $ 1 / wpd -- distance/width-      nmf = n - f-      a = scalar $ (n + f) / nmf-      b = scalar $ 2 * n * f / nmf--  {-# INLINE orthogonal #-}-  orthogonal n f w h = mat44f-    iw 0  0 0-    0  ih 0 0-    0  0  a b-    0  0  0 1-    where-      ih = scalar $ 2 / h-      iw = scalar $ 2 / w-      nmf = n - f-      a = scalar $ 2 / nmf-      b = scalar $ (n + f) / nmf--  {-# INLINE toHomPoint #-}-  toHomPoint (SingleFrame (FloatX3# x# y# z#)) = SingleFrame (FloatX4# x# y# z# 1.0#)--  {-# INLINE toHomVector #-}-  toHomVector (SingleFrame (FloatX3# x# y# z#)) = SingleFrame (FloatX4# x# y# z# 0.0#)--  {-# INLINE fromHom #-}-  fromHom (SingleFrame (FloatX4# x# y# z# 0.0#)) = SingleFrame (FloatX3# x# y# z#)-  fromHom (SingleFrame (FloatX4# x# y# z# w#)) = SingleFrame (FloatX3# (x# `divideFloat#` w#) (y# `divideFloat#` w#) (z# `divideFloat#` w#))
src/Numeric/PrimBytes.hs view
@@ -1,1428 +1,1792 @@-{-# LANGUAGE CPP                   #-}-{-# LANGUAGE DataKinds             #-}-{-# LANGUAGE DefaultSignatures     #-}-{-# LANGUAGE FlexibleContexts      #-}-{-# LANGUAGE FlexibleInstances     #-}--- {-# LANGUAGE IncoherentInstances   #-}-{-# LANGUAGE GADTs                 #-}-{-# LANGUAGE MagicHash             #-}-{-# LANGUAGE MultiParamTypeClasses #-}-{-# LANGUAGE ScopedTypeVariables   #-}-{-# LANGUAGE TypeApplications      #-}-{-# LANGUAGE TypeFamilies          #-}-{-# LANGUAGE TypeOperators         #-}-{-# LANGUAGE UnboxedTuples         #-}-{-# LANGUAGE UndecidableInstances  #-}--module Numeric.PrimBytes-  ( PrimBytes-    ( getBytes, fromBytes, readBytes, writeBytes, byteSize, byteAlign, byteOffset-    , indexArray, readArray, writeArray, readAddr, writeAddr)-  , PrimTag (..), primTag-  ) where--#include "MachDeps.h"--import           Data.Proxy              (Proxy (..))-import           GHC.Exts-import           GHC.Generics-import           GHC.Int-import           GHC.Word-import           Numeric.Dimensions.Idxs-import qualified Numeric.Tuple.Lazy      as TL-import qualified Numeric.Tuple.Strict    as TS-import qualified Numeric.Type.List       as L---- | Facilities to convert to and from raw byte array.-class PrimTagged a => PrimBytes a where-    -- | Store content of a data type in a primitive byte array-    --   Should be used together with @byteOffset@ function.-    getBytes :: a -> ByteArray#-    -- | Load content of a data type from a primitive byte array-    fromBytes :: Int# -- ^ offset in bytes-              -> ByteArray#-              -> a-    -- | Read data from a mutable byte array given an offset in bytes-    readBytes :: MutableByteArray# s -- ^ source array-              -> Int# -- ^ byte offset of the source array-              -> State# s -> (# State# s, a #)-    -- | Write data into a mutable byte array at a given position (offset in bytes)-    writeBytes :: MutableByteArray# s -- ^ destination array-               -> Int# -- ^ byte offset of the destination array-               -> a -- ^ data to write into array-               -> State# s -> State# s-    -- | Read data from a specified address-    readAddr :: Addr# -> State# s -> (# State# s, a #)-    -- | Write data to a specified address-    writeAddr :: a -> Addr# -> State# s -> State# s-    -- | Size of a data type in bytes-    byteSize :: a -> Int#-    -- | Alignment of a data type in bytes.-    --   @byteOffset@ should be multiple of this value.-    byteAlign :: 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.-    byteOffset :: a -> Int#--    -- | Index array given an element offset.-    ---    --   > indexArray arr i = fromBytes ( i *# byteSize t) arr-    indexArray :: ByteArray# -> Int# -> a-    indexArray ba i = fromBytes (i *# byteSize @a undefined) ba-    {-# INLINE indexArray #-}--    -- | Read a mutable array given an element offset.-    ---    --   > readArray arr i = readBytes arr ( i *# byteSize t)-    readArray  :: MutableByteArray# s -> Int# -> State# s -> (# State# s, a #)-    readArray ba i = readBytes ba (i *# byteSize @a undefined)-    {-# INLINE readArray #-}--    -- | Write a mutable array given an element offset.-    ---    --   > writeArray arr i = writeBytes arr ( i *# byteSize t)-    writeArray :: MutableByteArray# s -> Int# -> a -> State# s -> State# s-    writeArray ba i = writeBytes ba (i *# byteSize @a undefined)-    {-# INLINE writeArray #-}----    default getBytes :: (Generic a, GPrimBytes (Rep a)) => a -> ByteArray#-    getBytes a = ggetBytes (from a)-    {-# INLINE getBytes #-}--    default fromBytes :: (Generic a, GPrimBytes (Rep a))-                      => Int# -> ByteArray# -> a-    fromBytes i arr = to (gfromBytes 0## i arr)-    {-# INLINE fromBytes #-}--    default readBytes :: (Generic a, GPrimBytes (Rep a))-                      => MutableByteArray# s -> Int# -> State# s -> (# State# s, a #)-    readBytes mba i s = case greadBytes 0## mba i s of-      (# s', x #) -> (# s', to x #)-    {-# INLINE readBytes #-}--    default writeBytes :: (Generic a, GPrimBytes (Rep a))-                       => MutableByteArray# s -> Int# -> a -> State# s -> State# s-    writeBytes mba i = gwriteBytes 0## mba i . from-    {-# INLINE writeBytes #-}--    default readAddr :: (Generic a, GPrimBytes (Rep a))-                      => Addr# -> State# s -> (# State# s, a #)-    readAddr a s = case greadAddr 0## a s of-      (# s', x #) -> (# s', to x #)-    {-# INLINE readAddr #-}--    default writeAddr :: (Generic a, GPrimBytes (Rep a))-                       => a -> Addr# -> State# s -> State# s-    writeAddr = gwriteAddr 0## . from-    {-# INLINE writeAddr #-}---    default byteSize :: (Generic a, GPrimBytes (Rep a))-                     => a -> Int#-    byteSize a = gbyteSize (from a)-    {-# INLINE byteSize #-}--    default byteAlign :: (Generic a, GPrimBytes (Rep a))-                     => a -> Int#-    byteAlign a = gbyteAlign (from a)-    {-# INLINE byteAlign #-}--    default byteOffset :: (Generic a, GPrimBytes (Rep a))-                     => a -> Int#-    byteOffset a = gbyteOffset (from a)-    {-# INLINE byteOffset #-}----- | Deriving `PrimBytes` using generics-class GPrimBytes f where-    ggetBytes :: f p -> ByteArray#-    gfromBytes :: Word# -- ^ Starting value of a constructor tag-               -> Int# -> ByteArray# -> f p-    greadBytes :: Word# -- ^ Starting value of a constructor tag-               -> MutableByteArray# s -> Int#  -> State# s -> (# State# s, f p #)-    gwriteBytes :: Word# -- ^ Starting value of a constructor tag-                -> MutableByteArray# s -> Int# -> f p -> State# s -> State# s-    greadAddr :: Word# -- ^ Starting value of a constructor tag-              -> Addr# -> State# s -> (# State# s, f p #)-    gwriteAddr :: Word# -- ^ Starting value of a constructor tag-               -> f p -> Addr# -> State# s -> State# s-    gbyteSize :: f p -> Int#-    gbyteAlign :: f p -> Int#-    gbyteOffset :: f p -> Int#-    -- | Number of constructors in the tree of a sum type.-    --   This is equal to one for all other types.-    gconTags    :: f p -> Word#---instance GPrimBytes V1 where-    -- Probably, this is illegal due to zero size of the array.-    -- There is no bottom to put here, but one should not call this anyway.-    ggetBytes _ = case runRW#-       ( \s0 -> case newByteArray# 0# s0 of-           (# s1, marr #) -> unsafeFreezeByteArray# marr s1-       ) of (# _, a #) -> a-    {-# NOINLINE ggetBytes #-}-    gfromBytes _ _ _ = undefined-    {-# INLINE gfromBytes #-}-    greadBytes _ _ _ s = (# s, undefined #)-    {-# INLINE greadBytes #-}-    gwriteBytes _ _ _ _ s = s-    {-# INLINE gwriteBytes #-}-    greadAddr _ _ s = (# s, undefined #)-    {-# INLINE greadAddr #-}-    gwriteAddr _ _ _ s = s-    {-# INLINE gwriteAddr #-}-    gbyteSize _ = 0#-    {-# INLINE gbyteSize #-}-    gbyteAlign _ = 1#-    {-# INLINE gbyteAlign #-}-    gbyteOffset _ = 0#-    {-# INLINE gbyteOffset #-}-    gconTags _ = 1##-    {-# INLINE gconTags #-}--instance GPrimBytes U1 where-    -- Probably, this is illegal due to zero size of the array.-    -- There is no bottom to put here, but one should not call this anyway.-    ggetBytes _ = case runRW#-       ( \s0 -> case newByteArray# 0# s0 of-           (# s1, marr #) -> unsafeFreezeByteArray# marr s1-       ) of (# _, a #) -> a-    {-# NOINLINE ggetBytes #-}-    gfromBytes _ _ _ = U1-    {-# INLINE gfromBytes #-}-    greadBytes _ _ _ s = (# s, U1 #)-    {-# INLINE greadBytes #-}-    gwriteBytes _ _ _ _ s = s-    {-# INLINE gwriteBytes #-}-    greadAddr _ _ s = (# s, U1 #)-    {-# INLINE greadAddr #-}-    gwriteAddr _ _ _ s = s-    {-# INLINE gwriteAddr #-}-    gbyteSize _ = 0#-    {-# INLINE gbyteSize #-}-    gbyteAlign _ = 1#-    {-# INLINE gbyteAlign #-}-    gbyteOffset _ = 0#-    {-# INLINE gbyteOffset #-}-    gconTags _ = 1##-    {-# INLINE gconTags #-}--instance PrimBytes a => GPrimBytes (K1 i a) where-    ggetBytes ~(K1 a) = getBytes a-    {-# NOINLINE ggetBytes #-}-    gfromBytes _ i ba = K1 (fromBytes i ba)-    {-# INLINE gfromBytes #-}-    greadBytes _ = unsafeCoerce# (readBytes @a)-    {-# INLINE greadBytes #-}-    gwriteBytes _ mba i ~(K1 a) = writeBytes mba i a-    {-# INLINE gwriteBytes #-}-    greadAddr _ = unsafeCoerce# (readAddr @a)-    {-# INLINE greadAddr #-}-    gwriteAddr _ ~(K1 a) = writeAddr a-    {-# INLINE gwriteAddr #-}-    gbyteSize ~(K1 a) = byteSize a-    {-# INLINE gbyteSize #-}-    gbyteAlign ~(K1 a) = byteAlign a-    {-# INLINE gbyteAlign #-}-    gbyteOffset ~(K1 a) = byteOffset a-    {-# INLINE gbyteOffset #-}-    gconTags _ = 1##-    {-# INLINE gconTags #-}--instance GPrimBytes f => GPrimBytes (M1 i c f) where-    ggetBytes ~(M1 a) = ggetBytes a-    {-# NOINLINE ggetBytes #-}-    gfromBytes t i ba = M1 (gfromBytes t i ba)-    {-# INLINE gfromBytes #-}-    greadBytes = unsafeCoerce# (greadBytes @f)-    {-# INLINE greadBytes #-}-    gwriteBytes t  mba i ~(M1 a) = gwriteBytes t  mba i a-    {-# INLINE gwriteBytes #-}-    greadAddr = unsafeCoerce# (greadAddr @f)-    {-# INLINE greadAddr #-}-    gwriteAddr t ~(M1 a) = gwriteAddr t a-    {-# INLINE gwriteAddr #-}-    gbyteSize ~(M1 a) = gbyteSize a-    {-# INLINE gbyteSize #-}-    gbyteAlign ~(M1 a) = gbyteAlign a-    {-# INLINE gbyteAlign #-}-    gbyteOffset ~(M1 a) = gbyteOffset a-    {-# INLINE gbyteOffset #-}-    gconTags ~(M1 a) = gconTags a-    {-# INLINE gconTags #-}---instance (GPrimBytes f, GPrimBytes g) => GPrimBytes (f :*: g) where-    -- | This function return not pinned byte array, which is aligned to-    --   @SIZEOF_HSWORD@.-    --   Thus, it ignores alignment of the underlying data type if it is larger.-    --   However, alignment calculation still makes sense for data types-    --   that are smaller than @SIZEOF_HSWORD@ bytes: they are packed more densely.-    ggetBytes xy = case runRW#-       ( \s0 -> case newByteArray# (gbyteSize xy) s0 of-           (# s1, marr #) -> unsafeFreezeByteArray# marr-             (gwriteBytes 0## marr 0# xy s1)-       ) of (# _, a #) -> a-    {-# NOINLINE ggetBytes #-}-    gfromBytes _ i ba = x :*: y-      where-        x = gfromBytes 0## i ba-        y = gfromBytes 0## (i +# roundUpInt# (gbyteSize x) (gbyteAlign y)) ba-    {-# INLINE gfromBytes #-}-    greadBytes _ mba i s0 = case greadBytes 0## mba i s0 of-      (# s1, x #) -> case greadBytes 0## mba-                            (i +# roundUpInt# (gbyteSize x)-                                              (gbyteAlign @g undefined)-                            ) s1 of-        (# s2, y #) -> (# s2, x :*: y #)-    {-# INLINE greadBytes #-}-    gwriteBytes _ mba off ~(x :*: y) s =-      gwriteBytes 0## mba (off +# roundUpInt# (gbyteSize x) (gbyteAlign y)) y-      (gwriteBytes 0## mba off x s)-    {-# INLINE gwriteBytes #-}-    greadAddr _ addr s0 = case greadAddr 0## addr s0 of-      (# s1, x #) -> case greadAddr 0##-                            (plusAddr# addr-                              (roundUpInt# (gbyteSize x)-                                           (gbyteAlign @g undefined))-                            ) s1 of-        (# s2, y #) -> (# s2, x :*: y #)-    {-# INLINE greadAddr #-}-    gwriteAddr _ ~(x :*: y) addr s =-      gwriteAddr 0## y (plusAddr# addr (roundUpInt# (gbyteSize x) (gbyteAlign y)))-      (gwriteAddr 0## x addr s)-    {-# INLINE gwriteAddr #-}-    gbyteSize ~(x :*: y)-      = gbyteSize y +# roundUpInt# (gbyteSize x) (gbyteAlign y)-    {-# INLINE gbyteSize #-}-    gbyteAlign ~(x :*: y) = maxInt# (gbyteAlign x) (gbyteAlign y)-    {-# INLINE gbyteAlign #-}-    gbyteOffset _ = 0#-    {-# INLINE gbyteOffset #-}-    gconTags _ = 1##-    {-# INLINE gconTags #-}----- | Reserve 4 bytes for tag and try to pack alternatives as good as possible.-instance (GPrimBytes f, GPrimBytes g) => GPrimBytes (f :+: g) where-    ggetBytes xy = case runRW#-       ( \s0 -> case newByteArray# (gbyteSize xy) s0 of-           (# s1, marr #) -> unsafeFreezeByteArray# marr-             (gwriteBytes 0## marr 0# xy s1)-       ) of (# _, a #) -> a-    {-# NOINLINE ggetBytes #-}-    gfromBytes toff off ba-      = case (# gconTags (undefined :: f a)-              , gconTags (undefined :: g a)-              , indexWord32Array# ba (uncheckedIShiftRL# off 2#)-                       `minusWord#` toff-              #) of-         (# 1##, _  , 0## #) -> L1 (gfromBytes 0## (off +# 4#) ba)-         (# cl , 1##, t   #)-           | isTrue# (eqWord# cl t) -> R1 (gfromBytes 0## (off +# 4#) ba)-         (# cl , _  , t   #)-           | isTrue# (geWord# cl t) -> L1 (gfromBytes toff off ba)-           | otherwise -> R1 (gfromBytes (plusWord# toff cl) off ba)-    {-# INLINE gfromBytes #-}-    greadBytes toff mba off s0-      = case readWord32Array# mba (uncheckedIShiftRL# off 2#) s0 of-        (# s1, tval #) -> case (# gconTags (undefined :: f a)-                                , gconTags (undefined :: g a)-                                , tval `minusWord#` toff-                                #) of-         (# 1##, _  , 0## #) -> case greadBytes 0## mba (off +# 4#) s1 of-             (# s2, r #) -> (# s2, L1 r #)-         (# cl , 1##, t   #)-           | isTrue# (eqWord# cl t) -> case greadBytes 0## mba (off +# 4#) s1 of-             (# s2, r #) -> (# s2, R1 r #)-         (# cl , _  , t   #)-           | isTrue# (geWord# cl t) -> case greadBytes toff mba off s1 of-             (# s2, r #) -> (# s2, L1 r #)-           | otherwise -> case greadBytes (plusWord# toff cl) mba off s1 of-             (# s2, r #) -> (# s2, R1 r #)-    {-# INLINE greadBytes #-}-    gwriteBytes t mba off (L1 x) s-      = case gconTags x of-          1## -> gwriteBytes 0## mba (off +# 4#) x-                 (writeWord32Array# mba (uncheckedIShiftRL# off 2#) t s)-          _   -> gwriteBytes t mba off x s-    gwriteBytes t mba off xy@(R1 y) s-      = case (# gconTags y, plusWord# t (gconTags (undef1 @f xy)) #) of-          (# 1## , t' #) -> gwriteBytes 0## mba (off +# 4#) y-              (writeWord32Array# mba (uncheckedIShiftRL# off 2#) t' s)-          (# _   , t' #) -> gwriteBytes t' mba off y s-    {-# INLINE gwriteBytes #-}-    greadAddr toff addr s0-      = case readWord32OffAddr# addr 0# s0 of-        (# s1, tval #) -> case (# gconTags (undefined :: f a)-                                , gconTags (undefined :: g a)-                                , tval `minusWord#` toff-                                #) of-         (# 1##, _  , 0## #) -> case greadAddr 0## (plusAddr# addr 4#) s1 of-             (# s2, r #) -> (# s2, L1 r #)-         (# cl , 1##, t   #)-           | isTrue# (eqWord# cl t) -> case greadAddr 0## (plusAddr# addr 4#) s1 of-             (# s2, r #) -> (# s2, R1 r #)-         (# cl , _  , t   #)-           | isTrue# (geWord# cl t) -> case greadAddr toff addr s1 of-             (# s2, r #) -> (# s2, L1 r #)-           | otherwise -> case greadAddr (plusWord# toff cl) addr s1 of-             (# s2, r #) -> (# s2, R1 r #)-    {-# INLINE greadAddr #-}-    gwriteAddr t (L1 x) addr s-      = case gconTags x of-          1## -> gwriteAddr 0## x (plusAddr# addr 4#)-                 (writeWord32OffAddr# addr 0# t s)-          _   -> gwriteAddr t x addr s-    gwriteAddr t xy@(R1 y) addr s-      = case (# gconTags y, plusWord# t (gconTags (undef1 @f xy)) #) of-          (# 1## , t' #) -> gwriteAddr 0## y (plusAddr# addr 4#)-                              (writeWord32OffAddr# addr 0# t' s)-          (# _   , t' #) -> gwriteAddr t' y addr s-    {-# INLINE gwriteAddr #-}-    gbyteSize xy = maxInt#-        (roundUpInt# 4# (gbyteAlign x) +# gbyteSize x)-        (roundUpInt# 4# (gbyteAlign y) +# gbyteSize y)-      where-        x = undef1 @f xy-        y = undef1 @g xy-    {-# INLINE gbyteSize #-}-    gbyteAlign xy = maxInt# 4# ( maxInt# (gbyteAlign (undef1 @f xy))-                                         (gbyteAlign (undef1 @g xy))-                               )-    {-# INLINE gbyteAlign #-}-    gbyteOffset _ = 0#-    {-# INLINE gbyteOffset #-}-    gconTags xy = gconTags (undef1 @f xy) `plusWord#` gconTags (undef1 @g xy)-    {-# INLINE gconTags #-}--maxInt# :: Int# -> Int# -> Int#-maxInt# a b | isTrue# (a ># b) = a-            | otherwise        = b--roundUpInt# :: Int# -> Int# -> Int#-roundUpInt# a b = case remInt# a b of-  0# -> a-  q  -> a +# b -# q-{-# INLINE roundUpInt# #-}--undef1 :: forall p q a . q a -> p a-undef1 = const undefined-{-# INLINE undef1 #-}----#if SIZEOF_HSWORD == 4-#define OFFSHIFT_W 2-#else-#define OFFSHIFT_W 3-#endif--instance GPrimBytes (URec Word) where-    ggetBytes x = case runRW#-      ( \s0 -> case newByteArray# SIZEOF_HSWORD# s0 of-         (# s1, marr #) -> case writeWordArray# marr 0# (uWord# x) s1 of-             s2 -> unsafeFreezeByteArray# marr s2-      ) of (# _, a #) -> a-    {-# NOINLINE ggetBytes #-}-    gfromBytes _ off ba-      = UWord (indexWordArray# ba (uncheckedIShiftRL# off OFFSHIFT_W#))-    {-# INLINE gfromBytes #-}-    greadBytes _ mba off s-      = case readWordArray# mba (uncheckedIShiftRL# off OFFSHIFT_W#) s of-          (# s1, r #) -> (# s1, UWord r #)-    {-# INLINE greadBytes #-}-    gwriteBytes _ mba off x-      = writeWordArray# mba (uncheckedIShiftRL# off OFFSHIFT_W#) (uWord# x)-    {-# INLINE gwriteBytes #-}-    greadAddr _ a s-      = case readWordOffAddr# a 0# s of (# s', x #) -> (# s', UWord x #)-    {-# INLINE greadAddr #-}-    gwriteAddr _ x a-      = writeWordOffAddr# a 0# (uWord# x)-    {-# INLINE gwriteAddr #-}-    gbyteSize _ = SIZEOF_HSWORD#-    {-# INLINE gbyteSize #-}-    gbyteAlign _ = ALIGNMENT_HSWORD#-    {-# INLINE gbyteAlign #-}-    gbyteOffset _ = 0#-    {-# INLINE gbyteOffset #-}-    gconTags _ = 0##-    {-# INLINE gconTags #-}--#if SIZEOF_HSINT == 4-#define OFFSHIFT_I 2-#else-#define OFFSHIFT_I 3-#endif--instance GPrimBytes (URec Int) where-    ggetBytes x = case runRW#-      ( \s0 -> case newByteArray# SIZEOF_HSINT# s0 of-         (# s1, marr #) -> case writeIntArray# marr 0# (uInt# x) s1 of-             s2 -> unsafeFreezeByteArray# marr s2-      ) of (# _, a #) -> a-    {-# NOINLINE ggetBytes #-}-    gfromBytes _ off ba-      = UInt (indexIntArray# ba (uncheckedIShiftRL# off OFFSHIFT_I#))-    {-# INLINE gfromBytes #-}-    greadBytes _ mba off s-      = case readIntArray# mba (uncheckedIShiftRL# off OFFSHIFT_I#) s of-          (# s1, r #) -> (# s1, UInt r #)-    {-# INLINE greadBytes #-}-    gwriteBytes _ mba off x-      = writeIntArray# mba (uncheckedIShiftRL# off OFFSHIFT_I#) (uInt# x)-    {-# INLINE gwriteBytes #-}-    greadAddr _ a s-      = case readIntOffAddr# a 0# s of (# s', x #) -> (# s', UInt x #)-    {-# INLINE greadAddr #-}-    gwriteAddr _ x a-      = writeIntOffAddr# a 0# (uInt# x)-    {-# INLINE gwriteAddr #-}-    gbyteSize _ = SIZEOF_HSINT#-    {-# INLINE gbyteSize #-}-    gbyteAlign _ = ALIGNMENT_HSINT#-    {-# INLINE gbyteAlign #-}-    gbyteOffset _ = 0#-    {-# INLINE gbyteOffset #-}-    gconTags _ = 0##-    {-# INLINE gconTags #-}---#if SIZEOF_HSFLOAT == 4-#define OFFSHIFT_F 2-#else-#define OFFSHIFT_F 3-#endif--instance GPrimBytes (URec Float) where-    ggetBytes x = case runRW#-      ( \s0 -> case newByteArray# SIZEOF_HSFLOAT# s0 of-         (# s1, marr #) -> case writeFloatArray# marr 0# (uFloat# x) s1 of-             s2 -> unsafeFreezeByteArray# marr s2-      ) of (# _, a #) -> a-    {-# NOINLINE ggetBytes #-}-    gfromBytes _ off ba-      = UFloat (indexFloatArray# ba (uncheckedIShiftRL# off OFFSHIFT_F#))-    {-# INLINE gfromBytes #-}-    greadBytes _ mba off s-      = case readFloatArray# mba (uncheckedIShiftRL# off OFFSHIFT_F#) s of-          (# s1, r #) -> (# s1, UFloat r #)-    {-# INLINE greadBytes #-}-    gwriteBytes _ mba off x-      = writeFloatArray# mba (uncheckedIShiftRL# off OFFSHIFT_F#) (uFloat# x)-    {-# INLINE gwriteBytes #-}-    greadAddr _ a s-      = case readFloatOffAddr# a 0# s of (# s', x #) -> (# s', UFloat x #)-    {-# INLINE greadAddr #-}-    gwriteAddr _ x a-      = writeFloatOffAddr# a 0# (uFloat# x)-    {-# INLINE gwriteAddr #-}-    gbyteSize _ = SIZEOF_HSFLOAT#-    {-# INLINE gbyteSize #-}-    gbyteAlign _ = ALIGNMENT_HSFLOAT#-    {-# INLINE gbyteAlign #-}-    gbyteOffset _ = 0#-    {-# INLINE gbyteOffset #-}-    gconTags _ = 0##-    {-# INLINE gconTags #-}--#if SIZEOF_HSDOUBLE == 4-#define OFFSHIFT_D 2-#else-#define OFFSHIFT_D 3-#endif--instance GPrimBytes (URec Double) where-    ggetBytes x = case runRW#-      ( \s0 -> case newByteArray# SIZEOF_HSDOUBLE# s0 of-         (# s1, marr #) -> case writeDoubleArray# marr 0# (uDouble# x) s1 of-             s2 -> unsafeFreezeByteArray# marr s2-      ) of (# _, a #) -> a-    {-# NOINLINE ggetBytes #-}-    gfromBytes _ off ba-      = UDouble (indexDoubleArray# ba (uncheckedIShiftRL# off OFFSHIFT_D#))-    {-# INLINE gfromBytes #-}-    greadBytes _ mba off s-      = case readDoubleArray# mba (uncheckedIShiftRL# off OFFSHIFT_D#) s of-          (# s1, r #) -> (# s1, UDouble r #)-    {-# INLINE greadBytes #-}-    gwriteBytes _ mba off x-      = writeDoubleArray# mba (uncheckedIShiftRL# off OFFSHIFT_D#) (uDouble# x)-    {-# INLINE gwriteBytes #-}-    greadAddr _ a s-      = case readDoubleOffAddr# a 0# s of (# s', x #) -> (# s', UDouble x #)-    {-# INLINE greadAddr #-}-    gwriteAddr _ x a-      = writeDoubleOffAddr# a 0# (uDouble# x)-    {-# INLINE gwriteAddr #-}-    gbyteSize _ = SIZEOF_HSDOUBLE#-    {-# INLINE gbyteSize #-}-    gbyteAlign _ = ALIGNMENT_HSDOUBLE#-    {-# INLINE gbyteAlign #-}-    gbyteOffset _ = 0#-    {-# INLINE gbyteOffset #-}-    gconTags _ = 0##-    {-# INLINE gconTags #-}--#if SIZEOF_HSCHAR == 2-#define OFFSHIFT_C 1-#elif SIZEOF_HSCHAR == 4-#define OFFSHIFT_C 2-#else-#define OFFSHIFT_C 3-#endif--instance GPrimBytes (URec Char) where-    ggetBytes x = case runRW#-      ( \s0 -> case newByteArray# SIZEOF_HSCHAR# s0 of-         (# s1, marr #) -> case writeCharArray# marr 0# (uChar# x) s1 of-             s2 -> unsafeFreezeByteArray# marr s2-      ) of (# _, a #) -> a-    {-# NOINLINE ggetBytes #-}-    gfromBytes _ off ba-      = UChar (indexCharArray# ba (uncheckedIShiftRL# off OFFSHIFT_C#))-    {-# INLINE gfromBytes #-}-    greadBytes _ mba off s-      = case readCharArray# mba (uncheckedIShiftRL# off OFFSHIFT_C#) s of-          (# s1, r #) -> (# s1, UChar r #)-    {-# INLINE greadBytes #-}-    gwriteBytes _ mba off x-      = writeCharArray# mba (uncheckedIShiftRL# off OFFSHIFT_C#) (uChar# x)-    {-# INLINE gwriteBytes #-}-    greadAddr _ a s-      = case readCharOffAddr# a 0# s of (# s', x #) -> (# s', UChar x #)-    {-# INLINE greadAddr #-}-    gwriteAddr _ x a-      = writeCharOffAddr# a 0# (uChar# x)-    {-# INLINE gwriteAddr #-}-    gbyteSize _ = SIZEOF_HSCHAR#-    {-# INLINE gbyteSize #-}-    gbyteAlign _ = ALIGNMENT_HSCHAR#-    {-# INLINE gbyteAlign #-}-    gbyteOffset _ = 0#-    {-# INLINE gbyteOffset #-}-    gconTags _ = 0##-    {-# INLINE gconTags #-}--#if SIZEOF_HSPTR == 4-#define OFFSHIFT_P 2-#else-#define OFFSHIFT_P 3-#endif--instance GPrimBytes (URec (Ptr ())) where-    ggetBytes x = case runRW#-      ( \s0 -> case newByteArray# SIZEOF_HSPTR# s0 of-         (# s1, marr #) -> case writeAddrArray# marr 0# (uAddr# x) s1 of-             s2 -> unsafeFreezeByteArray# marr s2-      ) of (# _, a #) -> a-    {-# NOINLINE ggetBytes #-}-    gfromBytes _ off ba-      = UAddr (indexAddrArray# ba (uncheckedIShiftRL# off OFFSHIFT_P#))-    {-# INLINE gfromBytes #-}-    greadBytes _ mba off s-      = case readAddrArray# mba (uncheckedIShiftRL# off OFFSHIFT_P#) s of-          (# s1, r #) -> (# s1, UAddr r #)-    {-# INLINE greadBytes #-}-    gwriteBytes _ mba off x-      = writeAddrArray# mba (uncheckedIShiftRL# off OFFSHIFT_P#) (uAddr# x)-    {-# INLINE gwriteBytes #-}-    greadAddr _ a s-      = case readAddrOffAddr# a 0# s of (# s', x #) -> (# s', UAddr x #)-    {-# INLINE greadAddr #-}-    gwriteAddr _ x a-      = writeAddrOffAddr# a 0# (uAddr# x)-    {-# INLINE gwriteAddr #-}-    gbyteSize _ = SIZEOF_HSPTR#-    {-# INLINE gbyteSize #-}-    gbyteAlign _ = ALIGNMENT_HSPTR#-    {-# INLINE gbyteAlign #-}-    gbyteOffset _ = 0#-    {-# INLINE gbyteOffset #-}-    gconTags _ = 0##-    {-# INLINE gconTags #-}---------------------------------------------------------------------------------------- Basic instances------------------------------------------------------------------------------------instance PrimBytes Word where-    getBytes (W# x) = case runRW#-      ( \s0 -> case newByteArray# SIZEOF_HSWORD# s0 of-         (# s1, marr #) -> case writeWordArray# marr 0# x s1 of-             s2 -> unsafeFreezeByteArray# marr s2-      ) of (# _, a #) -> a-    {-# NOINLINE getBytes #-}-    fromBytes off ba-      = W# (indexWordArray# ba (uncheckedIShiftRL# off OFFSHIFT_W#))-    {-# INLINE fromBytes #-}-    readBytes mba off-      = readArray mba (uncheckedIShiftRL# off OFFSHIFT_W#)-    {-# INLINE readBytes #-}-    writeBytes mba off-      = writeArray mba (uncheckedIShiftRL# off OFFSHIFT_W#)-    {-# INLINE writeBytes #-}-    readAddr a s-      = case readWordOffAddr# a 0# s of (# s', x #) -> (# s', W# x #)-    {-# INLINE readAddr #-}-    writeAddr (W# x) a-      = writeWordOffAddr# a 0# x-    {-# INLINE writeAddr #-}-    byteSize _ = SIZEOF_HSWORD#-    {-# INLINE byteSize #-}-    byteAlign _ = ALIGNMENT_HSWORD#-    {-# INLINE byteAlign #-}-    byteOffset _ = 0#-    {-# INLINE byteOffset #-}-    indexArray ba i = W# (indexWordArray# ba i)-    {-# INLINE indexArray #-}-    readArray mba i s-      = case readWordArray# mba i s of (# s', x #) -> (# s', W# x #)-    {-# INLINE readArray #-}-    writeArray mba i (W# x) = writeWordArray# mba i x-    {-# INLINE writeArray #-}---instance PrimBytes Int where-    getBytes (I# x) = case runRW#-      ( \s0 -> case newByteArray# SIZEOF_HSINT# s0 of-         (# s1, marr #) -> case writeIntArray# marr 0# x s1 of-             s2 -> unsafeFreezeByteArray# marr s2-      ) of (# _, a #) -> a-    {-# NOINLINE getBytes #-}-    fromBytes off ba-      = I# (indexIntArray# ba (uncheckedIShiftRL# off OFFSHIFT_I#))-    {-# INLINE fromBytes #-}-    readBytes mba off-      = readArray mba (uncheckedIShiftRL# off OFFSHIFT_I#)-    {-# INLINE readBytes #-}-    writeBytes mba off-      = writeArray mba (uncheckedIShiftRL# off OFFSHIFT_I#)-    {-# INLINE writeBytes #-}-    readAddr a s-      = case readIntOffAddr# a 0# s of (# s', x #) -> (# s', I# x #)-    {-# INLINE readAddr #-}-    writeAddr (I# x) a-      = writeIntOffAddr# a 0# x-    {-# INLINE writeAddr #-}-    byteSize _ = SIZEOF_HSINT#-    {-# INLINE byteSize #-}-    byteAlign _ = ALIGNMENT_HSINT#-    {-# INLINE byteAlign #-}-    byteOffset _ = 0#-    {-# INLINE byteOffset #-}-    indexArray ba i = I# (indexIntArray# ba i)-    {-# INLINE indexArray #-}-    readArray mba i s-      = case readIntArray# mba i s of (# s', x #) -> (# s', I# x #)-    {-# INLINE readArray #-}-    writeArray mba i (I# x) = writeIntArray# mba i x-    {-# INLINE writeArray #-}--instance PrimBytes Float where-    getBytes (F# x) = case runRW#-      ( \s0 -> case newByteArray# SIZEOF_HSFLOAT# s0 of-         (# s1, marr #) -> case writeFloatArray# marr 0# x s1 of-             s2 -> unsafeFreezeByteArray# marr s2-      ) of (# _, a #) -> a-    {-# NOINLINE getBytes #-}-    fromBytes off ba-      = F# (indexFloatArray# ba (uncheckedIShiftRL# off OFFSHIFT_F#))-    {-# INLINE fromBytes #-}-    readBytes mba off-      = readArray mba (uncheckedIShiftRL# off OFFSHIFT_F#)-    {-# INLINE readBytes #-}-    writeBytes mba off-      = writeArray mba (uncheckedIShiftRL# off OFFSHIFT_F#)-    {-# INLINE writeBytes #-}-    readAddr a s-      = case readFloatOffAddr# a 0# s of (# s', x #) -> (# s', F# x #)-    {-# INLINE readAddr #-}-    writeAddr (F# x) a-      = writeFloatOffAddr# a 0# x-    {-# INLINE writeAddr #-}-    byteSize _ = SIZEOF_HSFLOAT#-    {-# INLINE byteSize #-}-    byteAlign _ = ALIGNMENT_HSFLOAT#-    {-# INLINE byteAlign #-}-    byteOffset _ = 0#-    {-# INLINE byteOffset #-}-    indexArray ba i = F# (indexFloatArray# ba i)-    {-# INLINE indexArray #-}-    readArray mba i s-      = case readFloatArray# mba i s of (# s', x #) -> (# s', F# x #)-    {-# INLINE readArray #-}-    writeArray mba i (F# x) = writeFloatArray# mba i x-    {-# INLINE writeArray #-}--instance PrimBytes Double where-    getBytes (D# x) = case runRW#-      ( \s0 -> case newByteArray# SIZEOF_HSDOUBLE# s0 of-         (# s1, marr #) -> case writeDoubleArray# marr 0# x s1 of-             s2 -> unsafeFreezeByteArray# marr s2-      ) of (# _, a #) -> a-    {-# NOINLINE getBytes #-}-    fromBytes off ba-      = D# (indexDoubleArray# ba (uncheckedIShiftRL# off OFFSHIFT_D#))-    {-# INLINE fromBytes #-}-    readBytes mba off-      = readArray mba (uncheckedIShiftRL# off OFFSHIFT_D#)-    {-# INLINE readBytes #-}-    writeBytes mba off-      = writeArray mba (uncheckedIShiftRL# off OFFSHIFT_D#)-    {-# INLINE writeBytes #-}-    readAddr a s-      = case readDoubleOffAddr# a 0# s of (# s', x #) -> (# s', D# x #)-    {-# INLINE readAddr #-}-    writeAddr (D# x) a-      = writeDoubleOffAddr# a 0# x-    {-# INLINE writeAddr #-}-    byteSize _ = SIZEOF_HSDOUBLE#-    {-# INLINE byteSize #-}-    byteAlign _ = ALIGNMENT_HSDOUBLE#-    {-# INLINE byteAlign #-}-    byteOffset _ = 0#-    {-# INLINE byteOffset #-}-    indexArray ba i = D# (indexDoubleArray# ba i)-    {-# INLINE indexArray #-}-    readArray mba i s-      = case readDoubleArray# mba i s of (# s', x #) -> (# s', D# x #)-    {-# INLINE readArray #-}-    writeArray mba i (D# x) = writeDoubleArray# mba i x-    {-# INLINE writeArray #-}---instance PrimBytes (Ptr a) where-    getBytes (Ptr x) = case runRW#-      ( \s0 -> case newByteArray# SIZEOF_HSPTR# s0 of-         (# s1, marr #) -> case writeAddrArray# marr 0# x s1 of-             s2 -> unsafeFreezeByteArray# marr s2-      ) of (# _, a #) -> a-    {-# NOINLINE getBytes #-}-    fromBytes off ba-      = Ptr (indexAddrArray# ba (uncheckedIShiftRL# off OFFSHIFT_P#))-    {-# INLINE fromBytes #-}-    readBytes mba off-      = readArray mba (uncheckedIShiftRL# off OFFSHIFT_P#)-    {-# INLINE readBytes #-}-    writeBytes mba off-      = writeArray mba (uncheckedIShiftRL# off OFFSHIFT_P#)-    {-# INLINE writeBytes #-}-    readAddr a s-      = case readAddrOffAddr# a 0# s of (# s', x #) -> (# s', Ptr x #)-    {-# INLINE readAddr #-}-    writeAddr (Ptr x) a-      = writeAddrOffAddr# a 0# x-    {-# INLINE writeAddr #-}-    byteSize _ = SIZEOF_HSPTR#-    {-# INLINE byteSize #-}-    byteAlign _ = ALIGNMENT_HSPTR#-    {-# INLINE byteAlign #-}-    byteOffset _ = 0#-    {-# INLINE byteOffset #-}-    indexArray ba i = Ptr (indexAddrArray# ba i)-    {-# INLINE indexArray #-}-    readArray mba i s-      = case readAddrArray# mba i s of (# s', x #) -> (# s', Ptr x #)-    {-# INLINE readArray #-}-    writeArray mba i (Ptr x) = writeAddrArray# mba i x-    {-# INLINE writeArray #-}---instance PrimBytes Int8 where-    getBytes (I8# x) = case runRW#-      ( \s0 -> case newByteArray# SIZEOF_INT8# s0 of-         (# s1, marr #) -> case writeInt8Array# marr 0# x s1 of-             s2 -> unsafeFreezeByteArray# marr s2-      ) of (# _, a #) -> a-    {-# NOINLINE getBytes #-}-    fromBytes off ba = indexArray ba off-    {-# INLINE fromBytes #-}-    readBytes = readArray-    {-# INLINE readBytes #-}-    writeBytes = writeArray-    {-# INLINE writeBytes #-}-    readAddr a s-      = case readInt8OffAddr# a 0# s of (# s', x #) -> (# s', I8# x #)-    {-# INLINE readAddr #-}-    writeAddr (I8# x) a-      = writeInt8OffAddr# a 0# x-    {-# INLINE writeAddr #-}-    byteSize _ = SIZEOF_INT8#-    {-# INLINE byteSize #-}-    byteAlign _ = ALIGNMENT_INT8#-    {-# INLINE byteAlign #-}-    byteOffset _ = 0#-    {-# INLINE byteOffset #-}-    indexArray ba i = I8# (indexInt8Array# ba i)-    {-# INLINE indexArray #-}-    readArray mba i s-      = case readInt8Array# mba i s of (# s', x #) -> (# s', I8# x #)-    {-# INLINE readArray #-}-    writeArray mba i (I8# x) = writeInt8Array# mba i x-    {-# INLINE writeArray #-}--instance PrimBytes Int16 where-    getBytes (I16# x) = case runRW#-      ( \s0 -> case newByteArray# SIZEOF_INT16# s0 of-         (# s1, marr #) -> case writeInt16Array# marr 0# x s1 of-             s2 -> unsafeFreezeByteArray# marr s2-      ) of (# _, a #) -> a-    {-# NOINLINE getBytes #-}-    fromBytes off ba-      = indexArray ba (uncheckedIShiftRL# off 1#)-    {-# INLINE fromBytes #-}-    readBytes mba off-      = readArray mba (uncheckedIShiftRL# off 1#)-    {-# INLINE readBytes #-}-    writeBytes mba off-      = writeArray mba (uncheckedIShiftRL# off 1#)-    {-# INLINE writeBytes #-}-    readAddr a s-      = case readInt16OffAddr# a 0# s of (# s', x #) -> (# s', I16# x #)-    {-# INLINE readAddr #-}-    writeAddr (I16# x) a-      = writeInt16OffAddr# a 0# x-    {-# INLINE writeAddr #-}-    byteSize _ = SIZEOF_INT16#-    {-# INLINE byteSize #-}-    byteAlign _ = ALIGNMENT_INT16#-    {-# INLINE byteAlign #-}-    byteOffset _ = 0#-    {-# INLINE byteOffset #-}-    indexArray ba i = I16# (indexInt16Array# ba i)-    {-# INLINE indexArray #-}-    readArray mba i s-      = case readInt16Array# mba i s of (# s', x #) -> (# s', I16# x #)-    {-# INLINE readArray #-}-    writeArray mba i (I16# x) = writeInt16Array# mba i x-    {-# INLINE writeArray #-}--instance PrimBytes Int32 where-    getBytes (I32# x) = case runRW#-      ( \s0 -> case newByteArray# SIZEOF_INT32# s0 of-         (# s1, marr #) -> case writeInt32Array# marr 0# x s1 of-             s2 -> unsafeFreezeByteArray# marr s2-      ) of (# _, a #) -> a-    {-# NOINLINE getBytes #-}-    fromBytes off ba-      = indexArray ba (uncheckedIShiftRL# off 2#)-    {-# INLINE fromBytes #-}-    readBytes mba off-      = readArray mba (uncheckedIShiftRL# off 2#)-    {-# INLINE readBytes #-}-    writeBytes mba off-      = writeArray mba (uncheckedIShiftRL# off 2#)-    {-# INLINE writeBytes #-}-    readAddr a s-      = case readInt32OffAddr# a 0# s of (# s', x #) -> (# s', I32# x #)-    {-# INLINE readAddr #-}-    writeAddr (I32# x) a-      = writeInt32OffAddr# a 0# x-    {-# INLINE writeAddr #-}-    byteSize _ = SIZEOF_INT32#-    {-# INLINE byteSize #-}-    byteAlign _ = ALIGNMENT_INT32#-    {-# INLINE byteAlign #-}-    byteOffset _ = 0#-    {-# INLINE byteOffset #-}-    indexArray ba i = I32# (indexInt32Array# ba i)-    {-# INLINE indexArray #-}-    readArray mba i s-      = case readInt32Array# mba i s of (# s', x #) -> (# s', I32# x #)-    {-# INLINE readArray #-}-    writeArray mba i (I32# x) = writeInt32Array# mba i x-    {-# INLINE writeArray #-}--instance PrimBytes Int64 where-    getBytes (I64# x) = case runRW#-      ( \s0 -> case newByteArray# SIZEOF_INT64# s0 of-         (# s1, marr #) -> case writeInt64Array# marr 0# x s1 of-             s2 -> unsafeFreezeByteArray# marr s2-      ) of (# _, a #) -> a-    {-# NOINLINE getBytes #-}-    fromBytes off ba-      = indexArray ba (uncheckedIShiftRL# off 3#)-    {-# INLINE fromBytes #-}-    readBytes mba off-      = readArray mba (uncheckedIShiftRL# off 3#)-    {-# INLINE readBytes #-}-    writeBytes mba off-      = writeArray mba (uncheckedIShiftRL# off 3#)-    {-# INLINE writeBytes #-}-    readAddr a s-      = case readInt64OffAddr# a 0# s of (# s', x #) -> (# s', I64# x #)-    {-# INLINE readAddr #-}-    writeAddr (I64# x) a-      = writeInt64OffAddr# a 0# x-    {-# INLINE writeAddr #-}-    byteSize _ = SIZEOF_INT64#-    {-# INLINE byteSize #-}-    byteAlign _ = ALIGNMENT_INT64#-    {-# INLINE byteAlign #-}-    byteOffset _ = 0#-    {-# INLINE byteOffset #-}-    indexArray ba i = I64# (indexInt64Array# ba i)-    {-# INLINE indexArray #-}-    readArray mba i s-      = case readInt64Array# mba i s of (# s', x #) -> (# s', I64# x #)-    {-# INLINE readArray #-}-    writeArray mba i (I64# x) = writeInt64Array# mba i x-    {-# INLINE writeArray #-}--instance PrimBytes Word8 where-    getBytes (W8# x) = case runRW#-      ( \s0 -> case newByteArray# SIZEOF_WORD8# s0 of-         (# s1, marr #) -> case writeWord8Array# marr 0# x s1 of-             s2 -> unsafeFreezeByteArray# marr s2-      ) of (# _, a #) -> a-    {-# NOINLINE getBytes #-}-    fromBytes off ba = indexArray ba off-    {-# INLINE fromBytes #-}-    readBytes = readArray-    {-# INLINE readBytes #-}-    writeBytes = writeArray-    {-# INLINE writeBytes #-}-    readAddr a s-      = case readWord8OffAddr# a 0# s of (# s', x #) -> (# s', W8# x #)-    {-# INLINE readAddr #-}-    writeAddr (W8# x) a-      = writeWord8OffAddr# a 0# x-    {-# INLINE writeAddr #-}-    byteSize _ = SIZEOF_WORD8#-    {-# INLINE byteSize #-}-    byteAlign _ = ALIGNMENT_WORD8#-    {-# INLINE byteAlign #-}-    byteOffset _ = 0#-    {-# INLINE byteOffset #-}-    indexArray ba i = W8# (indexWord8Array# ba i)-    {-# INLINE indexArray #-}-    readArray mba i s-      = case readWord8Array# mba i s of (# s', x #) -> (# s', W8# x #)-    {-# INLINE readArray #-}-    writeArray mba i (W8# x) = writeWord8Array# mba i x-    {-# INLINE writeArray #-}--instance PrimBytes Word16 where-    getBytes (W16# x) = case runRW#-      ( \s0 -> case newByteArray# SIZEOF_WORD16# s0 of-         (# s1, marr #) -> case writeWord16Array# marr 0# x s1 of-             s2 -> unsafeFreezeByteArray# marr s2-      ) of (# _, a #) -> a-    {-# NOINLINE getBytes #-}-    fromBytes off ba-      = indexArray ba (uncheckedIShiftRL# off 1#)-    {-# INLINE fromBytes #-}-    readBytes mba off-      = readArray mba (uncheckedIShiftRL# off 1#)-    {-# INLINE readBytes #-}-    writeBytes mba off-      = writeArray mba (uncheckedIShiftRL# off 1#)-    {-# INLINE writeBytes #-}-    readAddr a s-      = case readWord16OffAddr# a 0# s of (# s', x #) -> (# s', W16# x #)-    {-# INLINE readAddr #-}-    writeAddr (W16# x) a-      = writeWord16OffAddr# a 0# x-    {-# INLINE writeAddr #-}-    byteSize _ = SIZEOF_WORD16#-    {-# INLINE byteSize #-}-    byteAlign _ = ALIGNMENT_WORD16#-    {-# INLINE byteAlign #-}-    byteOffset _ = 0#-    {-# INLINE byteOffset #-}-    indexArray ba i = W16# (indexWord16Array# ba i)-    {-# INLINE indexArray #-}-    readArray mba i s-      = case readWord16Array# mba i s of (# s', x #) -> (# s', W16# x #)-    {-# INLINE readArray #-}-    writeArray mba i (W16# x) = writeWord16Array# mba i x-    {-# INLINE writeArray #-}--instance PrimBytes Word32 where-    getBytes (W32# x) = case runRW#-      ( \s0 -> case newByteArray# SIZEOF_WORD32# s0 of-         (# s1, marr #) -> case writeWord32Array# marr 0# x s1 of-             s2 -> unsafeFreezeByteArray# marr s2-      ) of (# _, a #) -> a-    {-# NOINLINE getBytes #-}-    fromBytes off ba-      = indexArray ba (uncheckedIShiftRL# off 2#)-    {-# INLINE fromBytes #-}-    readBytes mba off-      = readArray mba (uncheckedIShiftRL# off 2#)-    {-# INLINE readBytes #-}-    writeBytes mba off-      = writeArray mba (uncheckedIShiftRL# off 2#)-    {-# INLINE writeBytes #-}-    readAddr a s-      = case readWord32OffAddr# a 0# s of (# s', x #) -> (# s', W32# x #)-    {-# INLINE readAddr #-}-    writeAddr (W32# x) a-      = writeWord32OffAddr# a 0# x-    {-# INLINE writeAddr #-}-    byteSize _ = SIZEOF_WORD32#-    {-# INLINE byteSize #-}-    byteAlign _ = ALIGNMENT_WORD32#-    {-# INLINE byteAlign #-}-    byteOffset _ = 0#-    {-# INLINE byteOffset #-}-    indexArray ba i = W32# (indexWord32Array# ba i)-    {-# INLINE indexArray #-}-    readArray mba i s-      = case readWord32Array# mba i s of (# s', x #) -> (# s', W32# x #)-    {-# INLINE readArray #-}-    writeArray mba i (W32# x) = writeWord32Array# mba i x-    {-# INLINE writeArray #-}--instance PrimBytes Word64 where-    getBytes (W64# x) = case runRW#-      ( \s0 -> case newByteArray# SIZEOF_WORD64# s0 of-         (# s1, marr #) -> case writeWord64Array# marr 0# x s1 of-             s2 -> unsafeFreezeByteArray# marr s2-      ) of (# _, a #) -> a-    {-# NOINLINE getBytes #-}-    fromBytes off ba-      = indexArray ba (uncheckedIShiftRL# off 3#)-    {-# INLINE fromBytes #-}-    readBytes mba off-      = readArray mba (uncheckedIShiftRL# off 3#)-    {-# INLINE readBytes #-}-    writeBytes mba off-      = writeArray mba (uncheckedIShiftRL# off 3#)-    {-# INLINE writeBytes #-}-    readAddr a s-      = case readWord64OffAddr# a 0# s of (# s', x #) -> (# s', W64# x #)-    {-# INLINE readAddr #-}-    writeAddr (W64# x) a-      = writeWord64OffAddr# a 0# x-    {-# INLINE writeAddr #-}-    byteSize _ = SIZEOF_WORD64#-    {-# INLINE byteSize #-}-    byteAlign _ = ALIGNMENT_WORD64#-    {-# INLINE byteAlign #-}-    byteOffset _ = 0#-    {-# INLINE byteOffset #-}-    indexArray ba i = W64# (indexWord64Array# ba i)-    {-# INLINE indexArray #-}-    readArray mba i s-      = case readWord64Array# mba i s of (# s', x #) -> (# s', W64# x #)-    {-# INLINE readArray #-}-    writeArray mba i (W64# x) = writeWord64Array# mba i x-    {-# INLINE writeArray #-}--instance PrimBytes (Idx x) where-    getBytes = unsafeCoerce# (getBytes @Word)-    {-# INLINE getBytes #-}-    fromBytes  = unsafeCoerce# (fromBytes @Word)-    {-# INLINE fromBytes #-}-    readBytes = unsafeCoerce# (readBytes @Word)-    {-# INLINE readBytes #-}-    writeBytes = unsafeCoerce# (writeBytes @Word)-    {-# INLINE writeBytes #-}-    readAddr = unsafeCoerce# (readAddr @Word)-    {-# INLINE readAddr #-}-    writeAddr = unsafeCoerce# (readAddr @Word)-    {-# INLINE writeAddr #-}-    byteSize = unsafeCoerce# (byteSize @Word)-    {-# INLINE byteSize #-}-    byteAlign = unsafeCoerce# (byteAlign @Word)-    {-# INLINE byteAlign #-}-    byteOffset = unsafeCoerce# (byteOffset @Word)-    {-# INLINE byteOffset #-}-    indexArray = unsafeCoerce# (indexArray @Word)-    {-# INLINE indexArray #-}-    readArray = unsafeCoerce# (readArray @Word)-    {-# INLINE readArray #-}-    writeArray = unsafeCoerce# (writeArray @Word)-    {-# INLINE writeArray #-}--instance RepresentableList xs => PrimBytes (Idxs xs) where-    getBytes is = case runRW#-       ( \s0 -> case newByteArray# (byteSize is) s0 of-           (# s1, marr #) -> unsafeFreezeByteArray# marr-             (writeBytes marr 0# is s1)-       ) of (# _, a #) -> a-    {-# INLINE getBytes #-}-    fromBytes off ba = unsafeCoerce#-        (go (uncheckedIShiftRL# off OFFSHIFT_W#) (unsafeCoerce# (tList @_ @xs)))-      where-        go _ []           = []-        go i (Proxy : ls) = W# (indexWordArray# ba i) : go (i +# 1#) ls-    {-# INLINE fromBytes #-}-    readBytes mba off s = unsafeCoerce#-        (go (uncheckedIShiftRL# off OFFSHIFT_W#) (unsafeCoerce# (tList @_ @xs)) s)-      where-        go _ [] s0 = (# s0, [] #)-        go i (Proxy : ls) s0 = case readWordArray# mba off s0 of-          (# s1, w #) -> case go (i +# 1#) ls s1 of-             (# s2, xs #) -> (# s2, W# w : xs #)-    {-# INLINE readBytes #-}-    writeBytes mba off is-        = go (uncheckedIShiftRL# off OFFSHIFT_W#) (listIdxs is)-      where-        go _ [] s         = s-        go i (W# x :xs) s = go (i +# 1#) xs (writeWordArray# mba i x s)-    {-# INLINE writeBytes #-}-    readAddr addr s = unsafeCoerce#-        (go addr (unsafeCoerce# (tList @_ @xs)) s)-      where-        go _ [] s0 = (# s0, [] #)-        go i (Proxy : ls) s0 = case readWordOffAddr# i 0# s0 of-          (# s1, w #) -> case go (plusAddr# i SIZEOF_HSWORD#) ls s1 of-             (# s2, xs #) -> (# s2, W# w : xs #)-    {-# INLINE readAddr #-}-    writeAddr is addr-        = go addr (listIdxs is)-      where-        go _ [] s         = s-        go i (W# x :xs) s = go (plusAddr# i SIZEOF_HSWORD#) xs-                               (writeWordOffAddr# i 0# x s)-    {-# INLINE writeAddr #-}-    byteSize _ = case dimVal (order' @xs) of-      W# n -> byteSize (undefined :: Idx x) *# word2Int# n-    {-# INLINE byteSize #-}-    byteAlign _ = byteAlign (undefined :: Idx x)-    {-# INLINE byteAlign #-}-    byteOffset _ = 0#-    {-# INLINE byteOffset #-}-    indexArray ba off-      | n@(W# n#) <- dimVal (order' @xs)-        = unsafeCoerce# (go (off *# word2Int# n#) n)-      where-        go _ 0 = []-        go i n = W# (indexWordArray# ba i) : go (i +# 1#) (n-1)-    {-# INLINE indexArray #-}-    readArray mba off s-      | n@(W# n#) <- dimVal (order' @xs)-        = unsafeCoerce# (go (off *# word2Int# n#) n s)-      where-        go _ 0 s0 = (# s0, [] #)-        go i n s0 = case readWordArray# mba off s0 of-          (# s1, w #) -> case go (i +# 1#) (n-1) s1 of-             (# s2, xs #) -> (# s2, W# w : xs #)-    {-# INLINE readArray #-}-    writeArray mba off is-      | W# n# <- dimVal (order' @xs)-        = go (off *# word2Int# n#) (listIdxs is)-      where-        go _ [] s         = s-        go i (W# x :xs) s = go (i +# 1#) xs (writeWordArray# mba i x s)-    {-# INLINE writeArray #-}--instance ( RepresentableList xs-         , L.All PrimBytes xs-         ) => PrimBytes (TL.Tuple xs) where-    getBytes   = unsafeCoerce# (getBytes @(TS.Tuple xs))-    {-# INLINE getBytes #-}-    fromBytes  = unsafeCoerce# (fromBytes @(TS.Tuple xs))-    {-# INLINE fromBytes #-}-    readBytes  = unsafeCoerce# (readBytes @(TS.Tuple xs))-    {-# INLINE readBytes #-}-    writeBytes = unsafeCoerce# (writeBytes @(TS.Tuple xs))-    {-# INLINE writeBytes #-}-    readAddr   = unsafeCoerce# (readAddr  @(TS.Tuple xs))-    {-# INLINE readAddr  #-}-    writeAddr  = unsafeCoerce# (writeAddr  @(TS.Tuple xs))-    {-# INLINE writeAddr  #-}-    byteSize   = unsafeCoerce# (byteSize @(TS.Tuple xs))-    {-# INLINE byteSize #-}-    byteAlign  = unsafeCoerce# (byteAlign @(TS.Tuple xs))-    {-# INLINE byteAlign #-}-    byteOffset = unsafeCoerce# (byteOffset @(TS.Tuple xs))-    {-# INLINE byteOffset #-}-    indexArray = unsafeCoerce# (indexArray @(TS.Tuple xs))-    {-# INLINE indexArray #-}-    readArray  = unsafeCoerce# (readArray @(TS.Tuple xs))-    {-# INLINE readArray #-}-    writeArray = unsafeCoerce# (writeArray @(TS.Tuple xs))-    {-# INLINE writeArray #-}--instance ( RepresentableList xs-         , L.All PrimBytes xs-         ) => PrimBytes (TS.Tuple xs) where-    getBytes tup = case runRW#-        ( \s0 -> case newByteArray# (byteSize tup) s0 of-           (# s1, marr #) -> unsafeFreezeByteArray# marr-             (go marr 0# tup (types tup) s1)-        ) of (# _, a #) -> a-      where-        go :: L.All PrimBytes ds => MutableByteArray# s-          -> Int# -> TS.Tuple ds -> TypeList ds -> State# s -> State# s-        go _ _ _ Empty s = s-        go mb n (TS.Id x :* xs) (_ :* ts@TypeList) s-          | n' <- roundUpInt# n (byteAlign x)-          = go mb (n' +# byteSize x) xs ts (writeBytes mb n' x s)-    {-# INLINE getBytes #-}-    fromBytes off ba = go 0# (tList @_ @xs)-      where-        go :: L.All PrimBytes ds-           => Int# -> TypeList ds -> TS.Tuple ds-        go _ Empty = Empty-        go n (t :* ts@TypeList)-          | x <- undefP t-          , n' <- roundUpInt# n (byteAlign x)-          = TS.Id (fromBytes (off +# n') ba) :* go (n' +# byteSize x) ts-    {-# INLINE fromBytes #-}-    readBytes mb off = go mb 0# (tList @_ @xs)-      where-        go :: L.All PrimBytes ds-           => MutableByteArray# s-           -> Int# -> TypeList ds -> State# s -> (# State# s, TS.Tuple ds #)-        go _ _ Empty s0 = (# s0, Empty #)-        go mba n (t :* ts@TypeList) s0-          | x <- undefP t-          , n' <- roundUpInt# n (byteAlign x)-          = case readBytes mba (off +# n') s0 of-              (# s1, r #) -> case go mba (n' +# byteSize x) ts s1 of-                (# s2, rs #) -> (# s2, TS.Id r :* rs #)-    {-# INLINE readBytes #-}-    writeBytes mba off tup = go mba 0# tup (types tup)-      where-        go :: L.All PrimBytes ds => MutableByteArray# s-           -> Int# -> TS.Tuple ds -> TypeList ds -> State# s -> State# s-        go _ _ _ Empty s = s-        go mb n (TS.Id x :* xs) (_ :* ts@TypeList) s-          | n' <- roundUpInt# n (byteAlign x)-          = go mb (n' +# byteSize x) xs ts (writeBytes mb (off +# n') x s)-    {-# INLINE writeBytes #-}-    readAddr addr = go 0# (tList @_ @xs)-      where-        go :: L.All PrimBytes ds-           => Int# -> TypeList ds -> State# s -> (# State# s, TS.Tuple ds #)-        go _ Empty s0 = (# s0, Empty #)-        go n (t :* ts@TypeList) s0-          | x <- undefP t-          , n' <- roundUpInt# n (byteAlign x)-          = case readAddr (plusAddr# addr n') s0 of-              (# s1, r #) -> case go (n' +# byteSize x) ts s1 of-                (# s2, rs #) -> (# s2, TS.Id r :* rs #)-    {-# INLINE readAddr #-}-    writeAddr tup addr = go 0# tup (types tup)-      where-        go :: L.All PrimBytes ds-           => Int# -> TS.Tuple ds -> TypeList ds -> State# s -> State# s-        go _ _ Empty s = s-        go n (TS.Id x :* xs) (_ :* ts@TypeList) s-          | n' <- roundUpInt# n (byteAlign x)-          = go (n' +# byteSize x) xs ts (writeAddr x (plusAddr# addr n') s)-    {-# INLINE writeAddr #-}-    byteSize _  = go 0# (tList @_ @xs)-      where-        go :: L.All PrimBytes ys => Int# -> TypeList ys -> Int#-        go s Empty     = s-        go s (p :* ps) = let x = undefP p-                         in  go (roundUpInt# s (byteAlign x) +# byteSize x) ps-    {-# INLINE byteSize #-}-    byteAlign _ = go (tList @_ @xs)-      where-        go :: L.All PrimBytes ys => TypeList ys -> Int#-        go Empty     = 0#-        go (p :* ps) = maxInt# (byteAlign (undefP p)) (go ps)-    {-# INLINE byteAlign #-}-    byteOffset _ = 0#-    {-# INLINE byteOffset #-}---undefP :: Proxy p -> p-undefP = const undefined-{-# INLINE undefP #-}---instance PrimBytes a => PrimBytes (Maybe a)-instance (PrimBytes a, PrimBytes b) => PrimBytes (Either a b)-instance PrimBytes a => PrimBytes [a] -- ??? likely to give inf byteSize---data PrimTag a where-    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-    PTagPtr    :: PrimTag (Ptr a)-    PTagOther  :: PrimTag a--class PrimTagged a where-    primTag' :: a -> PrimTag a---- | This function allows to find out a type by comparing its tag.---   This is needed for array overloading, to infer array instances.---   For non-basic types it defaults to `PTagOther`-primTag :: PrimBytes a => a -> PrimTag a-primTag = primTag'-{-# INLINE primTag #-}--instance {-# OVERLAPPABLE #-} PrimTagged a where-    primTag' = const PTagOther-    {-# INLINE primTag' #-}--instance {-# OVERLAPPING #-} PrimTagged Float where-    primTag' = const PTagFloat-    {-# INLINE primTag' #-}--instance {-# OVERLAPPING #-} PrimTagged Double where-    primTag' = const PTagDouble-    {-# INLINE primTag' #-}--instance {-# OVERLAPPING #-} PrimTagged Int where-    primTag' = const PTagInt-    {-# INLINE primTag' #-}--instance {-# OVERLAPPING #-} PrimTagged Int8 where-    primTag' = const PTagInt8-    {-# INLINE primTag' #-}--instance {-# OVERLAPPING #-} PrimTagged Int16 where-    primTag' = const PTagInt16-    {-# INLINE primTag' #-}--instance {-# OVERLAPPING #-} PrimTagged Int32 where-    primTag' = const PTagInt32-    {-# INLINE primTag' #-}--instance {-# OVERLAPPING #-} PrimTagged Int64 where-    primTag' = const PTagInt64-    {-# INLINE primTag' #-}--instance {-# OVERLAPPING #-} PrimTagged Word where-    primTag' = const PTagWord-    {-# INLINE primTag' #-}--instance {-# OVERLAPPING #-} PrimTagged Word8 where-    primTag' = const PTagWord8-    {-# INLINE primTag' #-}--instance {-# OVERLAPPING #-} PrimTagged Word16 where-    primTag' = const PTagWord16-    {-# INLINE primTag' #-}--instance {-# OVERLAPPING #-} PrimTagged Word32 where-    primTag' = const PTagWord32-    {-# INLINE primTag' #-}--instance {-# OVERLAPPING #-} PrimTagged Word64 where-    primTag' = const PTagWord64-    {-# INLINE primTag' #-}--instance {-# OVERLAPPING #-} PrimTagged (Ptr a) where-    primTag' = const PTagPtr-    {-# INLINE primTag' #-}+{-# LANGUAGE AllowAmbiguousTypes   #-}+{-# LANGUAGE CPP                   #-}+{-# LANGUAGE DataKinds             #-}+{-# LANGUAGE DefaultSignatures     #-}+{-# LANGUAGE FlexibleContexts      #-}+{-# LANGUAGE FlexibleInstances     #-}+{-# LANGUAGE GADTs                 #-}+{-# LANGUAGE MagicHash             #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE PolyKinds             #-}+{-# LANGUAGE ScopedTypeVariables   #-}+{-# LANGUAGE StandaloneDeriving    #-}+{-# LANGUAGE TypeApplications      #-}+{-# LANGUAGE TypeFamilies          #-}+{-# LANGUAGE TypeOperators         #-}+{-# LANGUAGE UnboxedTuples         #-}+{-# LANGUAGE UndecidableInstances  #-}+{- |+Module      :  Numeric.PrimBytes+Copyright   :  (c) Artem Chirkin+License     :  BSD3++Facilities for converting Haskell data to and from raw bytes.++The main purpose of this module is to support the implementation of the @DataFrame@+`Numeric.DataFrame.Internal.Backend.Backend`. However, it also comes very useful for+writing FFI. To that end, the `PrimBytes` class is similar to+the `Foreign.Storable.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 `GHC.Generics.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:++  * the alignment is always a power of 2;+  * the size is always rounded up to a multiple of the alignment.++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+  ( -- * PrimBytes API+    PrimBytes (..)+  , bSizeOf, bAlignOf, bFieldOffsetOf+    -- * Storable API+    --+    -- |+    -- `Foreign.Storable.Storable` can be defined in terms of `PrimBytes`+    -- by doing something like the following for your data type:+    --+    -- @+    --   instance PrimBytes a => Storable a where+    --       sizeOf = bSizeOf+    --       alignment = bAlignOf+    --       peekElemOff = bPeekElemOff+    --       pokeElemOff = bPokeElemOff+    --       peekByteOff = bPeekByteOff+    --       pokeByteOff = bPokeByteOff+    --       peek = bPeek+    --       poke = bPoke+    -- @+  , bPeekElemOff, bPokeElemOff, bPeekByteOff, bPokeByteOff, bPeek, bPoke+    -- * Specialization tools+  , PrimTag (..), primTag+  ) where++#include "MachDeps.h"++import           Data.Kind            (Type)+import           Data.Proxy           (Proxy (..))+import           Data.Type.Equality   ((:~:) (..))+import qualified Data.Type.List       as L+import           Data.Type.Lits+import           GHC.Exts+import           GHC.Generics+import           GHC.Int+import           GHC.IO               (IO (..))+import           GHC.Ptr              (Ptr (..))+import           GHC.Word+import           Numeric.Dimensions+import qualified Numeric.Tuple.Lazy   as TL+import qualified Numeric.Tuple.Strict as TS+import           Text.Read            (readMaybe)++{- |++Defines how to read and write your data to and from Haskell unboxed byte arrays+and plain pointers.++Similarly to `Foreign.Storable.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+`GHC.Generics.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. The data uses record syntax to define its fields.+     -}+    type 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 @SIZEOF_HSWORD@.+    --   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 @SIZEOF_HSWORD@ bytes: they are packed more densely.+    getBytes :: a -> ByteArray#+    getBytes a = case runRW#+       ( \s0 -> case newByteArray# (byteSize a) s0 of+           (# s1, marr #) -> unsafeFreezeByteArray# marr (writeBytes marr 0# a s1)+       ) of (# _, r #) -> r+    {-# NOINLINE getBytes #-}+    -- | 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 :: a -> ByteArray#+    getBytesPinned a = case runRW#+       ( \s0 -> case newAlignedPinnedByteArray# (byteSize a) (byteAlign a) s0 of+           (# s1, marr #) -> unsafeFreezeByteArray# marr (writeBytes marr 0# a s1)+       ) of (# _, r #) -> r+    {-# NOINLINE getBytesPinned #-}+    -- | Load content of a data type from a primitive byte array given an offset in bytes.+    fromBytes :: Int# -- ^ Offset in bytes+              -> ByteArray# -- ^ Source array+              -> a+    -- | Read data from a mutable byte array given an offset in bytes.+    readBytes :: MutableByteArray# s -- ^ Source array+              -> Int# -- ^ Byte offset in the source array+              -> State# s -> (# State# s, a #)+    -- | Write data into a mutable byte array at a given position (offset in bytes).+    writeBytes :: MutableByteArray# s -- ^ Destination array+               -> Int# -- ^ Byte offset in the destination array+               -> a -- ^ Data to write into the array+               -> State# s -> State# s+    -- | Read data from a specified address.+    readAddr :: Addr# -> State# s -> (# State# s, a #)+    -- | Write data to a specified address.+    writeAddr :: 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 :: 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 :: 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 :: a -> Int#+    byteOffset _ = 0#+    {-# INLINE byteOffset #-}++    -- | 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 :: (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 :: ByteArray# -> Int# -> a+    indexArray ba i = fromBytes (i *# byteSize @a undefined) ba+    {-# INLINE indexArray #-}++    -- | Read a mutable array given an element offset+    --   (which is @byteSize a@ and should be a multiple of @byteAlign a@).+    readArray  :: MutableByteArray# s -> Int# -> State# s -> (# State# s, a #)+    readArray ba i = readBytes ba (i *# byteSize @a undefined)+    {-# INLINE readArray #-}++    -- | Write a mutable array given an element offset+    --   (which is @byteSize a@ and should be a multiple of @byteAlign a@).+    writeArray :: MutableByteArray# s -> Int# -> a -> State# s -> State# s+    writeArray ba i = writeBytes ba (i *# byteSize @a undefined)+    {-# INLINE writeArray #-}+++    default fromBytes :: (Generic a, GPrimBytes (Rep a))+                      => Int# -> ByteArray# -> a+    fromBytes i arr = to (gfromBytes proxy# 0## 0# i arr)+    {-# INLINE fromBytes #-}++    default readBytes :: (Generic a, GPrimBytes (Rep a))+                      => MutableByteArray# s -> Int# -> State# s -> (# State# s, a #)+    readBytes mba i s = case greadBytes proxy# 0## 0# mba i s of+      (# s', x #) -> (# s', to x #)+    {-# INLINE readBytes #-}++    default writeBytes :: (Generic a, GPrimBytes (Rep a))+                       => MutableByteArray# s -> Int# -> a -> State# s -> State# s+    writeBytes mba i = gwriteBytes proxy# 0## 0# mba i . from+    {-# INLINE writeBytes #-}++    default readAddr :: (Generic a, GPrimBytes (Rep a))+                      => Addr# -> State# s -> (# State# s, a #)+    readAddr a s = case greadAddr proxy# 0## 0# a s of+      (# s', x #) -> (# s', to x #)+    {-# INLINE readAddr #-}++    default writeAddr :: (Generic a, GPrimBytes (Rep a))+                       => a -> Addr# -> State# s -> State# s+    writeAddr = gwriteAddr proxy# 0## 0# . from+    {-# INLINE writeAddr #-}++    default byteSize :: (Generic a, GPrimBytes (Rep a))+                     => a -> Int#+    byteSize a = gbyteSize proxy# 0## 0# (from a) `roundUpInt` byteAlign a+    {-# INLINE byteSize #-}++    default byteAlign :: (Generic a, GPrimBytes (Rep a))+                     => a -> Int#+    byteAlign a = gbyteAlign proxy# (from a)+    {-# INLINE byteAlign #-}++    default byteFieldOffset :: ( Generic a, GPrimBytes (Rep a)+                               , KnownSymbol name)+                            => Proxy# name -> a -> Int#+    byteFieldOffset p a = gbyteFieldOffset proxy# 0## 0# p (from a)+    {-# INLINE byteFieldOffset #-}++-- | A wrapper on `byteSize`+bSizeOf :: (PrimBytes a, Num b) => a -> b+bSizeOf a = fromIntegral (I# (byteSize a))++-- | A wrapper on `byteAlign`+bAlignOf :: (PrimBytes a, Num b) => a -> b+bAlignOf a = fromIntegral (I# (byteAlign a))++-- | A wrapper on `byteFieldOffset`.+bFieldOffsetOf :: forall (name :: Symbol) (a :: Type) (b :: Type)+                . ( PrimBytes a, Elem name (PrimFields a)+                  , KnownSymbol name, Num b)+               => a -> b+bFieldOffsetOf a = fromIntegral (I# (byteFieldOffset (proxy# @Symbol @name) a))++-- | Same as `Foreign.Storable.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+bPeekElemOff (Ptr addr) (I# i)+  = IO (readAddr (plusAddr# addr (i *# byteSize @a undefined)))++-- | Same as `Foreign.Storable.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 ()+bPokeElemOff (Ptr addr) (I# i) a+  = IO (\s -> (# writeAddr a (plusAddr# addr (i *# byteSize a)) s, () #))++-- | Same as `Foreign.Storable.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 (`Foreign.Storable.peek`).+bPeekByteOff :: forall (a :: Type) (b :: Type) . PrimBytes a => Ptr b -> Int -> IO a+bPeekByteOff (Ptr addr) (I# i)+  = IO (readAddr (plusAddr# addr i))++-- | Same as `Foreign.Storable.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 (`Foreign.Storable.peek`).+bPokeByteOff :: forall (a :: Type) (b :: Type) . PrimBytes a => Ptr b -> Int -> a -> IO ()+bPokeByteOff (Ptr addr) (I# i) a+  = IO (\s -> (# writeAddr a (plusAddr# addr i) s, () #))++-- | Same as `Foreign.Storable.peek`: read a data from a pointer.+--+--   Note: you'd better be sure the address is a multiple of+--         the data alignment (`Foreign.Storable.peek`).+bPeek :: forall (a :: Type) . PrimBytes a => Ptr a -> IO a+bPeek (Ptr addr) = IO (readAddr addr)++-- | Same as `Foreign.Storable.poke`: write a data to a pointer.+--+--   Note: you'd better be sure the address is a multiple of+--         the data alignment (`Foreign.Storable.peek`).+bPoke :: forall (a :: Type) . PrimBytes a => Ptr a -> a -> IO ()+bPoke (Ptr addr) a = IO (\s -> (# writeAddr a addr s, () #))++-- | Derive a list of data selectors from the data representation @Rep a@.+type family GPrimFields (rep :: Type -> Type) :: [Symbol] where+    GPrimFields (M1 D _ f) = GPrimFields f+    GPrimFields (M1 C _ f) = GPrimFields f+    GPrimFields (M1 S ('MetaSel ('Just n) _ _ _) _) = '[n]+    GPrimFields (f :*: g) = Concat (GPrimFields f) (GPrimFields g)+    GPrimFields _ = '[]++{- | Deriving `PrimBytes` using generics++This implementation relies on two assumptions, which are probably true+in the GHC implementation of derived generics and __is not checked here__:++1. @Rep a@ is a sum-of-products.+     This means the struct offset is always @4@ for the parts of the sum type,+     and a constructor tag is always at position @0@ in the struct.++2. The @Rep a@ tree is balanced.+     Thus, I can implement a simple tag encoding:+     each bit in a tag corresponds to a nesting level.+     That is, maximum possible nesting level is 31 and minimum is 0.++Therefore, the general logic for the sum type is summarized as follows:+   reserve 4 bytes for the tag and try to pack alternatives as good as possible.++If a data type has only one constructor (@Rep a@ contains no @:+:@),+then the tag is not added.+++Every function in @GPrimBytes@ has the first Proxy# argument;+it is simply used to enforce type parameter and allows easy @coerce@ implementations+for @Meta@ wrapper types.++All functions except @gbyteAlign@ have the second and third arguments:+tag mask (@Word#@) and current struct size (@Int#@);+both start with zero at the top of the @Rep a@ hierarchy.++  The tag mask is used by the sum constructors to find out where to write a bit value+  to encode left or right branch.++  The current struct size is the size (in bytes) of all elements to the left of+  the current one (before alignment).++ -}+class GPrimBytes f where+    gfromBytes :: Proxy# p+               -> Word# -- ^ Constructor tag position (mask)+               -> Int# -- ^ Left neighbour cumulative size (current offset before alignment)+               -> Int# -> ByteArray# -> f p+    greadBytes :: Proxy# p+               -> Word# -- ^ Constructor tag position (mask)+               -> Int# -- ^ Left neighbour cumulative size (current offset before alignment)+               -> MutableByteArray# s -> Int#  -> State# s -> (# State# s, f p #)+    gwriteBytes :: Proxy# p+                -> Word# -- ^ Constructor tag position (mask)+                -> Int# -- ^ Left neighbour cumulative size (current offset before alignment)+                -> MutableByteArray# s -> Int# -> f p -> State# s -> State# s+    greadAddr :: Proxy# p+              -> Word# -- ^ Constructor tag position (mask)+              -> Int# -- ^ Left neighbour cumulative size (current offset before alignment)+              -> Addr# -> State# s -> (# State# s, f p #)+    gwriteAddr :: Proxy# p+               -> Word# -- ^ Constructor tag position (mask)+               -> Int# -- ^ Left neighbour cumulative size (current offset before alignment)+               -> f p -> Addr# -> State# s -> State# s+    -- | Cumulative size of a Rep structure+    gbyteSize :: Proxy# p+              -> Word# -- ^ Constructor tag position (mask)+              -> Int# -- ^ Left neighbour cumulative size (current offset before alignment)+              -> f p -> Int#+    gbyteAlign :: Proxy# p+               -> f p -> Int#+    -- | Gives an offset of the current piece of a Rep structure+    gbyteFieldOffset :: KnownSymbol name+                     => Proxy# p+                     -> Word# -- ^ Constructor tag position (mask)+                     -> Int# -- ^ Left neighbour cumulative size (current offset before alignment)+                     -> Proxy# name -> f p -> Int#+    gbyteFieldOffset _ _ _ _ _ = negateInt# 1#+    {-# INLINE gbyteFieldOffset #-}++instance GPrimBytes V1 where+    gfromBytes _ _ _ _ _ = undefined+    greadBytes _ _ _ _ _ s = (# s, undefined #)+    gwriteBytes _ _ _ _ _ _ s = s+    greadAddr _ _ _ _ s = (# s, undefined #)+    gwriteAddr _ _ _ _ _ s = s+    gbyteSize _ _ ps _ = ps+    gbyteAlign _ _ = 1#++instance GPrimBytes U1 where+    gfromBytes _ _ _ _ _ = U1+    greadBytes _ _ _ _ _ s = (# s, U1 #)+    gwriteBytes _ _ _ _ _ _ s = s+    greadAddr _ _ _ _ s = (# s, U1 #)+    gwriteAddr _ _ _ _ _ s = s+    gbyteSize _ _ ps _ = ps+    gbyteAlign _ _ = 1#++getGOff :: forall a . PrimBytes a+        => Int# --  parent cumulative size+        -> Int# --  original offset+        -> Int# --  new offset+getGOff ps i = i +# roundUpInt ps (byteAlign @a undefined)++instance PrimBytes a => GPrimBytes (K1 i a) where+    gfromBytes _ _ ps i ba = K1 (fromBytes (getGOff @a ps i) ba)+    greadBytes _ _ ps mba i = coerce (readBytes @a mba (getGOff @a ps i))+    gwriteBytes _ _ ps mba i = coerce (writeBytes @a mba (getGOff @a ps i))+    greadAddr _ _ ps addr = coerce (readAddr @a (plusAddr# addr (getGOff @a ps 0#)))+    gwriteAddr _ _ ps ka addr = writeAddr (unK1 ka) (plusAddr# addr (getGOff @a ps 0#))+    gbyteSize _ _ ps ~(K1 a) = roundUpInt ps (byteAlign a) +# byteSize a+    gbyteAlign _ = coerce (byteAlign @a)++instance {-# OVERLAPPING #-}+         (GPrimBytes f, KnownSymbol sn)+      => GPrimBytes (M1 S ('MetaSel ('Just sn) a b c) f) where+    gfromBytes p = coerce (gfromBytes @f p)+    greadBytes p = coerce (greadBytes @f p)+    gwriteBytes p = coerce (gwriteBytes @f p)+    greadAddr p = coerce (greadAddr @f p)+    gwriteAddr p = coerce (gwriteAddr @f p)+    gbyteSize p = coerce (gbyteSize @f p)+    gbyteAlign p = coerce (gbyteAlign @f p)+    gbyteFieldOffset p _ off (_ :: Proxy# n) ma+      | Just Refl <- sameSymbol (undefined :: Proxy n) (undefined :: Proxy sn)+        = off `roundUpInt` gbyteAlign p ma+      | otherwise+        = negateInt# 1#++instance GPrimBytes f => GPrimBytes (M1 i c f) where+    gfromBytes p = coerce (gfromBytes @f p)+    greadBytes p = coerce (greadBytes @f p)+    gwriteBytes p = coerce (gwriteBytes @f p)+    greadAddr p = coerce (greadAddr @f p)+    gwriteAddr p = coerce (gwriteAddr @f p)+    gbyteSize p = coerce (gbyteSize @f p)+    gbyteAlign p = coerce (gbyteAlign @f p)+    gbyteFieldOffset p = coerce (gbyteFieldOffset @f p)++instance (GPrimBytes f, GPrimBytes g) => GPrimBytes (f :*: g) where+    gfromBytes p t ps i ba = x :*: y+      where+        x = gfromBytes p t ps i ba+        y = gfromBytes p t (gbyteSize p t ps x) i ba+    greadBytes p t ps mba i s0+      | (# s1, x #) <- greadBytes p t ps mba i s0+      , (# s2, y #) <- greadBytes p t (gbyteSize p t ps x) mba i s1+        = (# s2, x :*: y #)+    gwriteBytes p t ps mba off (x :*: y) s0+      | s1 <- gwriteBytes p t ps mba off x s0+      , s2 <- gwriteBytes p t (gbyteSize p t ps x) mba off y s1+        = s2+    greadAddr p t ps addr s0+      | (# s1, x #) <- greadAddr p t ps addr s0+      , (# s2, y #) <- greadAddr p t (gbyteSize p t ps x) addr s1+        = (# s2, x :*: y #)+    gwriteAddr p t ps (x :*: y) addr s0+      | s1 <- gwriteAddr p t ps x addr s0+      , s2 <- gwriteAddr p t (gbyteSize p t ps x) y addr s1+        = s2+    gbyteSize p t ps ~(x :*: y) = gbyteSize p t (gbyteSize p t ps x) y+    gbyteAlign p ~(x :*: y) = gbyteAlign p x `maxInt` gbyteAlign p y+    gbyteFieldOffset p t ps n ~(x :*: y)+      | offX <- gbyteFieldOffset p t ps n x+      , bsX  <- gbyteSize p t ps x+      , offY <- gbyteFieldOffset p t bsX n y+      = if isTrue# (offX <# 0#) then offY else offX++instance (GPrimBytes f, GPrimBytes g) => GPrimBytes (f :+: g) where+    gfromBytes p t _ off ba+      | c <- indexWord8ArrayAsWord32# ba off+        = if isTrue# (eqWord# (and# c t1) 0##)+          then L1 (gfromBytes p t1 4# off ba)+          else R1 (gfromBytes p t1 4# off ba)+      where+        t1 = upTag t+    greadBytes p t _ mba off s0+      | (# s1, c #) <- readWord8ArrayAsWord32# mba off s0+        = if isTrue# (eqWord# (and# c t1) 0##)+          then case greadBytes p t1 4# mba off s1 of+            (# s2, x #) -> (# s2, L1 x #)+          else case greadBytes p t1 4# mba off s1 of+            (# s2, y #) -> (# s2, R1 y #)+      where+        t1 = upTag t+    -- if this is the uppermost sum, overwrite the tag.+    gwriteBytes p 0## _ mba off (L1 x) s0+      | s1 <- writeWord8ArrayAsWord32# mba off 0## s0+      , s2 <- gwriteBytes p 1## 4# mba off x s1 = s2+    gwriteBytes p 0## _ mba off (R1 y) s0+      | s1 <- writeWord8ArrayAsWord32# mba off 1## s0+      , s2 <- gwriteBytes p 1## 4# mba off y s1 = s2+    -- here I know that I have written zero to the corresponding bit already+    gwriteBytes p t _ mba off (L1 x) s0+      | s1 <- gwriteBytes p (upTag t) 4# mba off x s0 = s1+    -- otherwise, carefully write a single corresponding bit+    gwriteBytes p t _ mba off (R1 y) s0+      | (# s1, c #) <- readWord8ArrayAsWord32# mba off s0+      , s2 <- writeWord8ArrayAsWord32# mba off (or# c t1) s1+      , s3 <- gwriteBytes p t1 4# mba off y s2 = s3+      where+        t1 = upTag t+    greadAddr p t _ addr s0+      | (# s1, c #) <- readWord32OffAddr# addr 0# s0+        = if isTrue# (eqWord# (and# c t1) 0##)+          then case greadAddr p t1 4# addr s1 of+            (# s2, x #) -> (# s2, L1 x #)+          else case greadAddr p t1 4# addr s1 of+            (# s2, y #) -> (# s2, R1 y #)+      where+        t1 = upTag t+    -- if this is the uppermost sum, overwrite the tag.+    gwriteAddr p 0## _ (L1 x) addr s0+      | s1 <- writeWord32OffAddr# addr 0# 0## s0+      , s2 <- gwriteAddr p 1## 4# x addr s1 = s2+    gwriteAddr p 0## _ (R1 y) addr s0+      | s1 <- writeWord32OffAddr# addr 0# 1## s0+      , s2 <- gwriteAddr p 1## 4# y addr s1 = s2+    -- here I know that I have written zero to the corresponding bit already+    gwriteAddr p t _ (L1 x) addr s0+      | s1 <- gwriteAddr p (upTag t) 4# x addr s0 = s1+    -- otherwise, carefully write a single corresponding bit+    gwriteAddr p t _ (R1 y) addr s0+      | (# s1, c #) <- readWord32OffAddr# addr 0# s0+      , s2 <- writeWord32OffAddr# addr 0# (or# c t1) s1+      , s3 <- gwriteAddr p t1 4# y addr s2 = s3+      where+        t1 = upTag t+    gbyteSize p 0## ps xy+      = maxInt+        (roundUpInt 4# (gbyteAlign p x) +# gbyteSize p 1## ps x)+        (roundUpInt 4# (gbyteAlign p y) +# gbyteSize p 1## ps y)+      where+        x = undef1 @f xy+        y = undef1 @g xy+    gbyteSize p t ps xy+      = maxInt+        (gbyteSize p (upTag t) ps (undef1 @f xy))+        (gbyteSize p (upTag t) ps (undef1 @g xy))+    gbyteAlign p xy = 4# `maxInt`+        maxInt (gbyteAlign p (undef1 @f xy))+               (gbyteAlign p (undef1 @g xy))+    -- check both branches if any of them contain the field.+    -- If there are more than one branches containing the field, the left one+    -- is preferred.+    gbyteFieldOffset p t ps n xy+      | offX <- gbyteFieldOffset p (upTag t) ps n (undef1 @f xy)+      , offY <- gbyteFieldOffset p (upTag t) ps n (undef1 @g xy)+      = if isTrue# (offX <# 0#) then offY else offX++upTag :: Word# -> Word#+upTag 0## = 1##+upTag t   = uncheckedShiftL# t 1#+{-# INLINE upTag #-}+++maxInt :: Int# -> Int# -> Int#+maxInt a b = if isTrue# (a ># b) then a else b+{-# INLINE maxInt #-}++-- | Round up the first numer to a multiple of the second.+--+--   NB: this function is only used with alignment as the second number,+--       which is always a power of 2.+roundUpInt :: Int# -> Int# -> Int#+roundUpInt a b = (a +# b -# 1#) `andI#` negateInt# b+{-# INLINE roundUpInt #-}+-- It's pity that the assertion would not work due to kind of the result+-- not being Type.+-- assert (isTrue# (eqWord# (popCnt# (int2Word# b)) 1##))+--+-- The version above is optimized for second number being power of two (align)+-- The baseline implementation would be as follows:+-- roundUpInt a b = case remInt# a b of+--   0# -> a+  -- q  -> a +# b -# q++undef1 :: forall p q a . q a -> p a+undef1 = const undefined+{-# INLINE undef1 #-}++++#if SIZEOF_HSWORD == 4+#define OFFSHIFT_W 2+#else+#define OFFSHIFT_W 3+#endif++instance GPrimBytes (URec Word) where+    gfromBytes _ _ ps off ba+      = UWord (indexWord8ArrayAsWord# ba (off +# roundUpInt ps ALIGNMENT_HSWORD#))+    greadBytes _ _ ps mba off s+      = case readWord8ArrayAsWord# mba (off +# roundUpInt ps ALIGNMENT_HSWORD#) s of+          (# s1, r #) -> (# s1, UWord r #)+    gwriteBytes _ _ ps mba off x+      = writeWord8ArrayAsWord# mba (off +# roundUpInt ps ALIGNMENT_HSWORD#) (uWord# x)+    greadAddr _ _ ps a s+      = case readWordOffAddr# (plusAddr# a (roundUpInt ps ALIGNMENT_HSWORD#)) 0# s of+          (# s', x #) -> (# s', UWord x #)+    gwriteAddr _ _ ps x a+      = writeWordOffAddr# (plusAddr# a (roundUpInt ps ALIGNMENT_HSWORD#)) 0# (uWord# x)+    gbyteSize _ _ ps _ = roundUpInt ps ALIGNMENT_HSWORD# +# SIZEOF_HSWORD#+    gbyteAlign _ _ = ALIGNMENT_HSWORD#++#if SIZEOF_HSINT == 4+#define OFFSHIFT_I 2+#else+#define OFFSHIFT_I 3+#endif++instance GPrimBytes (URec Int) where+    gfromBytes _ _ ps off ba+      = UInt (indexWord8ArrayAsInt# ba (off +# roundUpInt ps ALIGNMENT_HSINT#))+    greadBytes _ _ ps mba off s+      = case readWord8ArrayAsInt# mba (off +# roundUpInt ps ALIGNMENT_HSINT#) s of+          (# s1, r #) -> (# s1, UInt r #)+    gwriteBytes _ _ ps mba off x+      = writeWord8ArrayAsInt# mba (off +# roundUpInt ps ALIGNMENT_HSINT#) (uInt# x)+    greadAddr _ _ ps a s+      = case readIntOffAddr# (plusAddr# a (roundUpInt ps ALIGNMENT_HSINT#)) 0# s of+          (# s', x #) -> (# s', UInt x #)+    gwriteAddr _ _ ps x a+      = writeIntOffAddr# (plusAddr# a (roundUpInt ps ALIGNMENT_HSINT#)) 0# (uInt# x)+    gbyteSize _ _ ps _ = roundUpInt ps ALIGNMENT_HSINT# +# SIZEOF_HSINT#+    gbyteAlign _ _ = ALIGNMENT_HSINT#++#if SIZEOF_HSFLOAT == 4+#define OFFSHIFT_F 2+#else+#define OFFSHIFT_F 3+#endif++instance GPrimBytes (URec Float) where+    gfromBytes _ _ ps off ba+      = UFloat (indexWord8ArrayAsFloat# ba (off +# roundUpInt ps ALIGNMENT_HSFLOAT#))+    greadBytes _ _ ps mba off s+      = case readWord8ArrayAsFloat# mba (off +# roundUpInt ps ALIGNMENT_HSFLOAT#) s of+          (# s1, r #) -> (# s1, UFloat r #)+    gwriteBytes _ _ ps mba off x+      = writeWord8ArrayAsFloat# mba (off +# roundUpInt ps ALIGNMENT_HSFLOAT#) (uFloat# x)+    greadAddr _ _ ps a s+      = case readFloatOffAddr# (plusAddr# a (roundUpInt ps ALIGNMENT_HSFLOAT#)) 0# s of+          (# s', x #) -> (# s', UFloat x #)+    gwriteAddr _ _ ps x a+      = writeFloatOffAddr# (plusAddr# a (roundUpInt ps ALIGNMENT_HSFLOAT#)) 0# (uFloat# x)+    gbyteSize _ _ ps _ = roundUpInt ps ALIGNMENT_HSFLOAT# +# SIZEOF_HSFLOAT#+    gbyteAlign _ _ = ALIGNMENT_HSFLOAT#++#if SIZEOF_HSDOUBLE == 4+#define OFFSHIFT_D 2+#else+#define OFFSHIFT_D 3+#endif++instance GPrimBytes (URec Double) where+    gfromBytes _ _ ps off ba+      = UDouble (indexWord8ArrayAsDouble# ba (off +# roundUpInt ps ALIGNMENT_HSDOUBLE#))+    greadBytes _ _ ps mba off s+      = case readWord8ArrayAsDouble# mba (off +# roundUpInt ps ALIGNMENT_HSDOUBLE#) s of+          (# s1, r #) -> (# s1, UDouble r #)+    gwriteBytes _ _ ps mba off x+      = writeWord8ArrayAsDouble# mba (off +# roundUpInt ps ALIGNMENT_HSDOUBLE#) (uDouble# x)+    greadAddr _ _ ps a s+      = case readDoubleOffAddr# (plusAddr# a (roundUpInt ps ALIGNMENT_HSDOUBLE#)) 0# s of+          (# s', x #) -> (# s', UDouble x #)+    gwriteAddr _ _ ps x a+      = writeDoubleOffAddr# (plusAddr# a (roundUpInt ps ALIGNMENT_HSDOUBLE#)) 0# (uDouble# x)+    gbyteSize _ _ ps _ = roundUpInt ps ALIGNMENT_HSDOUBLE# +# SIZEOF_HSDOUBLE#+    gbyteAlign _ _ = ALIGNMENT_HSDOUBLE#++-- I believe Char is always 31 bit, but checking this does not hurt+#if SIZEOF_HSCHAR == 2+#define OFFSHIFT_C 1+#elif SIZEOF_HSCHAR == 4+#define OFFSHIFT_C 2+#else+#define OFFSHIFT_C 3+#endif++instance GPrimBytes (URec Char) where+    gfromBytes _ _ ps off ba+      = UChar (indexWord8ArrayAsWideChar# ba (off +# roundUpInt ps ALIGNMENT_HSCHAR#))+    greadBytes _ _ ps mba off s+      = case readWord8ArrayAsWideChar# mba (off +# roundUpInt ps ALIGNMENT_HSCHAR#) s of+          (# s1, r #) -> (# s1, UChar r #)+    gwriteBytes _ _ ps mba off x+      = writeWord8ArrayAsWideChar# mba (off +# roundUpInt ps ALIGNMENT_HSCHAR#) (uChar# x)+    greadAddr _ _ ps a s+      = case readWideCharOffAddr# (plusAddr# a (roundUpInt ps ALIGNMENT_HSCHAR#)) 0# s of+          (# s', x #) -> (# s', UChar x #)+    gwriteAddr _ _ ps x a+      = writeWideCharOffAddr# (plusAddr# a (roundUpInt ps ALIGNMENT_HSCHAR#)) 0# (uChar# x)+    gbyteSize _ _ ps _ = roundUpInt ps ALIGNMENT_HSCHAR# +# SIZEOF_HSCHAR#+    gbyteAlign _ _ = ALIGNMENT_HSCHAR#++#if SIZEOF_HSPTR == 4+#define OFFSHIFT_P 2+#else+#define OFFSHIFT_P 3+#endif++instance GPrimBytes (URec (Ptr ())) where+    gfromBytes _ _ ps off ba+      = UAddr (indexWord8ArrayAsAddr# ba (off +# roundUpInt ps ALIGNMENT_HSPTR#))+    greadBytes _ _ ps mba off s+      = case readWord8ArrayAsAddr# mba (off +# roundUpInt ps ALIGNMENT_HSPTR#) s of+          (# s1, r #) -> (# s1, UAddr r #)+    gwriteBytes _ _ ps mba off x+      = writeWord8ArrayAsAddr# mba (off +# roundUpInt ps ALIGNMENT_HSPTR#) (uAddr# x)+    greadAddr _ _ ps a s+      = case readAddrOffAddr# (plusAddr# a (roundUpInt ps ALIGNMENT_HSPTR#)) 0# s of+          (# s', x #) -> (# s', UAddr x #)+    gwriteAddr _ _ ps x a+      = writeAddrOffAddr# (plusAddr# a (roundUpInt ps ALIGNMENT_HSPTR#)) 0# (uAddr# x)+    gbyteSize _ _ ps _ = roundUpInt ps ALIGNMENT_HSPTR# +# SIZEOF_HSPTR#+    gbyteAlign _ _ = ALIGNMENT_HSPTR#+++++--------------------------------------------------------------------------------+-- Basic instances+--------------------------------------------------------------------------------+++instance PrimBytes Word where+    type PrimFields Word = '[]+    getBytes (W# x) = case runRW#+      ( \s0 -> case newByteArray# SIZEOF_HSWORD# s0 of+         (# s1, marr #) -> case writeWordArray# marr 0# x s1 of+             s2 -> unsafeFreezeByteArray# marr s2+      ) of (# _, a #) -> a+    {-# NOINLINE getBytes #-}+    fromBytes off ba+      = W# (indexWord8ArrayAsWord# ba off)+    {-# INLINE fromBytes #-}+    readBytes mba off s+      = case readWord8ArrayAsWord# mba off s of (# s', r #) -> (# s', W# r #)+    {-# INLINE readBytes #-}+    writeBytes mba off (W# x)+      = writeWord8ArrayAsWord# mba off x+    {-# INLINE writeBytes #-}+    readAddr a s+      = case readWordOffAddr# a 0# s of (# s', x #) -> (# s', W# x #)+    {-# INLINE readAddr #-}+    writeAddr (W# x) a+      = writeWordOffAddr# a 0# x+    {-# INLINE writeAddr #-}+    byteSize _ = SIZEOF_HSWORD#+    {-# INLINE byteSize #-}+    byteAlign _ = ALIGNMENT_HSWORD#+    {-# INLINE byteAlign #-}+    byteFieldOffset _ _ = negateInt# 1#+    {-# INLINE byteFieldOffset #-}+    indexArray ba i = W# (indexWordArray# ba i)+    {-# INLINE indexArray #-}+    readArray mba i s+      = case readWordArray# mba i s of (# s', x #) -> (# s', W# x #)+    {-# INLINE readArray #-}+    writeArray mba i (W# x) = writeWordArray# mba i x+    {-# INLINE writeArray #-}+++instance PrimBytes Int where+    type PrimFields Int = '[]+    getBytes (I# x) = case runRW#+      ( \s0 -> case newByteArray# SIZEOF_HSINT# s0 of+         (# s1, marr #) -> case writeIntArray# marr 0# x s1 of+             s2 -> unsafeFreezeByteArray# marr s2+      ) of (# _, a #) -> a+    {-# NOINLINE getBytes #-}+    fromBytes off ba+      = I# (indexWord8ArrayAsInt# ba off)+    {-# INLINE fromBytes #-}+    readBytes mba off s+      = case readWord8ArrayAsInt# mba off s of (# s', r #) -> (# s', I# r #)+    {-# INLINE readBytes #-}+    writeBytes mba off (I# x)+      = writeWord8ArrayAsInt# mba off x+    {-# INLINE writeBytes #-}+    readAddr a s+      = case readIntOffAddr# a 0# s of (# s', x #) -> (# s', I# x #)+    {-# INLINE readAddr #-}+    writeAddr (I# x) a+      = writeIntOffAddr# a 0# x+    {-# INLINE writeAddr #-}+    byteSize _ = SIZEOF_HSINT#+    {-# INLINE byteSize #-}+    byteAlign _ = ALIGNMENT_HSINT#+    {-# INLINE byteAlign #-}+    byteFieldOffset _ _ = negateInt# 1#+    {-# INLINE byteFieldOffset #-}+    indexArray ba i = I# (indexIntArray# ba i)+    {-# INLINE indexArray #-}+    readArray mba i s+      = case readIntArray# mba i s of (# s', x #) -> (# s', I# x #)+    {-# INLINE readArray #-}+    writeArray mba i (I# x) = writeIntArray# mba i x+    {-# INLINE writeArray #-}++instance PrimBytes Float where+    type PrimFields Float = '[]+    getBytes (F# x) = case runRW#+      ( \s0 -> case newByteArray# SIZEOF_HSFLOAT# s0 of+         (# s1, marr #) -> case writeFloatArray# marr 0# x s1 of+             s2 -> unsafeFreezeByteArray# marr s2+      ) of (# _, a #) -> a+    {-# NOINLINE getBytes #-}+    fromBytes off ba+      = F# (indexWord8ArrayAsFloat# ba off)+    {-# INLINE fromBytes #-}+    readBytes mba off s+      = case readWord8ArrayAsFloat# mba off s of (# s', r #) -> (# s', F# r #)+    {-# INLINE readBytes #-}+    writeBytes mba off (F# x)+      = writeWord8ArrayAsFloat# mba off x+    {-# INLINE writeBytes #-}+    readAddr a s+      = case readFloatOffAddr# a 0# s of (# s', x #) -> (# s', F# x #)+    {-# INLINE readAddr #-}+    writeAddr (F# x) a+      = writeFloatOffAddr# a 0# x+    {-# INLINE writeAddr #-}+    byteSize _ = SIZEOF_HSFLOAT#+    {-# INLINE byteSize #-}+    byteAlign _ = ALIGNMENT_HSFLOAT#+    {-# INLINE byteAlign #-}+    byteFieldOffset _ _ = negateInt# 1#+    {-# INLINE byteFieldOffset #-}+    indexArray ba i = F# (indexFloatArray# ba i)+    {-# INLINE indexArray #-}+    readArray mba i s+      = case readFloatArray# mba i s of (# s', x #) -> (# s', F# x #)+    {-# INLINE readArray #-}+    writeArray mba i (F# x) = writeFloatArray# mba i x+    {-# INLINE writeArray #-}++instance PrimBytes Double where+    type PrimFields Double = '[]+    getBytes (D# x) = case runRW#+      ( \s0 -> case newByteArray# SIZEOF_HSDOUBLE# s0 of+         (# s1, marr #) -> case writeDoubleArray# marr 0# x s1 of+             s2 -> unsafeFreezeByteArray# marr s2+      ) of (# _, a #) -> a+    {-# NOINLINE getBytes #-}+    fromBytes off ba+      = D# (indexWord8ArrayAsDouble# ba off)+    {-# INLINE fromBytes #-}+    readBytes mba off s+      = case readWord8ArrayAsDouble# mba off s of (# s', r #) -> (# s', D# r #)+    {-# INLINE readBytes #-}+    writeBytes mba off (D# x)+      = writeWord8ArrayAsDouble# mba off x+    {-# INLINE writeBytes #-}+    readAddr a s+      = case readDoubleOffAddr# a 0# s of (# s', x #) -> (# s', D# x #)+    {-# INLINE readAddr #-}+    writeAddr (D# x) a+      = writeDoubleOffAddr# a 0# x+    {-# INLINE writeAddr #-}+    byteSize _ = SIZEOF_HSDOUBLE#+    {-# INLINE byteSize #-}+    byteAlign _ = ALIGNMENT_HSDOUBLE#+    {-# INLINE byteAlign #-}+    byteFieldOffset _ _ = negateInt# 1#+    {-# INLINE byteFieldOffset #-}+    indexArray ba i = D# (indexDoubleArray# ba i)+    {-# INLINE indexArray #-}+    readArray mba i s+      = case readDoubleArray# mba i s of (# s', x #) -> (# s', D# x #)+    {-# INLINE readArray #-}+    writeArray mba i (D# x) = writeDoubleArray# mba i x+    {-# INLINE writeArray #-}+++instance PrimBytes (Ptr a) where+    type PrimFields (Ptr a) = '[]+    getBytes (Ptr x) = case runRW#+      ( \s0 -> case newByteArray# SIZEOF_HSPTR# s0 of+         (# s1, marr #) -> case writeAddrArray# marr 0# x s1 of+             s2 -> unsafeFreezeByteArray# marr s2+      ) of (# _, a #) -> a+    {-# NOINLINE getBytes #-}+    fromBytes off ba+      = Ptr (indexWord8ArrayAsAddr# ba off)+    {-# INLINE fromBytes #-}+    readBytes mba off s+      = case readWord8ArrayAsAddr# mba off s of (# s', r #) -> (# s', Ptr r #)+    {-# INLINE readBytes #-}+    writeBytes mba off (Ptr x)+      = writeWord8ArrayAsAddr# mba off x+    {-# INLINE writeBytes #-}+    readAddr a s+      = case readAddrOffAddr# a 0# s of (# s', x #) -> (# s', Ptr x #)+    {-# INLINE readAddr #-}+    writeAddr (Ptr x) a+      = writeAddrOffAddr# a 0# x+    {-# INLINE writeAddr #-}+    byteSize _ = SIZEOF_HSPTR#+    {-# INLINE byteSize #-}+    byteAlign _ = ALIGNMENT_HSPTR#+    {-# INLINE byteAlign #-}+    byteFieldOffset _ _ = negateInt# 1#+    {-# INLINE byteFieldOffset #-}+    indexArray ba i = Ptr (indexAddrArray# ba i)+    {-# INLINE indexArray #-}+    readArray mba i s+      = case readAddrArray# mba i s of (# s', x #) -> (# s', Ptr x #)+    {-# INLINE readArray #-}+    writeArray mba i (Ptr x) = writeAddrArray# mba i x+    {-# INLINE writeArray #-}+++instance PrimBytes Int8 where+    type PrimFields Int8 = '[]+    getBytes (I8# x) = case runRW#+      ( \s0 -> case newByteArray# SIZEOF_INT8# s0 of+         (# s1, marr #) -> case writeInt8Array# marr 0# x s1 of+             s2 -> unsafeFreezeByteArray# marr s2+      ) of (# _, a #) -> a+    {-# NOINLINE getBytes #-}+    fromBytes off ba = indexArray ba off+    {-# INLINE fromBytes #-}+    readBytes = readArray+    {-# INLINE readBytes #-}+    writeBytes = writeArray+    {-# INLINE writeBytes #-}+    readAddr a s+      = case readInt8OffAddr# a 0# s of (# s', x #) -> (# s', I8# x #)+    {-# INLINE readAddr #-}+    writeAddr (I8# x) a+      = writeInt8OffAddr# a 0# x+    {-# INLINE writeAddr #-}+    byteSize _ = SIZEOF_INT8#+    {-# INLINE byteSize #-}+    byteAlign _ = ALIGNMENT_INT8#+    {-# INLINE byteAlign #-}+    byteFieldOffset _ _ = negateInt# 1#+    {-# INLINE byteFieldOffset #-}+    indexArray ba i = I8# (indexInt8Array# ba i)+    {-# INLINE indexArray #-}+    readArray mba i s+      = case readInt8Array# mba i s of (# s', x #) -> (# s', I8# x #)+    {-# INLINE readArray #-}+    writeArray mba i (I8# x) = writeInt8Array# mba i x+    {-# INLINE writeArray #-}++instance PrimBytes Int16 where+    type PrimFields Int16 = '[]+    getBytes (I16# x) = case runRW#+      ( \s0 -> case newByteArray# SIZEOF_INT16# s0 of+         (# s1, marr #) -> case writeInt16Array# marr 0# x s1 of+             s2 -> unsafeFreezeByteArray# marr s2+      ) of (# _, a #) -> a+    {-# NOINLINE getBytes #-}+    fromBytes off ba+      = I16# (indexWord8ArrayAsInt16# ba off)+    {-# INLINE fromBytes #-}+    readBytes mba off s+      = case readWord8ArrayAsInt16# mba off s of (# s', r #) -> (# s', I16# r #)+    {-# INLINE readBytes #-}+    writeBytes mba off (I16# x)+      = writeWord8ArrayAsInt16# mba off x+    {-# INLINE writeBytes #-}+    readAddr a s+      = case readInt16OffAddr# a 0# s of (# s', x #) -> (# s', I16# x #)+    {-# INLINE readAddr #-}+    writeAddr (I16# x) a+      = writeInt16OffAddr# a 0# x+    {-# INLINE writeAddr #-}+    byteSize _ = SIZEOF_INT16#+    {-# INLINE byteSize #-}+    byteAlign _ = ALIGNMENT_INT16#+    {-# INLINE byteAlign #-}+    byteFieldOffset _ _ = negateInt# 1#+    {-# INLINE byteFieldOffset #-}+    indexArray ba i = I16# (indexInt16Array# ba i)+    {-# INLINE indexArray #-}+    readArray mba i s+      = case readInt16Array# mba i s of (# s', x #) -> (# s', I16# x #)+    {-# INLINE readArray #-}+    writeArray mba i (I16# x) = writeInt16Array# mba i x+    {-# INLINE writeArray #-}++instance PrimBytes Int32 where+    type PrimFields Int32 = '[]+    getBytes (I32# x) = case runRW#+      ( \s0 -> case newByteArray# SIZEOF_INT32# s0 of+         (# s1, marr #) -> case writeInt32Array# marr 0# x s1 of+             s2 -> unsafeFreezeByteArray# marr s2+      ) of (# _, a #) -> a+    {-# NOINLINE getBytes #-}+    fromBytes off ba+      = I32# (indexWord8ArrayAsInt32# ba off)+    {-# INLINE fromBytes #-}+    readBytes mba off s+      = case readWord8ArrayAsInt32# mba off s of (# s', r #) -> (# s', I32# r #)+    {-# INLINE readBytes #-}+    writeBytes mba off (I32# x)+      = writeWord8ArrayAsInt32# mba off x+    {-# INLINE writeBytes #-}+    readAddr a s+      = case readInt32OffAddr# a 0# s of (# s', x #) -> (# s', I32# x #)+    {-# INLINE readAddr #-}+    writeAddr (I32# x) a+      = writeInt32OffAddr# a 0# x+    {-# INLINE writeAddr #-}+    byteSize _ = SIZEOF_INT32#+    {-# INLINE byteSize #-}+    byteAlign _ = ALIGNMENT_INT32#+    {-# INLINE byteAlign #-}+    byteFieldOffset _ _ = negateInt# 1#+    {-# INLINE byteFieldOffset #-}+    indexArray ba i = I32# (indexInt32Array# ba i)+    {-# INLINE indexArray #-}+    readArray mba i s+      = case readInt32Array# mba i s of (# s', x #) -> (# s', I32# x #)+    {-# INLINE readArray #-}+    writeArray mba i (I32# x) = writeInt32Array# mba i x+    {-# INLINE writeArray #-}++instance PrimBytes Int64 where+    type PrimFields Int64 = '[]+    getBytes (I64# x) = case runRW#+      ( \s0 -> case newByteArray# SIZEOF_INT64# s0 of+         (# s1, marr #) -> case writeInt64Array# marr 0# x s1 of+             s2 -> unsafeFreezeByteArray# marr s2+      ) of (# _, a #) -> a+    {-# NOINLINE getBytes #-}+    fromBytes off ba+      = I64# (indexWord8ArrayAsInt64# ba off)+    {-# INLINE fromBytes #-}+    readBytes mba off s+      = case readWord8ArrayAsInt64# mba off s of (# s', r #) -> (# s', I64# r #)+    {-# INLINE readBytes #-}+    writeBytes mba off (I64# x)+      = writeWord8ArrayAsInt64# mba off x+    {-# INLINE writeBytes #-}+    readAddr a s+      = case readInt64OffAddr# a 0# s of (# s', x #) -> (# s', I64# x #)+    {-# INLINE readAddr #-}+    writeAddr (I64# x) a+      = writeInt64OffAddr# a 0# x+    {-# INLINE writeAddr #-}+    byteSize _ = SIZEOF_INT64#+    {-# INLINE byteSize #-}+    byteAlign _ = ALIGNMENT_INT64#+    {-# INLINE byteAlign #-}+    byteFieldOffset _ _ = negateInt# 1#+    {-# INLINE byteFieldOffset #-}+    indexArray ba i = I64# (indexInt64Array# ba i)+    {-# INLINE indexArray #-}+    readArray mba i s+      = case readInt64Array# mba i s of (# s', x #) -> (# s', I64# x #)+    {-# INLINE readArray #-}+    writeArray mba i (I64# x) = writeInt64Array# mba i x+    {-# INLINE writeArray #-}++instance PrimBytes Word8 where+    type PrimFields Word8 = '[]+    getBytes (W8# x) = case runRW#+      ( \s0 -> case newByteArray# SIZEOF_WORD8# s0 of+         (# s1, marr #) -> case writeWord8Array# marr 0# x s1 of+             s2 -> unsafeFreezeByteArray# marr s2+      ) of (# _, a #) -> a+    {-# NOINLINE getBytes #-}+    fromBytes off ba = indexArray ba off+    {-# INLINE fromBytes #-}+    readBytes = readArray+    {-# INLINE readBytes #-}+    writeBytes = writeArray+    {-# INLINE writeBytes #-}+    readAddr a s+      = case readWord8OffAddr# a 0# s of (# s', x #) -> (# s', W8# x #)+    {-# INLINE readAddr #-}+    writeAddr (W8# x) a+      = writeWord8OffAddr# a 0# x+    {-# INLINE writeAddr #-}+    byteSize _ = SIZEOF_WORD8#+    {-# INLINE byteSize #-}+    byteAlign _ = ALIGNMENT_WORD8#+    {-# INLINE byteAlign #-}+    byteFieldOffset _ _ = negateInt# 1#+    {-# INLINE byteFieldOffset #-}+    indexArray ba i = W8# (indexWord8Array# ba i)+    {-# INLINE indexArray #-}+    readArray mba i s+      = case readWord8Array# mba i s of (# s', x #) -> (# s', W8# x #)+    {-# INLINE readArray #-}+    writeArray mba i (W8# x) = writeWord8Array# mba i x+    {-# INLINE writeArray #-}++instance PrimBytes Word16 where+    type PrimFields Word16 = '[]+    getBytes (W16# x) = case runRW#+      ( \s0 -> case newByteArray# SIZEOF_WORD16# s0 of+         (# s1, marr #) -> case writeWord16Array# marr 0# x s1 of+             s2 -> unsafeFreezeByteArray# marr s2+      ) of (# _, a #) -> a+    {-# NOINLINE getBytes #-}+    fromBytes off ba+      = W16# (indexWord8ArrayAsWord16# ba off)+    {-# INLINE fromBytes #-}+    readBytes mba off s+      = case readWord8ArrayAsWord16# mba off s of (# s', r #) -> (# s', W16# r #)+    {-# INLINE readBytes #-}+    writeBytes mba off (W16# x)+      = writeWord8ArrayAsWord16# mba off x+    {-# INLINE writeBytes #-}+    readAddr a s+      = case readWord16OffAddr# a 0# s of (# s', x #) -> (# s', W16# x #)+    {-# INLINE readAddr #-}+    writeAddr (W16# x) a+      = writeWord16OffAddr# a 0# x+    {-# INLINE writeAddr #-}+    byteSize _ = SIZEOF_WORD16#+    {-# INLINE byteSize #-}+    byteAlign _ = ALIGNMENT_WORD16#+    {-# INLINE byteAlign #-}+    byteFieldOffset _ _ = negateInt# 1#+    {-# INLINE byteFieldOffset #-}+    indexArray ba i = W16# (indexWord16Array# ba i)+    {-# INLINE indexArray #-}+    readArray mba i s+      = case readWord16Array# mba i s of (# s', x #) -> (# s', W16# x #)+    {-# INLINE readArray #-}+    writeArray mba i (W16# x) = writeWord16Array# mba i x+    {-# INLINE writeArray #-}++instance PrimBytes Word32 where+    type PrimFields Word32 = '[]+    getBytes (W32# x) = case runRW#+      ( \s0 -> case newByteArray# SIZEOF_WORD32# s0 of+         (# s1, marr #) -> case writeWord32Array# marr 0# x s1 of+             s2 -> unsafeFreezeByteArray# marr s2+      ) of (# _, a #) -> a+    {-# NOINLINE getBytes #-}+    fromBytes off ba+      = W32# (indexWord8ArrayAsWord32# ba off)+    {-# INLINE fromBytes #-}+    readBytes mba off s+      = case readWord8ArrayAsWord32# mba off s of (# s', r #) -> (# s', W32# r #)+    {-# INLINE readBytes #-}+    writeBytes mba off (W32# x)+      = writeWord8ArrayAsWord32# mba off x+    {-# INLINE writeBytes #-}+    readAddr a s+      = case readWord32OffAddr# a 0# s of (# s', x #) -> (# s', W32# x #)+    {-# INLINE readAddr #-}+    writeAddr (W32# x) a+      = writeWord32OffAddr# a 0# x+    {-# INLINE writeAddr #-}+    byteSize _ = SIZEOF_WORD32#+    {-# INLINE byteSize #-}+    byteAlign _ = ALIGNMENT_WORD32#+    {-# INLINE byteAlign #-}+    byteFieldOffset _ _ = negateInt# 1#+    {-# INLINE byteFieldOffset #-}+    indexArray ba i = W32# (indexWord32Array# ba i)+    {-# INLINE indexArray #-}+    readArray mba i s+      = case readWord32Array# mba i s of (# s', x #) -> (# s', W32# x #)+    {-# INLINE readArray #-}+    writeArray mba i (W32# x) = writeWord32Array# mba i x+    {-# INLINE writeArray #-}++instance PrimBytes Word64 where+    type PrimFields Word64 = '[]+    getBytes (W64# x) = case runRW#+      ( \s0 -> case newByteArray# SIZEOF_WORD64# s0 of+         (# s1, marr #) -> case writeWord64Array# marr 0# x s1 of+             s2 -> unsafeFreezeByteArray# marr s2+      ) of (# _, a #) -> a+    {-# NOINLINE getBytes #-}+    fromBytes off ba+      = W64# (indexWord8ArrayAsWord64# ba off)+    {-# INLINE fromBytes #-}+    readBytes mba off s+      = case readWord8ArrayAsWord64# mba off s of (# s', r #) -> (# s', W64# r #)+    {-# INLINE readBytes #-}+    writeBytes mba off (W64# x)+      = writeWord8ArrayAsWord64# mba off x+    {-# INLINE writeBytes #-}+    readAddr a s+      = case readWord64OffAddr# a 0# s of (# s', x #) -> (# s', W64# x #)+    {-# INLINE readAddr #-}+    writeAddr (W64# x) a+      = writeWord64OffAddr# a 0# x+    {-# INLINE writeAddr #-}+    byteSize _ = SIZEOF_WORD64#+    {-# INLINE byteSize #-}+    byteAlign _ = ALIGNMENT_WORD64#+    {-# INLINE byteAlign #-}+    byteFieldOffset _ _ = negateInt# 1#+    {-# INLINE byteFieldOffset #-}+    indexArray ba i = W64# (indexWord64Array# ba i)+    {-# INLINE indexArray #-}+    readArray mba i s+      = case readWord64Array# mba i s of (# s', x #) -> (# s', W64# x #)+    {-# INLINE readArray #-}+    writeArray mba i (W64# x) = writeWord64Array# mba i x+    {-# INLINE writeArray #-}++instance PrimBytes Char where+    type PrimFields Char = '[]+    getBytes (C# x) = case runRW#+      ( \s0 -> case newByteArray# SIZEOF_HSCHAR# s0 of+         (# s1, marr #) -> case writeWideCharArray# marr 0# x s1 of+             s2 -> unsafeFreezeByteArray# marr s2+      ) of (# _, a #) -> a+    {-# NOINLINE getBytes #-}+    fromBytes off ba+      = C# (indexWord8ArrayAsWideChar# ba off)+    {-# INLINE fromBytes #-}+    readBytes mba off s+      = case readWord8ArrayAsWideChar# mba off s of (# s', r #) -> (# s', C# r #)+    {-# INLINE readBytes #-}+    writeBytes mba off (C# x)+      = writeWord8ArrayAsWideChar# mba off x+    {-# INLINE writeBytes #-}+    readAddr a s+      = case readWideCharOffAddr# a 0# s of (# s', x #) -> (# s', C# x #)+    {-# INLINE readAddr #-}+    writeAddr (C# x) a+      = writeWideCharOffAddr# a 0# x+    {-# INLINE writeAddr #-}+    byteSize _ = SIZEOF_HSCHAR#+    {-# INLINE byteSize #-}+    byteAlign _ = ALIGNMENT_HSCHAR#+    {-# INLINE byteAlign #-}+    byteFieldOffset _ _ = negateInt# 1#+    {-# INLINE byteFieldOffset #-}+    indexArray ba i = C# (indexWideCharArray# ba i)+    {-# INLINE indexArray #-}+    readArray mba i s+      = case readWideCharArray# mba i s of (# s', x #) -> (# s', C# x #)+    {-# INLINE readArray #-}+    writeArray mba i (C# x) = writeWideCharArray# mba i x+    {-# INLINE writeArray #-}++instance PrimBytes (Idx (x :: k)) where+    type PrimFields (Idx x) = '[]+    getBytes = unsafeCoerce# (getBytes @Word)+    {-# INLINE getBytes #-}+    fromBytes = unsafeCoerce# (fromBytes @Word)+    {-# INLINE fromBytes #-}+    readBytes = unsafeCoerce# (readBytes @Word)+    {-# INLINE readBytes #-}+    writeBytes = unsafeCoerce# (writeBytes @Word)+    {-# INLINE writeBytes #-}+    readAddr = unsafeCoerce# (readAddr @Word)+    {-# INLINE readAddr #-}+    writeAddr = unsafeCoerce# (writeAddr @Word)+    {-# INLINE writeAddr #-}+    byteSize = unsafeCoerce# (byteSize @Word)+    {-# INLINE byteSize #-}+    byteAlign = unsafeCoerce# (byteAlign @Word)+    {-# INLINE byteAlign #-}+    byteFieldOffset b = unsafeCoerce# (byteFieldOffset @Word b)+    {-# INLINE byteFieldOffset #-}+    indexArray = unsafeCoerce# (indexArray @Word)+    {-# INLINE indexArray #-}+    readArray = unsafeCoerce# (readArray @Word)+    {-# INLINE readArray #-}+    writeArray = unsafeCoerce# (writeArray @Word)+    {-# INLINE writeArray #-}++anyList :: forall (k :: Type) (xs :: [k])+        . RepresentableList xs => [Any]+anyList = unsafeCoerce# (tList @_ @xs)+{-# INLINE anyList #-}++instance RepresentableList xs => PrimBytes (Idxs (xs :: [k])) where+    type PrimFields (Idxs xs) = '[]+    fromBytes off ba = unsafeCoerce# (go off (anyList @_ @xs))+      where+        go _ []       = []+        go i (_ : ls) = W# (indexWord8ArrayAsWord# ba i) : go (i +# SIZEOF_HSWORD#) ls+    {-# INLINE fromBytes #-}+    readBytes mba = unsafeCoerce# (go (anyList @_ @xs))+      where+        go [] _ s0 = (# s0, [] #)+        go (_ : ls) i s0+          | (# s1, w  #) <- readWord8ArrayAsWord# mba i s0+          , (# s2, ws #) <- go ls (i +# SIZEOF_HSWORD#) s1+            = (# s2, W# w : ws #)+    {-# INLINE readBytes #-}+    writeBytes mba off = go off . listIdxs+      where+        go _ [] s         = s+        go i (W# x :xs) s = go (i +# SIZEOF_HSWORD#) xs (writeWord8ArrayAsWord# mba i x s)+    {-# INLINE writeBytes #-}+    readAddr addr = unsafeCoerce# (go addr (anyList @_ @xs))+      where+        go :: forall s . Addr# -> [Any] -> State# s -> (# State# s, [Word] #)+        go _ [] s0 = (# s0, [] #)+        go i (_ : ls) s0+          | (# s1, w #)  <- readWordOffAddr# i 0# s0+          , (# s2, xs #) <- go (plusAddr# i SIZEOF_HSWORD#) ls s1+            = (# s2, W# w : xs #)+    {-# INLINE readAddr #-}+    writeAddr is addr+        = go addr (listIdxs is)+      where+        go :: forall s . Addr# -> [Word] -> State# s -> State# s+        go _ [] s         = s+        go i (W# x :xs) s = go (plusAddr# i SIZEOF_HSWORD#) xs+                               (writeWordOffAddr# i 0# x s)+    {-# INLINE writeAddr #-}+    byteSize _ = case dimVal (order' @_ @xs) of+      W# n -> byteSize (undefined :: Idx x) *# word2Int# n+    {-# INLINE byteSize #-}+    byteAlign _ = byteAlign (undefined :: Idx x)+    {-# INLINE byteAlign #-}+    byteFieldOffset _ _ = negateInt# 1#+    {-# INLINE byteFieldOffset #-}+    indexArray ba off+      | n@(W# n#) <- dimVal (order' @_ @xs)+        = unsafeCoerce# (go (off *# word2Int# n#) n)+      where+        go _ 0 = []+        go i n = W# (indexWordArray# ba i) : go (i +# 1#) (n-1)+    {-# INLINE indexArray #-}+    readArray mba off s+      | n@(W# n#) <- dimVal (order' @_ @xs)+        = unsafeCoerce# (go (off *# word2Int# n#) n s)+      where+        go _ 0 s0 = (# s0, [] #)+        go i n s0+          | (# s1, w #)  <- readWordArray# mba i s0+          , (# s2, xs #) <- go (i +# 1#) (n-1) s1+            = (# s2, W# w : xs #)+    {-# INLINE readArray #-}+    writeArray mba off is+      | W# n# <- dimVal (order' @_ @xs)+        = go (off *# word2Int# n#) (listIdxs is)+      where+        go _ [] s         = s+        go i (W# x :xs) s = go (i +# 1#) xs (writeWordArray# mba i x s)+    {-# INLINE writeArray #-}++type family TupleFields (n :: Nat) (xs :: [Type]) :: [Symbol] where+    TupleFields _ '[] = '[]+    TupleFields n (_ ': xs) = ShowNat n ': TupleFields (n + 1) xs++instance ( RepresentableList xs+         , L.All PrimBytes xs+         ) => PrimBytes (TL.Tuple xs) where+    type PrimFields (TL.Tuple xs) = TupleFields 1 xs+    getBytes   = unsafeCoerce# (getBytes @(TS.Tuple xs))+    {-# INLINE getBytes #-}+    fromBytes  = unsafeCoerce# (fromBytes @(TS.Tuple xs))+    {-# INLINE fromBytes #-}+    readBytes  = unsafeCoerce# (readBytes @(TS.Tuple xs))+    {-# INLINE readBytes #-}+    writeBytes = unsafeCoerce# (writeBytes @(TS.Tuple xs))+    {-# INLINE writeBytes #-}+    readAddr   = unsafeCoerce# (readAddr  @(TS.Tuple xs))+    {-# INLINE readAddr  #-}+    writeAddr  = unsafeCoerce# (writeAddr  @(TS.Tuple xs))+    {-# INLINE writeAddr  #-}+    byteSize   = unsafeCoerce# (byteSize @(TS.Tuple xs))+    {-# INLINE byteSize #-}+    byteAlign  = unsafeCoerce# (byteAlign @(TS.Tuple xs))+    {-# INLINE byteAlign #-}+    byteFieldOffset p = unsafeCoerce# (byteFieldOffset @(TS.Tuple xs) p)+    {-# INLINE byteFieldOffset #-}+    indexArray = unsafeCoerce# (indexArray @(TS.Tuple xs))+    {-# INLINE indexArray #-}+    readArray  = unsafeCoerce# (readArray @(TS.Tuple xs))+    {-# INLINE readArray #-}+    writeArray = unsafeCoerce# (writeArray @(TS.Tuple xs))+    {-# INLINE writeArray #-}++instance ( RepresentableList xs+         , L.All PrimBytes xs+         ) => PrimBytes (TS.Tuple xs) where+    type PrimFields (TS.Tuple xs) = TupleFields 1 xs+    fromBytes off ba = go 0# (tList @_ @xs)+      where+        go :: L.All PrimBytes ds+           => Int# -> TypeList ds -> TS.Tuple ds+        go _ Empty = Empty+        go n (t :* ts@TypeList)+          | x <- undefP t+          , n' <- roundUpInt n (byteAlign x)+          = TS.Id (fromBytes (off +# n') ba) :* go (n' +# byteSize x) ts+    {-# INLINE fromBytes #-}+    readBytes mb off = go mb 0# (tList @_ @xs)+      where+        go :: L.All PrimBytes ds+           => MutableByteArray# s+           -> Int# -> TypeList ds -> State# s -> (# State# s, TS.Tuple ds #)+        go _ _ Empty s0 = (# s0, Empty #)+        go mba n (t :* ts@TypeList) s0+          | x <- undefP t+          , n' <- roundUpInt n (byteAlign x)+          = case readBytes mba (off +# n') s0 of+              (# s1, r #) -> case go mba (n' +# byteSize x) ts s1 of+                (# s2, rs #) -> (# s2, TS.Id r :* rs #)+    {-# INLINE readBytes #-}+    writeBytes mba off tup = go mba 0# tup (types tup)+      where+        go :: L.All PrimBytes ds => MutableByteArray# s+           -> Int# -> TS.Tuple ds -> TypeList ds -> State# s -> State# s+        go _ _ _ Empty s = s+        go mb n (TS.Id x :* xs) (_ :* ts@TypeList) s+          | n' <- roundUpInt n (byteAlign x)+          = go mb (n' +# byteSize x) xs ts (writeBytes mb (off +# n') x s)+    {-# INLINE writeBytes #-}+    readAddr addr = go 0# (tList @_ @xs)+      where+        go :: L.All PrimBytes ds+           => Int# -> TypeList ds -> State# s -> (# State# s, TS.Tuple ds #)+        go _ Empty s0 = (# s0, Empty #)+        go n (t :* ts@TypeList) s0+          | x <- undefP t+          , n' <- roundUpInt n (byteAlign x)+          = case readAddr (plusAddr# addr n') s0 of+              (# s1, r #) -> case go (n' +# byteSize x) ts s1 of+                (# s2, rs #) -> (# s2, TS.Id r :* rs #)+    {-# INLINE readAddr #-}+    writeAddr tup addr = go 0# tup (types tup)+      where+        go :: L.All PrimBytes ds+           => Int# -> TS.Tuple ds -> TypeList ds -> State# s -> State# s+        go _ _ Empty s = s+        go n (TS.Id x :* xs) (_ :* ts@TypeList) s+          | n' <- roundUpInt n (byteAlign x)+          = go (n' +# byteSize x) xs ts (writeAddr x (plusAddr# addr n') s)+    {-# INLINE writeAddr #-}+    byteSize _ = go 0# 1# (tList @_ @xs)+      where+        go :: L.All PrimBytes ys => Int# -> Int# -> TypeList ys -> Int#+        go s a Empty     = s `roundUpInt` a+        go s a (p :* ps) = let x = undefP p+                               xa = byteAlign x+                           in  go ( roundUpInt s xa +# byteSize x)+                                  ( maxInt a xa ) ps+    {-# INLINE byteSize #-}+    byteAlign _ = go (tList @_ @xs)+      where+        go :: L.All PrimBytes ys => TypeList ys -> Int#+        go Empty     = 0#+        go (p :* ps) = maxInt (byteAlign (undefP p)) (go ps)+    {-# INLINE byteAlign #-}+    byteFieldOffset name _+      | Just n <- readMaybe $ symbolVal' name+        = go (n-1) 0# (tList @_ @xs)+      | otherwise = negateInt# 1#+      where+        go :: L.All PrimBytes ys => Word -> Int# -> TypeList ys -> Int#+        go 0 s (p :* _)  = s `roundUpInt` byteAlign (undefP p)+        go n s (p :* ps) = let x = undefP p+                           in  go (n-1) ( roundUpInt s (byteAlign x) +# byteSize x) ps+        go _ _ Empty     = negateInt# 1#+    {-# INLINE byteFieldOffset #-}+++undefP :: Proxy p -> p+undefP = const undefined+{-# INLINE undefP #-}+++instance PrimBytes ()+instance PrimBytes a => PrimBytes (Maybe a)+instance ( PrimBytes a, PrimBytes b ) => PrimBytes (Either a b)+instance ( PrimBytes a, PrimBytes b )+      => PrimBytes (a, b)+instance ( PrimBytes a, PrimBytes b, PrimBytes c )+      => PrimBytes (a, b, c)+instance ( PrimBytes a, PrimBytes b, PrimBytes c, PrimBytes d )+      => PrimBytes (a, b, c, d)+instance ( PrimBytes a, PrimBytes b, PrimBytes c, PrimBytes d, PrimBytes e )+      => PrimBytes (a, b, c, d, e)+instance ( PrimBytes a, PrimBytes b, PrimBytes c, PrimBytes d, PrimBytes e+         , PrimBytes f )+      => PrimBytes (a, b, c, d, e, f)+instance ( PrimBytes a, PrimBytes b, PrimBytes c, PrimBytes d, PrimBytes e+         , PrimBytes f, PrimBytes g )+      => PrimBytes (a, b, c, d, e, f, g)+++-- | 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 where+    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++deriving instance Show (PrimTag a)+++-- | Find out which basic GHC type it is at runtime.+class PrimTagged a where+    -- | This function allows to find out a type by comparing its tag+    primTag' :: a -> 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+primTag = primTag'+{-# INLINE primTag #-}++instance {-# OVERLAPPABLE #-} PrimTagged a where+    primTag' = const PTagOther+    {-# INLINE primTag' #-}++instance {-# OVERLAPPING #-} PrimTagged Float where+    primTag' = const PTagFloat+    {-# INLINE primTag' #-}++instance {-# OVERLAPPING #-} PrimTagged Double where+    primTag' = const PTagDouble+    {-# INLINE primTag' #-}++instance {-# OVERLAPPING #-} PrimTagged Int where+    primTag' = const PTagInt+    {-# INLINE primTag' #-}++instance {-# OVERLAPPING #-} PrimTagged Int8 where+    primTag' = const PTagInt8+    {-# INLINE primTag' #-}++instance {-# OVERLAPPING #-} PrimTagged Int16 where+    primTag' = const PTagInt16+    {-# INLINE primTag' #-}++instance {-# OVERLAPPING #-} PrimTagged Int32 where+    primTag' = const PTagInt32+    {-# INLINE primTag' #-}++instance {-# OVERLAPPING #-} PrimTagged Int64 where+    primTag' = const PTagInt64+    {-# INLINE primTag' #-}++instance {-# OVERLAPPING #-} PrimTagged Word where+    primTag' = const PTagWord+    {-# INLINE primTag' #-}++instance {-# OVERLAPPING #-} PrimTagged Word8 where+    primTag' = const PTagWord8+    {-# INLINE primTag' #-}++instance {-# OVERLAPPING #-} PrimTagged Word16 where+    primTag' = const PTagWord16+    {-# INLINE primTag' #-}++instance {-# OVERLAPPING #-} PrimTagged Word32 where+    primTag' = const PTagWord32+    {-# INLINE primTag' #-}++instance {-# OVERLAPPING #-} PrimTagged Word64 where+    primTag' = const PTagWord64+    {-# INLINE primTag' #-}++instance {-# OVERLAPPING #-} PrimTagged Char where+    primTag' = const PTagChar+    {-# INLINE primTag' #-}++instance {-# OVERLAPPING #-} PrimTagged (Ptr a) where+    primTag' = const PTagPtr+    {-# INLINE primTag' #-}++++#if !(MIN_VERSION_base(4,12,0))+-- these functions were introduced in base-4.12.0++writeWord8ArrayAsWideChar# :: MutableByteArray# d -> Int# -> Char# -> State# d -> State# d+writeWord8ArrayAsWideChar# mba off = writeWideCharArray# mba (uncheckedIShiftRL# off OFFSHIFT_C#)+{-# INLINE writeWord8ArrayAsWideChar# #-}++writeWord8ArrayAsAddr# :: MutableByteArray# d -> Int# -> Addr# -> State# d -> State# d+writeWord8ArrayAsAddr# mba off = writeAddrArray# mba (uncheckedIShiftRL# off OFFSHIFT_P#)+{-# INLINE writeWord8ArrayAsAddr# #-}++writeWord8ArrayAsFloat# :: MutableByteArray# d -> Int# -> Float# -> State# d -> State# d+writeWord8ArrayAsFloat# mba off = writeFloatArray# mba (uncheckedIShiftRL# off OFFSHIFT_F#)+{-# INLINE writeWord8ArrayAsFloat# #-}++writeWord8ArrayAsDouble# :: MutableByteArray# d -> Int# -> Double# -> State# d -> State# d+writeWord8ArrayAsDouble# mba off = writeDoubleArray# mba (uncheckedIShiftRL# off OFFSHIFT_D#)+{-# INLINE writeWord8ArrayAsDouble# #-}++writeWord8ArrayAsInt16# :: MutableByteArray# d -> Int# -> Int# -> State# d -> State# d+writeWord8ArrayAsInt16# mba off = writeInt16Array# mba (uncheckedIShiftRL# off 1#)+{-# INLINE writeWord8ArrayAsInt16# #-}++writeWord8ArrayAsInt32# :: MutableByteArray# d -> Int# -> Int# -> State# d -> State# d+writeWord8ArrayAsInt32# mba off = writeInt32Array# mba (uncheckedIShiftRL# off 2#)+{-# INLINE writeWord8ArrayAsInt32# #-}++writeWord8ArrayAsInt64# :: MutableByteArray# d -> Int# -> Int# -> State# d -> State# d+writeWord8ArrayAsInt64# mba off = writeInt64Array# mba (uncheckedIShiftRL# off 3#)+{-# INLINE writeWord8ArrayAsInt64# #-}++writeWord8ArrayAsInt# :: MutableByteArray# d -> Int# -> Int# -> State# d -> State# d+writeWord8ArrayAsInt# mba off = writeIntArray# mba (uncheckedIShiftRL# off OFFSHIFT_I#)+{-# INLINE writeWord8ArrayAsInt# #-}++writeWord8ArrayAsWord16# :: MutableByteArray# d -> Int# -> Word# -> State# d -> State# d+writeWord8ArrayAsWord16# mba off = writeWord16Array# mba (uncheckedIShiftRL# off 1#)+{-# INLINE writeWord8ArrayAsWord16# #-}++writeWord8ArrayAsWord32# :: MutableByteArray# d -> Int# -> Word# -> State# d -> State# d+writeWord8ArrayAsWord32# mba off = writeWord32Array# mba (uncheckedIShiftRL# off 2#)+{-# INLINE writeWord8ArrayAsWord32# #-}++writeWord8ArrayAsWord64# :: MutableByteArray# d -> Int# -> Word# -> State# d -> State# d+writeWord8ArrayAsWord64# mba off = writeWord64Array# mba (uncheckedIShiftRL# off 3#)+{-# INLINE writeWord8ArrayAsWord64# #-}++writeWord8ArrayAsWord# :: MutableByteArray# d -> Int# -> Word# -> State# d -> State# d+writeWord8ArrayAsWord# mba off = writeWordArray# mba (uncheckedIShiftRL# off OFFSHIFT_W#)+{-# INLINE writeWord8ArrayAsWord# #-}++readWord8ArrayAsWideChar# :: MutableByteArray# d -> Int# -> State# d -> (# State# d, Char# #)+readWord8ArrayAsWideChar# mba off = readWideCharArray# mba (uncheckedIShiftRL# off OFFSHIFT_C#)+{-# INLINE readWord8ArrayAsWideChar# #-}++readWord8ArrayAsAddr# :: MutableByteArray# d -> Int# -> State# d -> (# State# d, Addr# #)+readWord8ArrayAsAddr# mba off = readAddrArray# mba (uncheckedIShiftRL# off OFFSHIFT_P#)+{-# INLINE readWord8ArrayAsAddr# #-}++readWord8ArrayAsFloat# :: MutableByteArray# d -> Int# -> State# d -> (# State# d, Float# #)+readWord8ArrayAsFloat# mba off = readFloatArray# mba (uncheckedIShiftRL# off OFFSHIFT_F#)+{-# INLINE readWord8ArrayAsFloat# #-}++readWord8ArrayAsDouble# :: MutableByteArray# d -> Int# -> State# d -> (# State# d, Double# #)+readWord8ArrayAsDouble# mba off = readDoubleArray# mba (uncheckedIShiftRL# off OFFSHIFT_D#)+{-# INLINE readWord8ArrayAsDouble# #-}++readWord8ArrayAsInt16# :: MutableByteArray# d -> Int# -> State# d -> (# State# d, Int# #)+readWord8ArrayAsInt16# mba off = readInt16Array# mba (uncheckedIShiftRL# off 1#)+{-# INLINE readWord8ArrayAsInt16# #-}++readWord8ArrayAsInt32# :: MutableByteArray# d -> Int# -> State# d -> (# State# d, Int# #)+readWord8ArrayAsInt32# mba off = readInt32Array# mba (uncheckedIShiftRL# off 2#)+{-# INLINE readWord8ArrayAsInt32# #-}++readWord8ArrayAsInt64# :: MutableByteArray# d -> Int# -> State# d -> (# State# d, Int# #)+readWord8ArrayAsInt64# mba off = readInt64Array# mba (uncheckedIShiftRL# off 3#)+{-# INLINE readWord8ArrayAsInt64# #-}++readWord8ArrayAsInt# :: MutableByteArray# d -> Int# -> State# d -> (# State# d, Int# #)+readWord8ArrayAsInt# mba off = readIntArray# mba (uncheckedIShiftRL# off OFFSHIFT_I#)+{-# INLINE readWord8ArrayAsInt# #-}++readWord8ArrayAsWord16# :: MutableByteArray# d -> Int# -> State# d -> (# State# d, Word# #)+readWord8ArrayAsWord16# mba off = readWord16Array# mba (uncheckedIShiftRL# off 1#)+{-# INLINE readWord8ArrayAsWord16# #-}++readWord8ArrayAsWord32# :: MutableByteArray# d -> Int# -> State# d -> (# State# d, Word# #)+readWord8ArrayAsWord32# mba off = readWord32Array# mba (uncheckedIShiftRL# off 2#)+{-# INLINE readWord8ArrayAsWord32# #-}++readWord8ArrayAsWord64# :: MutableByteArray# d -> Int# -> State# d -> (# State# d, Word# #)+readWord8ArrayAsWord64# mba off = readWord64Array# mba (uncheckedIShiftRL# off 3#)+{-# INLINE readWord8ArrayAsWord64# #-}++readWord8ArrayAsWord# :: MutableByteArray# d -> Int# -> State# d -> (# State# d, Word# #)+readWord8ArrayAsWord# mba off = readWordArray# mba (uncheckedIShiftRL# off OFFSHIFT_W#)+{-# INLINE readWord8ArrayAsWord# #-}++indexWord8ArrayAsWideChar# :: ByteArray# -> Int# -> Char#+indexWord8ArrayAsWideChar# ba off = indexWideCharArray# ba (uncheckedIShiftRL# off OFFSHIFT_C#)+{-# INLINE indexWord8ArrayAsWideChar# #-}++indexWord8ArrayAsAddr# :: ByteArray# -> Int# -> Addr#+indexWord8ArrayAsAddr# ba off = indexAddrArray# ba (uncheckedIShiftRL# off OFFSHIFT_P#)+{-# INLINE indexWord8ArrayAsAddr# #-}++indexWord8ArrayAsFloat# :: ByteArray# -> Int# -> Float#+indexWord8ArrayAsFloat# ba off = indexFloatArray# ba (uncheckedIShiftRL# off OFFSHIFT_F#)+{-# INLINE indexWord8ArrayAsFloat# #-}++indexWord8ArrayAsDouble# :: ByteArray# -> Int# -> Double#+indexWord8ArrayAsDouble# ba off = indexDoubleArray# ba (uncheckedIShiftRL# off OFFSHIFT_D#)+{-# INLINE indexWord8ArrayAsDouble# #-}++indexWord8ArrayAsInt16# :: ByteArray# -> Int# -> Int#+indexWord8ArrayAsInt16# ba off = indexInt16Array# ba (uncheckedIShiftRL# off 1#)+{-# INLINE indexWord8ArrayAsInt16# #-}++indexWord8ArrayAsInt32# :: ByteArray# -> Int# -> Int#+indexWord8ArrayAsInt32# ba off = indexInt32Array# ba (uncheckedIShiftRL# off 2#)+{-# INLINE indexWord8ArrayAsInt32# #-}++indexWord8ArrayAsInt64# :: ByteArray# -> Int# -> Int#+indexWord8ArrayAsInt64# ba off = indexInt64Array# ba (uncheckedIShiftRL# off 3#)+{-# INLINE indexWord8ArrayAsInt64# #-}++indexWord8ArrayAsInt# :: ByteArray# -> Int# -> Int#+indexWord8ArrayAsInt# ba off = indexIntArray# ba (uncheckedIShiftRL# off OFFSHIFT_I#)+{-# INLINE indexWord8ArrayAsInt# #-}++indexWord8ArrayAsWord16# :: ByteArray# -> Int# -> Word#+indexWord8ArrayAsWord16# ba off = indexWord16Array# ba (uncheckedIShiftRL# off 1#)+{-# INLINE indexWord8ArrayAsWord16# #-}++indexWord8ArrayAsWord32# :: ByteArray# -> Int# -> Word#+indexWord8ArrayAsWord32# ba off = indexWord32Array# ba (uncheckedIShiftRL# off 2#)+{-# INLINE indexWord8ArrayAsWord32# #-}++indexWord8ArrayAsWord64# :: ByteArray# -> Int# -> Word#+indexWord8ArrayAsWord64# ba off = indexWord64Array# ba (uncheckedIShiftRL# off 3#)+{-# INLINE indexWord8ArrayAsWord64# #-}++indexWord8ArrayAsWord# :: ByteArray# -> Int# -> Word#+indexWord8ArrayAsWord# ba off = indexWordArray# ba (uncheckedIShiftRL# off OFFSHIFT_W#)+{-# INLINE indexWord8ArrayAsWord# #-}++#endif
+ src/Numeric/ProductOrd.hs view
@@ -0,0 +1,128 @@+{-# LANGUAGE CPP                  #-}+{-# LANGUAGE DataKinds            #-}+{-# LANGUAGE DeriveDataTypeable   #-}+{-# LANGUAGE DeriveGeneric        #-}+{-# LANGUAGE FlexibleContexts     #-}+{-# LANGUAGE PolyKinds            #-}+{-# LANGUAGE UndecidableInstances #-}+-----------------------------------------------------------------------------+-- |+-- Module      :  Numeric.ProductOrd+-- Copyright   :  (c) Artem Chirkin+-- License     :  BSD3+--+--+-- Compare product types -- partial order.+--+-----------------------------------------------------------------------------+module Numeric.ProductOrd (ProductOrder (..), PartialOrdering (..), fromOrdering) where+++import Data.Data+import Data.Kind      (Type)+import Data.Monoid    as Mon (Monoid (..))+import Data.Semigroup as Sem (Semigroup (..), stimesIdempotentMonoid)+import GHC.Generics++import Numeric.TypedList++-- | Partial order for comparing product types --+--     [product order](https://en.wikipedia.org/wiki/Product_order).+class ProductOrder a where+    -- | Same as `compare`, but may return @Incomparable@.+    cmp :: a -> a -> PartialOrdering++-- | Similar to `Ordering`, but may be @Incomparable@.+data PartialOrdering = PLT | PEQ | PGT | Incomparable+  deriving ( Eq, Ord, Show, Read, Data, Typeable, Generic, Enum, Bounded )++-- | Extend `Ordering` with @Incomparable@ option.+fromOrdering :: Ordering -> PartialOrdering+fromOrdering LT = PLT+fromOrdering EQ = PEQ+fromOrdering GT = PGT+{-# INLINE fromOrdering #-}++instance Sem.Semigroup PartialOrdering where+    Incomparable <> _ = Incomparable+    _ <> Incomparable = Incomparable+    PLT <> PGT = Incomparable+    PGT <> PLT = Incomparable+    PLT <> _ = PLT+    PGT <> _ = PGT+    PEQ <> y = y++    stimes = stimesIdempotentMonoid++instance Mon.Monoid PartialOrdering where+    mempty = PEQ+#if !(MIN_VERSION_base(4,11,0))+    mappend = (<>)+#endif++instance All Ord (Map f xs)+      => ProductOrder (TypedList (f :: k -> Type) (xs :: [k])) where+    cmp U U                 = PEQ+    cmp (a :* as) (b :* bs) = fromOrdering (compare a b) <> cmp as bs+++cmp' :: Ord a => a -> a -> PartialOrdering+cmp' a b = fromOrdering (compare a b)+{-# INLINE cmp' #-}++instance (Ord a1, Ord a2)+      => ProductOrder (a1, a2) where+    cmp (a1, a2)+        (b1, b2)+      =  cmp' a1 b1 <> cmp' a2 b2++instance (Ord a1, Ord a2, Ord a3)+      => ProductOrder (a1, a2, a3) where+    cmp (a1, a2, a3)+        (b1, b2, b3)+      =  cmp' a1 b1 <> cmp' a2 b2 <> cmp' a3 b3++instance (Ord a1, Ord a2, Ord a3, Ord a4)+      => ProductOrder (a1, a2, a3, a4) where+    cmp (a1, a2, a3, a4)+        (b1, b2, b3, b4)+      =  cmp' a1 b1 <> cmp' a2 b2 <> cmp' a3 b3+      <> cmp' a4 b4++instance (Ord a1, Ord a2, Ord a3, Ord a4, Ord a5)+      => ProductOrder (a1, a2, a3, a4, a5) where+    cmp (a1, a2, a3, a4, a5)+        (b1, b2, b3, b4, b5)+      =  cmp' a1 b1 <> cmp' a2 b2 <> cmp' a3 b3+      <> cmp' a4 b4 <> cmp' a5 b5++instance (Ord a1, Ord a2, Ord a3, Ord a4, Ord a5, Ord a6)+      => ProductOrder (a1, a2, a3, a4, a5, a6) where+    cmp (a1, a2, a3, a4, a5, a6)+        (b1, b2, b3, b4, b5, b6)+      =  cmp' a1 b1 <> cmp' a2 b2 <> cmp' a3 b3+      <> cmp' a4 b4 <> cmp' a5 b5 <> cmp' a6 b6++instance (Ord a1, Ord a2, Ord a3, Ord a4, Ord a5, Ord a6, Ord a7)+      => ProductOrder (a1, a2, a3, a4, a5, a6, a7) where+    cmp (a1, a2, a3, a4, a5, a6, a7)+        (b1, b2, b3, b4, b5, b6, b7)+      =  cmp' a1 b1 <> cmp' a2 b2 <> cmp' a3 b3+      <> cmp' a4 b4 <> cmp' a5 b5 <> cmp' a6 b6+      <> cmp' a7 b7++instance (Ord a1, Ord a2, Ord a3, Ord a4, Ord a5, Ord a6, Ord a7, Ord a8)+      => ProductOrder (a1, a2, a3, a4, a5, a6, a7, a8) where+    cmp (a1, a2, a3, a4, a5, a6, a7, a8)+        (b1, b2, b3, b4, b5, b6, b7, b8)+      =  cmp' a1 b1 <> cmp' a2 b2 <> cmp' a3 b3+      <> cmp' a4 b4 <> cmp' a5 b5 <> cmp' a6 b6+      <> cmp' a7 b7 <> cmp' a8 b8++instance (Ord a1, Ord a2, Ord a3, Ord a4, Ord a5, Ord a6, Ord a7, Ord a8, Ord a9)+      => ProductOrder (a1, a2, a3, a4, a5, a6, a7, a8, a9) where+    cmp (a1, a2, a3, a4, a5, a6, a7, a8, a9)+        (b1, b2, b3, b4, b5, b6, b7, b8, b9)+      =  cmp' a1 b1 <> cmp' a2 b2 <> cmp' a3 b3+      <> cmp' a4 b4 <> cmp' a5 b5 <> cmp' a6 b6+      <> cmp' a7 b7 <> cmp' a8 b8 <> cmp' a9 b9
+ src/Numeric/ProductOrd/NonTransitive.hs view
@@ -0,0 +1,315 @@+{-# LANGUAGE DataKinds                  #-}+{-# LANGUAGE DeriveDataTypeable         #-}+{-# LANGUAGE DeriveGeneric              #-}+{-# LANGUAGE DeriveTraversable          #-}+{-# LANGUAGE FlexibleContexts           #-}+{-# LANGUAGE FlexibleInstances          #-}+{-# LANGUAGE GeneralizedNewtypeDeriving #-}+{-# LANGUAGE PolyKinds                  #-}+{-# LANGUAGE StandaloneDeriving         #-}+{-# LANGUAGE UndecidableInstances       #-}+-----------------------------------------------------------------------------+-- |+-- Module      :  Numeric.ProductOrd.NonTransitive+-- Copyright   :  (c) Artem Chirkin+-- License     :  BSD3+--+--+-- Compare product types using non-transitive `Ord` instances:+--+-- * \( a = b \) and  \( b = c \) __does not mean__ \( a = c \);+-- * but, if nor \( a > b \) neither \( b > a \), then \( a = b \).+--+-- 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 (ProductOrd (..), toOrdering) where++import Control.Monad.Fix+import Control.Monad.Zip+import Data.Bits         (Bits, FiniteBits)+import Data.Coerce+import Data.Data+import Data.Foldable+import Data.Kind         (Type)+import Data.Monoid       as Mon (Monoid (..))+import Data.Semigroup    as Sem (Semigroup (..))+import Foreign.Storable  (Storable)+import GHC.Generics++import Numeric.ProductOrd+import Numeric.TypedList++{-|+  Redefine `Ord` instance for a type which is a cartesian product --+    as a partial __[product order](https://en.wikipedia.org/wiki/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__:+  \[+    a = b \iff \neg (a > b) \land \neg (b > a)+  \]++  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](https://en.wikipedia.org/wiki/Pareto_efficiency),+  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 { getProductOrd :: a }+  deriving ( Show, Read, Data, Typeable, Generic, Generic1+           , Num, Enum, Bounded, Floating, Fractional+           , Semigroup, Monoid, Storable, Traversable)++deriving instance (Ord (ProductOrd a), Integral a)   => Integral (ProductOrd a)+deriving instance (Ord (ProductOrd a), Bits a)       => Bits (ProductOrd a)+deriving instance (Ord (ProductOrd a), FiniteBits a) => FiniteBits (ProductOrd a)+deriving instance (Ord (ProductOrd a), Real a)       => Real (ProductOrd a)+deriving instance (Ord (ProductOrd a), RealFrac a)   => RealFrac (ProductOrd a)+deriving instance (Ord (ProductOrd a), RealFloat a)  => RealFloat (ProductOrd a)++instance Foldable ProductOrd where+    foldMap                  = coerce+    elem                     = k (==)+      where+        k :: (a -> a -> Bool) -> a -> ProductOrd a -> Bool+        k = coerce+    foldl                    = coerce+    foldl'                   = coerce+    foldl1 _                 = coerce+    foldr f z (ProductOrd x) = f x z+    foldr'                   = foldr+    foldr1 _                 = coerce+    length _                 = 1+    maximum                  = coerce+    minimum                  = coerce+    null _                   = False+    product                  = coerce+    sum                      = coerce+    toList (ProductOrd x)    = [x]++instance Functor ProductOrd where+    fmap  = coerce++instance Applicative ProductOrd where+    pure  = ProductOrd+    (<*>) = coerce++instance Monad ProductOrd where+    m >>= k = k (getProductOrd m)++instance MonadFix ProductOrd where+    mfix f   = ProductOrd (fix (getProductOrd . f))++instance MonadZip ProductOrd where+    mzipWith = coerce+    munzip   = coerce++{-# ANN module "HLint: ignore Redundant compare" #-}+instance Ord (ProductOrd a) => Eq (ProductOrd a) where+    a == b = compare a b == EQ+    {-# INLINE (==) #-}++instance All Ord (Map f xs)+      => Ord (ProductOrd (TypedList (f :: k -> Type) (xs :: [k]))) where+    ProductOrd x > ProductOrd y = cmp x y == PGT+    {-# INLINE (>) #-}+    ProductOrd x < ProductOrd y = cmp x y == PLT+    {-# INLINE (<) #-}+    ProductOrd U >= ProductOrd U = True+    ProductOrd (a :* as) >= ProductOrd (b :* bs)+      = a >= b && ProductOrd as >= ProductOrd bs+    ProductOrd U <= ProductOrd U = True+    ProductOrd (a :* as) <= ProductOrd (b :* bs)+      = a <= b && ProductOrd as <= ProductOrd bs+    compare (ProductOrd a) (ProductOrd b) = toOrdering $ cmp a b+    min (ProductOrd U) (ProductOrd U) = ProductOrd U+    min (ProductOrd (a :* as)) (ProductOrd (b :* bs))+      = ProductOrd (min a b :* getProductOrd (min (ProductOrd as) (ProductOrd bs)))+    max (ProductOrd U) (ProductOrd U) = ProductOrd U+    max (ProductOrd (a :* as)) (ProductOrd (b :* bs))+      = ProductOrd (max a b :* getProductOrd (max (ProductOrd as) (ProductOrd bs)))++instance (Ord a1, Ord a2) => Ord (ProductOrd (a1, a2)) where+    ProductOrd x > ProductOrd y = cmp x y == PGT+    {-# INLINE (>) #-}+    ProductOrd x < ProductOrd y = cmp x y == PLT+    {-# INLINE (<) #-}+    ProductOrd (a1, a2) >= ProductOrd (b1, b2)+      = a1 >= b1 && a2 >= b2+    {-# INLINE (>=) #-}+    ProductOrd (a1, a2) <= ProductOrd (b1, b2)+      = a1 <= b1 && a2 <= b2+    {-# INLINE (<=) #-}+    compare (ProductOrd a) (ProductOrd b) = toOrdering $ cmp a b+    {-# INLINE compare #-}+    min (ProductOrd (a1, a2)) (ProductOrd (b1, b2))+      = ProductOrd (min a1 b1, min a2 b2)+    {-# INLINE min #-}+    max (ProductOrd (a1, a2)) (ProductOrd (b1, b2))+      = ProductOrd (max a1 b1, max a2 b2)+    {-# INLINE max #-}++instance (Ord a1, Ord a2, Ord a3) => Ord (ProductOrd (a1, a2, a3)) where+    ProductOrd x > ProductOrd y = cmp x y == PGT+    {-# INLINE (>) #-}+    ProductOrd x < ProductOrd y = cmp x y == PLT+    {-# INLINE (<) #-}+    ProductOrd (a1, a2, a3) >= ProductOrd (b1, b2, b3)+      = a1 >= b1 && a2 >= b2 && a3 >= b3+    {-# INLINE (>=) #-}+    ProductOrd (a1, a2, a3) <= ProductOrd (b1, b2, b3)+      = a1 <= b1 && a2 <= b2 && a3 <= b3+    {-# INLINE (<=) #-}+    compare (ProductOrd a) (ProductOrd b) = toOrdering $ cmp a b+    {-# INLINE compare #-}+    min (ProductOrd (a1, a2, a3)) (ProductOrd (b1, b2, b3))+      = ProductOrd (min a1 b1, min a2 b2, min a3 b3)+    {-# INLINE min #-}+    max (ProductOrd (a1, a2, a3)) (ProductOrd (b1, b2, b3))+      = ProductOrd (max a1 b1, max a2 b2, max a3 b3)+    {-# INLINE max #-}++instance (Ord a1, Ord a2, Ord a3, Ord a4)+      => Ord (ProductOrd (a1, a2, a3, a4)) where+    ProductOrd x > ProductOrd y = cmp x y == PGT+    {-# INLINE (>) #-}+    ProductOrd x < ProductOrd y = cmp x y == PLT+    {-# INLINE (<) #-}+    ProductOrd (a1, a2, a3, a4) >= ProductOrd (b1, b2, b3, b4)+      = a1 >= b1 && a2 >= b2 && a3 >= b3 && a4 >= b4+    {-# INLINE (>=) #-}+    ProductOrd (a1, a2, a3, a4) <= ProductOrd (b1, b2, b3, b4)+      = a1 <= b1 && a2 <= b2 && a3 <= b3 && a4 <= b4+    {-# INLINE (<=) #-}+    compare (ProductOrd a) (ProductOrd b) = toOrdering $ cmp a b+    {-# INLINE compare #-}+    min (ProductOrd (a1, a2, a3, a4)) (ProductOrd (b1, b2, b3, b4))+      = ProductOrd (min a1 b1, min a2 b2, min a3 b3, min a4 b4)+    {-# INLINE min #-}+    max (ProductOrd (a1, a2, a3, a4)) (ProductOrd (b1, b2, b3, b4))+      = ProductOrd (max a1 b1, max a2 b2, max a3 b3, max a4 b4)+    {-# INLINE max #-}++instance (Ord a1, Ord a2, Ord a3, Ord a4, Ord a5)+      => Ord (ProductOrd (a1, a2, a3, a4, a5)) where+    ProductOrd x > ProductOrd y = cmp x y == PGT+    {-# INLINE (>) #-}+    ProductOrd x < ProductOrd y = cmp x y == PLT+    {-# INLINE (<) #-}+    ProductOrd (a1, a2, a3, a4, a5) >= ProductOrd (b1, b2, b3, b4, b5)+      = a1 >= b1 && a2 >= b2 && a3 >= b3 && a4 >= b4 && a5 >= b5+    {-# INLINE (>=) #-}+    ProductOrd (a1, a2, a3, a4, a5) <= ProductOrd (b1, b2, b3, b4, b5)+      = a1 <= b1 && a2 <= b2 && a3 <= b3 && a4 <= b4 && a5 <= b5+    {-# INLINE (<=) #-}+    compare (ProductOrd a) (ProductOrd b) = toOrdering $ cmp a b+    {-# INLINE compare #-}+    min (ProductOrd (a1, a2, a3, a4, a5)) (ProductOrd (b1, b2, b3, b4, b5))+      = ProductOrd (min a1 b1, min a2 b2, min a3 b3, min a4 b4, min a5 b5)+    {-# INLINE min #-}+    max (ProductOrd (a1, a2, a3, a4, a5)) (ProductOrd (b1, b2, b3, b4, b5))+      = ProductOrd (max a1 b1, max a2 b2, max a3 b3, max a4 b4, max a5 b5)+    {-# INLINE max #-}++instance (Ord a1, Ord a2, Ord a3, Ord a4, Ord a5, Ord a6)+      => Ord (ProductOrd (a1, a2, a3, a4, a5, a6)) where+    ProductOrd x > ProductOrd y = cmp x y == PGT+    {-# INLINE (>) #-}+    ProductOrd x < ProductOrd y = cmp x y == PLT+    {-# INLINE (<) #-}+    ProductOrd (a1, a2, a3, a4, a5, a6) >= ProductOrd (b1, b2, b3, b4, b5, b6)+      = a1 >= b1 && a2 >= b2 && a3 >= b3 && a4 >= b4 && a5 >= b5 && a6 >= b6+    {-# INLINE (>=) #-}+    ProductOrd (a1, a2, a3, a4, a5, a6) <= ProductOrd (b1, b2, b3, b4, b5, b6)+      = a1 <= b1 && a2 <= b2 && a3 <= b3 && a4 <= b4 && a5 <= b5 && a6 <= b6+    {-# INLINE (<=) #-}+    compare (ProductOrd a) (ProductOrd b) = toOrdering $ cmp a b+    {-# INLINE compare #-}+    min (ProductOrd (a1, a2, a3, a4, a5, a6)) (ProductOrd (b1, b2, b3, b4, b5, b6))+      = ProductOrd (min a1 b1, min a2 b2, min a3 b3, min a4 b4, min a5 b5, min a6 b6)+    {-# INLINE min #-}+    max (ProductOrd (a1, a2, a3, a4, a5, a6)) (ProductOrd (b1, b2, b3, b4, b5, b6))+      = ProductOrd (max a1 b1, max a2 b2, max a3 b3, max a4 b4, max a5 b5, max a6 b6)+    {-# INLINE max #-}++instance (Ord a1, Ord a2, Ord a3, Ord a4, Ord a5, Ord a6, Ord a7)+      => Ord (ProductOrd (a1, a2, a3, a4, a5, a6, a7)) where+    ProductOrd x > ProductOrd y = cmp x y == PGT+    {-# INLINE (>) #-}+    ProductOrd x < ProductOrd y = cmp x y == PLT+    {-# INLINE (<) #-}+    ProductOrd (a1, a2, a3, a4, a5, a6, a7) >= ProductOrd (b1, b2, b3, b4, b5, b6, b7)+      = a1 >= b1 && a2 >= b2 && a3 >= b3 && a4 >= b4 && a5 >= b5 && a6 >= b6 && a7 >= b7+    {-# INLINE (>=) #-}+    ProductOrd (a1, a2, a3, a4, a5, a6, a7) <= ProductOrd (b1, b2, b3, b4, b5, b6, b7)+      = a1 <= b1 && a2 <= b2 && a3 <= b3 && a4 <= b4 && a5 <= b5 && a6 <= b6 && a7 <= b7+    {-# INLINE (<=) #-}+    compare (ProductOrd a) (ProductOrd b) = toOrdering $ cmp a b+    {-# INLINE compare #-}+    min (ProductOrd (a1, a2, a3, a4, a5, a6, a7)) (ProductOrd (b1, b2, b3, b4, b5, b6, b7))+      = ProductOrd (min a1 b1, min a2 b2, min a3 b3, min a4 b4, min a5 b5, min a6 b6, min a7 b7)+    {-# INLINE min #-}+    max (ProductOrd (a1, a2, a3, a4, a5, a6, a7)) (ProductOrd (b1, b2, b3, b4, b5, b6, b7))+      = ProductOrd (max a1 b1, max a2 b2, max a3 b3, max a4 b4, max a5 b5, max a6 b6, max a7 b7)+    {-# INLINE max #-}++instance (Ord a1, Ord a2, Ord a3, Ord a4, Ord a5, Ord a6, Ord a7, Ord a8)+      => Ord (ProductOrd (a1, a2, a3, a4, a5, a6, a7, a8)) where+    ProductOrd x > ProductOrd y = cmp x y == PGT+    {-# INLINE (>) #-}+    ProductOrd x < ProductOrd y = cmp x y == PLT+    {-# INLINE (<) #-}+    ProductOrd (a1, a2, a3, a4, a5, a6, a7, a8) >= ProductOrd (b1, b2, b3, b4, b5, b6, b7, b8)+      = a1 >= b1 && a2 >= b2 && a3 >= b3 && a4 >= b4 && a5 >= b5 && a6 >= b6 && a7 >= b7 && a8 >= b8+    {-# INLINE (>=) #-}+    ProductOrd (a1, a2, a3, a4, a5, a6, a7, a8) <= ProductOrd (b1, b2, b3, b4, b5, b6, b7, b8)+      = a1 <= b1 && a2 <= b2 && a3 <= b3 && a4 <= b4 && a5 <= b5 && a6 <= b6 && a7 <= b7 && a8 <= b8+    {-# INLINE (<=) #-}+    compare (ProductOrd a) (ProductOrd b) = toOrdering $ cmp a b+    {-# INLINE compare #-}+    min (ProductOrd (a1, a2, a3, a4, a5, a6, a7, a8)) (ProductOrd (b1, b2, b3, b4, b5, b6, b7, b8))+      = ProductOrd (min a1 b1, min a2 b2, min a3 b3, min a4 b4, min a5 b5, min a6 b6, min a7 b7, min a8 b8)+    {-# INLINE min #-}+    max (ProductOrd (a1, a2, a3, a4, a5, a6, a7, a8)) (ProductOrd (b1, b2, b3, b4, b5, b6, b7, b8))+      = ProductOrd (max a1 b1, max a2 b2, max a3 b3, max a4 b4, max a5 b5, max a6 b6, max a7 b7, max a8 b8)+    {-# INLINE max #-}++instance (Ord a1, Ord a2, Ord a3, Ord a4, Ord a5, Ord a6, Ord a7, Ord a8, Ord a9)+      => Ord (ProductOrd (a1, a2, a3, a4, a5, a6, a7, a8, a9)) where+    ProductOrd x > ProductOrd y = cmp x y == PGT+    {-# INLINE (>) #-}+    ProductOrd x < ProductOrd y = cmp x y == PLT+    {-# INLINE (<) #-}+    ProductOrd (a1, a2, a3, a4, a5, a6, a7, a8, a9) >= ProductOrd (b1, b2, b3, b4, b5, b6, b7, b8, b9)+      = a1 >= b1 && a2 >= b2 && a3 >= b3 && a4 >= b4 && a5 >= b5 && a6 >= b6 && a7 >= b7 && a8 >= b8 && a9 >= b9+    {-# INLINE (>=) #-}+    ProductOrd (a1, a2, a3, a4, a5, a6, a7, a8, a9) <= ProductOrd (b1, b2, b3, b4, b5, b6, b7, b8, b9)+      = a1 <= b1 && a2 <= b2 && a3 <= b3 && a4 <= b4 && a5 <= b5 && a6 <= b6 && a7 <= b7 && a8 <= b8 && a9 <= b9+    {-# INLINE (<=) #-}+    compare (ProductOrd a) (ProductOrd b) = toOrdering $ cmp a b+    {-# INLINE compare #-}+    min (ProductOrd (a1, a2, a3, a4, a5, a6, a7, a8, a9)) (ProductOrd (b1, b2, b3, b4, b5, b6, b7, b8, b9))+      = ProductOrd (min a1 b1, min a2 b2, min a3 b3, min a4 b4, min a5 b5, min a6 b6, min a7 b7, min a8 b8, min a9 b9)+    {-# INLINE min #-}+    max (ProductOrd (a1, a2, a3, a4, a5, a6, a7, a8, a9)) (ProductOrd (b1, b2, b3, b4, b5, b6, b7, b8, b9))+      = ProductOrd (max a1 b1, max a2 b2, max a3 b3, max a4 b4, max a5 b5, max a6 b6, max a7 b7, max a8 b8, max a9 b9)+    {-# INLINE max #-}++-- | Treat `Incomparable` as EQ (non-transitive equality).+toOrdering :: PartialOrdering -> Ordering+toOrdering PLT = LT+toOrdering PGT = GT+toOrdering _   = EQ
+ src/Numeric/ProductOrd/Partial.hs view
@@ -0,0 +1,318 @@+{-# LANGUAGE DataKinds                  #-}+{-# LANGUAGE DeriveDataTypeable         #-}+{-# LANGUAGE DeriveGeneric              #-}+{-# LANGUAGE DeriveTraversable          #-}+{-# LANGUAGE FlexibleContexts           #-}+{-# LANGUAGE FlexibleInstances          #-}+{-# LANGUAGE GeneralizedNewtypeDeriving #-}+{-# LANGUAGE PolyKinds                  #-}+{-# LANGUAGE StandaloneDeriving         #-}+{-# LANGUAGE UndecidableInstances       #-}+-----------------------------------------------------------------------------+-- |+-- Module      :  Numeric.ProductOrd.Partial+-- Copyright   :  (c) Artem Chirkin+-- License     :  BSD3+--+--+-- Compare product types using partial `Ord` instances:+--+-- *  if nor \( a > b \), nor \( b > a \), neither, \( a = b \),+--      then @compare a b == undefined@+--+-- 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 (ProductOrd (..), toOrdering) where++import Control.Monad.Fix+import Control.Monad.Zip+import Data.Bits         (Bits, FiniteBits)+import Data.Coerce+import Data.Data+import Data.Foldable+import Data.Kind         (Type)+import Data.Monoid       as Mon (Monoid (..))+import Data.Semigroup    as Sem (Semigroup (..))+import Foreign.Storable  (Storable)+import GHC.Generics++import Numeric.ProductOrd+import Numeric.TypedList++{-|+  Redefine `Ord` instance for a type which is a cartesian product --+    as a partial __[product order](https://en.wikipedia.org/wiki/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__:+  \[+    \neg (a > b) \land \neg (b > a) \land \neg (a = b)+      \Rightarrow \mathtt{compare\ a\ b == undefined}+  \]++  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](https://en.wikipedia.org/wiki/Pareto_efficiency),+  but should be used with care.+  In particular, never use @ProductOrd@ as a key to a @Set@ or a @Map@!+ -}+newtype ProductOrd a = ProductOrd { getProductOrd :: a }+  deriving ( Eq, Show, Read, Data, Typeable, Generic, Generic1+           , Num, Enum, Bounded, Floating, Fractional+           , Semigroup, Monoid, Storable, Traversable+           , Bits, FiniteBits)++deriving instance (Ord (ProductOrd a), Integral a)   => Integral (ProductOrd a)+deriving instance (Ord (ProductOrd a), Real a)       => Real (ProductOrd a)+deriving instance (Ord (ProductOrd a), RealFrac a)   => RealFrac (ProductOrd a)+deriving instance (Ord (ProductOrd a), RealFloat a)  => RealFloat (ProductOrd a)++instance Foldable ProductOrd where+    foldMap                  = coerce+    elem                     = k (==)+      where+        k :: (a -> a -> Bool) -> a -> ProductOrd a -> Bool+        k = coerce+    foldl                    = coerce+    foldl'                   = coerce+    foldl1 _                 = coerce+    foldr f z (ProductOrd x) = f x z+    foldr'                   = foldr+    foldr1 _                 = coerce+    length _                 = 1+    maximum                  = coerce+    minimum                  = coerce+    null _                   = False+    product                  = coerce+    sum                      = coerce+    toList (ProductOrd x)    = [x]++instance Functor ProductOrd where+    fmap  = coerce++instance Applicative ProductOrd where+    pure  = ProductOrd+    (<*>) = coerce++instance Monad ProductOrd where+    m >>= k = k (getProductOrd m)++instance MonadFix ProductOrd where+    mfix f   = ProductOrd (fix (getProductOrd . f))++instance MonadZip ProductOrd where+    mzipWith = coerce+    munzip   = coerce++instance {-# INCOHERENT #-}+         All Ord (Map f xs)+      => Eq (ProductOrd (TypedList (f :: k -> Type) (xs :: [k]))) where+    ProductOrd U == ProductOrd U = True+    ProductOrd (a :* as) == ProductOrd (b :* bs)+      = a == b && ProductOrd as == ProductOrd bs++instance All Ord (Map f xs)+      => Ord (ProductOrd (TypedList (f :: k -> Type) (xs :: [k]))) where+    ProductOrd x > ProductOrd y = cmp x y == PGT+    {-# INLINE (>) #-}+    ProductOrd x < ProductOrd y = cmp x y == PLT+    {-# INLINE (<) #-}+    ProductOrd U >= ProductOrd U = True+    ProductOrd (a :* as) >= ProductOrd (b :* bs)+      = a >= b && ProductOrd as >= ProductOrd bs+    ProductOrd U <= ProductOrd U = True+    ProductOrd (a :* as) <= ProductOrd (b :* bs)+      = a <= b && ProductOrd as <= ProductOrd bs+    compare (ProductOrd a) (ProductOrd b) = toOrdering $ cmp a b+    min (ProductOrd U) (ProductOrd U) = ProductOrd U+    min (ProductOrd (a :* as)) (ProductOrd (b :* bs))+      = ProductOrd (min a b :* getProductOrd (min (ProductOrd as) (ProductOrd bs)))+    max (ProductOrd U) (ProductOrd U) = ProductOrd U+    max (ProductOrd (a :* as)) (ProductOrd (b :* bs))+      = ProductOrd (max a b :* getProductOrd (max (ProductOrd as) (ProductOrd bs)))++instance (Ord a1, Ord a2) => Ord (ProductOrd (a1, a2)) where+    ProductOrd x > ProductOrd y = cmp x y == PGT+    {-# INLINE (>) #-}+    ProductOrd x < ProductOrd y = cmp x y == PLT+    {-# INLINE (<) #-}+    ProductOrd (a1, a2) >= ProductOrd (b1, b2)+      = a1 >= b1 && a2 >= b2+    {-# INLINE (>=) #-}+    ProductOrd (a1, a2) <= ProductOrd (b1, b2)+      = a1 <= b1 && a2 <= b2+    {-# INLINE (<=) #-}+    compare (ProductOrd a) (ProductOrd b) = toOrdering $ cmp a b+    {-# INLINE compare #-}+    min (ProductOrd (a1, a2)) (ProductOrd (b1, b2))+      = ProductOrd (min a1 b1, min a2 b2)+    {-# INLINE min #-}+    max (ProductOrd (a1, a2)) (ProductOrd (b1, b2))+      = ProductOrd (max a1 b1, max a2 b2)+    {-# INLINE max #-}++instance (Ord a1, Ord a2, Ord a3) => Ord (ProductOrd (a1, a2, a3)) where+    ProductOrd x > ProductOrd y = cmp x y == PGT+    {-# INLINE (>) #-}+    ProductOrd x < ProductOrd y = cmp x y == PLT+    {-# INLINE (<) #-}+    ProductOrd (a1, a2, a3) >= ProductOrd (b1, b2, b3)+      = a1 >= b1 && a2 >= b2 && a3 >= b3+    {-# INLINE (>=) #-}+    ProductOrd (a1, a2, a3) <= ProductOrd (b1, b2, b3)+      = a1 <= b1 && a2 <= b2 && a3 <= b3+    {-# INLINE (<=) #-}+    compare (ProductOrd a) (ProductOrd b) = toOrdering $ cmp a b+    {-# INLINE compare #-}+    min (ProductOrd (a1, a2, a3)) (ProductOrd (b1, b2, b3))+      = ProductOrd (min a1 b1, min a2 b2, min a3 b3)+    {-# INLINE min #-}+    max (ProductOrd (a1, a2, a3)) (ProductOrd (b1, b2, b3))+      = ProductOrd (max a1 b1, max a2 b2, max a3 b3)+    {-# INLINE max #-}++instance (Ord a1, Ord a2, Ord a3, Ord a4)+      => Ord (ProductOrd (a1, a2, a3, a4)) where+    ProductOrd x > ProductOrd y = cmp x y == PGT+    {-# INLINE (>) #-}+    ProductOrd x < ProductOrd y = cmp x y == PLT+    {-# INLINE (<) #-}+    ProductOrd (a1, a2, a3, a4) >= ProductOrd (b1, b2, b3, b4)+      = a1 >= b1 && a2 >= b2 && a3 >= b3 && a4 >= b4+    {-# INLINE (>=) #-}+    ProductOrd (a1, a2, a3, a4) <= ProductOrd (b1, b2, b3, b4)+      = a1 <= b1 && a2 <= b2 && a3 <= b3 && a4 <= b4+    {-# INLINE (<=) #-}+    compare (ProductOrd a) (ProductOrd b) = toOrdering $ cmp a b+    {-# INLINE compare #-}+    min (ProductOrd (a1, a2, a3, a4)) (ProductOrd (b1, b2, b3, b4))+      = ProductOrd (min a1 b1, min a2 b2, min a3 b3, min a4 b4)+    {-# INLINE min #-}+    max (ProductOrd (a1, a2, a3, a4)) (ProductOrd (b1, b2, b3, b4))+      = ProductOrd (max a1 b1, max a2 b2, max a3 b3, max a4 b4)+    {-# INLINE max #-}++instance (Ord a1, Ord a2, Ord a3, Ord a4, Ord a5)+      => Ord (ProductOrd (a1, a2, a3, a4, a5)) where+    ProductOrd x > ProductOrd y = cmp x y == PGT+    {-# INLINE (>) #-}+    ProductOrd x < ProductOrd y = cmp x y == PLT+    {-# INLINE (<) #-}+    ProductOrd (a1, a2, a3, a4, a5) >= ProductOrd (b1, b2, b3, b4, b5)+      = a1 >= b1 && a2 >= b2 && a3 >= b3 && a4 >= b4 && a5 >= b5+    {-# INLINE (>=) #-}+    ProductOrd (a1, a2, a3, a4, a5) <= ProductOrd (b1, b2, b3, b4, b5)+      = a1 <= b1 && a2 <= b2 && a3 <= b3 && a4 <= b4 && a5 <= b5+    {-# INLINE (<=) #-}+    compare (ProductOrd a) (ProductOrd b) = toOrdering $ cmp a b+    {-# INLINE compare #-}+    min (ProductOrd (a1, a2, a3, a4, a5)) (ProductOrd (b1, b2, b3, b4, b5))+      = ProductOrd (min a1 b1, min a2 b2, min a3 b3, min a4 b4, min a5 b5)+    {-# INLINE min #-}+    max (ProductOrd (a1, a2, a3, a4, a5)) (ProductOrd (b1, b2, b3, b4, b5))+      = ProductOrd (max a1 b1, max a2 b2, max a3 b3, max a4 b4, max a5 b5)+    {-# INLINE max #-}++instance (Ord a1, Ord a2, Ord a3, Ord a4, Ord a5, Ord a6)+      => Ord (ProductOrd (a1, a2, a3, a4, a5, a6)) where+    ProductOrd x > ProductOrd y = cmp x y == PGT+    {-# INLINE (>) #-}+    ProductOrd x < ProductOrd y = cmp x y == PLT+    {-# INLINE (<) #-}+    ProductOrd (a1, a2, a3, a4, a5, a6) >= ProductOrd (b1, b2, b3, b4, b5, b6)+      = a1 >= b1 && a2 >= b2 && a3 >= b3 && a4 >= b4 && a5 >= b5 && a6 >= b6+    {-# INLINE (>=) #-}+    ProductOrd (a1, a2, a3, a4, a5, a6) <= ProductOrd (b1, b2, b3, b4, b5, b6)+      = a1 <= b1 && a2 <= b2 && a3 <= b3 && a4 <= b4 && a5 <= b5 && a6 <= b6+    {-# INLINE (<=) #-}+    compare (ProductOrd a) (ProductOrd b) = toOrdering $ cmp a b+    {-# INLINE compare #-}+    min (ProductOrd (a1, a2, a3, a4, a5, a6)) (ProductOrd (b1, b2, b3, b4, b5, b6))+      = ProductOrd (min a1 b1, min a2 b2, min a3 b3, min a4 b4, min a5 b5, min a6 b6)+    {-# INLINE min #-}+    max (ProductOrd (a1, a2, a3, a4, a5, a6)) (ProductOrd (b1, b2, b3, b4, b5, b6))+      = ProductOrd (max a1 b1, max a2 b2, max a3 b3, max a4 b4, max a5 b5, max a6 b6)+    {-# INLINE max #-}++instance (Ord a1, Ord a2, Ord a3, Ord a4, Ord a5, Ord a6, Ord a7)+      => Ord (ProductOrd (a1, a2, a3, a4, a5, a6, a7)) where+    ProductOrd x > ProductOrd y = cmp x y == PGT+    {-# INLINE (>) #-}+    ProductOrd x < ProductOrd y = cmp x y == PLT+    {-# INLINE (<) #-}+    ProductOrd (a1, a2, a3, a4, a5, a6, a7) >= ProductOrd (b1, b2, b3, b4, b5, b6, b7)+      = a1 >= b1 && a2 >= b2 && a3 >= b3 && a4 >= b4 && a5 >= b5 && a6 >= b6 && a7 >= b7+    {-# INLINE (>=) #-}+    ProductOrd (a1, a2, a3, a4, a5, a6, a7) <= ProductOrd (b1, b2, b3, b4, b5, b6, b7)+      = a1 <= b1 && a2 <= b2 && a3 <= b3 && a4 <= b4 && a5 <= b5 && a6 <= b6 && a7 <= b7+    {-# INLINE (<=) #-}+    compare (ProductOrd a) (ProductOrd b) = toOrdering $ cmp a b+    {-# INLINE compare #-}+    min (ProductOrd (a1, a2, a3, a4, a5, a6, a7)) (ProductOrd (b1, b2, b3, b4, b5, b6, b7))+      = ProductOrd (min a1 b1, min a2 b2, min a3 b3, min a4 b4, min a5 b5, min a6 b6, min a7 b7)+    {-# INLINE min #-}+    max (ProductOrd (a1, a2, a3, a4, a5, a6, a7)) (ProductOrd (b1, b2, b3, b4, b5, b6, b7))+      = ProductOrd (max a1 b1, max a2 b2, max a3 b3, max a4 b4, max a5 b5, max a6 b6, max a7 b7)+    {-# INLINE max #-}++instance (Ord a1, Ord a2, Ord a3, Ord a4, Ord a5, Ord a6, Ord a7, Ord a8)+      => Ord (ProductOrd (a1, a2, a3, a4, a5, a6, a7, a8)) where+    ProductOrd x > ProductOrd y = cmp x y == PGT+    {-# INLINE (>) #-}+    ProductOrd x < ProductOrd y = cmp x y == PLT+    {-# INLINE (<) #-}+    ProductOrd (a1, a2, a3, a4, a5, a6, a7, a8) >= ProductOrd (b1, b2, b3, b4, b5, b6, b7, b8)+      = a1 >= b1 && a2 >= b2 && a3 >= b3 && a4 >= b4 && a5 >= b5 && a6 >= b6 && a7 >= b7 && a8 >= b8+    {-# INLINE (>=) #-}+    ProductOrd (a1, a2, a3, a4, a5, a6, a7, a8) <= ProductOrd (b1, b2, b3, b4, b5, b6, b7, b8)+      = a1 <= b1 && a2 <= b2 && a3 <= b3 && a4 <= b4 && a5 <= b5 && a6 <= b6 && a7 <= b7 && a8 <= b8+    {-# INLINE (<=) #-}+    compare (ProductOrd a) (ProductOrd b) = toOrdering $ cmp a b+    {-# INLINE compare #-}+    min (ProductOrd (a1, a2, a3, a4, a5, a6, a7, a8)) (ProductOrd (b1, b2, b3, b4, b5, b6, b7, b8))+      = ProductOrd (min a1 b1, min a2 b2, min a3 b3, min a4 b4, min a5 b5, min a6 b6, min a7 b7, min a8 b8)+    {-# INLINE min #-}+    max (ProductOrd (a1, a2, a3, a4, a5, a6, a7, a8)) (ProductOrd (b1, b2, b3, b4, b5, b6, b7, b8))+      = ProductOrd (max a1 b1, max a2 b2, max a3 b3, max a4 b4, max a5 b5, max a6 b6, max a7 b7, max a8 b8)+    {-# INLINE max #-}++instance (Ord a1, Ord a2, Ord a3, Ord a4, Ord a5, Ord a6, Ord a7, Ord a8, Ord a9)+      => Ord (ProductOrd (a1, a2, a3, a4, a5, a6, a7, a8, a9)) where+    ProductOrd x > ProductOrd y = cmp x y == PGT+    {-# INLINE (>) #-}+    ProductOrd x < ProductOrd y = cmp x y == PLT+    {-# INLINE (<) #-}+    ProductOrd (a1, a2, a3, a4, a5, a6, a7, a8, a9) >= ProductOrd (b1, b2, b3, b4, b5, b6, b7, b8, b9)+      = a1 >= b1 && a2 >= b2 && a3 >= b3 && a4 >= b4 && a5 >= b5 && a6 >= b6 && a7 >= b7 && a8 >= b8 && a9 >= b9+    {-# INLINE (>=) #-}+    ProductOrd (a1, a2, a3, a4, a5, a6, a7, a8, a9) <= ProductOrd (b1, b2, b3, b4, b5, b6, b7, b8, b9)+      = a1 <= b1 && a2 <= b2 && a3 <= b3 && a4 <= b4 && a5 <= b5 && a6 <= b6 && a7 <= b7 && a8 <= b8 && a9 <= b9+    {-# INLINE (<=) #-}+    compare (ProductOrd a) (ProductOrd b) = toOrdering $ cmp a b+    {-# INLINE compare #-}+    min (ProductOrd (a1, a2, a3, a4, a5, a6, a7, a8, a9)) (ProductOrd (b1, b2, b3, b4, b5, b6, b7, b8, b9))+      = ProductOrd (min a1 b1, min a2 b2, min a3 b3, min a4 b4, min a5 b5, min a6 b6, min a7 b7, min a8 b8, min a9 b9)+    {-# INLINE min #-}+    max (ProductOrd (a1, a2, a3, a4, a5, a6, a7, a8, a9)) (ProductOrd (b1, b2, b3, b4, b5, b6, b7, b8, b9))+      = ProductOrd (max a1 b1, max a2 b2, max a3 b3, max a4 b4, max a5 b5, max a6 b6, max a7 b7, max a8 b8, max a9 b9)+    {-# INLINE max #-}++-- | Treat `Incomparable` as error (partial function).+toOrdering :: PartialOrdering -> Ordering+toOrdering PLT = LT+toOrdering PGT = GT+toOrdering PEQ = EQ+toOrdering Incomparable = error "incomparable items (this is a partial function)"
src/Numeric/Quaternion.hs view
@@ -1,14 +1,9 @@ ----------------------------------------------------------------------------- -- |--- Module      :  Numeric.Quaternion--- Copyright   :  (c) Artem Chirkin--- License     :  BSD3 ----- Maintainer  :  chirkin@arch.ethz.ch--- -- Quaternion operations implemented for Floats and Doubles. ----- The types `QDouble` and `QFloat` have the same representation as corresponding `Vector t 4`.+-- 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.@@ -19,17 +14,20 @@ -- -- All other numeric operations for vectors are element-wise, but for quaternions I have implemented -- the actual quaternion math.--- Some of the operations (such as trigonometric operations) are ambiguous for quaternions;--- the general rules I follow:------  1. Preserve imaginary vector axis same if possible;---  2. If both @+q@ and @-q@ are possible, prefer real value positive (@re q >= 0@).+-- 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 \( \sqrt{-1} = \pm i \), but also \( \sqrt{-1} = \pm j \),+-- and \( \sqrt{-1} = \pm k \), and any other unit quaterion with zero real part.+-- In cases like this, I stick to the @i@-th axis:  \( \sqrt{-1} := i \) ----------------------------------------------------------------------------- module Numeric.Quaternion     ( Quaternion (..)+    , Quater(Quater)     , QDouble, QFloat     ) where -import Numeric.Quaternion.Class-import Numeric.Quaternion.QFloat-import Numeric.Quaternion.QDouble+import Numeric.DataFrame.Internal.Backend  ()+import Numeric.Quaternion.Internal+import Numeric.Quaternion.Internal.QDouble+import Numeric.Quaternion.Internal.QFloat
− src/Numeric/Quaternion/Class.hs
@@ -1,85 +0,0 @@-{-# LANGUAGE DataKinds #-}-{-# LANGUAGE TypeFamilies #-}-module Numeric.Quaternion.Class-    ( Quaternion (..)-    ) where--import Numeric.Matrix (Matrix)-import Numeric.Vector (Vector)---- | Quaternion operations-class Quaternion t where-    -- | Quaternion data type. The ordering of coordinates is @x y z w@,-    --   where @w@ is an argument, and @x y z@ are components of a 3D vector-    data Quater t-    -- | Set the quaternion in format (x,y,z,w)-    packQ :: t -> t -> t -> t -> Quater t-    -- | Get the values of the quaternion in format (x,y,z,w)-    unpackQ :: Quater t -> (t,t,t,t)-    -- | Set the quaternion from 3D axis vector and argument-    fromVecNum :: Vector t 3 -> t -> Quater t-    -- | Set the quaternion from 4D vector in format (x,y,z,w)-    fromVec4 :: Vector t 4 -> Quater t-    -- | Transform the quaternion to 4D vector in format (x,y,z,w)-    toVec4 :: Quater t -> Vector t 4-    -- | Get scalar square of the quaternion.-    ---    --   >> realToFrac (square q) == q * conjugate q-    square :: Quater t -> t-    -- | Imagine part of quaternion (orientation vector)-    im :: Quater t -> Quater t-    -- | Real part of the quaternion-    re :: Quater t -> Quater t-    -- | Get imagenery 3D vector of the quaternion-    imVec :: Quater t -> Vector t 3-    -- | Real part of the quaternion into number-    taker :: Quater t -> t-    -- | i-th component-    takei :: Quater t -> t-    -- | j-th component-    takej :: Quater t -> t-    -- | k-th component-    takek :: Quater t -> t-    -- | Conjugate quaternion (negate imaginary part)-    conjugate :: Quater t -> Quater t-    -- | Rotates and scales vector in 3D using quaternion.-    --   Let @q = (cos (a\/2), sin (a\/2) * v)@; then the rotation angle is @a@, and the axis of rotation is @v@.-    --   Scaling is proportional to @|v|^2@.-    ---    --   >>> rotScale q x == q * x * (conjugate q)-    rotScale :: Quater t -> Vector t 3 -> Vector t 3-    -- | Creates a quaternion @q@ from two vectors @a@ and @b@.-    --   @rotScale q a == b@-    getRotScale :: 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 :: Vector t 3 -> t -> Quater t-    -- | Quaternion rotation angle-    ---    --   >>> q /= 0 ==> axisRotation (imVec q) (qArg q) == signum q-    qArg :: Quater t -> t-    -- | Create a quaternion from a rotation matrix.-    --   Note, that rotations of `q` and `-q` are equivalent, there result of this function may be-    --   ambiguious. I decided to force its real part be positive:-    ---    --   >>> taker (fromMatrix33 m) >= 0-    fromMatrix33 :: Matrix t 3 3 -> Quater t-    -- | Create a quaternion from a homogenious coordinates trasform matrix.-    --   Ignores matrix translation transform.-    --   Note, that rotations of `q` and `-q` are equivalent, there result of this function may be-    --   ambiguious. I decided to force its real part be positive:-    ---    --   >>> taker (fromMatrix44 m) >= 0-    fromMatrix44 :: Matrix t 4 4 -> Quater t-    -- | Create a rotation matrix from a quaternion.-    --   Note, that rotations of `q` and `-q` are equivalent, so the following property holds:-    ---    --   >>> toMatrix33 q == toMatrix33 (-q)-    toMatrix33 :: 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 `q` and `-q` are equivalent, so the following property holds:-    ---    --   >>> toMatrix44 q == toMatrix44 (-q)-    toMatrix44 :: Quater t -> Matrix t 4 4
+ src/Numeric/Quaternion/Internal.hs view
@@ -0,0 +1,154 @@+{-# LANGUAGE DataKinds           #-}+{-# LANGUAGE MagicHash           #-}+{-# LANGUAGE PatternSynonyms     #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeFamilies        #-}+{-# LANGUAGE UnboxedTuples       #-}+{-# LANGUAGE ViewPatterns        #-}+module Numeric.Quaternion.Internal+    ( Quaternion (..), Quater(Quater)+    ) where++import Numeric.Matrix.Internal (Matrix)+import Numeric.Vector.Internal (Vector)+import Text.Read++-- | @(x,y,z,w)@ of a quaternion+pattern Quater :: Quaternion t => t -> t -> t -> t -> Quater t+pattern Quater a b c d <- (unpackQ# -> (# a, b, c, d #))+  where+    Quater = packQ+{-# COMPLETE Quater #-}++-- | 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 Quater t+    -- | Set the quaternion in format @(x,y,z,w)@+    packQ :: t -> t -> t -> t -> Quater t+    -- | Get the values of the quaternion in format @(x,y,z,w)@+    unpackQ# :: Quater t -> (# t, t, t, t #)+    -- | Set the quaternion from 3D axis vector and argument+    fromVecNum :: Vector t 3 -> t -> Quater t+    -- | Set the quaternion from 4D vector in format @(x,y,z,w)@+    fromVec4 :: Vector t 4 -> Quater t+    -- | Transform the quaternion to 4D vector in format @(x,y,z,w)@+    toVec4 :: Quater t -> Vector t 4+    -- | Get scalar square of the quaternion.+    --+    --   >>> realToFrac (square q) == q * conjugate q+    square :: Quater t -> t+    -- | Imaginary part of the quaternion (orientation vector)+    im :: Quater t -> Quater t+    -- | Real part of the quaternion+    re :: Quater t -> Quater t+    -- | Imaginary part of the quaternion as a 3D vector+    imVec :: Quater t -> Vector t 3+    -- | Real part of the quaternion as a scalar+    taker :: Quater t -> t+    -- | i-th component+    takei :: Quater t -> t+    -- | j-th component+    takej :: Quater t -> t+    -- | k-th component+    takek :: Quater t -> t+    -- | Conjugate quaternion (negate imaginary part)+    conjugate :: Quater t -> Quater t+    -- | Rotates and scales vector in 3D using quaternion.+    --   Let \( q = c (\cos \frac{\alpha}{2}, v \sin \frac{\alpha}{2}) \)+    --     , \( c > 0 \), \( {|v|}^2 = 1 \);+    --   then the rotation angle is \( \alpha \), and the axis of rotation is \(v\).+    --   Scaling is proportional to \( c^2 \).+    --+    --   >>> rotScale q x == q * x * (conjugate q)+    rotScale :: 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 :: 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 :: Vector t 3 -> t -> Quater t+    -- | Quaternion rotation angle \( \alpha \)+    --   (where \( q = c (\cos \frac{\alpha}{2},  v \sin \frac{\alpha}{2}) \)+    --     , \( c > 0 \), \( {|v|}^2 = 1 \)).+    --+    --   >>> q /= 0 ==> axisRotation (imVec q) (qArg q) == signum q+    qArg :: Quater t -> t+    -- | Create a quaternion from a rotation matrix.+    --   Note, that rotations of \(q\) and \(-q\) are equivalent, there result of this+    --   function may be ambiguious. Assume the sign of the result to be chosen arbitrarily.+    fromMatrix33 :: Matrix t 3 3 -> Quater t+    -- | Create a quaternion from a homogenious coordinates trasform matrix.+    --   Ignores matrix translation transform.+    --   Note, that rotations of \(q\) and \(-q\) are equivalent, there result of this+    --   function may be ambiguious. Assume the sign of the result to be chosen arbitrarily.+    fromMatrix44 :: Matrix t 4 4 -> Quater t+    -- | Create a rotation matrix from a quaternion.+    --   Note, that rotations of \(q\) and \(-q\) are equivalent, so the following property holds:+    --+    --   >>> toMatrix33 q == toMatrix33 (-q)+    toMatrix33 :: 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 \(q\) and \(-q\) are equivalent, so the following property holds:+    --+    --   >>> toMatrix44 q == toMatrix44 (-q)+    toMatrix44 :: Quater t -> Matrix t 4 4+++instance (Show t, Quaternion t, Ord t, Num t) => Show (Quater t) where+    showsPrec p (Quater x y z w)+        = case finS of+            SEmpty -> showChar '0'+            Simple -> finF+            SParen -> showParen (p > 6) finF+      where+        (finS, finF) = go SEmpty+          [(w, Nothing), (x, Just 'i'), (y, Just 'j'), (z, Just 'k')]+        go :: ShowState -> [(t, Maybe Char)] -> (ShowState, ShowS)+        go s ((v,l):xs)+          | (s0, f0) <- showComponent s v l+          , (s', f') <- go s0 xs+            = (s', f0 . f')+        go s [] = (s, id)+        showLabel Nothing  = id+        showLabel (Just c) = showChar c+        showComponent :: ShowState -> t -> Maybe Char -> (ShowState, ShowS)+        showComponent sState val mLabel = case (sState, compare val 0) of+          (_     , EQ) -> ( sState, id )+          (SEmpty, GT) -> ( Simple, shows val . showLabel mLabel )+          (SEmpty, LT) -> ( SParen, shows val . showLabel mLabel )+          (_     , GT) -> ( SParen+                          , showString " + " . shows val . showLabel mLabel )+          (_     , LT) -> ( SParen+                          , showString " - " . shows (negate val) . showLabel mLabel )+++data ShowState = SEmpty | Simple | SParen+    deriving Eq++instance (Read t, Quaternion t, Num t) => Read (Quater t) where+    readPrec     = parens $ readPrec >>= go id 0 0 0 0+      where+        go :: (t -> t) -> t -> t -> t -> t -> t -> ReadPrec (Quater t)+        go f x y z w new =+          let def = pure (Quater x y z (f new))+              withLabel EOF         = def+              withLabel (Ident "i")+                = (lexP >>= proceed (f new) y z w) <++ pure (Quater (f new) y z w)+              withLabel (Ident "j")+                = (lexP >>= proceed x (f new) z w) <++ pure (Quater x (f new) z w)+              withLabel (Ident "k")+                = (lexP >>= proceed x y (f new) w) <++ pure (Quater x y (f new) w)+              withLabel l           = proceed x y z (f new) l+          in (lexP >>= withLabel) <++ def+        proceed :: t -> t -> t -> t -> Lexeme -> ReadPrec (Quater t)+        proceed x y z w (Symbol "+") = readPrec >>= go id x y z w+        proceed x y z w (Symbol "-") = readPrec >>= go negate x y z w+        proceed x y z w EOF          = pure (Quater x y z w)+        proceed _ _ _ _ _            = pfail++    readListPrec = readListPrecDefault+    readList     = readListDefault
+ src/Numeric/Quaternion/Internal/QDouble.hs view
@@ -0,0 +1,478 @@+{-# LANGUAGE DataKinds                  #-}+{-# LANGUAGE FlexibleContexts           #-}+{-# LANGUAGE FlexibleInstances          #-}+{-# LANGUAGE GeneralizedNewtypeDeriving #-}+{-# LANGUAGE MagicHash                  #-}+{-# LANGUAGE MultiParamTypeClasses      #-}+{-# LANGUAGE StandaloneDeriving         #-}+{-# LANGUAGE TypeFamilies               #-}+{-# LANGUAGE TypeInType                 #-}+{-# LANGUAGE UnboxedTuples              #-}+{-# LANGUAGE UndecidableInstances       #-}+{-# LANGUAGE ViewPatterns               #-}+{-# OPTIONS_GHC -fno-warn-orphans  #-}+module Numeric.Quaternion.Internal.QDouble+    ( QDouble, Quater (..)+    ) where++import qualified Control.Monad.ST                     as ST+import           Data.Coerce                          (coerce)+import           Numeric.DataFrame.Internal.PrimArray+import qualified Numeric.DataFrame.ST                 as ST+import           Numeric.DataFrame.Type+import           Numeric.PrimBytes                    (PrimBytes)+import           Numeric.Quaternion.Internal+import           Numeric.Scalar.Internal+import           Numeric.Vector.Internal++type QDouble = Quater Double++deriving instance PrimBytes (Quater Double)+deriving instance PrimArray Double (Quater Double)++instance Quaternion Double where+    newtype Quater Double = QDouble Vec4d+    {-# INLINE packQ #-}+    packQ = coerce (vec4 :: Double -> Double -> Double -> Double -> Vec4d)+    {-# INLINE unpackQ# #-}+    unpackQ# = coerce (unpackV4# :: Vec4d -> (# Double, Double, Double, Double #))+    {-# INLINE fromVecNum #-}+    fromVecNum (unpackV3# -> (# x, y, z #))  = packQ x y z+    {-# INLINE fromVec4 #-}+    fromVec4 = coerce+    {-# INLINE toVec4 #-}+    toVec4 = coerce+    {-# INLINE square #-}+    square (unpackQ# -> (# x, y, z, w #)) = (x * x) + (y * y) + (z * z) + (w * w)+    {-# INLINE im #-}+    im (unpackQ# -> (# x, y, z, _ #)) = packQ x y z 0.0+    {-# INLINE re #-}+    re (unpackQ# -> (# _, _, _, w #)) = packQ 0.0 0.0 0.0 w+    {-# INLINE imVec #-}+    imVec (unpackQ# -> (# x, y, z, _ #)) = vec3 x y z+    {-# INLINE taker #-}+    taker (unpackQ# -> (# _, _, _, w #)) = w+    {-# INLINE takei #-}+    takei (unpackQ# -> (# x, _, _, _ #)) = x+    {-# INLINE takej #-}+    takej (unpackQ# -> (# _, y, _, _ #)) = y+    {-# INLINE takek #-}+    takek (unpackQ# -> (# _, _, z, _ #)) = z+    {-# INLINE conjugate #-}+    conjugate (unpackQ# -> (# x, y, z, w #))+      = packQ (negate x) (negate y) (negate z) w+    {-# INLINE rotScale #-}+    rotScale (unpackQ# -> (# i, j, k, t #))+             (unpackV3# -> (# x, y, z #))+      = let l = t*t - i*i - j*j - k*k+            d = 2.0 * ( i*x + j*y + k*z)+            t2 = t * 2.0+        in vec3 (l*x + d*i + t2 * (z*j - y*k))+                (l*y + d*j + t2 * (x*k - z*i))+                (l*z + d*k + t2 * (y*i - x*j))+    {-# INLINE getRotScale #-}+    getRotScale a b = case (# unpackV3# a, unpackV3# b #) of+      (# _, (# 0, 0, 0 #) #) -> packQ 0.0 0.0 0.0 0.0+      (# (# 0, 0, 0 #), _ #) -> let x = (1 / 0 :: Double) in packQ x x x x+      (# (# a1, a2, a3 #), (# b1, b2, b3 #) #) ->+        let ma = sqrt (a1*a1 + a2*a2 + a3*a3)+            mb = sqrt (b1*b1 + b2*b2 + b3*b3)+            d  = a1*b1 + a2*b2 + a3*b3+            c  = sqrt (ma*mb + d)+            ma2 = ma * 1.4142135623730951 -- sqrt 2.0+            r  = recip (ma2 * c)+            c' = sqrt (mb / ma) -- ratio of a and b for corner cases+            r' = recip (sqrt ( negate (a1*b1 + a2*b2) ))+        in case unpackV3# (cross a b) of+          (# 0, 0, 0 #)+              -- if a and b face the same direction, q is fully real+            | d >= 0       -> packQ 0 0 0 c'+              -- if a and b face opposite directions, find an orthogonal vector+              -- prerequisites: w == 0  and  a·(x,y,z) == 0+              -- corner cases: only one vector component is non-zero+            | b1 == 0      -> packQ c' 0 0 0+              -- otherwise set the last component to zero,+              -- and get an orthogonal vector in 2D.+            | otherwise    -> packQ (-b2*r') (b1*r') 0 0+              -- NB: here we have some precision troubles+              --     when a and b are close to parallel and opposite.+          (# t1, t2, t3 #) -> packQ (t1 * r) (t2 * r) (t3 * r) (c / ma2)+    {-# INLINE axisRotation #-}+    axisRotation v a = case unpackV3# v of+      (# 0, 0, 0 #) -> packQ 0.0 0.0 0.0 (if abs a < pi then 1 else -1)+      (# x, y, z #) ->+        let c = cos (a * 0.5)+            s = sin (a * 0.5)+                / sqrt (x*x + y*y + z*z)+        in packQ (x * s) (y * s) (z * s) c+    {-# INLINE qArg #-}+    qArg (unpackQ# -> (# x, y, z, w #)) = 2 * atan2 (sqrt (x*x + y*y + z*z)) w+    {-# INLINE fromMatrix33 #-}+    fromMatrix33 m = fromM 1+      (ix# 0# m) (ix# 1# m) (ix# 2# m)+      (ix# 3# m) (ix# 4# m) (ix# 5# m)+      (ix# 6# m) (ix# 7# m) (ix# 8# m)++    {-# INLINE fromMatrix44 #-}+    fromMatrix44 m = fromM (ix# 15# m)+      (ix# 0# m) (ix# 1# m) (ix# 2# m)+      (ix# 4# m) (ix# 5# m) (ix# 6# m)+      (ix# 8# m) (ix# 9# m) (ix# 10# m)++    {-# INLINE toMatrix33 #-}+    toMatrix33 (unpackQ# -> (# 0.0, 0.0, 0.0, w #))+      = let x = w * w+            f 0 = (# 3 :: Int , x #)+            f k = (# k-1, 0 #)+        in case gen# (CumulDims [9,3,1]) f 0 of+            (# _, m #) -> m -- diag (scalar (w * w))+    toMatrix33 (unpackQ# -> (# x', y', z', w' #)) =+      let x = scalar x'+          y = scalar y'+          z = scalar z'+          w = scalar w'+          x2 = x * x+          y2 = y * y+          z2 = z * z+          w2 = w * w+          l2 = x2 + y2 + z2 + w2+      in ST.runST $ do+        df <- ST.newDataFrame+        ST.writeDataFrameOff df 0 $ l2 - 2*(z2 + y2)+        ST.writeDataFrameOff df 1 $ 2*(x*y + z*w)+        ST.writeDataFrameOff df 2 $ 2*(x*z - y*w)+        ST.writeDataFrameOff df 3 $ 2*(x*y - z*w)+        ST.writeDataFrameOff df 4 $ l2 - 2*(z2 + x2)+        ST.writeDataFrameOff df 5 $ 2*(y*z + x*w)+        ST.writeDataFrameOff df 6 $ 2*(x*z + y*w)+        ST.writeDataFrameOff df 7 $ 2*(y*z - x*w)+        ST.writeDataFrameOff df 8 $ l2 - 2*(y2 + x2)+        ST.unsafeFreezeDataFrame df+    {-# INLINE toMatrix44 #-}+    toMatrix44 (unpackQ# -> (# 0.0, 0.0, 0.0, w #)) = ST.runST $ do+      df <- ST.newDataFrame+      mapM_ (flip (ST.writeDataFrameOff df) 0) [0..15]+      let w2 = scalar (w * w)+      ST.writeDataFrameOff df 0 w2+      ST.writeDataFrameOff df 5 w2+      ST.writeDataFrameOff df 10 w2+      ST.writeDataFrameOff df 15 1+      ST.unsafeFreezeDataFrame df+    toMatrix44 (unpackQ# -> (# x', y', z', w' #)) =+      let x = scalar x'+          y = scalar y'+          z = scalar z'+          w = scalar w'+          x2 = x * x+          y2 = y * y+          z2 = z * z+          w2 = w * w+          l2 = x2 + y2 + z2 + w2+      in ST.runST $ do+        df <- ST.newDataFrame+        ST.writeDataFrameOff df 0 $ l2 - 2*(z2 + y2)+        ST.writeDataFrameOff df 1 $ 2*(x*y + z*w)+        ST.writeDataFrameOff df 2 $ 2*(x*z - y*w)+        ST.writeDataFrameOff df 3 0+        ST.writeDataFrameOff df 4 $ 2*(x*y - z*w)+        ST.writeDataFrameOff df 5 $ l2 - 2*(z2 + x2)+        ST.writeDataFrameOff df 6 $ 2*(y*z + x*w)+        ST.writeDataFrameOff df 7 0+        ST.writeDataFrameOff df 8 $ 2*(x*z + y*w)+        ST.writeDataFrameOff df 9 $ 2*(y*z - x*w)+        ST.writeDataFrameOff df 10 $ l2 - 2*(y2 + x2)+        ST.writeDataFrameOff df 11 0+        ST.writeDataFrameOff df 12 0+        ST.writeDataFrameOff df 13 0+        ST.writeDataFrameOff df 14 0+        ST.writeDataFrameOff df 15 1+        ST.unsafeFreezeDataFrame df+++{- Calculate quaternion from a 3x3 matrix.++   First argument is a constant; it is either 1 for a 3x3 matrix,+   or m44 for a 4x4 matrix. I just need to multiply all components by+   this number.++   Further NB for the formulae:++   d == square q == det m ** (1/3)+   t == trace m  == 4 w w - d+   m01 - m10 == 4 z w+   m20 - m02 == 4 y w+   m12 - m21 == 4 x w+   m01 + m10 == 4 x y+   m20 + m02 == 4 x z+   m12 + m21 == 4 y z+   m00 == + x x - y y - z z + w w+   m11 == - x x + y y - z z + w w+   m22 == - x x - y y + z z + w w+   4 x x == d + m00 - m11 - m22+   4 y y == d - m00 + m11 - m22+   4 z z == d - m00 - m11 + m22+   4 w w == d + m00 + m11 + m22+ -}+fromM :: Double+      -> Double -> Double -> Double+      -> Double -> Double -> Double+      -> Double -> Double -> Double+      -> QDouble+fromM c'+  m00 m01 m02+  m10 m11 m12+  m20 m21 m22+    | t > 0+      = let dd = sqrt ( d + t )+            is = c / dd+        in packQ ((m12 - m21)*is) ((m20 - m02)*is) ((m01 - m10)*is) (c*dd)+    | m00 > m11 && m00 > m22+      = let dd = sqrt ( d + m00 - m11 - m22 )+            is = c / dd+        in packQ (c*dd) ((m01 + m10)*is) ((m02 + m20)*is) ((m12 - m21)*is)+    | m11 > m22+      = let dd = sqrt ( d - m00 + m11 - m22 )+            is = c / dd+        in packQ ((m01 + m10)*is) (c*dd) ((m12 + m21)*is) ((m20 - m02)*is)+    | otherwise+      = let dd = sqrt ( d - m00 - m11 + m22 )+            is = c / dd+        in packQ ((m02 + m20)*is) ((m12 + m21)*is) (c*dd) ((m01 - m10)*is)++  where+    -- normalizing constant+    c = recip $ 2 * sqrt c'+    -- trace+    t = m00 + m11 + m22+    -- cubic root of determinant+    d = ( m00 * ( m11 * m22 - m12 * m21 )+        - m01 * ( m10 * m22 - m12 * m20 )+        + m02 * ( m10 * m21 - m11 * m20 )+        ) ** 0.33333333333333333333333333333333+++++instance Num QDouble where+    QDouble a + QDouble b+      = QDouble (a + b)+    {-# INLINE (+) #-}+    QDouble a - QDouble b+      = QDouble (a - b)+    {-# INLINE (-) #-}+    (unpackQ# -> (# a1, a2, a3, a4 #)) * (unpackQ# -> (# b1, b2, b3, b4 #))+      = packQ+           ((a4 * b1) ++            (a1 * b4) ++            (a2 * b3) -+            (a3 * b2)+            )+           ((a4 * b2) -+            (a1 * b3) ++            (a2 * b4) ++            (a3 * b1)+            )+           ((a4 * b3) ++            (a1 * b2) -+            (a2 * b1) ++            (a3 * b4)+            )+           ((a4 * b4) -+            (a1 * b1) -+            (a2 * b2) -+            (a3 * b3)+            )+    {-# INLINE (*) #-}+    negate (QDouble a) = QDouble (negate a)+    {-# INLINE negate #-}+    abs = packQ 0.0 0.0 0.0 . sqrt . square+    {-# INLINE abs #-}+    signum q@(unpackQ# -> (# x, y, z, w #))+      = case square q of+          0.0 -> packQ 0.0 0.0 0.0 0.0+          qd -> case recip (sqrt qd) of+             s -> packQ (x * s) (y * s) (z * s) (w * s)+    {-# INLINE signum #-}+    fromInteger = packQ 0.0 0.0 0.0 . fromInteger+    {-# INLINE fromInteger #-}+++instance Fractional QDouble where+    {-# INLINE recip #-}+    recip q@(unpackQ# -> (# x, y, z, w #)) = case negate (recip (square q)) of+      c -> packQ (x * c) (y * c) (z * c) (negate (w * c))+    {-# INLINE (/) #-}+    a / b = a * recip b+    {-# INLINE fromRational #-}+    fromRational = packQ 0.0 0.0 0.0 . fromRational+++instance Floating QDouble where+    {-# INLINE pi #-}+    pi = packQ 0.0 0.0 0.0 3.141592653589793+    {-# INLINE exp #-}+    exp (unpackQ# -> (# x, y, z, w #))+      = case (# (x * x) ++                (y * y) ++                (z * z)+             , exp w+             #) of+        (# 0.0, et #) -> packQ 0.0 0.0 0.0 et+        (# mv2, et #) -> case sqrt mv2 of+          mv -> case et * sin mv / mv of+            l -> packQ (x * l) (y * l) (z * l) (et * cos mv)+    {-# INLINE log #-}+    log = log' (Vec3 1 0 0)+    {-# INLINE sqrt #-}+    sqrt = sqrt' (Vec3 1 0 0)+    {-# INLINE sin #-}+    sin (unpackQ# -> (# x, y, z, w #))+      = case (x * x) + (y * y) + (z * z) of+        0.0 -> packQ 0.0 0.0 0.0 (sin w)+        mv2 -> case sqrt mv2 of+          mv -> case cos w * sinh mv / mv of+            l -> packQ (x * l) (y * l) (z * l) (sin w * cosh mv)+    {-# INLINE cos #-}+    cos (unpackQ# -> (# x, y, z, w #))+      = case (x * x) + (y * y) + (z * z) of+        0.0 -> packQ 0.0 0.0 0.0 (cos w)+        mv2 -> case sqrt mv2 of+          mv -> case sin w * sinh mv / negate mv of+            l -> packQ (x * l) (y * l) (z * l) (cos w * cosh mv)+    {-# INLINE tan #-}+    tan (unpackQ# -> (# x, y, z, w #))+      = case (x * x) + (y * y) + (z * z) of+        0.0 -> packQ 0.0 0.0 0.0 (tan w)+        mv2 ->+          let mv = sqrt mv2+              chv = cosh mv+              shv = sinh mv+              ct = cos w+              st = sin w+              cq = recip ( (ct * ct * chv * chv) + (st * st * shv * shv) )+              l = chv * shv * cq / mv+          in packQ (x * l) (y * l) (z * l) (ct * st * cq)+    {-# INLINE sinh #-}+    sinh (unpackQ# -> (# x, y, z, w #))+      = case (x * x) + (y * y) + (z * z) of+        0.0 -> packQ 0.0 0.0 0.0 (sinh w)+        mv2 -> case sqrt mv2 of+          mv -> case cosh w * sin mv / mv of+            l -> packQ (x * l) (y * l) (z * l) (sinh w * cos mv)+    {-# INLINE cosh #-}+    cosh (unpackQ# -> (# x, y, z, w #))+      = case (x * x) + (y * y) + (z * z) of+        0.0 -> packQ 0.0 0.0 0.0 (cosh w)+        mv2 -> case sqrt mv2 of+          mv -> case sinh w * sin mv / mv of+            l -> packQ (x * l) (y * l) (z * l) (cosh w * cos mv)+    {-# INLINE tanh #-}+    tanh (unpackQ# -> (# x, y, z, w #))+      = case (x * x) + (y * y) + (z * z) of+        0.0 -> packQ 0.0 0.0 0.0 (tanh w)+        mv2 ->+          let mv = sqrt mv2+              cv = cos mv+              sv = sin mv+              cht = cosh w+              sht = sinh w+              cq = recip ( (cht * cht * cv * cv) + (sht * sht * sv * sv) )+              l = cv * sv * cq / mv+          in packQ (x * l) (y * l) (z * l) (cht * sht * cq)+    {-# INLINE asin #-}+    asin q = -i * log' axis (i*q + sqrt' axis (1 - q*q))+        where+          axis = sigVec q+          i = fromVecNum axis 0+    {-# INLINE acos #-}+    acos q = pi/2 - asin q+    {-# INLINE atan #-}+    -- atan q = i / 2 * log ( (i + q) / (i - q) )+    atan (unpackQ# -> (# x, y, z, w #))+      = case (x * x) + (y * y) + (z * z) of+        0 -> packQ 0 0 0 (atan w)+        v2 ->+          let v = sqrt v2+              w2 = w*w+              vw2 = w2 + v2+              t  = 1 + vw2+              c  = 0.25 * log ((t + 2*v) / (t - 2*v)) / v+          in packQ (c*x) (c*y) (c*z) $ 0.5 * atan2 (2*w) (1 - vw2)+    {-# INLINE asinh #-}+    -- The original formula:+    -- asinh q = log (q + sqrt (q*q + 1))+    -- below is a more numerically stable version.+    asinh (unpackQ# -> (# x, y, z, w #))+      | v2 == 0+        = packQ 0 0 0 (asinh w)+      | w == 0+        = if v2 <= 1+          then let c = asin v / v+               in  packQ (c*x) (c*y) (c*z) 0+          else let c  = 0.5 * pi / v+                   w' = 0.5 * log (2*v2 - 1 + 2 * v * sqrt ( v2 - 1 ))+               in  packQ (c*x) (c*y) (c*z) w'+      | otherwise+        = let c = atan2 v t / v+              w' = 0.5 * log ( t2  + v2) - log t+                     + if w >= 0+                       then log ( t + w )+                       else log 2 + log w2 - log ( t - w ) - log ( r + w2 + v2 - 1 )+          in packQ (c*x) (c*y) (c*z) w'+      where+        v2 = (x * x) + (y * y) + (z * z)+        v  = sqrt v2+        w2 = w*w+        wvp1 = w2 - v2 + 1+        r = sqrt $ wvp1*wvp1 + 4*w2*v2+        t = sqrt $ ( r + wvp1 ) * 0.5+        t2 = t*t+    {-# INLINE acosh #-}+    -- note, log (q + sqrt (q*q - 1)) would not work, because that would not+    -- be the principal value.+    acosh q = log' axis (q + sqrt' axis (q + 1) * sqrt' axis (q - 1))+      where+        axis = sigVec q+    {-# INLINE atanh #-}+    atanh q = 0.5 * log' (sigVec q) ((1+q)/(1-q))++-- If q is negative real, provide a fallback axis to align log.+log' :: Vec3d -> QDouble -> QDouble+log' r (unpackQ# -> (# x, y, z, w #))+  = case (x * x) + (y * y) + (z * z) of+    0.0 | w >= 0+           -> packQ 0.0 0.0 0.0 (log w)+        | Vec3 rx ry rz <- r+           ->  packQ (pi*rx) (pi*ry) (pi*rz) (log (negate w))+    mv2 -> case (# sqrt (mv2 + (w * w)), sqrt mv2 #) of+      (# mq, mv #) -> case atan2 mv w / mv of+        l -> packQ (x * l) (y * l) (z * l) (log mq)+++-- If q is negative real, provide a fallback axis to align sqrt.+sqrt' :: Vec3d -> QDouble -> QDouble+sqrt' r (unpackQ# -> (# x, y, z, w #))+  = case (x * x) + (y * y) + (z * z) of+    0.0 | w >= 0+          -> packQ 0.0 0.0 0.0 (sqrt w)+        | Vec3 rx ry rz <- r+        , sw <- sqrt (negate w)+          -> packQ (sw*rx) (sw*ry) (sw*rz) 0+    mv2 ->+      let mq = sqrt (mv2 + w * w)+          l2 = sqrt mq+          tq = w / (mq * 2.0)+          sina = sqrt (0.5 - tq) * l2 / sqrt mv2+      in packQ (x * sina) (y * sina) (z * sina) (sqrt (0.5 + tq) * l2)++sigVec :: QDouble -> Vec3d+sigVec (unpackQ# -> (# x, y, z, _ #))+  = case sqrt ((x * x) + (y * y) + (z * z)) of+      0 -> vec3 1 0 0+      l -> vec3 (x/l) (y/l) (z/l)++instance Eq QDouble where+    {-# INLINE (==) #-}+    QDouble a == QDouble b = a == b+    {-# INLINE (/=) #-}+    QDouble a /= QDouble b = a /= b
+ src/Numeric/Quaternion/Internal/QFloat.hs view
@@ -0,0 +1,478 @@+{-# LANGUAGE DataKinds                  #-}+{-# LANGUAGE FlexibleContexts           #-}+{-# LANGUAGE FlexibleInstances          #-}+{-# LANGUAGE GeneralizedNewtypeDeriving #-}+{-# LANGUAGE MagicHash                  #-}+{-# LANGUAGE MultiParamTypeClasses      #-}+{-# LANGUAGE StandaloneDeriving         #-}+{-# LANGUAGE TypeFamilies               #-}+{-# LANGUAGE TypeInType                 #-}+{-# LANGUAGE UnboxedTuples              #-}+{-# LANGUAGE UndecidableInstances       #-}+{-# LANGUAGE ViewPatterns               #-}+{-# OPTIONS_GHC -fno-warn-orphans  #-}+module Numeric.Quaternion.Internal.QFloat+    ( QFloat, Quater (..)+    ) where++import qualified Control.Monad.ST                     as ST+import           Data.Coerce                          (coerce)+import           Numeric.DataFrame.Internal.PrimArray+import qualified Numeric.DataFrame.ST                 as ST+import           Numeric.DataFrame.Type+import           Numeric.PrimBytes                    (PrimBytes)+import           Numeric.Quaternion.Internal+import           Numeric.Scalar.Internal+import           Numeric.Vector.Internal++type QFloat = Quater Float++deriving instance PrimBytes (Quater Float)+deriving instance PrimArray Float (Quater Float)++instance Quaternion Float where+    newtype Quater Float = QFloat Vec4f+    {-# INLINE packQ #-}+    packQ = coerce (vec4 :: Float -> Float -> Float -> Float -> Vec4f)+    {-# INLINE unpackQ# #-}+    unpackQ# = coerce (unpackV4# :: Vec4f -> (# Float, Float, Float, Float #))+    {-# INLINE fromVecNum #-}+    fromVecNum (unpackV3# -> (# x, y, z #))  = packQ x y z+    {-# INLINE fromVec4 #-}+    fromVec4 = coerce+    {-# INLINE toVec4 #-}+    toVec4 = coerce+    {-# INLINE square #-}+    square (unpackQ# -> (# x, y, z, w #)) = (x * x) + (y * y) + (z * z) + (w * w)+    {-# INLINE im #-}+    im (unpackQ# -> (# x, y, z, _ #)) = packQ x y z 0.0+    {-# INLINE re #-}+    re (unpackQ# -> (# _, _, _, w #)) = packQ 0.0 0.0 0.0 w+    {-# INLINE imVec #-}+    imVec (unpackQ# -> (# x, y, z, _ #)) = vec3 x y z+    {-# INLINE taker #-}+    taker (unpackQ# -> (# _, _, _, w #)) = w+    {-# INLINE takei #-}+    takei (unpackQ# -> (# x, _, _, _ #)) = x+    {-# INLINE takej #-}+    takej (unpackQ# -> (# _, y, _, _ #)) = y+    {-# INLINE takek #-}+    takek (unpackQ# -> (# _, _, z, _ #)) = z+    {-# INLINE conjugate #-}+    conjugate (unpackQ# -> (# x, y, z, w #))+      = packQ (negate x) (negate y) (negate z) w+    {-# INLINE rotScale #-}+    rotScale (unpackQ# -> (# i, j, k, t #))+             (unpackV3# -> (# x, y, z #))+      = let l = t*t - i*i - j*j - k*k+            d = 2.0 * ( i*x + j*y + k*z)+            t2 = t * 2.0+        in vec3 (l*x + d*i + t2 * (z*j - y*k))+                (l*y + d*j + t2 * (x*k - z*i))+                (l*z + d*k + t2 * (y*i - x*j))+    {-# INLINE getRotScale #-}+    getRotScale a b = case (# unpackV3# a, unpackV3# b #) of+      (# _, (# 0, 0, 0 #) #) -> packQ 0.0 0.0 0.0 0.0+      (# (# 0, 0, 0 #), _ #) -> let x = (1 / 0 :: Float) in packQ x x x x+      (# (# a1, a2, a3 #), (# b1, b2, b3 #) #) ->+        let ma = sqrt (a1*a1 + a2*a2 + a3*a3)+            mb = sqrt (b1*b1 + b2*b2 + b3*b3)+            d  = a1*b1 + a2*b2 + a3*b3+            c  = sqrt (ma*mb + d)+            ma2 = ma * 1.4142135623730951 -- sqrt 2.0+            r  = recip (ma2 * c)+            c' = sqrt (mb / ma) -- ratio of a and b for corner cases+            r' = recip (sqrt ( negate (a1*b1 + a2*b2) ))+        in case unpackV3# (cross a b) of+          (# 0, 0, 0 #)+              -- if a and b face the same direction, q is fully real+            | d >= 0       -> packQ 0 0 0 c'+              -- if a and b face opposite directions, find an orthogonal vector+              -- prerequisites: w == 0  and  a·(x,y,z) == 0+              -- corner cases: only one vector component is non-zero+            | b1 == 0      -> packQ c' 0 0 0+              -- otherwise set the last component to zero,+              -- and get an orthogonal vector in 2D.+            | otherwise    -> packQ (-b2*r') (b1*r') 0 0+              -- NB: here we have some precision troubles+              --     when a and b are close to parallel and opposite.+          (# t1, t2, t3 #) -> packQ (t1 * r) (t2 * r) (t3 * r) (c / ma2)+    {-# INLINE axisRotation #-}+    axisRotation v a = case unpackV3# v of+      (# 0, 0, 0 #) -> packQ 0.0 0.0 0.0 (if abs a < pi then 1 else -1)+      (# x, y, z #) ->+        let c = cos (a * 0.5)+            s = sin (a * 0.5)+                / sqrt (x*x + y*y + z*z)+        in packQ (x * s) (y * s) (z * s) c+    {-# INLINE qArg #-}+    qArg (unpackQ# -> (# x, y, z, w #)) = 2 * atan2 (sqrt (x*x + y*y + z*z)) w+    {-# INLINE fromMatrix33 #-}+    fromMatrix33 m = fromM 1+      (ix# 0# m) (ix# 1# m) (ix# 2# m)+      (ix# 3# m) (ix# 4# m) (ix# 5# m)+      (ix# 6# m) (ix# 7# m) (ix# 8# m)++    {-# INLINE fromMatrix44 #-}+    fromMatrix44 m = fromM (ix# 15# m)+      (ix# 0# m) (ix# 1# m) (ix# 2# m)+      (ix# 4# m) (ix# 5# m) (ix# 6# m)+      (ix# 8# m) (ix# 9# m) (ix# 10# m)++    {-# INLINE toMatrix33 #-}+    toMatrix33 (unpackQ# -> (# 0.0, 0.0, 0.0, w #))+      = let x = w * w+            f 0 = (# 3 :: Int , x #)+            f k = (# k-1, 0 #)+        in case gen# (CumulDims [9,3,1]) f 0 of+            (# _, m #) -> m -- diag (scalar (w * w))+    toMatrix33 (unpackQ# -> (# x', y', z', w' #)) =+      let x = scalar x'+          y = scalar y'+          z = scalar z'+          w = scalar w'+          x2 = x * x+          y2 = y * y+          z2 = z * z+          w2 = w * w+          l2 = x2 + y2 + z2 + w2+      in ST.runST $ do+        df <- ST.newDataFrame+        ST.writeDataFrameOff df 0 $ l2 - 2*(z2 + y2)+        ST.writeDataFrameOff df 1 $ 2*(x*y + z*w)+        ST.writeDataFrameOff df 2 $ 2*(x*z - y*w)+        ST.writeDataFrameOff df 3 $ 2*(x*y - z*w)+        ST.writeDataFrameOff df 4 $ l2 - 2*(z2 + x2)+        ST.writeDataFrameOff df 5 $ 2*(y*z + x*w)+        ST.writeDataFrameOff df 6 $ 2*(x*z + y*w)+        ST.writeDataFrameOff df 7 $ 2*(y*z - x*w)+        ST.writeDataFrameOff df 8 $ l2 - 2*(y2 + x2)+        ST.unsafeFreezeDataFrame df+    {-# INLINE toMatrix44 #-}+    toMatrix44 (unpackQ# -> (# 0.0, 0.0, 0.0, w #)) = ST.runST $ do+      df <- ST.newDataFrame+      mapM_ (flip (ST.writeDataFrameOff df) 0) [0..15]+      let w2 = scalar (w * w)+      ST.writeDataFrameOff df 0 w2+      ST.writeDataFrameOff df 5 w2+      ST.writeDataFrameOff df 10 w2+      ST.writeDataFrameOff df 15 1+      ST.unsafeFreezeDataFrame df+    toMatrix44 (unpackQ# -> (# x', y', z', w' #)) =+      let x = scalar x'+          y = scalar y'+          z = scalar z'+          w = scalar w'+          x2 = x * x+          y2 = y * y+          z2 = z * z+          w2 = w * w+          l2 = x2 + y2 + z2 + w2+      in ST.runST $ do+        df <- ST.newDataFrame+        ST.writeDataFrameOff df 0 $ l2 - 2*(z2 + y2)+        ST.writeDataFrameOff df 1 $ 2*(x*y + z*w)+        ST.writeDataFrameOff df 2 $ 2*(x*z - y*w)+        ST.writeDataFrameOff df 3 0+        ST.writeDataFrameOff df 4 $ 2*(x*y - z*w)+        ST.writeDataFrameOff df 5 $ l2 - 2*(z2 + x2)+        ST.writeDataFrameOff df 6 $ 2*(y*z + x*w)+        ST.writeDataFrameOff df 7 0+        ST.writeDataFrameOff df 8 $ 2*(x*z + y*w)+        ST.writeDataFrameOff df 9 $ 2*(y*z - x*w)+        ST.writeDataFrameOff df 10 $ l2 - 2*(y2 + x2)+        ST.writeDataFrameOff df 11 0+        ST.writeDataFrameOff df 12 0+        ST.writeDataFrameOff df 13 0+        ST.writeDataFrameOff df 14 0+        ST.writeDataFrameOff df 15 1+        ST.unsafeFreezeDataFrame df+++{- Calculate quaternion from a 3x3 matrix.++   First argument is a constant; it is either 1 for a 3x3 matrix,+   or m44 for a 4x4 matrix. I just need to multiply all components by+   this number.++   Further NB for the formulae:++   d == square q == det m ** (1/3)+   t == trace m  == 4 w w - d+   m01 - m10 == 4 z w+   m20 - m02 == 4 y w+   m12 - m21 == 4 x w+   m01 + m10 == 4 x y+   m20 + m02 == 4 x z+   m12 + m21 == 4 y z+   m00 == + x x - y y - z z + w w+   m11 == - x x + y y - z z + w w+   m22 == - x x - y y + z z + w w+   4 x x == d + m00 - m11 - m22+   4 y y == d - m00 + m11 - m22+   4 z z == d - m00 - m11 + m22+   4 w w == d + m00 + m11 + m22+ -}+fromM :: Float+      -> Float -> Float -> Float+      -> Float -> Float -> Float+      -> Float -> Float -> Float+      -> QFloat+fromM c'+  m00 m01 m02+  m10 m11 m12+  m20 m21 m22+    | t > 0+      = let dd = sqrt ( d + t )+            is = c / dd+        in packQ ((m12 - m21)*is) ((m20 - m02)*is) ((m01 - m10)*is) (c*dd)+    | m00 > m11 && m00 > m22+      = let dd = sqrt ( d + m00 - m11 - m22 )+            is = c / dd+        in packQ (c*dd) ((m01 + m10)*is) ((m02 + m20)*is) ((m12 - m21)*is)+    | m11 > m22+      = let dd = sqrt ( d - m00 + m11 - m22 )+            is = c / dd+        in packQ ((m01 + m10)*is) (c*dd) ((m12 + m21)*is) ((m20 - m02)*is)+    | otherwise+      = let dd = sqrt ( d - m00 - m11 + m22 )+            is = c / dd+        in packQ ((m02 + m20)*is) ((m12 + m21)*is) (c*dd) ((m01 - m10)*is)++  where+    -- normalizing constant+    c = recip $ 2 * sqrt c'+    -- trace+    t = m00 + m11 + m22+    -- cubic root of determinant+    d = ( m00 * ( m11 * m22 - m12 * m21 )+        - m01 * ( m10 * m22 - m12 * m20 )+        + m02 * ( m10 * m21 - m11 * m20 )+        ) ** 0.33333333333333333333333333333333+++++instance Num QFloat where+    QFloat a + QFloat b+      = QFloat (a + b)+    {-# INLINE (+) #-}+    QFloat a - QFloat b+      = QFloat (a - b)+    {-# INLINE (-) #-}+    (unpackQ# -> (# a1, a2, a3, a4 #)) * (unpackQ# -> (# b1, b2, b3, b4 #))+      = packQ+           ((a4 * b1) ++            (a1 * b4) ++            (a2 * b3) -+            (a3 * b2)+            )+           ((a4 * b2) -+            (a1 * b3) ++            (a2 * b4) ++            (a3 * b1)+            )+           ((a4 * b3) ++            (a1 * b2) -+            (a2 * b1) ++            (a3 * b4)+            )+           ((a4 * b4) -+            (a1 * b1) -+            (a2 * b2) -+            (a3 * b3)+            )+    {-# INLINE (*) #-}+    negate (QFloat a) = QFloat (negate a)+    {-# INLINE negate #-}+    abs = packQ 0.0 0.0 0.0 . sqrt . square+    {-# INLINE abs #-}+    signum q@(unpackQ# -> (# x, y, z, w #))+      = case square q of+          0.0 -> packQ 0.0 0.0 0.0 0.0+          qd -> case recip (sqrt qd) of+             s -> packQ (x * s) (y * s) (z * s) (w * s)+    {-# INLINE signum #-}+    fromInteger = packQ 0.0 0.0 0.0 . fromInteger+    {-# INLINE fromInteger #-}+++instance Fractional QFloat where+    {-# INLINE recip #-}+    recip q@(unpackQ# -> (# x, y, z, w #)) = case negate (recip (square q)) of+      c -> packQ (x * c) (y * c) (z * c) (negate (w * c))+    {-# INLINE (/) #-}+    a / b = a * recip b+    {-# INLINE fromRational #-}+    fromRational = packQ 0.0 0.0 0.0 . fromRational+++instance Floating QFloat where+    {-# INLINE pi #-}+    pi = packQ 0.0 0.0 0.0 3.141592653589793+    {-# INLINE exp #-}+    exp (unpackQ# -> (# x, y, z, w #))+      = case (# (x * x) ++                (y * y) ++                (z * z)+             , exp w+             #) of+        (# 0.0, et #) -> packQ 0.0 0.0 0.0 et+        (# mv2, et #) -> case sqrt mv2 of+          mv -> case et * sin mv / mv of+            l -> packQ (x * l) (y * l) (z * l) (et * cos mv)+    {-# INLINE log #-}+    log = log' (Vec3 1 0 0)+    {-# INLINE sqrt #-}+    sqrt = sqrt' (Vec3 1 0 0)+    {-# INLINE sin #-}+    sin (unpackQ# -> (# x, y, z, w #))+      = case (x * x) + (y * y) + (z * z) of+        0.0 -> packQ 0.0 0.0 0.0 (sin w)+        mv2 -> case sqrt mv2 of+          mv -> case cos w * sinh mv / mv of+            l -> packQ (x * l) (y * l) (z * l) (sin w * cosh mv)+    {-# INLINE cos #-}+    cos (unpackQ# -> (# x, y, z, w #))+      = case (x * x) + (y * y) + (z * z) of+        0.0 -> packQ 0.0 0.0 0.0 (cos w)+        mv2 -> case sqrt mv2 of+          mv -> case sin w * sinh mv / negate mv of+            l -> packQ (x * l) (y * l) (z * l) (cos w * cosh mv)+    {-# INLINE tan #-}+    tan (unpackQ# -> (# x, y, z, w #))+      = case (x * x) + (y * y) + (z * z) of+        0.0 -> packQ 0.0 0.0 0.0 (tan w)+        mv2 ->+          let mv = sqrt mv2+              chv = cosh mv+              shv = sinh mv+              ct = cos w+              st = sin w+              cq = recip ( (ct * ct * chv * chv) + (st * st * shv * shv) )+              l = chv * shv * cq / mv+          in packQ (x * l) (y * l) (z * l) (ct * st * cq)+    {-# INLINE sinh #-}+    sinh (unpackQ# -> (# x, y, z, w #))+      = case (x * x) + (y * y) + (z * z) of+        0.0 -> packQ 0.0 0.0 0.0 (sinh w)+        mv2 -> case sqrt mv2 of+          mv -> case cosh w * sin mv / mv of+            l -> packQ (x * l) (y * l) (z * l) (sinh w * cos mv)+    {-# INLINE cosh #-}+    cosh (unpackQ# -> (# x, y, z, w #))+      = case (x * x) + (y * y) + (z * z) of+        0.0 -> packQ 0.0 0.0 0.0 (cosh w)+        mv2 -> case sqrt mv2 of+          mv -> case sinh w * sin mv / mv of+            l -> packQ (x * l) (y * l) (z * l) (cosh w * cos mv)+    {-# INLINE tanh #-}+    tanh (unpackQ# -> (# x, y, z, w #))+      = case (x * x) + (y * y) + (z * z) of+        0.0 -> packQ 0.0 0.0 0.0 (tanh w)+        mv2 ->+          let mv = sqrt mv2+              cv = cos mv+              sv = sin mv+              cht = cosh w+              sht = sinh w+              cq = recip ( (cht * cht * cv * cv) + (sht * sht * sv * sv) )+              l = cv * sv * cq / mv+          in packQ (x * l) (y * l) (z * l) (cht * sht * cq)+    {-# INLINE asin #-}+    asin q = -i * log' axis (i*q + sqrt' axis (1 - q*q))+        where+          axis = sigVec q+          i = fromVecNum axis 0+    {-# INLINE acos #-}+    acos q = pi/2 - asin q+    {-# INLINE atan #-}+    -- atan q = i / 2 * log ( (i + q) / (i - q) )+    atan (unpackQ# -> (# x, y, z, w #))+      = case (x * x) + (y * y) + (z * z) of+        0 -> packQ 0 0 0 (atan w)+        v2 ->+          let v = sqrt v2+              w2 = w*w+              vw2 = w2 + v2+              t  = 1 + vw2+              c  = 0.25 * log ((t + 2*v) / (t - 2*v)) / v+          in packQ (c*x) (c*y) (c*z) $ 0.5 * atan2 (2*w) (1 - vw2)+    {-# INLINE asinh #-}+    -- The original formula:+    -- asinh q = log (q + sqrt (q*q + 1))+    -- below is a more numerically stable version.+    asinh (unpackQ# -> (# x, y, z, w #))+      | v2 == 0+        = packQ 0 0 0 (asinh w)+      | w == 0+        = if v2 <= 1+          then let c = asin v / v+               in  packQ (c*x) (c*y) (c*z) 0+          else let c  = 0.5 * pi / v+                   w' = 0.5 * log (2*v2 - 1 + 2 * v * sqrt ( v2 - 1 ))+               in  packQ (c*x) (c*y) (c*z) w'+      | otherwise+        = let c = atan2 v t / v+              w' = 0.5 * log ( t2  + v2) - log t+                     + if w >= 0+                       then log ( t + w )+                       else log 2 + log w2 - log ( t - w ) - log ( r + w2 + v2 - 1 )+          in packQ (c*x) (c*y) (c*z) w'+      where+        v2 = (x * x) + (y * y) + (z * z)+        v  = sqrt v2+        w2 = w*w+        wvp1 = w2 - v2 + 1+        r = sqrt $ wvp1*wvp1 + 4*w2*v2+        t = sqrt $ ( r + wvp1 ) * 0.5+        t2 = t*t+    {-# INLINE acosh #-}+    -- note, log (q + sqrt (q*q - 1)) would not work, because that would not+    -- be the principal value.+    acosh q = log' axis (q + sqrt' axis (q + 1) * sqrt' axis (q - 1))+      where+        axis = sigVec q+    {-# INLINE atanh #-}+    atanh q = 0.5 * log ((1+q)/(1-q))++-- If q is negative real, provide a fallback axis to align log.+log' :: Vec3f -> QFloat -> QFloat+log' r (unpackQ# -> (# x, y, z, w #))+  = case (x * x) + (y * y) + (z * z) of+    0.0 | w >= 0+           -> packQ 0.0 0.0 0.0 (log w)+        | Vec3 rx ry rz <- r+           ->  packQ (pi*rx) (pi*ry) (pi*rz) (log (negate w))+    mv2 -> case (# sqrt (mv2 + (w * w)), sqrt mv2 #) of+      (# mq, mv #) -> case atan2 mv w / mv of+        l -> packQ (x * l) (y * l) (z * l) (log mq)+++-- If q is negative real, provide a fallback axis to align sqrt.+sqrt' :: Vec3f -> QFloat -> QFloat+sqrt' r (unpackQ# -> (# x, y, z, w #))+  = case (x * x) + (y * y) + (z * z) of+    0.0 | w >= 0+          -> packQ 0.0 0.0 0.0 (sqrt w)+        | Vec3 rx ry rz <- r+        , sw <- sqrt (negate w)+          -> packQ (sw*rx) (sw*ry) (sw*rz) 0+    mv2 ->+      let mq = sqrt (mv2 + w * w)+          l2 = sqrt mq+          tq = w / (mq * 2.0)+          sina = sqrt (0.5 - tq) * l2 / sqrt mv2+      in packQ (x * sina) (y * sina) (z * sina) (sqrt (0.5 + tq) * l2)++sigVec :: QFloat -> Vec3f+sigVec (unpackQ# -> (# x, y, z, _ #))+  = case sqrt ((x * x) + (y * y) + (z * z)) of+      0 -> vec3 1 0 0+      l -> vec3 (x/l) (y/l) (z/l)++instance Eq QFloat where+    {-# INLINE (==) #-}+    QFloat a == QFloat b = a == b+    {-# INLINE (/=) #-}+    QFloat a /= QFloat b = a /= b
− src/Numeric/Quaternion/QDouble.hs
@@ -1,559 +0,0 @@-{-# LANGUAGE DataKinds                  #-}-{-# LANGUAGE FlexibleContexts           #-}-{-# LANGUAGE FlexibleInstances          #-}-{-# LANGUAGE GeneralizedNewtypeDeriving #-}-{-# LANGUAGE MagicHash                  #-}-{-# LANGUAGE MultiParamTypeClasses      #-}-{-# LANGUAGE StandaloneDeriving         #-}-{-# LANGUAGE TypeFamilies               #-}-{-# LANGUAGE TypeInType                 #-}-{-# LANGUAGE TypeSynonymInstances       #-}-{-# LANGUAGE UnboxedTuples              #-}-{-# OPTIONS_GHC -fno-warn-orphans  #-}-module Numeric.Quaternion.QDouble-    ( QDouble, Quater (..)-    ) where--import           Data.Coerce                                      (coerce)-import           GHC.Exts--import qualified Control.Monad.ST                                 as ST-import           Numeric.DataFrame.Internal.Array.Class-import           Numeric.DataFrame.Internal.Array.Family.DoubleX3-import           Numeric.DataFrame.Internal.Array.Family.DoubleX4-import qualified Numeric.DataFrame.ST                             as ST-import           Numeric.DataFrame.Type-import           Numeric.Dimensions-import qualified Numeric.Dimensions.Fold                          as ST-import           Numeric.PrimBytes                                (PrimBytes)-import           Numeric.Quaternion.Class-import           Numeric.Scalar-import           Numeric.Vector---type QDouble = Quater Double--deriving instance PrimBytes (Quater Double)-deriving instance PrimArray Double (Quater Double)--instance Quaternion Double where-    newtype Quater Double = QDouble DoubleX4-    {-# INLINE packQ #-}-    packQ (D# x) (D# y) (D# z) (D# w) = QDouble (DoubleX4# x y z w)-    {-# INLINE unpackQ #-}-    unpackQ (QDouble (DoubleX4# x y z w)) = (D# x, D# y, D# z, D# w)-    {-# INLINE fromVecNum #-}-    fromVecNum (SingleFrame (DoubleX3# x y z)) (D# w) = QDouble (DoubleX4# x y z w)-    {-# INLINE fromVec4 #-}-    fromVec4 = coerce-    {-# INLINE toVec4 #-}-    toVec4 = coerce-    {-# INLINE square #-}-    square q = D# (qdot q)-    {-# INLINE im #-}-    im (QDouble (DoubleX4# x y z _)) = QDouble (DoubleX4# x y z 0.0##)-    {-# INLINE re #-}-    re (QDouble (DoubleX4# _ _ _ w)) = QDouble (DoubleX4# 0.0## 0.0## 0.0## w)-    {-# INLINE imVec #-}-    imVec (QDouble (DoubleX4# x y z _)) = SingleFrame (DoubleX3# x y z)-    {-# INLINE taker #-}-    taker (QDouble (DoubleX4# _ _ _ w)) = D# w-    {-# INLINE takei #-}-    takei (QDouble (DoubleX4# x _ _ _)) = D# x-    {-# INLINE takej #-}-    takej (QDouble (DoubleX4# _ y _ _)) = D# y-    {-# INLINE takek #-}-    takek (QDouble (DoubleX4# _ _ z _)) = D# z-    {-# INLINE conjugate #-}-    conjugate (QDouble (DoubleX4# x y z w)) = QDouble (DoubleX4#-                                                (negateDouble# x)-                                                (negateDouble# y)-                                                (negateDouble# z) w)-    {-# INLINE rotScale #-}-    rotScale (QDouble (DoubleX4# i j k t))-             (SingleFrame (DoubleX3# x y z))-      = let l = t*##t -## i*##i -## j*##j -## k*##k-            d = 2.0## *## ( i*##x +## j*##y +## k*##z)-            t2 = t *## 2.0##-        in SingleFrame-            ( DoubleX3#-                (l*##x +## d*##i +## t2 *## (z*##j -## y*##k))-                (l*##y +## d*##j +## t2 *## (x*##k -## z*##i))-                (l*##z +## d*##k +## t2 *## (y*##i -## x*##j))-            )-    {-# INLINE getRotScale #-}-    getRotScale _ (SingleFrame (DoubleX3# 0.0## 0.0## 0.0##))-      = QDouble (DoubleX4# 0.0## 0.0## 0.0## 0.0##)-    getRotScale (SingleFrame (DoubleX3# 0.0## 0.0## 0.0##)) _-      = case infty of D# x -> QDouble (DoubleX4# x x x x)-    getRotScale a@(SingleFrame (DoubleX3# a1 a2 a3))-                b@(SingleFrame (DoubleX3# b1 b2 b3))-      = let ma = sqrtDouble# (a1*##a1 +## a2*##a2 +## a3*##a3)-            mb = sqrtDouble# (b1*##b1 +## b2*##b2 +## b3*##b3)-            d  = a1*##b1 +## a2*##b2 +## a3*##b3-            c  = sqrtDouble# (ma*##mb +## d)-            ma2 = ma *## sqrtDouble# 2.0##-            r  = 1.0## /## (ma2 *## c)-        in case cross a b of-          SingleFrame (DoubleX3# 0.0## 0.0## 0.0##) ->-            if isTrue# (d >## 0.0##)-            then QDouble (DoubleX4#  0.0## 0.0## 0.0## (sqrtDouble# (mb /## ma)))-                 -- Shall we move result from k to i component?-            else QDouble (DoubleX4#  0.0## 0.0## (sqrtDouble# (mb /## ma)) 0.0##)-          SingleFrame (DoubleX3# t1 t2 t3) -> QDouble-                ( DoubleX4#-                    (t1 *## r)-                    (t2 *## r)-                    (t3 *## r)-                    (c /## ma2)-                )-    {-# INLINE axisRotation #-}-    axisRotation (SingleFrame (DoubleX3# 0.0## 0.0## 0.0##)) _-      = QDouble (DoubleX4# 0.0## 0.0## 0.0## 1.0##)-    axisRotation (SingleFrame (DoubleX3# x y z)) (D# a)-      = let c = cosDouble# (a *## 0.5##)-            s = sinDouble# (a *## 0.5##)-                /## sqrtDouble# (x*##x +## y*##y +## z*##z)-        in QDouble-              ( DoubleX4#-                  (x *## s)-                  (y *## s)-                  (z *## s)-                  c-              )-    {-# INLINE qArg #-}-    qArg (QDouble (DoubleX4# x y z w))-       = case atan2 (D# (sqrtDouble# (x*##x +## y*##y +## z*##z)))-                    (D# w) of-           D# a -> D# (a *## 2.0##)-    {-# INLINE fromMatrix33 #-}-    fromMatrix33 m-      = let d =-              (  ix 0# m *## ( ix 4# m *## ix 8# m -## ix 5# m *## ix 7# m )-              -## ix 1# m *## ( ix 3# m *## ix 8# m -## ix 5# m *## ix 6# m )-              +## ix 2# m *## ( ix 3# m *## ix 7# m -## ix 4# m *## ix 6# m )-              ) **## 0.33333333333333333333333333333333##-        in QDouble-           ( DoubleX4#-            (sqrtDouble# (max# 0.0## (d +## ix 0# m -## ix 4# m -## ix 8# m )) *## sign# (ix 5# m -## ix 7# m) *## 0.5##)-            (sqrtDouble# (max# 0.0## (d -## ix 0# m +## ix 4# m -## ix 8# m )) *## sign# (ix 6# m -## ix 2# m) *## 0.5##)-            (sqrtDouble# (max# 0.0## (d -## ix 0# m -## ix 4# m +## ix 8# m )) *## sign# (ix 1# m -## ix 3# m) *## 0.5##)-            (sqrtDouble# (max# 0.0## (d +## ix 0# m +## ix 4# m +## ix 8# m )) *## 0.5##)-           )-    {-# INLINE fromMatrix44 #-}-    fromMatrix44 m-      = let d =-              (  ix 0# m *## ( ix 5# m *## ix 10# m -## ix 6# m *## ix 9# m )-              -## ix 1# m *## ( ix 4# m *## ix 10# m -## ix 6# m *## ix 8# m )-              +## ix 2# m *## ( ix 4# m *## ix  9# m -## ix 5# m *## ix 8# m )-              ) **## 0.33333333333333333333333333333333##-            c = 0.5## /## ix 15# m-        in QDouble-           ( DoubleX4#-            (sqrtDouble# (max# 0.0## (d +## ix 0# m -## ix 5# m -## ix 10# m )) *## sign# (ix 6# m -## ix 9# m) *## c)-            (sqrtDouble# (max# 0.0## (d -## ix 0# m +## ix 5# m -## ix 10# m )) *## sign# (ix 8# m -## ix 2# m) *## c)-            (sqrtDouble# (max# 0.0## (d -## ix 0# m -## ix 5# m +## ix 10# m )) *## sign# (ix 1# m -## ix 4# m) *## c)-            (sqrtDouble# (max# 0.0## (d +## ix 0# m +## ix 5# m +## ix 10# m )) *## c)-           )-    {-# INLINE toMatrix33 #-}-    toMatrix33 (QDouble (DoubleX4# 0.0## 0.0## 0.0## w))-      = let x = D# (w *## w)-            f 0 = (# 3 :: Int , x #)-            f k = (# k-1, 0 #)-        in case gen# 9# f 0 of-            (# _, m #) -> m -- diag (scalar (D# (w *## w)))-    toMatrix33 (QDouble (DoubleX4# x' y' z' w')) =-      let x = scalar (D# x')-          y = scalar (D# y')-          z = scalar (D# z')-          w = scalar (D# w')-          x2 = x * x-          y2 = y * y-          z2 = z * z-          w2 = w * w-          l2 = x2 + y2 + z2 + w2-      in ST.runST $ do-        df <- ST.newDataFrame-        ST.writeDataFrameOff df 0 $ l2 - 2*(z2 + y2)-        ST.writeDataFrameOff df 1 $ 2*(x*y + z*w)-        ST.writeDataFrameOff df 2 $ 2*(x*z - y*w)-        ST.writeDataFrameOff df 3 $ 2*(x*y - z*w)-        ST.writeDataFrameOff df 4 $ l2 - 2*(z2 + x2)-        ST.writeDataFrameOff df 5 $ 2*(y*z + x*w)-        ST.writeDataFrameOff df 6 $ 2*(x*z + y*w)-        ST.writeDataFrameOff df 7 $ 2*(y*z - x*w)-        ST.writeDataFrameOff df 8 $ l2 - 2*(y2 + x2)-        ST.unsafeFreezeDataFrame df-    {-# INLINE toMatrix44 #-}-    toMatrix44 (QDouble (DoubleX4# 0.0## 0.0## 0.0## w)) = ST.runST $ do-      df <- ST.newDataFrame-      ST.overDimOff_ (dims :: Dims '[4,4]) (\i -> ST.writeDataFrameOff df i 0) 0 1-      let w2 = scalar (D# (w *## w))-      ST.writeDataFrameOff df 0 w2-      ST.writeDataFrameOff df 5 w2-      ST.writeDataFrameOff df 10 w2-      ST.writeDataFrameOff df 15 1-      ST.unsafeFreezeDataFrame df-    toMatrix44 (QDouble (DoubleX4# x' y' z' w')) =-      let x = scalar (D# x')-          y = scalar (D# y')-          z = scalar (D# z')-          w = scalar (D# w')-          x2 = x * x-          y2 = y * y-          z2 = z * z-          w2 = w * w-          l2 = x2 + y2 + z2 + w2-      in ST.runST $ do-        df <- ST.newDataFrame-        ST.writeDataFrameOff df 0 $ l2 - 2*(z2 + y2)-        ST.writeDataFrameOff df 1 $ 2*(x*y + z*w)-        ST.writeDataFrameOff df 2 $ 2*(x*z - y*w)-        ST.writeDataFrameOff df 3 0-        ST.writeDataFrameOff df 4 $ 2*(x*y - z*w)-        ST.writeDataFrameOff df 5 $ l2 - 2*(z2 + x2)-        ST.writeDataFrameOff df 6 $ 2*(y*z + x*w)-        ST.writeDataFrameOff df 7 0-        ST.writeDataFrameOff df 8 $ 2*(x*z + y*w)-        ST.writeDataFrameOff df 9 $ 2*(y*z - x*w)-        ST.writeDataFrameOff df 10 $ l2 - 2*(y2 + x2)-        ST.writeDataFrameOff df 11 0-        ST.writeDataFrameOff df 12 0-        ST.writeDataFrameOff df 13 0-        ST.writeDataFrameOff df 14 0-        ST.writeDataFrameOff df 15 1-        ST.unsafeFreezeDataFrame df--qdot :: QDouble -> Double#-qdot (QDouble (DoubleX4# x y z w)) = (x *## x) +##-                                   (y *## y) +##-                                   (z *## z) +##-                                   (w *## w)-{-# INLINE qdot #-}--infty :: Double-infty = read "Infinity"--max# :: Double# -> Double# -> Double#-max# a b | isTrue# (a >## b) = a-         | otherwise = b-{-# INLINE max# #-}--sign# :: Double# -> Double#-sign# a | isTrue# (a >## 0.0##) = 1.0##-        | isTrue# (a <## 0.0##) = negateDouble# 1.0##-        | otherwise = 0.0##-{-# INLINE sign# #-}--ix :: PrimArray Double a => Int# -> a -> Double#-ix i a = case ix# i a of D# r -> r-{-# INLINE ix #-}------------------------------------------------------------------------------- Num-----------------------------------------------------------------------------instance Num QDouble where-    QDouble a + QDouble b-      = QDouble (a + b)-    {-# INLINE (+) #-}-    QDouble a - QDouble b-      = QDouble (a - b)-    {-# INLINE (-) #-}-    QDouble (DoubleX4# a1 a2 a3 a4) * QDouble (DoubleX4# b1 b2 b3 b4)-      = QDouble-         ( DoubleX4#-           ((a4 *## b1) +##-            (a1 *## b4) +##-            (a2 *## b3) -##-            (a3 *## b2)-            )-           ((a4 *## b2) -##-            (a1 *## b3) +##-            (a2 *## b4) +##-            (a3 *## b1)-            )-           ((a4 *## b3) +##-            (a1 *## b2) -##-            (a2 *## b1) +##-            (a3 *## b4)-            )-           ((a4 *## b4) -##-            (a1 *## b1) -##-            (a2 *## b2) -##-            (a3 *## b3)-            )-         )-    {-# INLINE (*) #-}-    negate (QDouble a) = QDouble (negate a)-    {-# INLINE negate #-}-    abs q = QDouble (DoubleX4# 0.0## 0.0## 0.0## (sqrtDouble# (qdot q)))-    {-# INLINE abs #-}-    signum q@(QDouble (DoubleX4# x y z w))-      = case qdot q of-          0.0## -> QDouble (DoubleX4# 0.0## 0.0## 0.0## 0.0##)-          qd -> case 1.0## /## sqrtDouble# qd of-             s -> QDouble-               ( DoubleX4#-                (x *## s)-                (y *## s)-                (z *## s)-                (w *## s)-               )-    {-# INLINE signum #-}-    fromInteger n = case fromInteger n of-      D# x -> QDouble (DoubleX4# 0.0## 0.0## 0.0## x)-    {-# INLINE fromInteger #-}--------------------------------------------------------------------------------- Fractional-----------------------------------------------------------------------------instance Fractional QDouble where-    {-# INLINE recip #-}-    recip q@(QDouble (DoubleX4# x y z w)) = case -1.0## /## qdot q of-      c -> QDouble-        ( DoubleX4#-         (x *## c)-         (y *## c)-         (z *## c)-         (negateDouble# (w *## c))-        )-    {-# INLINE (/) #-}-    a / b = a * recip b-    {-# INLINE fromRational #-}-    fromRational q = case fromRational q of-      D# x -> QDouble (DoubleX4# 0.0## 0.0## 0.0## x)------------------------------------------------------------------------------- Doubleing-----------------------------------------------------------------------------instance  Floating QDouble where-    {-# INLINE pi #-}-    pi = QDouble (DoubleX4# 0.0## 0.0## 0.0##-                          3.141592653589793##)-    {-# INLINE exp #-}-    exp (QDouble (DoubleX4# x y z w))-      = case (# (x *## x) +##-                (y *## y) +##-                (z *## z)-             , expDouble# w-             #) of-        (# 0.0##, et #) -> QDouble (DoubleX4# 0.0## 0.0## 0.0## et)-        (# mv2, et #) -> case sqrtDouble# mv2 of-          mv -> case et *## sinDouble# mv-                        /## mv of-            l -> QDouble-              ( DoubleX4#-               (x *## l)-               (y *## l)-               (z *## l)-               (et *## cosDouble# mv)-              )-    {-# INLINE log #-}-    log (QDouble (DoubleX4# x y z w))-      = case (x *## x) +##-             (y *## y) +##-             (z *## z) of-        0.0## -> if isTrue# (w >=## 0.0##)-                then QDouble (DoubleX4# 0.0## 0.0## 0.0## (logDouble# w))-                else QDouble (DoubleX4# 3.141592653589793## 0.0## 0.0##-                                     (logDouble# (negateDouble# w)))-        mv2 -> case (# sqrtDouble# (mv2 +## (w *## w))-                     , sqrtDouble# mv2-                    #) of-          (# mq, mv #) -> case atan2 (D# mv) (D# w) / D# mv of-            D# l -> QDouble-              ( DoubleX4#-               (x *## l)-               (y *## l)-               (z *## l)-               (logDouble# mq)-              )-    {-# INLINE sqrt #-}-    sqrt (QDouble (DoubleX4# x y z w))-      = case (x *## x) +##-             (y *## y) +##-             (z *## z) of-        0.0## -> if isTrue# (w >=## 0.0##)-                then QDouble (DoubleX4# 0.0## 0.0## 0.0## (sqrtDouble# w))-                else QDouble (DoubleX4# (sqrtDouble# (negateDouble# w)) 0.0## 0.0## 0.0##)-        mv2 ->-          let mq = sqrtDouble# (mv2 +## w *## w)-              l2 = sqrtDouble# mq-              tq = w /## (mq *## 2.0##)-              sina = sqrtDouble# (0.5## -## tq) *## l2 /## sqrtDouble# mv2-          in QDouble-                ( DoubleX4#-                 (x *## sina)-                 (y *## sina)-                 (z *## sina)-                 (sqrtDouble# (0.5## +## tq) *## l2)-                )-    {-# INLINE sin #-}-    sin (QDouble (DoubleX4# x y z w))-      = case (x *## x) +##-             (y *## y) +##-             (z *## z) of-        0.0## -> QDouble (DoubleX4# 0.0## 0.0## 0.0## (sinDouble# w))-        mv2 -> case sqrtDouble# mv2 of-          mv -> case cosDouble# w *## sinhDouble# mv-                                 /## mv of-            l -> QDouble-              ( DoubleX4#-               (x *## l)-               (y *## l)-               (z *## l)-               (sinDouble# w *## coshDouble# mv)-              )-    {-# INLINE cos #-}-    cos (QDouble (DoubleX4# x y z w))-      = case (x *## x) +##-             (y *## y) +##-             (z *## z) of-        0.0## -> QDouble (DoubleX4# 0.0## 0.0## 0.0## (cosDouble# w))-        mv2 -> case sqrtDouble# mv2 of-          mv -> case sinDouble# w *## sinhDouble# mv-                                 /## negateDouble# mv of-            l -> QDouble-              ( DoubleX4#-               (x *## l)-               (y *## l)-               (z *## l)-               (cosDouble# w *## coshDouble# mv)-              )-    {-# INLINE tan #-}-    tan (QDouble (DoubleX4# x y z w))-      = case (x *## x) +##-             (y *## y) +##-             (z *## z) of-        0.0## -> QDouble (DoubleX4# 0.0## 0.0## 0.0## (tanDouble# w))-        mv2 ->-          let mv = sqrtDouble# mv2-              chv = coshDouble# mv-              shv = sinhDouble# mv-              ct = cosDouble# w-              st = sinDouble# w-              cq = 1.0## /##-                  ( (ct *## ct *## chv *## chv)-                    +##-                    (st *## st *## shv *## shv)-                  )-              l = chv *## shv *## cq-                      /## mv-          in QDouble-            ( DoubleX4#-             (x *## l)-             (y *## l)-             (z *## l)-             (ct *## st *## cq)-            )-    {-# INLINE sinh #-}-    sinh (QDouble (DoubleX4# x y z w))-      = case (x *## x) +##-             (y *## y) +##-             (z *## z) of-        0.0## -> QDouble (DoubleX4# 0.0## 0.0## 0.0## (sinhDouble# w))-        mv2 -> case sqrtDouble# mv2 of-          mv -> case coshDouble# w *## sinDouble# mv-                                  /## mv of-            l -> QDouble-              ( DoubleX4#-               (x *## l)-               (y *## l)-               (z *## l)-               (sinhDouble# w *## cosDouble# mv)-              )-    {-# INLINE cosh #-}-    cosh (QDouble (DoubleX4# x y z w))-      = case (x *## x) +##-             (y *## y) +##-             (z *## z) of-        0.0## -> QDouble (DoubleX4# 0.0## 0.0## 0.0## (coshDouble# w))-        mv2 -> case sqrtDouble# mv2 of-          mv -> case sinhDouble# w *## sinDouble# mv-                                  /## mv of-            l -> QDouble-              ( DoubleX4#-               (x *## l)-               (y *## l)-               (z *## l)-               (coshDouble# w *## cosDouble# mv)-              )-    {-# INLINE tanh #-}-    tanh (QDouble (DoubleX4# x y z w))-      = case (x *## x) +##-             (y *## y) +##-             (z *## z) of-        0.0## -> QDouble (DoubleX4# 0.0## 0.0## 0.0## (tanhDouble# w))-        mv2 ->-          let mv = sqrtDouble# mv2-              cv = cosDouble# mv-              sv = sinDouble# mv-              cht = coshDouble# w-              sht = sinhDouble# w-              cq = 1.0## /##-                  ( (cht *## cht *## cv *## cv)-                    +##-                    (sht *## sht *## sv *## sv)-                  )-              l = cv *## sv *## cq-                      /## mv-          in QDouble-            ( DoubleX4#-             (x *## l)-             (y *## l)-             (z *## l)-             (cht *## sht *## cq)-            )-    {-# INLINE asin #-}-    asin q = -i * log (i*q + sqrt (1 - q*q))-        where-          i = case signum . im $ q of-                0  -> QDouble (DoubleX4# 1.0## 0.0## 0.0## 0.0##)-                i' -> i'-    {-# INLINE acos #-}-    acos q = pi/2 - asin q-    {-# INLINE atan #-}-    atan q@(QDouble (DoubleX4# _ _ _ w))-      = if square imq == 0-        then QDouble (DoubleX4# 0.0## 0.0## 0.0## (atanDouble# w))-        else i / 2 * log ( (i + q) / (i - q) )-      where-        i = signum imq-        imq = im q-    {-# INLINE asinh #-}-    asinh q = log (q + sqrt (q*q + 1))-    {-# INLINE acosh #-}-    acosh q = log (q + sqrt (q*q - 1))-    {-# INLINE atanh #-}-    atanh q = 0.5 * log ((1+q)/(1-q))------------------------------------------------------------------------------- Eq-----------------------------------------------------------------------------instance Eq QDouble where-    {-# INLINE (==) #-}-    QDouble a == QDouble b = a == b-    {-# INLINE (/=) #-}-    QDouble a /= QDouble b = a /= b--------------------------------------------------------------------------------- Show-----------------------------------------------------------------------------instance Show QDouble where-    show (QDouble (DoubleX4# x y z w)) =-        show (D# w) ++ ss x ++ "i"-                    ++ ss y ++ "j"-                    ++ ss z ++ "k"-      where-        ss a# = case D# a# of-          a -> if a >= 0 then " + " ++ show a-                         else " - " ++ show (negate a)
− src/Numeric/Quaternion/QFloat.hs
@@ -1,579 +0,0 @@-{-# LANGUAGE DataKinds                  #-}-{-# LANGUAGE FlexibleContexts           #-}-{-# LANGUAGE FlexibleInstances          #-}-{-# LANGUAGE GeneralizedNewtypeDeriving #-}-{-# LANGUAGE MagicHash                  #-}-{-# LANGUAGE MultiParamTypeClasses      #-}-{-# LANGUAGE StandaloneDeriving         #-}-{-# LANGUAGE TypeFamilies               #-}-{-# LANGUAGE TypeInType                 #-}-{-# LANGUAGE TypeSynonymInstances       #-}-{-# LANGUAGE UnboxedTuples              #-}-{-# OPTIONS_GHC -fno-warn-orphans  #-}-module Numeric.Quaternion.QFloat-    ( QFloat, Quater (..)-    ) where--import           Data.Coerce                                     (coerce)-import           GHC.Exts--import qualified Control.Monad.ST                                as ST-import           Numeric.DataFrame.Internal.Array.Class-import           Numeric.DataFrame.Internal.Array.Family.FloatX3-import           Numeric.DataFrame.Internal.Array.Family.FloatX4-import qualified Numeric.DataFrame.ST                            as ST-import           Numeric.DataFrame.Type-import           Numeric.Dimensions-import qualified Numeric.Dimensions.Fold                         as ST-import           Numeric.PrimBytes                               (PrimBytes)-import           Numeric.Quaternion.Class-import           Numeric.Scalar-import           Numeric.Vector---type QFloat = Quater Float--deriving instance PrimBytes (Quater Float)-deriving instance PrimArray Float (Quater Float)--instance Quaternion Float where-    newtype Quater Float = QFloat FloatX4-    {-# INLINE packQ #-}-    packQ (F# x) (F# y) (F# z) (F# w) = QFloat (FloatX4# x y z w)-    {-# INLINE unpackQ #-}-    unpackQ (QFloat (FloatX4# x y z w)) = (F# x, F# y, F# z, F# w)-    {-# INLINE fromVecNum #-}-    fromVecNum (SingleFrame (FloatX3# x y z)) (F# w) = QFloat (FloatX4# x y z w)-    {-# INLINE fromVec4 #-}-    fromVec4 = coerce-    {-# INLINE toVec4 #-}-    toVec4 = coerce-    {-# INLINE square #-}-    square q = F# (qdot q)-    {-# INLINE im #-}-    im (QFloat (FloatX4# x y z _)) = QFloat (FloatX4# x y z 0.0#)-    {-# INLINE re #-}-    re (QFloat (FloatX4# _ _ _ w)) = QFloat (FloatX4# 0.0# 0.0# 0.0# w)-    {-# INLINE imVec #-}-    imVec (QFloat (FloatX4# x y z _)) = SingleFrame (FloatX3# x y z)-    {-# INLINE taker #-}-    taker (QFloat (FloatX4# _ _ _ w)) = F# w-    {-# INLINE takei #-}-    takei (QFloat (FloatX4# x _ _ _)) = F# x-    {-# INLINE takej #-}-    takej (QFloat (FloatX4# _ y _ _)) = F# y-    {-# INLINE takek #-}-    takek (QFloat (FloatX4# _ _ z _)) = F# z-    {-# INLINE conjugate #-}-    conjugate (QFloat (FloatX4# x y z w)) = QFloat (FloatX4#-                                                (negateFloat# x)-                                                (negateFloat# y)-                                                (negateFloat# z) w)-    {-# INLINE rotScale #-}-    rotScale (QFloat (FloatX4# i j k t))-             (SingleFrame (FloatX3# x y z))-      = let l = t*%t -% i*%i -% j*%j -% k*%k-            d = 2.0# *% ( i*%x +% j*%y +% k*%z)-            t2 = t *% 2.0#-        in SingleFrame-            ( FloatX3#-                (l*%x +% d*%i +% t2 *% (z*%j -% y*%k))-                (l*%y +% d*%j +% t2 *% (x*%k -% z*%i))-                (l*%z +% d*%k +% t2 *% (y*%i -% x*%j))-            )-    {-# INLINE getRotScale #-}-    getRotScale _ (SingleFrame (FloatX3# 0.0# 0.0# 0.0#))-      = QFloat (FloatX4# 0.0# 0.0# 0.0# 0.0#)-    getRotScale (SingleFrame (FloatX3# 0.0# 0.0# 0.0#)) _-      = case infty of F# x -> QFloat (FloatX4# x x x x)-    getRotScale a@(SingleFrame (FloatX3# a1 a2 a3))-                b@(SingleFrame (FloatX3# b1 b2 b3))-      = let ma = sqrtFloat# (a1*%a1 +% a2*%a2 +% a3*%a3)-            mb = sqrtFloat# (b1*%b1 +% b2*%b2 +% b3*%b3)-            d  = a1*%b1 +% a2*%b2 +% a3*%b3-            c  = sqrtFloat# (ma*%mb +% d)-            ma2 = ma *% sqrtFloat# 2.0#-            r  = 1.0# /% (ma2 *% c)-        in case cross a b of-          SingleFrame (FloatX3# 0.0# 0.0# 0.0#) ->-            if isTrue# (gtFloat# d 0.0#)-            then QFloat (FloatX4#  0.0# 0.0# 0.0# (sqrtFloat# (mb /% ma)))-                 -- Shall we move result from k to i component?-            else QFloat (FloatX4#  0.0# 0.0# (sqrtFloat# (mb /% ma)) 0.0#)-          SingleFrame (FloatX3# t1 t2 t3) -> QFloat-                ( FloatX4#-                    (t1 *% r)-                    (t2 *% r)-                    (t3 *% r)-                    (c /% ma2)-                )-    {-# INLINE axisRotation #-}-    axisRotation (SingleFrame (FloatX3# 0.0# 0.0# 0.0#)) _-      = QFloat (FloatX4# 0.0# 0.0# 0.0# 1.0#)-    axisRotation (SingleFrame (FloatX3# x y z)) (F# a)-      = let c = cosFloat# (a *% 0.5#)-            s = sinFloat# (a *% 0.5#)-                /% sqrtFloat# (x*%x +% y*%y +% z*%z)-        in QFloat-              ( FloatX4#-                  (x *% s)-                  (y *% s)-                  (z *% s)-                  c-              )-    {-# INLINE qArg #-}-    qArg (QFloat (FloatX4# x y z w))-       = case atan2 (F# (sqrtFloat# (x*%x +% y*%y +% z*%z)))-                    (F# w) of-           F# a -> F# (a *% 2.0#)-    {-# INLINE fromMatrix33 #-}-    fromMatrix33 m-      = let d = powerFloat#-              (  ix 0# m *% ( ix 4# m *% ix 8# m -% ix 5# m *% ix 7# m )-              -% ix 1# m *% ( ix 3# m *% ix 8# m -% ix 5# m *% ix 6# m )-              +% ix 2# m *% ( ix 3# m *% ix 7# m -% ix 4# m *% ix 6# m )-              ) 0.33333333333333333333333333333333#-        in QFloat-           ( FloatX4#-            (sqrtFloat# (max# 0.0# (d +% ix 0# m -% ix 4# m -% ix 8# m )) *% sign# (ix 5# m -% ix 7# m) *% 0.5#)-            (sqrtFloat# (max# 0.0# (d -% ix 0# m +% ix 4# m -% ix 8# m )) *% sign# (ix 6# m -% ix 2# m) *% 0.5#)-            (sqrtFloat# (max# 0.0# (d -% ix 0# m -% ix 4# m +% ix 8# m )) *% sign# (ix 1# m -% ix 3# m) *% 0.5#)-            (sqrtFloat# (max# 0.0# (d +% ix 0# m +% ix 4# m +% ix 8# m )) *% 0.5#)-           )-    {-# INLINE fromMatrix44 #-}-    fromMatrix44 m-      = let d = powerFloat#-              (  ix 0# m *% ( ix 5# m *% ix 10# m -% ix 6# m *% ix 9# m )-              -% ix 1# m *% ( ix 4# m *% ix 10# m -% ix 6# m *% ix 8# m )-              +% ix 2# m *% ( ix 4# m *% ix  9# m -% ix 5# m *% ix 8# m )-              ) 0.33333333333333333333333333333333#-            c = 0.5# /% ix 15# m-        in QFloat-           ( FloatX4#-            (sqrtFloat# (max# 0.0# (d +% ix 0# m -% ix 5# m -% ix 10# m )) *% sign# (ix 6# m -% ix 9# m) *% c)-            (sqrtFloat# (max# 0.0# (d -% ix 0# m +% ix 5# m -% ix 10# m )) *% sign# (ix 8# m -% ix 2# m) *% c)-            (sqrtFloat# (max# 0.0# (d -% ix 0# m -% ix 5# m +% ix 10# m )) *% sign# (ix 1# m -% ix 4# m) *% c)-            (sqrtFloat# (max# 0.0# (d +% ix 0# m +% ix 5# m +% ix 10# m )) *% c)-           )-    {-# INLINE toMatrix33 #-}-    toMatrix33 (QFloat (FloatX4# 0.0# 0.0# 0.0# w))-      = let x = F# (w *% w)-            f 0 = (# 3 :: Int , x #)-            f k = (# k-1, 0 #)-        in case gen# 9# f 0 of-            (# _, m #) -> m -- diag (scalar (F# (w *% w)))-    toMatrix33 (QFloat (FloatX4# x' y' z' w')) =-      let x = scalar (F# x')-          y = scalar (F# y')-          z = scalar (F# z')-          w = scalar (F# w')-          x2 = x * x-          y2 = y * y-          z2 = z * z-          w2 = w * w-          l2 = x2 + y2 + z2 + w2-      in ST.runST $ do-        df <- ST.newDataFrame-        ST.writeDataFrameOff df 0 $ l2 - 2*(z2 + y2)-        ST.writeDataFrameOff df 1 $ 2*(x*y + z*w)-        ST.writeDataFrameOff df 2 $ 2*(x*z - y*w)-        ST.writeDataFrameOff df 3 $ 2*(x*y - z*w)-        ST.writeDataFrameOff df 4 $ l2 - 2*(z2 + x2)-        ST.writeDataFrameOff df 5 $ 2*(y*z + x*w)-        ST.writeDataFrameOff df 6 $ 2*(x*z + y*w)-        ST.writeDataFrameOff df 7 $ 2*(y*z - x*w)-        ST.writeDataFrameOff df 8 $ l2 - 2*(y2 + x2)-        ST.unsafeFreezeDataFrame df-    {-# INLINE toMatrix44 #-}-    toMatrix44 (QFloat (FloatX4# 0.0# 0.0# 0.0# w)) = ST.runST $ do-      df <- ST.newDataFrame-      ST.overDimOff_ (dims :: Dims '[4,4]) (\i -> ST.writeDataFrameOff df i 0) 0 1-      let w2 = scalar (F# (w *% w))-      ST.writeDataFrameOff df 0 w2-      ST.writeDataFrameOff df 5 w2-      ST.writeDataFrameOff df 10 w2-      ST.writeDataFrameOff df 15 1-      ST.unsafeFreezeDataFrame df-    toMatrix44 (QFloat (FloatX4# x' y' z' w')) =-      let x = scalar (F# x')-          y = scalar (F# y')-          z = scalar (F# z')-          w = scalar (F# w')-          x2 = x * x-          y2 = y * y-          z2 = z * z-          w2 = w * w-          l2 = x2 + y2 + z2 + w2-      in ST.runST $ do-        df <- ST.newDataFrame-        ST.writeDataFrameOff df 0 $ l2 - 2*(z2 + y2)-        ST.writeDataFrameOff df 1 $ 2*(x*y + z*w)-        ST.writeDataFrameOff df 2 $ 2*(x*z - y*w)-        ST.writeDataFrameOff df 3 0-        ST.writeDataFrameOff df 4 $ 2*(x*y - z*w)-        ST.writeDataFrameOff df 5 $ l2 - 2*(z2 + x2)-        ST.writeDataFrameOff df 6 $ 2*(y*z + x*w)-        ST.writeDataFrameOff df 7 0-        ST.writeDataFrameOff df 8 $ 2*(x*z + y*w)-        ST.writeDataFrameOff df 9 $ 2*(y*z - x*w)-        ST.writeDataFrameOff df 10 $ l2 - 2*(y2 + x2)-        ST.writeDataFrameOff df 11 0-        ST.writeDataFrameOff df 12 0-        ST.writeDataFrameOff df 13 0-        ST.writeDataFrameOff df 14 0-        ST.writeDataFrameOff df 15 0-        ST.unsafeFreezeDataFrame df--qdot :: QFloat -> Float#-qdot (QFloat (FloatX4# x y z w)) = (x *% x) +%-                                   (y *% y) +%-                                   (z *% z) +%-                                   (w *% w)-{-# INLINE qdot #-}--(*%) :: Float# -> Float# -> Float#-(*%) = timesFloat#-{-# INLINE (*%) #-}-infixl 7 *%--(-%) :: Float# -> Float# -> Float#-(-%) = minusFloat#-{-# INLINE (-%) #-}-infixl 6 -%--(+%) :: Float# -> Float# -> Float#-(+%) = plusFloat#-{-# INLINE (+%) #-}-infixl 6 +%--(/%) :: Float# -> Float# -> Float#-(/%) = divideFloat#-{-# INLINE (/%) #-}-infixl 7 /%--infty :: Float-infty = read "Infinity"--max# :: Float# -> Float# -> Float#-max# a b | isTrue# (gtFloat# a b) = a-         | otherwise = b-{-# INLINE max# #-}--sign# :: Float# -> Float#-sign# a | isTrue# (gtFloat# a 0.0#) = 1.0#-        | isTrue# (ltFloat# a 0.0#) = negateFloat# 1.0#-        | otherwise = 0.0#-{-# INLINE sign# #-}--ix :: PrimArray Float a => Int# -> a -> Float#-ix i a = case ix# i a of F# r -> r-{-# INLINE ix #-}------------------------------------------------------------------------------- Num-----------------------------------------------------------------------------instance Num QFloat where-    QFloat a + QFloat b-      = QFloat (a + b)-    {-# INLINE (+) #-}-    QFloat a - QFloat b-      = QFloat (a - b)-    {-# INLINE (-) #-}-    QFloat (FloatX4# a1 a2 a3 a4) * QFloat (FloatX4# b1 b2 b3 b4)-      = QFloat-         ( FloatX4#-           ((a4 *% b1) +%-            (a1 *% b4) +%-            (a2 *% b3) -%-            (a3 *% b2)-            )-           ((a4 *% b2) -%-            (a1 *% b3) +%-            (a2 *% b4) +%-            (a3 *% b1)-            )-           ((a4 *% b3) +%-            (a1 *% b2) -%-            (a2 *% b1) +%-            (a3 *% b4)-            )-           ((a4 *% b4) -%-            (a1 *% b1) -%-            (a2 *% b2) -%-            (a3 *% b3)-            )-         )-    {-# INLINE (*) #-}-    negate (QFloat a) = QFloat (negate a)-    {-# INLINE negate #-}-    abs q = QFloat (FloatX4# 0.0# 0.0# 0.0# (sqrtFloat# (qdot q)))-    {-# INLINE abs #-}-    signum q@(QFloat (FloatX4# x y z w))-      = case qdot q of-          0.0# -> QFloat (FloatX4# 0.0# 0.0# 0.0# 0.0#)-          qd -> case 1.0# /% sqrtFloat# qd of-             s -> QFloat-               ( FloatX4#-                (x *% s)-                (y *% s)-                (z *% s)-                (w *% s)-               )-    {-# INLINE signum #-}-    fromInteger n = case fromInteger n of-      F# x -> QFloat (FloatX4# 0.0# 0.0# 0.0# x)-    {-# INLINE fromInteger #-}--------------------------------------------------------------------------------- Fractional-----------------------------------------------------------------------------instance Fractional QFloat where-    {-# INLINE recip #-}-    recip q@(QFloat (FloatX4# x y z w)) = case -1.0# /% qdot q of-      c -> QFloat-        ( FloatX4#-         (x *% c)-         (y *% c)-         (z *% c)-         (negateFloat# (w *% c))-        )-    {-# INLINE (/) #-}-    a / b = a * recip b-    {-# INLINE fromRational #-}-    fromRational q = case fromRational q of-      F# x -> QFloat (FloatX4# 0.0# 0.0# 0.0# x)------------------------------------------------------------------------------- Floating-----------------------------------------------------------------------------instance  Floating QFloat where-    {-# INLINE pi #-}-    pi = QFloat (FloatX4# 0.0# 0.0# 0.0#-                          3.141592653589793#)-    {-# INLINE exp #-}-    exp (QFloat (FloatX4# x y z w))-      = case (# (x *% x) +%-                (y *% y) +%-                (z *% z)-             , expFloat# w-             #) of-        (# 0.0#, et #) -> QFloat (FloatX4# 0.0# 0.0# 0.0# et)-        (# mv2, et #) -> case sqrtFloat# mv2 of-          mv -> case et *% sinFloat# mv-                        /% mv of-            l -> QFloat-              ( FloatX4#-               (x *% l)-               (y *% l)-               (z *% l)-               (et *% cosFloat# mv)-              )-    {-# INLINE log #-}-    log (QFloat (FloatX4# x y z w))-      = case (x *% x) +%-             (y *% y) +%-             (z *% z) of-        0.0# -> if isTrue# (w `geFloat#` 0.0#)-                then QFloat (FloatX4# 0.0# 0.0# 0.0# (logFloat# w))-                else QFloat (FloatX4# 3.141592653589793# 0.0# 0.0#-                                     (logFloat# (negateFloat# w)))-        mv2 -> case (# sqrtFloat# (mv2 +% (w *% w))-                     , sqrtFloat# mv2-                    #) of-          (# mq, mv #) -> case atan2 (F# mv) (F# w) / F# mv of-            F# l -> QFloat-              ( FloatX4#-               (x *% l)-               (y *% l)-               (z *% l)-               (logFloat# mq)-              )-    {-# INLINE sqrt #-}-    sqrt (QFloat (FloatX4# x y z w))-      = case (x *% x) +%-             (y *% y) +%-             (z *% z) of-        0.0# -> if isTrue# (w `geFloat#` 0.0#)-                then QFloat (FloatX4# 0.0# 0.0# 0.0# (sqrtFloat# w))-                else QFloat (FloatX4# (sqrtFloat# (negateFloat# w)) 0.0# 0.0# 0.0#)-        mv2 ->-          let mq = sqrtFloat# (mv2 +% w *% w)-              l2 = sqrtFloat# mq-              tq = w /% (mq *% 2.0#)-              sina = sqrtFloat# (0.5# -% tq) *% l2 /% sqrtFloat# mv2-          in QFloat-                ( FloatX4#-                 (x *% sina)-                 (y *% sina)-                 (z *% sina)-                 (sqrtFloat# (0.5# +% tq) *% l2)-                )-    {-# INLINE sin #-}-    sin (QFloat (FloatX4# x y z w))-      = case (x *% x) +%-             (y *% y) +%-             (z *% z) of-        0.0# -> QFloat (FloatX4# 0.0# 0.0# 0.0# (sinFloat# w))-        mv2 -> case sqrtFloat# mv2 of-          mv -> case cosFloat# w *% sinhFloat# mv-                                 /% mv of-            l -> QFloat-              ( FloatX4#-               (x *% l)-               (y *% l)-               (z *% l)-               (sinFloat# w *% coshFloat# mv)-              )-    {-# INLINE cos #-}-    cos (QFloat (FloatX4# x y z w))-      = case (x *% x) +%-             (y *% y) +%-             (z *% z) of-        0.0# -> QFloat (FloatX4# 0.0# 0.0# 0.0# (cosFloat# w))-        mv2 -> case sqrtFloat# mv2 of-          mv -> case sinFloat# w *% sinhFloat# mv-                                 /% negateFloat# mv of-            l -> QFloat-              ( FloatX4#-               (x *% l)-               (y *% l)-               (z *% l)-               (cosFloat# w *% coshFloat# mv)-              )-    {-# INLINE tan #-}-    tan (QFloat (FloatX4# x y z w))-      = case (x *% x) +%-             (y *% y) +%-             (z *% z) of-        0.0# -> QFloat (FloatX4# 0.0# 0.0# 0.0# (tanFloat# w))-        mv2 ->-          let mv = sqrtFloat# mv2-              chv = coshFloat# mv-              shv = sinhFloat# mv-              ct = cosFloat# w-              st = sinFloat# w-              cq = 1.0# /%-                  ( (ct *% ct *% chv *% chv)-                    +%-                    (st *% st *% shv *% shv)-                  )-              l = chv *% shv *% cq-                      /% mv-          in QFloat-            ( FloatX4#-             (x *% l)-             (y *% l)-             (z *% l)-             (ct *% st *% cq)-            )-    {-# INLINE sinh #-}-    sinh (QFloat (FloatX4# x y z w))-      = case (x *% x) +%-             (y *% y) +%-             (z *% z) of-        0.0# -> QFloat (FloatX4# 0.0# 0.0# 0.0# (sinhFloat# w))-        mv2 -> case sqrtFloat# mv2 of-          mv -> case coshFloat# w *% sinFloat# mv-                                  /% mv of-            l -> QFloat-              ( FloatX4#-               (x *% l)-               (y *% l)-               (z *% l)-               (sinhFloat# w *% cosFloat# mv)-              )-    {-# INLINE cosh #-}-    cosh (QFloat (FloatX4# x y z w))-      = case (x *% x) +%-             (y *% y) +%-             (z *% z) of-        0.0# -> QFloat (FloatX4# 0.0# 0.0# 0.0# (coshFloat# w))-        mv2 -> case sqrtFloat# mv2 of-          mv -> case sinhFloat# w *% sinFloat# mv-                                  /% mv of-            l -> QFloat-              ( FloatX4#-               (x *% l)-               (y *% l)-               (z *% l)-               (coshFloat# w *% cosFloat# mv)-              )-    {-# INLINE tanh #-}-    tanh (QFloat (FloatX4# x y z w))-      = case (x *% x) +%-             (y *% y) +%-             (z *% z) of-        0.0# -> QFloat (FloatX4# 0.0# 0.0# 0.0# (tanhFloat# w))-        mv2 ->-          let mv = sqrtFloat# mv2-              cv = cosFloat# mv-              sv = sinFloat# mv-              cht = coshFloat# w-              sht = sinhFloat# w-              cq = 1.0# /%-                  ( (cht *% cht *% cv *% cv)-                    +%-                    (sht *% sht *% sv *% sv)-                  )-              l = cv *% sv *% cq-                      /% mv-          in QFloat-            ( FloatX4#-             (x *% l)-             (y *% l)-             (z *% l)-             (cht *% sht *% cq)-            )-    {-# INLINE asin #-}-    asin q = -i * log (i*q + sqrt (1 - q*q))-        where-          i = case signum . im $ q of-                0  -> QFloat (FloatX4# 1.0# 0.0# 0.0# 0.0#)-                i' -> i'-    {-# INLINE acos #-}-    acos q = pi/2 - asin q-    {-# INLINE atan #-}-    atan q@(QFloat (FloatX4# _ _ _ w))-      = if square imq == 0-        then QFloat (FloatX4# 0.0# 0.0# 0.0# (atanFloat# w))-        else i / 2 * log ( (i + q) / (i - q) )-      where-        i = signum imq-        imq = im q-    {-# INLINE asinh #-}-    asinh q = log (q + sqrt (q*q + 1))-    {-# INLINE acosh #-}-    acosh q = log (q + sqrt (q*q - 1))-    {-# INLINE atanh #-}-    atanh q = 0.5 * log ((1+q)/(1-q))------------------------------------------------------------------------------- Eq-----------------------------------------------------------------------------instance Eq QFloat where-    {-# INLINE (==) #-}-    QFloat a == QFloat b = a == b-    {-# INLINE (/=) #-}-    QFloat a /= QFloat b = a /= b--------------------------------------------------------------------------------- Show-----------------------------------------------------------------------------instance Show QFloat where-    show (QFloat (FloatX4# x y z w)) =-        show (F# w) ++ ss x ++ "i"-                    ++ ss y ++ "j"-                    ++ ss z ++ "k"-      where-        ss a# = case F# a# of-          a -> if a >= 0 then " + " ++ show a-                         else " - " ++ show (negate a)
src/Numeric/Scalar.hs view
@@ -1,41 +1,8 @@-{-# LANGUAGE DataKinds        #-}-{-# LANGUAGE FlexibleContexts #-}-{-# LANGUAGE KindSignatures   #-}-{-# LANGUAGE MagicHash        #-}-{-# LANGUAGE MonoLocalBinds   #-} -- | Scalar is an alias to zero-dimensional DataFrame module Numeric.Scalar     ( Scalar, unScalar, scalar, fromScalar     , Scf, Scd, Sci, Scw     ) where --import           GHC.Base                   (unsafeCoerce#)-import           Numeric.DataFrame.Family   (DataFrame)-import           Numeric.DataFrame.SubSpace (SubSpace (ewgen))-import           Numeric.Dim                (Nat)---- | Alias for zero-dimensional DataFrame-type Scalar t = DataFrame t ('[] :: [Nat])-type Scf   = Scalar Float-type Scd   = Scalar Double-type Sci   = Scalar Int-type Scw   = Scalar Word---- | Convert scalar back to ordinary type-unScalar :: Scalar t -> t--- rely on that Scalar is just two times newtype alias to t-unScalar = unsafeCoerce#-{-# INLINE unScalar #-}---- | Convert any type to scalar wrapper-scalar :: t -> Scalar t--- rely on that Scalar is just two times newtype alias to t-scalar = unsafeCoerce#-{-# INLINE scalar #-}---- | Broadcast scalar value onto a whole data frame-fromScalar :: SubSpace t '[] ds ds-           => Scalar t -> DataFrame t ds-fromScalar = ewgen-{-# INLINE fromScalar #-}+import Numeric.DataFrame.Internal.Backend ()+import Numeric.Scalar.Internal
+ src/Numeric/Scalar/Internal.hs view
@@ -0,0 +1,43 @@+{-# LANGUAGE DataKinds        #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE KindSignatures   #-}+{-# LANGUAGE MagicHash        #-}+{-# LANGUAGE MonoLocalBinds   #-}+{-# LANGUAGE PatternSynonyms  #-}+-- | Scalar is an alias to zero-dimensional DataFrame+module Numeric.Scalar.Internal+    ( Scalar, unScalar, scalar, fromScalar+    , Scf, Scd, Sci, Scw+    , pattern S+    ) where+++import Data.Type.Lits             (Nat)+import GHC.Base                   (unsafeCoerce#)+import Numeric.DataFrame.SubSpace (SubSpace (ewgen))+import Numeric.DataFrame.Type     (DataFrame, pattern S)++-- | Alias for zero-dimensional DataFrame+type Scalar t = DataFrame t ('[] :: [Nat])+type Scf   = Scalar Float+type Scd   = Scalar Double+type Sci   = Scalar Int+type Scw   = Scalar Word++-- | Convert scalar back to ordinary type+unScalar :: Scalar t -> t+-- rely on that Scalar is just two times newtype alias to t+unScalar = unsafeCoerce#+{-# INLINE unScalar #-}++-- | Convert any type to scalar wrapper+scalar :: t -> Scalar t+-- rely on that Scalar is just two times newtype alias to t+scalar = unsafeCoerce#+{-# INLINE scalar #-}++-- | Broadcast scalar value onto a whole data frame+fromScalar :: SubSpace t ds '[] ds+           => Scalar t -> DataFrame t ds+fromScalar = ewgen+{-# INLINE fromScalar #-}
− src/Numeric/Semigroup.hs
@@ -1,219 +0,0 @@-{-# LANGUAGE DeriveDataTypeable         #-}-{-# LANGUAGE DeriveGeneric              #-}-{-# LANGUAGE BangPatterns               #-}-{-# LANGUAGE GeneralizedNewtypeDeriving #-}--------------------------------------------------------------------------------- |--- Module      :  Numeric.Semigroup--- Copyright   :  (c) Artem Chirkin--- License     :  BSD3------ Maintainer  :  chirkin@arch.ethz.ch------ Re-export most of "Data.Semigroup" with a few changes---  and new definitions.------ The main initiative behind this module is to provide more strict--- alternatives to widely used semigroups.--- For example, 'Data.Semigroup.Option' has lazy @(\<\>)@ implementation,--- which causes memory leaks in large foldMaps.----------------------------------------------------------------------------------module Numeric.Semigroup-    ( Semigroup(..)-    , stimesMonoid-    , stimesIdempotent-    , stimesIdempotentMonoid-    , mtimesDefault-    , foldMap'-    -- * Semigroups-    , Min(..)-    , Max(..)-    , First(..)-    , Last(..)-    , WrappedMonoid(..)-    -- * Re-exported monoids from Data.Monoid-    , Monoid(..)-    , Dual(..)-    , Endo(..)-    , All(..)-    , Any(..)-    , Sum(..)-    , Product(..)-    -- * A better monoid for Maybe-    , Option (..)-    , option, fromOption, toOption-    -- * Difference lists of a semigroup-    , diff-    , cycle1-    -- * ArgMin, ArgMax-    , Arg(..)-    , ArgMin-    , ArgMax-    , MinMax (..)-    , minMax, mmDiff, mmAvg-    ) where--import Data.Semigroup hiding (Option (..), option)-import Data.Foldable (foldl')-import Data.Data-import Control.Applicative-import Control.Monad.Fix-import GHC.Generics---- | 'Option' is effectively 'Maybe' with a better instance of--- 'Monoid', built off of an underlying 'Semigroup' instead of an--- underlying 'Monoid'.------ This version of 'Option' data type is more strict than the one from--- "Data.Semigroup".-newtype Option a = Option { getOption :: Maybe a }-  deriving ( Eq, Ord, Show, Read, Data, Typeable, Generic, Generic1-           , Functor, Alternative, Applicative, Monad, MonadFix)---- | Fold an 'Option' case-wise, just like 'maybe'.---   Eagerly evaluates the value before returning!-option :: b -> (a -> b) -> Option a -> b-option !b _ (Option Nothing)   = b-option _  f (Option (Just !a)) = f a---- | Get value from 'Option' with default value.---   Eagerly evaluates the value before returning!-fromOption :: a -> Option a -> a-fromOption !a (Option Nothing)  = a-fromOption _ (Option (Just !a)) = a---- | Wrap a value into 'Option' container.---   Eagerly evaluates the value before wrapping!-toOption :: a -> Option a-toOption !a = Option (Just a)---instance Foldable Option where-  foldMap _ (Option Nothing)   = mempty-  foldMap f (Option (Just !a)) = f a--instance Traversable Option where-  traverse _ (Option Nothing)    = pure (Option Nothing)-  traverse f (Option (Just !a))  = (\ !b -> Option (Just b)) <$> f a--instance Semigroup a => Semigroup (Option a) where-  Option Nothing   <> Option Nothing   = Option Nothing-  Option Nothing   <> Option (Just !a) = Option (Just a)-  Option (Just !a) <> Option Nothing   = Option (Just a)-  Option (Just !a) <> Option (Just !b) = Option (Just $! a <> b)--  stimes _ (Option Nothing) = Option Nothing-  stimes n (Option (Just a)) = case compare n 0 of-    LT -> errorWithoutStackTrace "stimes: Option, negative multiplier"-    EQ -> Option Nothing-    GT -> Option (Just $! stimes n a)--instance Semigroup a => Monoid (Option a) where-  mappend = (<>)-  mempty  = Option Nothing------ | Evaluate minimum and maximum at the same time.---   Arithmetics and semigroup operations are eager,---   functorial operations are lazy.------   This data type is especially useful for calculating bounds---   of foldable containers with numeric data using @foldMap minMax@.-data MinMax a = MinMax a a-  deriving (Eq, Read, Show, Data, Typeable, Generic, Generic1)--minMax :: a -> MinMax a-minMax !a = MinMax a a--mmDiff :: Num a => MinMax a -> a-mmDiff (MinMax !x !y) = y - x--mmAvg :: Fractional a => MinMax a -> a-mmAvg (MinMax !x !y) = 0.5 * (x+y)--strictMinMax :: a -> a -> MinMax a-strictMinMax !a !b = MinMax a b--instance Ord a => Semigroup (MinMax a) where-  (MinMax !x1 !y1) <> (MinMax !x2 !y2) = strictMinMax (min x1 x2) (max y1 y2)--  -- 'MinMax' is idempotent.-  -- Also we don't care if @n@ is not positive.-  stimes _ (MinMax !x !y) = MinMax x y----instance (Ord a, Bounded a) => Monoid (MinMax a) where-  -- | Empty instance of minmax is an invalid value @min >= max@.-  --   However, this gives a good monoid append behavior.-  mempty = strictMinMax maxBound minBound-  mappend = (<>)---instance Functor MinMax where-  fmap f (MinMax a b) = MinMax (f a) (f b)--instance Applicative MinMax where-  pure a = MinMax a a-  MinMax f g <*> MinMax a b = MinMax (f a) (g b)--instance Monad MinMax where-  return = pure-  MinMax a b >>= m = case (m a, m b) of-      (MinMax x _, MinMax _ y) -> MinMax x y--instance MonadFix MinMax where-  mfix mf = let MinMax x _ = mf x-                MinMax _ y = mf y-            in MinMax x y--instance Bounded a => Bounded (MinMax a) where-  minBound = strictMinMax minBound minBound-  maxBound = strictMinMax maxBound maxBound---- | MinMax checks whether bounds overlap.------    * Strict inequality means that intervals do not overlap.---    * Non-strict inequality means non-strict inequality in both constructor arguments.---    * `EQ` means intervals overlap-instance Ord a => Ord (MinMax a) where-  MinMax _ amax < MinMax bmin _ = amax < bmin-  MinMax amin _ > MinMax _ bmax = amin > bmax-  MinMax amin amax <= MinMax bmin bmax = amin <= bmin && amax <= bmax-  MinMax amin amax >= MinMax bmin bmax = amin >= bmin && amax >= bmax-  -- |  A contraversal decision was made here: implementing `compare` operation.-  --    `compare` returns GT or LT only if bounds do not overlap and returns EQ otherwise.-  compare (MinMax amin amax) (MinMax bmin bmax)-    | amin > bmax = GT-    | bmin > amax = LT-    | otherwise   = EQ-  min (MinMax amin amax) (MinMax bmin bmax) = strictMinMax (min amin bmin) (min amax bmax)-  max (MinMax amin amax) (MinMax bmin bmax) = strictMinMax (max amin bmin) (max amax bmax)--instance (Num a, Ord a) => Num (MinMax a) where-  (MinMax !x1 !y1) + (MinMax !x2 !y2) = strictMinMax (x1+x2) (y1+y2)-  (MinMax !x1 !y1) - (MinMax !x2 !y2) = strictMinMax (x1-y2) (y1-x2)-  (MinMax !x1 !y1) * (MinMax !x2 !y2) = strictMinMax (x1*x2) (y1*y2)-  abs (MinMax !x !y) = case (abs x, abs y) of-      (!ax, !ay) -> strictMinMax (min ax ay) (max ax ay)-  negate (MinMax !x !y) = strictMinMax (negate y) (negate x)-  signum (MinMax !x !y) = strictMinMax (signum x) (signum y)-  fromInteger = minMax . fromInteger----- | Map each element of the structure to a monoid,---   and combine the results.------   This function differs from @Data.Foldable.foldMap@ in that uses @foldl'@---   instead of @foldr@ inside.---   This makes this function suitable for Monoids with strict `mappend` operation.---   For example,------   > foldMap' Sum $ take 1000000000 ([1..] :: [Int])------   runs in constant memory, whereas normal @foldMap@ would cause a memory leak there.-foldMap' :: (Foldable t, Monoid m) => (a -> m) -> t a -> m-foldMap' f = foldl' (flip $ mappend . f) mempty-{-# INLINE foldMap' #-}
src/Numeric/Vector.hs view
@@ -1,184 +1,18 @@-{-# LANGUAGE DataKinds        #-}-{-# LANGUAGE FlexibleContexts #-}-{-# LANGUAGE GADTs            #-}-{-# LANGUAGE KindSignatures   #-}-{-# LANGUAGE PolyKinds        #-} -- | Vector is an alias to a DataFrame with order 1. module Numeric.Vector-    ( -- * Type aliases+    (  -- * Type aliases       Vector     , Vec2f, Vec3f, Vec4f, Vec2d, Vec3d, Vec4d     , Vec2i, Vec3i, Vec4i, Vec2w, Vec3w, Vec4w+      -- * Vector constructors+    , Vector2 (..), Vector3 (..), Vector4 (..)+    , DataFrame(Vec2, Vec3, Vec4)       -- * Common operations     , (.*.), dot, (·)     , normL1, normL2, normLPInf, normLNInf, normLP     , normalized-    , vec2, vec3, vec4     , det2, cross, (×)-    , unpackV2, unpackV3, unpackV4     ) where -import           Numeric.DataFrame.SubSpace-import           Numeric.DataFrame.Type-import           Numeric.Scalar------------------------------------------------------------------------------------- * Vector type-----------------------------------------------------------------------------------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----- | 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-(.*.) a b = fromScalar . ewfoldl (+) 0 $ a * b-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 a b = ewfoldl (+) 0 $ a * b---- | Dot product of two vectors-infixl 7 ·-(·) :: ( Num t-       , Num (Vector t n)-       , SubSpace t '[] '[n] '[n]-       )-    => Vector t n -> Vector t n -> Scalar t-(·) = dot-{-# INLINE (·) #-}----- | Sum of absolute values-normL1 :: ( Num t, SubSpace t '[] '[n] '[n] )-       => Vector t n -> Scalar t-normL1 = ewfoldr (\a -> (abs a +)) 0---- | hypot function (square root of squares)-normL2 :: ( Floating t , SubSpace t '[] '[n] '[n] )-       => Vector t n -> Scalar t-normL2 = sqrt . ewfoldr (\a -> (a*a +)) 0---- | 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-normalized v = v / n-  where-    n = fromScalar . sqrt $ ewfoldr (\a -> (a*a +)) 0 v---- | Maximum of absolute values-normLPInf :: ( Ord t, Num t , SubSpace t '[] '[n] '[n] )-          => Vector t n -> Scalar t-normLPInf = ewfoldr (max . abs) 0---- | Minimum of absolute values-normLNInf :: ( Ord t, Num t , SubSpace t '[] '[n] '[n] )-          => Vector t n -> Scalar t-normLNInf x = ewfoldr (min . abs) (abs $ x ! Idx 1 :* U) x---- | Norm in Lp space-normLP :: ( Floating t , SubSpace t '[] '[n] '[n] )-       => Int -> Vector t n -> Scalar t-normLP i' = (**ri) . ewfoldr (\a -> (a**i +)) 0-  where-    i  = fromIntegral i'-    ri = recip i-{-# INLINE [2] normLP #-}-{-# RULES-"normLP/L1" normLP 1 = normL1-"normLP/L2" normLP 2 = normL2-  #-}---- | Compose a 2D vector-vec2 :: SubSpace t '[] '[2] '[2] => t -> t -> Vector t 2-vec2 a b = iwgen f-  where-    f (1 :* U) = scalar a-    f _        = scalar b---- | 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-det2 a b = (a ! 1 :* U) * (b ! 2 :* U)-         - (a ! 2 :* U) * (b ! 1 :* U)---- | Compose a 3D vector-vec3 :: SubSpace t '[] '[3] '[3] => t -> t -> t -> Vector t 3-vec3 a b c = iwgen f-  where-    f (1 :* U) = scalar a-    f (2 :* U) = scalar b-    f _        = scalar c---- | Cross product-cross :: ( Num t, SubSpace t '[] '[3] '[3] )-      => Vector t 3 -> Vector t 3 -> Vector t 3-cross a b = vec3 ( unScalar-                 $ (a ! 2 :* U) * (b ! 3 :* U)-                 - (a ! 3 :* U) * (b ! 2 :* U) )-                 ( unScalar-                 $ (a ! 3 :* U) * (b ! 1 :* U)-                 - (a ! 1 :* U) * (b ! 3 :* U) )-                 ( unScalar-                 $ (a ! 1 :* U) * (b ! 2 :* U)-                 - (a ! 2 :* U) * (b ! 1 :* U) )----- | Cross product for two vectors in 3D-infixl 7 ×-(×) :: ( Num t, SubSpace t '[] '[3] '[3] )-    => Vector t 3 -> Vector t 3 -> Vector t 3-(×) = cross-{-# INLINE (×) #-}----- | Compose a 4D vector-vec4 :: SubSpace t '[] '[4] '[4]-     => t -> t -> t -> t -> Vector t 4-vec4 a b c d = iwgen f-  where-    f (1 :* U) = scalar a-    f (2 :* U) = scalar b-    f (3 :* U) = scalar c-    f _        = scalar d---unpackV2 :: SubSpace t '[] '[2] '[2]-         => Vector t 2 -> (t, t)-unpackV2 v = (unScalar $ v ! 1, unScalar $ v ! 2)-{-# INLINE unpackV2 #-}---unpackV3 :: SubSpace t '[] '[3] '[3]-         => Vector t 3 -> (t, t, t)-unpackV3 v = (unScalar $ v ! 1, unScalar $ v ! 2, unScalar $ v ! 3)-{-# INLINE unpackV3 #-}---unpackV4 :: SubSpace t '[] '[4] '[4]-         => Vector t 4 -> (t, t, t, t)-unpackV4 v = (unScalar $ v ! 1, unScalar $ v ! 2, unScalar $ v ! 3, unScalar $ v ! 4)-{-# INLINE unpackV4 #-}+import Numeric.DataFrame.Internal.Backend ()+import Numeric.Vector.Internal
+ src/Numeric/Vector/Internal.hs view
@@ -0,0 +1,229 @@+{-# LANGUAGE DataKinds                 #-}+{-# LANGUAGE ExistentialQuantification #-}+{-# LANGUAGE FlexibleContexts          #-}+{-# LANGUAGE FlexibleInstances         #-}+{-# LANGUAGE GADTs                     #-}+{-# LANGUAGE MagicHash                 #-}+{-# LANGUAGE MultiParamTypeClasses     #-}+{-# LANGUAGE PatternSynonyms           #-}+{-# LANGUAGE PolyKinds                 #-}+{-# LANGUAGE ScopedTypeVariables       #-}+{-# LANGUAGE TypeFamilies              #-}+{-# LANGUAGE TypeOperators             #-}+{-# LANGUAGE UnboxedTuples             #-}+{-# LANGUAGE UndecidableInstances      #-}+{-# LANGUAGE ViewPatterns              #-}++module Numeric.Vector.Internal+    (  -- * Type aliases+      Vector+    , Vec2f, Vec3f, Vec4f, Vec2d, Vec3d, Vec4d+    , Vec2i, Vec3i, Vec4i, Vec2w, Vec3w, Vec4w+      -- * Vector constructors+    , Vector2 (..), Vector3 (..), Vector4 (..)+    , DataFrame(Vec2, Vec3, Vec4)+      -- * Common operations+    , (.*.), dot, (·)+    , normL1, normL2, normLPInf, normLNInf, normLP+    , normalized+    , det2, cross, (×)+    ) where++import Numeric.DataFrame.SubSpace+import Numeric.DataFrame.Type+import Numeric.Scalar.Internal++++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+++pattern Vec4 :: Vector4 t => t -> t -> t -> t -> Vector t 4+pattern Vec4 a b c d <- (unpackV4# -> (# a, b, c, d #))+  where+    Vec4 = vec4+{-# COMPLETE Vec4 #-}++pattern Vec3 :: Vector3 t => t -> t -> t -> Vector t 3+pattern Vec3 a b c <- (unpackV3# -> (# a, b, c #))+  where+    Vec3 = vec3+{-# COMPLETE Vec3 #-}++pattern Vec2 :: Vector2 t => t -> t -> Vector t 2+pattern Vec2 a b <- (unpackV2# -> (# a, b #))+  where+    Vec2 = vec2+{-# COMPLETE Vec2 #-}++-- | Packing and unpacking 2D vectors+class Vector2 t where+  -- | Compose a 2D vector+  vec2 :: t -> t -> Vector t 2+  -- | Unpack 2D vector elements+  unpackV2# :: Vector t 2 -> (# t, t #)++-- | Packing and unpacking 3D vectors+class Vector3 t where+  -- | Compose a 3D vector+  vec3 :: t -> t -> t -> Vector t 3+  -- | Unpack 3D vector elements+  unpackV3# :: Vector t 3 -> (# t, t, t #)++-- | Packing and unpacking 4D vectors+class Vector4 t where+  -- | Compose a 4D vector+  vec4 :: t -> t -> t -> t -> Vector t 4+  -- | Unpack 4D vector elements+  unpackV4# :: Vector t 4 -> (# t, t, t, t #)++instance {-# OVERLAPPABLE #-} SubSpace t '[2] '[] '[2] => Vector2 t where+  vec2 a b = iwgen f+    where+      f (0 :* U) = scalar a+      f _        = scalar b+  {-# INLINE vec2 #-}+  unpackV2# v =+    (# unScalar (indexOffset# 0# v)+     , unScalar (indexOffset# 1# v) #)+  {-# INLINE unpackV2# #-}++instance {-# OVERLAPPABLE #-} SubSpace t '[3] '[] '[3] => Vector3 t where+  vec3 a b c = iwgen f+    where+      f (0 :* U) = scalar a+      f (1 :* U) = scalar b+      f _        = scalar c+  {-# INLINE vec3 #-}+  unpackV3# v =+    (# unScalar (indexOffset# 0# v)+     , unScalar (indexOffset# 1# v)+     , unScalar (indexOffset# 2# v) #)+  {-# INLINE unpackV3# #-}++instance {-# OVERLAPPABLE #-} SubSpace t '[4] '[] '[4] => Vector4 t where+  vec4 a b c d = iwgen f+    where+      f (0 :* U) = scalar a+      f (1 :* U) = scalar b+      f (2 :* U) = scalar c+      f _        = scalar d+  {-# INLINE vec4 #-}+  unpackV4# v =+    (# unScalar (indexOffset# 0# v)+     , unScalar (indexOffset# 1# v)+     , unScalar (indexOffset# 2# v)+     , unScalar (indexOffset# 3# v) #)+  {-# INLINE unpackV4# #-}++++-- | 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+(.*.) a b = fromScalar . ewfoldl (+) 0 $ a * b+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 a b = ewfoldl (+) 0 $ a * b++-- | Dot product of two vectors+infixl 7 ·+(·) :: ( Num t+       , Num (Vector t n)+       , SubSpace t '[n] '[] '[n]+       )+    => Vector t n -> Vector t n -> Scalar t+(·) = dot+{-# INLINE (·) #-}+++-- | Sum of absolute values+normL1 :: ( Num t, SubSpace t '[n] '[] '[n] )+       => Vector t n -> Scalar t+normL1 = ewfoldr (\a -> (abs a +)) 0++-- | hypot function (square root of squares)+normL2 :: ( Floating t , SubSpace t '[n] '[] '[n] )+       => Vector t n -> Scalar t+normL2 = sqrt . ewfoldr (\a -> (a*a +)) 0++-- | 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+normalized v = v / n+  where+    n = fromScalar . sqrt $ ewfoldr (\a -> (a*a +)) 0 v++-- | Maximum of absolute values+normLPInf :: ( Ord t, Num t , SubSpace t '[n] '[] '[n] )+          => Vector t n -> Scalar t+normLPInf = ewfoldr (max . abs) 0++-- | Minimum of absolute values+normLNInf :: ( Ord t, Num t , SubSpace t '[n] '[] '[n] )+          => Vector t n -> Scalar t+normLNInf x = ewfoldr (min . abs) (scalar . abs $ ixOff 0 x) x++-- | Norm in Lp space+normLP :: ( Floating t , SubSpace t '[n] '[] '[n] )+       => Int -> Vector t n -> Scalar t+normLP i' = (**ri) . ewfoldr (\a -> (a**i +)) 0+  where+    i  = fromIntegral i'+    ri = recip i+{-# INLINE [2] normLP #-}+{-# RULES+"normLP/L1" normLP 1 = normL1+"normLP/L2" normLP 2 = normL2+  #-}++-- | 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+det2 a b = (a ! 0 :* U) * (b ! 1 :* U)+         - (a ! 1 :* U) * (b ! 0 :* U)++-- | Cross product+cross :: ( Num t, SubSpace t '[3] '[] '[3] )+      => Vector t 3 -> Vector t 3 -> Vector t 3+cross a b = vec3 ( unScalar+                 $ (a ! 1 :* U) * (b ! 2 :* U)+                 - (a ! 2 :* U) * (b ! 1 :* U) )+                 ( unScalar+                 $ (a ! 2 :* U) * (b ! 0 :* U)+                 - (a ! 0 :* U) * (b ! 2 :* U) )+                 ( unScalar+                 $ (a ! 0 :* U) * (b ! 1 :* U)+                 - (a ! 1 :* U) * (b ! 0 :* U) )+++-- | Cross product for two vectors in 3D+infixl 7 ×+(×) :: ( Num t, SubSpace t '[3] '[] '[3] )+    => Vector t 3 -> Vector t 3 -> Vector t 3+(×) = cross+{-# INLINE (×) #-}
test/Numeric/DataFrame/Arbitraries.hs view
@@ -1,61 +1,114 @@-{-# LANGUAGE AllowAmbiguousTypes   #-}-{-# LANGUAGE ConstraintKinds       #-}-{-# LANGUAGE DataKinds             #-}-{-# LANGUAGE FlexibleContexts      #-}-{-# LANGUAGE FlexibleInstances     #-}-{-# LANGUAGE GADTs                 #-}-{-# LANGUAGE KindSignatures        #-}-{-# LANGUAGE PartialTypeSignatures #-}-{-# LANGUAGE PolyKinds             #-}-{-# LANGUAGE Rank2Types            #-}-{-# LANGUAGE ScopedTypeVariables   #-}-{-# LANGUAGE TypeApplications      #-}-{-# LANGUAGE TypeOperators         #-}-{-# LANGUAGE UndecidableInstances  #-}+{-# LANGUAGE AllowAmbiguousTypes       #-}+{-# LANGUAGE ConstraintKinds           #-}+{-# LANGUAGE DataKinds                 #-}+{-# LANGUAGE ExistentialQuantification #-}+{-# LANGUAGE FlexibleContexts          #-}+{-# LANGUAGE FlexibleInstances         #-}+{-# LANGUAGE GADTs                     #-}+{-# LANGUAGE PartialTypeSignatures     #-}+{-# LANGUAGE PolyKinds                 #-}+{-# LANGUAGE RankNTypes                #-}+{-# LANGUAGE ScopedTypeVariables       #-}+{-# LANGUAGE TypeApplications          #-}+{-# LANGUAGE TypeOperators             #-}+{-# LANGUAGE UndecidableInstances      #-} {-# OPTIONS_GHC -fno-warn-orphans  #-} -- | Provide instance of Arbitrary for all DataFrame types. --   Also, this module is an example of fancy type inference and DataFrame --   traversals with monadic actions. module Numeric.DataFrame.Arbitraries where -import           Test.QuickCheck+import Test.QuickCheck +import           Data.Kind            (Type)+import           Data.Semigroup       hiding (All) import           Numeric.DataFrame import           Numeric.Dimensions-import           Numeric.PrimBytes+import           Numeric.Quaternion+import qualified Numeric.Tuple.Lazy   as LT+import qualified Numeric.Tuple.Strict as ST -instance (Arbitrary t, PrimBytes t, Dimensions ds)++maxDims :: Word+maxDims = 5++maxDimSize :: Word+maxDimSize = 7++fromScalarChanceFactor :: Int+fromScalarChanceFactor = 5+++instance (Quaternion t, Arbitrary t, Num t) => Arbitrary (Quater t) where+  arbitrary = sequence+    [ Quater <$> arbitrary <*> arbitrary <*> arbitrary <*> arbitrary+    , Quater <$> arbitrary <*> arbitrary <*> arbitrary <*> arbitrary+    , Quater <$> arbitrary <*> arbitrary <*> arbitrary <*> arbitrary+    , Quater <$> arbitrary <*> arbitrary <*> arbitrary <*> arbitrary+    , Quater <$> arbitrary <*> pure 0 <*> pure 0 <*> pure 0+    , Quater <$> pure 0 <*> arbitrary <*> pure 0 <*> pure 0+    , Quater <$> pure 0 <*> pure 0 <*> arbitrary <*> pure 0+    , Quater <$> pure 0 <*> pure 0 <*> pure 0 <*> arbitrary+    , Quater <$> arbitrary <*> arbitrary <*> pure 0 <*> pure 0+    , Quater <$> arbitrary <*> pure 0 <*> arbitrary <*> pure 0+    , Quater <$> arbitrary <*> pure 0 <*> pure 0 <*> arbitrary+    , Quater <$> pure 0 <*> arbitrary <*> arbitrary <*> pure 0+    , Quater <$> pure 0 <*> arbitrary <*> pure 0 <*> arbitrary+    , Quater <$> pure 0 <*> pure 0 <*> arbitrary <*> arbitrary+    , Quater <$> arbitrary <*> arbitrary <*> arbitrary <*> pure 0+    , Quater <$> arbitrary <*> arbitrary <*> pure 0 <*> arbitrary+    , Quater <$> arbitrary <*> pure 0 <*> arbitrary <*> arbitrary+    , Quater <$> pure 0 <*> arbitrary <*> arbitrary <*> arbitrary+    ] >>= elements++  shrink (Quater x y z t)+      -- shrink either real or the whole imaginary part+    = ($) <$> zipWith3 Quater (shrink x) (shrink y) (shrink z) <*> shrink t++++instance (Arbitrary t, PrimBytes t, Num t, Ord t, Dimensions ds)       => Arbitrary (DataFrame t (ds :: [Nat])) where     arbitrary         | -- First, we need to find out exact array implementation to use           -- inside this DataFrame.           -- We need to do that whenever exact value of ds is not known-          E <- inferASing' @t @ds-          -- Then, we need to get basic byte manipulation type classes, such as-          -- PrimBytes and PrimArray.-        , E <- inferPrim' @t @ds+          Dict <- inferKnownBackend @t @ds           -- After that, GHC can infer all necessary fancy things like SubSpace           -- to do complex operations on sub-dimensions of a DataFrame.           --           -- Note, we could put SubSpace into constraints of this instance as well.           -- That would render the above lines unnecessary, but would make           -- inference more difficult later.-        = arbitrary >>= elementWise @_ @_ @ds f . ewgen . scalar+        = do+        full <- (1 < ) <$> choose (1, fromScalarChanceFactor)+        if full -- I want to check fromScalar code path sometimes+        then arbitrary >>= elementWise @_ @ds @'[] f . ewgen . scalar+        else fromScalar . scalar <$> arbitrary       where         f :: Arbitrary a => Scalar a -> Gen (Scalar a)         f _ = scalar <$> arbitrary-    shrink-        | E <- inferASing' @t @ds-        , E <- inferPrim' @t @ds-        = elementWise @_ @_ @ds f-      where-        -- Unfortunately, Scalar is not a proper second-rank data type-        -- (it is just type alias for DataFrame t []).-        -- So it cannot be functor or traversable.-        f :: Arbitrary a => Scalar a -> [Scalar a]-        f = fmap scalar . shrink . unScalar+    shrink df+        | Dict <- inferKnownBackend @t @ds+        , mma <- ewfoldMap @t @ds @'[] @ds+            ((\x -> if x == 0 then Nothing else Just (Max x)) . abs) df+        = case mma of+            Nothing+              -> [] -- all-zero is the most primitive DF possible+            Just (Max ma)+             -> [ ewmap (\x -> if abs x == ma then 0 else x) df+                , ewmap (scalar . withAbs . unScalar) df+                ]+            where+              withAbs :: t -> t+              withAbs x+                | abs x <= 1 = 0+                | otherwise  = signum x * closest2 (abs x) 1+              closest2 :: t -> t -> t+              closest2 x b = if x <= b * 2 then b else closest2 x (b*2) -instance (All Arbitrary ts, All PrimBytes ts, RepresentableList ts, Dimensions ds)+instance ( All Arbitrary ts, All PrimBytes ts, All Num ts, All Ord ts+         , RepresentableList ts, Dimensions ds)       => Arbitrary (DataFrame ts (ds :: [Nat])) where     -- We create arbitrary MultiFrame by combining several SingleFrames.     -- SingleFrames are "variables" or "columns" of a MultiFrame that are@@ -71,28 +124,22 @@           at   <- arbitrary           ats' <- arbitrary @(DataFrame ts' ds)           return (at :*: ats')-    shrink Z = []     -- MultiFrame is a newtype wrapper on a TypedList.     -- Thus, we can always recover RepresentableList ts by using function @types@     shrink (at :*: ats@(MultiFrame ats'))       | TypeList <- types ats'       = (:*:) <$> shrink at <*> shrink ats+    shrink _ = []  -maxDims :: Word-maxDims = 5--maxDimSize :: Word-maxDimSize = 7- instance KnownDim a => Arbitrary (Dim (N a)) where-    arbitrary = return $ Dn (dim @_ @a)+    arbitrary = return $ Dn (dim @a)     shrink _ = []  instance KnownDim m => Arbitrary (Dim (XN m)) where     arbitrary = do       dimN <- choose (dimVal' @m, maxDims)-      case constrain @m (someDimVal dimN) of+      case constrainDim @XNat @(XN m) (someDimVal dimN) of         Nothing -> error "impossible argument"         Just d  -> return d     shrink _ = []@@ -117,42 +164,111 @@     arbitrary = (:*) <$> arbitrary <*> arbitrary     shrink _ = [] -instance (Arbitrary t, PrimBytes t)+instance (Arbitrary t, PrimBytes t, Num t, Ord t)       => Arbitrary (SomeDataFrame t) where     arbitrary = do       -- Generate random dimension list+      SomeDims ds <- arbitrary       --  and pattern-match against it with Dims pattern.       --  This gives Dimensions ds evidence immediately.-      SomeDims (Dims :: Dims ds) <- arbitrary-      -- We also need to figure out an array implementation...-      case inferASing' @t @ds of-        -- ... and generating a random DataFrame becomes a one-liner-        E -> SomeDataFrame <$> arbitrary @(DataFrame t ds)-    shrink _ = []+      case ds of+        -- We also need to figure out an array implementation...+        (Dims :: Dims ds) -> case inferKnownBackend @t @ds of+          -- ... and generating a random DataFrame becomes a one-liner+          Dict -> SomeDataFrame <$> arbitrary @(DataFrame t ds)+    shrink (SomeDataFrame df) = SomeDataFrame <$> shrink df  -- All same as above, just change constraints a bit-instance (All Arbitrary ts, All PrimBytes ts, RepresentableList ts)+instance ( All Arbitrary ts, All PrimBytes ts, All Num ts, All Ord ts+         , RepresentableList ts)       => Arbitrary (SomeDataFrame ts) where     arbitrary = do-      SomeDims (Dims :: Dims ds) <- arbitrary-      case inferASing' @ts @ds of-        E -> SomeDataFrame <$> arbitrary @(DataFrame ts ds)-    shrink _ = []+      SomeDims ds <- arbitrary+      case ds of+        (Dims :: Dims ds) -> case inferKnownBackend @ts @ds of+          Dict -> SomeDataFrame <$> arbitrary @(DataFrame ts ds)+    shrink (SomeDataFrame df) = SomeDataFrame <$> shrink df -instance ( Arbitrary t, PrimBytes t+instance ( Arbitrary t, PrimBytes t, Num t, Ord t          , Arbitrary (Dims xs), All KnownXNatType xs)       => Arbitrary (DataFrame t (xs :: [XNat])) where     arbitrary = do-      XDims (_ :: Dims ds) <- arbitrary @(Dims xs)-      case inferASing' @t @ds of-        E -> XFrame <$> arbitrary @(DataFrame t ds)+      ds <- arbitrary @(Dims xs)+      case ds of+        XDims (_ :: Dims ds) -> case inferKnownBackend @t @ds of+          Dict -> XFrame <$> arbitrary @(DataFrame t ds)     shrink (XFrame df) = XFrame <$> shrink df -instance ( All Arbitrary ts, All PrimBytes ts, RepresentableList ts+instance ( All Arbitrary ts, All PrimBytes ts, All Num ts, All Ord ts+         , RepresentableList ts          , Arbitrary (Dims xs), All KnownXNatType xs)       => Arbitrary (DataFrame ts (xs :: [XNat])) where     arbitrary = do-      XDims (_ :: Dims ds) <- arbitrary @(Dims xs)-      case inferASing' @ts @ds of-        E -> XFrame <$> arbitrary @(DataFrame ts ds)+      ds <- arbitrary @(Dims xs)+      case ds of+        XDims (_ :: Dims ds) -> case inferKnownBackend @ts @ds of+          Dict -> XFrame <$> arbitrary @(DataFrame ts ds)     shrink (XFrame df) = XFrame <$> shrink df+++instance KnownDim n => Arbitrary (Idx n) where+    arbitrary = elements [0..]++instance Dimensions ns => Arbitrary (Idxs ns) where+    arbitrary = go (Dims @ns)+      where+        go :: forall (bs :: [Nat]) . Dims bs -> Gen (Idxs bs)+        go U         = pure U+        go (D :* bs) = (:*) <$> arbitrary <*> go bs++instance (RepresentableList xs, All Arbitrary xs) => Arbitrary (ST.Tuple xs) where+    arbitrary = go (tList @Type @xs)+      where+        go :: forall (bs :: [Type])+            . All Arbitrary bs+           => TypeList bs -> Gen (ST.Tuple bs)+        go U         = pure U+        go (_ :* bs) = (ST.:$) <$> arbitrary <*> go bs++instance (RepresentableList xs, All Arbitrary xs) => Arbitrary (LT.Tuple xs) where+    arbitrary = go (tList @Type @xs)+      where+        go :: forall (bs :: [Type])+            . All Arbitrary bs+           => TypeList bs -> Gen (LT.Tuple bs)+        go U         = pure U+        go (_ :* bs) = (LT.:$) <$> arbitrary <*> go bs++data AnyMatrix+data NonSingular++data SomeSquareMatrix prop t+  = forall (n :: Nat)+  . (KnownDim n, KnownBackend t '[n], KnownBackend t '[n, n])+  => SSM (DataFrame t '[n,n])++instance (Show t, PrimBytes t) => Show (SomeSquareMatrix prop t) where+  show (SSM df) = show df++instance (Arbitrary t, PrimBytes t, Num t, Ord t)+      => Arbitrary (SomeSquareMatrix AnyMatrix t) where+    arbitrary = do+      dx <- arbitrary @(Dim (XN 2))+      case dx of+        Dx (D :: Dim n) -> case inferKnownBackend @t @'[n] of+          Dict -> SSM <$> arbitrary @(DataFrame t '[n,n])+    shrink (SSM df)= SSM <$> shrink df++instance (Arbitrary t, PrimBytes t, Num t, Ord t)+      => Arbitrary (SomeSquareMatrix NonSingular t) where+    arbitrary = do+      SSM (someMat :: DataFrame t '[n, n]) <- arbitrary @(SomeSquareMatrix AnyMatrix t)+      -- https://en.wikipedia.org/wiki/Diagonally_dominant_matrix+      return . SSM $+        iwmap @t @'[n] @'[n] @'[n,n]+              @t @'[n] @'[n,n]+          ( \i v ->+            let s = ewfoldl (\a -> (a +) . abs) 1 v+            in update i s v+          ) someMat+    shrink _ = []
test/Numeric/DataFrame/BasicTest.hs view
@@ -15,7 +15,7 @@ {-# LANGUAGE FlexibleContexts     #-} {-# LANGUAGE GADTs                #-} {-# LANGUAGE KindSignatures       #-}-{-# LANGUAGE Rank2Types           #-}+{-# LANGUAGE RankNTypes           #-} {-# LANGUAGE ScopedTypeVariables  #-} {-# LANGUAGE TemplateHaskell      #-} {-# LANGUAGE TypeApplications     #-}@@ -26,38 +26,112 @@ module Numeric.DataFrame.BasicTest (runTests) where  import           Numeric.DataFrame-import           Numeric.DataFrame.Arbitraries ()-import           Numeric.Dimensions+import           Numeric.DataFrame.Arbitraries    ()+import qualified Numeric.ProductOrd.NonTransitive as NonTransitive+import qualified Numeric.ProductOrd.Partial       as Partial import           Test.QuickCheck +{-# ANN module "HLint: ignore Use <" #-}+{-# ANN module "HLint: ignore Use >" #-}+{-# ANN module "HLint: ignore Use >=" #-}+{-# ANN module "HLint: ignore Use <=" #-}+{-# ANN module "HLint: ignore Redundant compare" #-} -prop_Comparisons :: SomeDataFrame '[Float, Float] -> Bool-prop_Comparisons (SomeDataFrame (x :*: y :*: Z))-  | E <- inferOrd x-  , E <- inferFractional x-  = and-    [ abs x >= abs x / 2-    , abs x <= abs x + abs y-    , x <= x, x <= x-    , x >= x, y >= y-    , x == x, y == y-    , x < x + 1, x > x - 1-    , abs x >= x, abs (-x) >= (-x)-    , x > y            ===> x >= y-    , x < y            ===> x <= y-    , not (x >= y)     ===> not (x > y)-    , not (x <= y)     ===> not (x < y)-    , x == y           ===> and [ not (x > y), not (y < x), x >= y, y <= x ]-    , x >= y && x <= y ===> x == y+(===>) :: Bool -> Bool -> Bool+a ===> b = not a || b+infix 2 ===>++prop_vanillaOrdTransitivity :: SomeDataFrame '[Double, Double, Double] -> Property+prop_vanillaOrdTransitivity (SomeDataFrame (x :*: y :*: z :*: Z))+  = property $ (x <= y) && (y <= z) ===> x <= z++vanillaOrdComparisons :: Ord t => t -> t -> Property+vanillaOrdComparisons x y+  = conjoin+    [ counterexample "(x < y) == (compare x y == LT)"+          $ (x < y) == (compare x y == LT)+    , counterexample "(x > y) == (compare x y == GT)"+          $ (x > y) == (compare x y == GT)+    , counterexample "(x == y) == (compare x y == EQ)"+          $ (x == y) == (compare x y == EQ)+    , counterexample "min x y == if x <= y then x else y"+          $ min x y == if x <= y then x else y+    , counterexample "max x y == if x >= y then x else y"+          $ max x y == if x >= y then x else y     ]-  where-    a ===> b = not a || b-    infix 2 ===> ++comparisons :: (Ord t, Num t) => t -> t -> Property+comparisons x y+  = conjoin+    [ counterexample "abs x <= abs x + abs y" $ abs x <= abs x + abs y+    , counterexample "x <= x" $ x <= x+    , counterexample "y <= y" $ y <= y+    , counterexample "x >= x" $ x >= x+    , counterexample "y >= y" $ y >= y+    , counterexample "x == x" $ x == x+    , counterexample "y == y" $ y == y+    , counterexample "(x > y) == (y < x)"+                              $ (x > y) == (y < x)+    , counterexample "(x >= y) == (y <= x)"+                              $ (x >= y) == (y <= x)+    , counterexample "(x < y) == (x <= y && x /= y)"+                              $ (x < y) == (x <= y && x /= y)+    , counterexample "(x > y) == (x >= y && x /= y)"+                              $ (x > y) == (x >= y && x /= y)+    , counterexample "x < x + 1" $ abs x < 10000000 ===> x < x + 1+    , counterexample "x > x - 1" $ abs x < 10000000 ===> x > x - 1+    , counterexample "abs x >= x" $ abs x >= x+    , counterexample "abs (-x) >= (-x)" $ abs (-x) >= (-x)+    , counterexample "x > y ==> x >= y"+      $ x > y            ===> x >= y+    , counterexample "x < y ==> x <= y"+      $ x < y            ===> x <= y+    , counterexample "not (x >= y) ==> not (x > y)"+      $ not (x >= y)     ===> not (x > y)+    , counterexample "not (x <= y) ==> not (x < y)"+      $ not (x <= y)     ===> not (x < y)+    , counterexample "x == y ==> not GT or LT, but GE and LE"+      $ x == y           ===> and [ not (x > y), not (y < x), x >= y, y <= x ]+    , counterexample "x >= y && x <= y ==> x == y"+      $ x >= y && x <= y ===> x == y+    ]++prop_comparisonsVanillaOrdFloat :: SomeDataFrame '[Float, Float] -> Property+prop_comparisonsVanillaOrdFloat (SomeDataFrame (x :*: y :*: Z)) =+  comparisons x y .&&. vanillaOrdComparisons x y+prop_comparisonsVanillaOrdDouble :: SomeDataFrame '[Double, Double] -> Property+prop_comparisonsVanillaOrdDouble (SomeDataFrame (x :*: y :*: Z)) =+  comparisons x y .&&. vanillaOrdComparisons x y+prop_comparisonsVanillaOrdInt :: SomeDataFrame '[Int, Int] -> Property+prop_comparisonsVanillaOrdInt (SomeDataFrame (x :*: y :*: Z)) =+  comparisons x y .&&. vanillaOrdComparisons x y+++prop_comparisonsPPOrdFloat :: SomeDataFrame '[Float, Float] -> Property+prop_comparisonsPPOrdFloat (SomeDataFrame (x :*: y :*: Z))+  = comparisons (Partial.ProductOrd x) (Partial.ProductOrd y)+prop_comparisonsPPOrdDouble :: SomeDataFrame '[Double, Double] -> Property+prop_comparisonsPPOrdDouble (SomeDataFrame (x :*: y :*: Z))+  = comparisons (Partial.ProductOrd x) (Partial.ProductOrd y)+prop_comparisonsPPOrdInt :: SomeDataFrame '[Int, Int] -> Property+prop_comparisonsPPOrdInt (SomeDataFrame (x :*: y :*: Z))+  = comparisons (Partial.ProductOrd x) (Partial.ProductOrd y)+++prop_comparisonsNTPOrdFloat :: SomeDataFrame '[Float, Float] -> Property+prop_comparisonsNTPOrdFloat (SomeDataFrame (x :*: y :*: Z))+  = comparisons (NonTransitive.ProductOrd x) (NonTransitive.ProductOrd y)+prop_comparisonsNTPOrdDouble :: SomeDataFrame '[Double, Double] -> Property+prop_comparisonsNTPOrdDouble (SomeDataFrame (x :*: y :*: Z))+  = comparisons (NonTransitive.ProductOrd x) (NonTransitive.ProductOrd y)+prop_comparisonsNTPOrdInt :: SomeDataFrame '[Int, Int] -> Property+prop_comparisonsNTPOrdInt (SomeDataFrame (x :*: y :*: Z))+  = comparisons (NonTransitive.ProductOrd x) (NonTransitive.ProductOrd y)++ prop_Numeric :: SomeDataFrame '[Int, Int] -> Bool prop_Numeric (SomeDataFrame (x :*: y :*: Z))-  | E <- inferOrd x-  , E <- inferNum x   = and     [ x + x == 2 * x     , x + y == y + x@@ -70,9 +144,7 @@  prop_Floating :: SomeDataFrame '[Double, Double] -> Bool prop_Floating (SomeDataFrame (x :*: y :*: Z))-  | E <- inferOrd x-  , E <- inferFloating x-  , lx <- log (0.01 + abs x)+  | lx <- log (0.01 + abs x)   , ly <- log (0.01 + abs y)   , eps <- 0.001   = all ((eps >=) . abs)@@ -85,5 +157,6 @@   return []-runTests :: IO Bool-runTests = $quickCheckAll+runTests :: Int -> IO Bool+runTests n = $forAllProperties+  $ quickCheckWithResult stdArgs { maxSuccess = n }
test/Numeric/DataFrame/SubSpaceTest.hs view
@@ -8,10 +8,10 @@  module Numeric.DataFrame.SubSpaceTest (runTests) where -import           Numeric.DataFrame-import           Numeric.DataFrame.Arbitraries ()-import           Numeric.Dimensions-import           Test.QuickCheck+import Numeric.DataFrame+import Numeric.DataFrame.Arbitraries ()+import Numeric.Dimensions+import Test.QuickCheck  type SFull = '[2,5,4,3,7] type SPref = '[2,5,4]@@ -19,31 +19,31 @@  prop_IndexDimMax :: DataFrame Int SPref -> DataFrame Int SSuff -> Bool prop_IndexDimMax x y =-   ((maxBound `inSpaceOf` y) !. z) == x+   (z ! (maxBound `inSpaceOf` x)) == y   where-    z = ewgen x :: DataFrame Int SFull+    z = ewgen y :: DataFrame Int SFull -prop_IndexCustom1 :: DataFrame Word SPref -> Bool-prop_IndexCustom1 x = (1:*3 !. z) == x+prop_IndexCustom1 :: DataFrame Word SSuff -> Bool+prop_IndexCustom1 x = (z ! 1:*3:*2) == x   where     z = ewgen x :: DataFrame Word SFull --prop_IndexCustom2 :: DataFrame Double SPref -> Bool-prop_IndexCustom2 x = (2:*2 !. z) %* eye == x-  where-    z = ewgen x :: DataFrame Double SFull+-- TODO:!+-- prop_IndexCustom2 :: DataFrame Double SSuff -> Bool+-- prop_IndexCustom2 x = (z ! 2:*2:*1) %* eye == x+--   where+--     z = ewgen x :: DataFrame Double SFull -prop_Foldlr :: DataFrame Double SPref -> Bool+prop_Foldlr :: DataFrame Double SSuff -> Bool prop_Foldlr x =     abs (ewfoldl (+) 10 z - ewfoldr @_ @SPref (+) 0 z - 10)       <= fromScalar (zmax * 0.0001)   where     z = ewgen x :: DataFrame Double SFull-    zmax = ewfoldl @Double @'[] @SFull (max . abs) 0.001 z+    zmax = ewfoldl @Double @SFull @'[] (max . abs) 0.001 z  prop_Ewmap :: DataFrame Double SFull -> Bool-prop_Ewmap x = x * 2 == ewmap @_ @'[Head SFull] (*2) x+prop_Ewmap x = x * 2 == ewmap @_  @_ @'[Last SFull] (*2) x  prop_ProdTranspose :: DataFrame Double '[2,6] -> DataFrame Double '[6,7] -> Bool prop_ProdTranspose x y = transpose (x %* y) == transpose y %* transpose x@@ -52,5 +52,6 @@ prop_Eye x = eye %* x == x && x %* eye == x  return []-runTests :: IO Bool-runTests = $quickCheckAll+runTests :: Int -> IO Bool+runTests n = $forAllProperties+  $ quickCheckWithResult stdArgs { maxSuccess = n }
test/Numeric/MatrixDoubleTest.hs view
@@ -10,146 +10,161 @@ module Numeric.MatrixDoubleTest (runTests) where  -import           Data.Fixed-import           Numeric.DataFrame-import           Numeric.DataFrame.Arbitraries ()-import           Numeric.DataFrame.Internal.Array.Class-import           Numeric.Dimensions-import           Numeric.PrimBytes-import           Test.QuickCheck+import Data.Fixed+import Data.Semigroup+import Numeric.DataFrame+import Numeric.DataFrame.Arbitraries+import Numeric.Dimensions+import Test.QuickCheck -eps :: Scd-eps = 0.0000001+type TestElem = Double+type TestDF = DataFrame TestElem -dropW :: (SubSpace t '[] '[3] '[3], SubSpace t '[] '[4] '[4]) => Vector t 4 -> Vector t 3-dropW v | (x,y,z,_) <- unpackV4 v = vec3 x y z+eps :: Scalar TestElem+eps = 0.000000001 +dropW :: (SubSpace t '[3] '[] '[3], SubSpace t '[4] '[] '[4])+      => Vector t 4 -> Vector t 3+dropW (Vec4 x y z _) = Vec3 x y z++-- | Most of the time, the error is proportional to the maginutude of the biggest element+maxElem :: (SubSpace TestElem ds '[] ds)+        => TestDF (ds :: [Nat]) -> Scalar TestElem+maxElem = ewfoldl (\a -> max a . abs) 0++-- | For operations like @det@, the error is proportional to maximum possible product+--   over rows or columns+maxRows :: forall ds+         . (SubSpace TestElem '[Head ds] (Tail ds) ds)+        => TestDF (ds :: [Nat]) -> Scalar TestElem+maxRows = getProduct . ewfoldMap @_ @'[Head ds] @(Tail ds) @ds (Product . maxElem)+ approxEq ::-  forall (ds :: [Nat]).+  forall (ds :: [Nat]) .   (     Dimensions ds,-    Num (DataFrame Double ds),-    PrimBytes (DataFrame Double ds),-    PrimArray Double (DataFrame Double ds)+    Num (TestDF ds),+    PrimBytes (TestDF ds),+    PrimArray TestElem (TestDF ds)   ) =>-  DataFrame Double ds -> DataFrame Double ds -> Bool-approxEq a b = (eps >=) . ewfoldl @_ @'[] max 0 . abs $ a - b+  TestDF ds -> TestDF ds -> Bool+approxEq a b = maxElem (a - b) <= eps * m+  where+    m = maxElem a `max` maxElem b infix 4 `approxEq` -prop_detTranspose :: Matrix '[Double, Double] (XN 2) (XN 2) -> Bool-prop_detTranspose (XFrame (x :*: y :*: Z))-  | -- infer KnownDim for both dimensions of matrix x (and y)-    KnownDims <- dims `inSpaceOf` x-  = let m = diag (ewfoldl max 0 $ abs x) + x %* transpose y-        a = det m+prop_detTranspose :: SomeSquareMatrix AnyMatrix TestElem -> Property+prop_detTranspose (SSM m)+  = let a = det m         b = det $ transpose m-    in abs (a - b) / (abs a + abs b + 1) <= eps+        n = (case dims `inSpaceOf` m of dn :* _ -> dimVal dn) :: Word+        mag = eps * maxRows m * fromIntegral (product [1..n])+    in  counterexample+          (unlines+            [ "failed det/transpose:"+            , "m:  " ++ show m+            , "mT: " ++ show (transpose m)+            , show a ++ " /= " ++ show b+              ++ " (tolerance: " ++ show mag ++ ")."+            ]+          ) $ abs (a - b) <= mag -prop_inverse :: Matrix '[Double, Double] (XN 2) (XN 2) -> Bool-prop_inverse (XFrame (x :*: y :*: Z))-  | -- infer KnownDim for both dimensions of matrix x (and y)-    (KnownDims :: Dims ns) <- dims `inSpaceOf` x-    -- cumbersose inverse instance requires PrimBytes (Vector t n)-  , E <- inferASing' @Double @'[Head ns]-  , E <- inferPrim' @Double @'[Head ns]-  = let m = diag base + x %* transpose y-        mi = inverse m-        err a b = ewfoldl max 0 (abs (b - a)) / base-        base = ewfoldl max 0.5 (abs x) + ewfoldl max 0.5 (abs y)-    in   err eye (m %* mi) <= eps-      && err eye (mi %* m) <= eps+prop_inverse :: SomeSquareMatrix NonSingular TestElem -> Property+prop_inverse (SSM m)+  = let mi = inverse m+        aeq a b = maxElem (b - a) <= eps * maxRows m+    in  counterexample ("failed inverse:" +++                            show (m, mi, m %* mi, mi %* m)) $+         aeq eye (m %* mi) && aeq eye (mi %* m) -prop_LU :: Matrix '[Double, Double] (XN 2) (XN 2) -> Bool-prop_LU (XFrame (x :*: y :*: Z))-  | -- infer KnownDim for both dimensions of matrix x (and y)-    (KnownDims :: Dims ns) <- dims `inSpaceOf` x-    -- cumbersose inverse instance requires PrimBytes (Vector t n)-  , E <- inferASing' @Double @'[Head ns]-  , E <- inferPrim' @Double @'[Head ns]-  = let m = diag base + x %* transpose y-        f = lu m-        err a b = ewfoldl max 0 (abs (b - a)) / base-        base = ewfoldl max 0.5 (abs x) + ewfoldl max 0.5 (abs y)-    in err (luPerm f %* m) (luLower f %* luUpper f) <= eps+prop_LU :: SomeSquareMatrix NonSingular TestElem -> Bool+prop_LU (SSM m)+  = let f = lu m+        aeq a b = maxElem (b - a) <= eps * maxRows m+    in aeq (luPerm f %* m) (luLower f %* luUpper f) -prop_translate3vs4 :: Vector Double 4 -> Bool+prop_translate3vs4 :: Vector TestElem 4 -> Bool prop_translate3vs4 v = translate4 v == translate3 (dropW v)-  -prop_translate4 :: Vector Double 4 -> Vector Double 3 -> Bool-prop_translate4 a b = translate4 a %* toHomPoint b == toHomPoint (dropW a + b) -prop_translate3 :: Vector Double 3 -> Vector Double 3 -> Bool-prop_translate3 a b = translate3 a %* toHomPoint b == toHomPoint (a + b)+prop_translate4 :: Vector TestElem 4 -> Vector TestElem 3 -> Bool+prop_translate4 a b = toHomPoint b %* translate4 a == toHomPoint (dropW a + b) -prop_rotateX :: Vector Double 4 -> Bool-prop_rotateX v | (x,y,z,w) <- unpackV4 v =-  and [-    rotateX (-2 * pi)   %* v `approxEq` v,-    rotateX (-1.5 * pi) %* v `approxEq` vec4 x (-z) y w,-    rotateX (-pi)       %* v `approxEq` vec4 x (-y) (-z) w,-    rotateX (-0.5 * pi) %* v `approxEq` vec4 x z (-y) w,-    rotateX 0           %* v `approxEq` v,-    rotateX (0.5 * pi)  %* v `approxEq` vec4 x (-z) y w,-    rotateX pi          %* v `approxEq` vec4 x (-y) (-z) w,-    rotateX (1.5 * pi)  %* v `approxEq` vec4 x z (-y) w,-    rotateX (2 * pi)    %* v `approxEq` v+prop_translate3 :: Vector TestElem 3 -> Vector TestElem 3 -> Bool+prop_translate3 a b = toHomPoint b %* translate3 a == toHomPoint (a + b)++prop_rotateX :: Vector TestElem 4 -> Property+prop_rotateX v@(Vec4 x y z w) =+  conjoin [+    v %* rotateX (-2 * pi)   `approxEq` v,+    v %* rotateX (-1.5 * pi) `approxEq` vec4 x (-z) y w,+    v %* rotateX (-pi)       `approxEq` vec4 x (-y) (-z) w,+    v %* rotateX (-0.5 * pi) `approxEq` vec4 x z (-y) w,+    v %* rotateX 0           `approxEq` v,+    v %* rotateX (0.5 * pi)  `approxEq` vec4 x (-z) y w,+    v %* rotateX pi          `approxEq` vec4 x (-y) (-z) w,+    v %* rotateX (1.5 * pi)  `approxEq` vec4 x z (-y) w,+    v %* rotateX (2 * pi)    `approxEq` v   ] -prop_rotateY :: Vector Double 4 -> Bool-prop_rotateY v | (x,y,z,w) <- unpackV4 v =-  and [-    rotateY (-2 * pi)   %* v `approxEq` v,-    rotateY (-1.5 * pi) %* v `approxEq` vec4 z y (-x) w,-    rotateY (-pi)       %* v `approxEq` vec4 (-x) y (-z) w,-    rotateY (-0.5 * pi) %* v `approxEq` vec4 (-z) y x w,-    rotateY 0           %* v `approxEq` v,-    rotateY (0.5 * pi)  %* v `approxEq` vec4 z y (-x) w,-    rotateY pi          %* v `approxEq` vec4 (-x) y (-z) w,-    rotateY (1.5 * pi)  %* v `approxEq` vec4 (-z) y x w,-    rotateY (2 * pi)    %* v `approxEq` v+prop_rotateY :: Vector TestElem 4 -> Property+prop_rotateY v@(Vec4 x y z w) =+  conjoin [+    v %* rotateY (-2 * pi)   `approxEq` v,+    v %* rotateY (-1.5 * pi) `approxEq` vec4 z y (-x) w,+    v %* rotateY (-pi)       `approxEq` vec4 (-x) y (-z) w,+    v %* rotateY (-0.5 * pi) `approxEq` vec4 (-z) y x w,+    v %* rotateY 0           `approxEq` v,+    v %* rotateY (0.5 * pi)  `approxEq` vec4 z y (-x) w,+    v %* rotateY pi          `approxEq` vec4 (-x) y (-z) w,+    v %* rotateY (1.5 * pi)  `approxEq` vec4 (-z) y x w,+    v %* rotateY (2 * pi)    `approxEq` v   ] -prop_rotateZ :: Vector Double 4 -> Bool-prop_rotateZ v | (x,y,z,w) <- unpackV4 v =-  and [-    rotateZ (-2 * pi)   %* v `approxEq` v,-    rotateZ (-1.5 * pi) %* v `approxEq` vec4 (-y) x z w,-    rotateZ (-pi)       %* v `approxEq` vec4 (-x) (-y) z w,-    rotateZ (-0.5 * pi) %* v `approxEq` vec4 y (-x) z w,-    rotateZ 0           %* v `approxEq` v,-    rotateZ (0.5 * pi)  %* v `approxEq` vec4 (-y) x z w,-    rotateZ pi          %* v `approxEq` vec4 (-x) (-y) z w,-    rotateZ (1.5 * pi)  %* v `approxEq` vec4 y (-x) z w,-    rotateZ (2 * pi)    %* v `approxEq` v+prop_rotateZ :: Vector TestElem 4 -> Property+prop_rotateZ v@(Vec4 x y z w) =+  conjoin [+    v %* rotateZ (-2 * pi)   `approxEq` v,+    v %* rotateZ (-1.5 * pi) `approxEq` vec4 (-y) x z w,+    v %* rotateZ (-pi)       `approxEq` vec4 (-x) (-y) z w,+    v %* rotateZ (-0.5 * pi) `approxEq` vec4 y (-x) z w,+    v %* rotateZ 0           `approxEq` v,+    v %* rotateZ (0.5 * pi)  `approxEq` vec4 (-y) x z w,+    v %* rotateZ pi          `approxEq` vec4 (-x) (-y) z w,+    v %* rotateZ (1.5 * pi)  `approxEq` vec4 y (-x) z w,+    v %* rotateZ (2 * pi)    `approxEq` v   ] -prop_rotate :: Double -> Bool+prop_rotate :: TestElem -> Property prop_rotate a =-  and [+  conjoin [     rotate (vec3 1 0 0) a `approxEq` rotateX a,     rotate (vec3 0 1 0) a `approxEq` rotateY a,     rotate (vec3 0 0 1) a `approxEq` rotateZ a   ] -prop_rotateEuler :: Double -> Double -> Double -> Bool-prop_rotateEuler pitch yaw roll = rotateEuler pitch yaw roll `approxEq` rotateX pitch %* rotateY yaw %* rotateZ roll+prop_rotateEuler :: TestElem -> TestElem -> TestElem -> Bool+prop_rotateEuler pitch yaw roll =+  rotateEuler pitch yaw roll `approxEq` rotateZ roll %* rotateY yaw %* rotateX pitch -prop_lookAt :: Vector Double 3 -> Vector Double 3 -> Vector Double 3 -> Bool+prop_lookAt :: Vector TestElem 3 -> Vector TestElem 3 -> Vector TestElem 3 -> Property prop_lookAt up cam foc =-  and [-    (normalized . fromHom $ m %* toHomPoint foc) `approxEq` vec3 0 0 (-1),-    fromHom (m %* toHomPoint cam) `approxEq` 0,-    fromHom (m %* toHomVector xb) `approxEq` vec3 1 0 0,-    fromHom (m %* toHomVector yb) `approxEq` vec3 0 1 0,-    fromHom (m %* toHomVector zb) `approxEq` vec3 0 0 1+  (apart cam foc && apart up cam) ==>+  conjoin [+    (normalized . fromHom $ toHomPoint foc %* m) `approxEq` vec3 0 0 (-1),+    fromHom (toHomPoint cam %* m) `approxEq` 0,+    fromHom (toHomVector xb %* m) `approxEq` vec3 1 0 0,+    fromHom (toHomVector yb %* m) `approxEq` vec3 0 1 0,+    fromHom (toHomVector zb %* m) `approxEq` vec3 0 0 1   ]   where+    apart :: Vector TestElem 3 -> Vector TestElem 3 -> Bool+    apart a b = maxElem (a - b) > 0.01 * (maxElem a `max` maxElem b)     m = lookAt up cam foc     zb = normalized $ cam - foc     xb = normalized $ up `cross` zb     yb = zb `cross` xb -prop_perspective :: Double -> Double -> Double -> Double -> Bool+prop_perspective :: TestElem -> TestElem -> TestElem -> TestElem -> Bool prop_perspective a b c d =   and [     projectTo 0 0 n       `approxEq` vec3 0 0 (-1),@@ -171,9 +186,9 @@     hpd = tan (fovy * 0.5) -- height/distance     wpd = aspect * hpd -- width/distance     m = perspective n f fovy aspect-    projectTo x' y' z = fromHom $ m %* vec4 (x' * wpd * z) (y' * hpd * z) (-z) 1+    projectTo x' y' z = fromHom $ vec4 (x' * wpd * z) (y' * hpd * z) (-z) 1 %* m -prop_orthogonal :: Double -> Double -> Double -> Double -> Bool+prop_orthogonal :: TestElem -> TestElem -> TestElem -> TestElem -> Bool prop_orthogonal a b c d =   and [     projectTo 0 0 n       `approxEq` vec3 0 0 (-1),@@ -193,20 +208,21 @@     w = 1.0 + mod' c 9999.0 -- Width in range [1, 10000)     h = 1.0 + mod' d 9999.0 -- Height in range [1, 10000)     m = orthogonal n f w h-    projectTo x' y' z = fromHom $ m %* vec4 (x' * w * 0.5) (y' * h * 0.5) (-z) 1+    projectTo x' y' z = fromHom $ vec4 (x' * w * 0.5) (y' * h * 0.5) (-z) 1 %* m -prop_toHomPoint :: Vector Double 3 -> Bool-prop_toHomPoint v | (x,y,z) <- unpackV3 v = toHomPoint v == vec4 x y z 1+prop_toHomPoint :: Vector TestElem 3 -> Bool+prop_toHomPoint v@(Vec3 x y z) = toHomPoint v == vec4 x y z 1 -prop_toHomVector :: Vector Double 3 -> Bool-prop_toHomVector v | (x,y,z) <- unpackV3 v = toHomVector v == vec4 x y z 0+prop_toHomVector :: Vector TestElem 3 -> Bool+prop_toHomVector v@(Vec3 x y z) = toHomVector v == vec4 x y z 0 -prop_fromHom :: Vector Double 4 -> Bool-prop_fromHom v | (x,y,z,w) <- unpackV4 v =+prop_fromHom :: Vector TestElem 4 -> Bool+prop_fromHom v@(Vec4 x y z w) =   case w of     0 -> fromHom v == vec3 x y z     _ -> fromHom v `approxEq` vec3 (x/w) (y/w) (z/w)  return []-runTests :: IO Bool-runTests = $quickCheckAll+runTests :: Int -> IO Bool+runTests n = $forAllProperties+  $ quickCheckWithResult stdArgs { maxSuccess = n }
test/Numeric/MatrixFloatTest.hs view
@@ -10,146 +10,167 @@ module Numeric.MatrixFloatTest (runTests) where  -import           Data.Fixed-import           Numeric.DataFrame-import           Numeric.DataFrame.Arbitraries ()-import           Numeric.DataFrame.Internal.Array.Class-import           Numeric.Dimensions-import           Numeric.PrimBytes-import           Test.QuickCheck+import Data.Fixed+import Data.Semigroup+import Numeric.DataFrame+import Numeric.DataFrame.Arbitraries+import Numeric.Dimensions+import Test.QuickCheck -eps :: Scf-eps = 0.01+type TestElem = Float+type TestDF = DataFrame TestElem -dropW :: (SubSpace t '[] '[3] '[3], SubSpace t '[] '[4] '[4]) => Vector t 4 -> Vector t 3-dropW v | (x,y,z,_) <- unpackV4 v = vec3 x y z+eps :: Scalar TestElem+eps = 0.00001 +dropW :: (SubSpace t '[3] '[] '[3], SubSpace t '[4] '[] '[4])+      => Vector t 4 -> Vector t 3+dropW (Vec4 x y z _) = Vec3 x y z++-- | Most of the time, the error is proportional to the maginutude of the biggest element+maxElem :: (SubSpace TestElem ds '[] ds)+        => TestDF (ds :: [Nat]) -> Scalar TestElem+maxElem = ewfoldl (\a -> max a . abs) 0++-- | For operations like @det@, the error is proportional to maximum possible product+--   over rows or columns+maxRows :: forall ds+         . (SubSpace TestElem '[Head ds] (Tail ds) ds)+        => TestDF (ds :: [Nat]) -> Scalar TestElem+maxRows = getProduct . ewfoldMap @_ @'[Head ds] @(Tail ds) @ds (Product . maxElem)+ approxEq ::-  forall (ds :: [Nat]).+  forall (ds :: [Nat]) .   (     Dimensions ds,-    Num (DataFrame Float ds),-    PrimBytes (DataFrame Float ds),-    PrimArray Float (DataFrame Float ds)+    Num (TestDF ds),+    PrimBytes (TestDF ds),+    PrimArray TestElem (TestDF ds)   ) =>-  DataFrame Float ds -> DataFrame Float ds -> Bool-approxEq a b = (eps >=) . ewfoldl @_ @'[] max 0 . abs $ a - b+  TestDF ds -> TestDF ds -> Bool+approxEq a b = maxElem (a - b) <= eps * m+  where+    m = maxElem a `max` maxElem b infix 4 `approxEq` -prop_detTranspose :: Matrix '[Float, Float] (XN 2) (XN 2) -> Bool-prop_detTranspose (XFrame (x :*: y :*: Z))-  | -- infer KnownDim for both dimensions of matrix x (and y)-    KnownDims <- dims `inSpaceOf` x-  = let m = diag (ewfoldl max 0 $ abs x) + x %* transpose y-        a = det m+prop_detTranspose :: SomeSquareMatrix AnyMatrix TestElem -> Property+prop_detTranspose (SSM m)+  = let a = det m         b = det $ transpose m-    in abs (a - b) / (abs a + abs b + 1) <= eps+        n = (case dims `inSpaceOf` m of dn :* _ -> dimVal dn) :: Word+        mag = eps * maxRows m * fromIntegral (product [1..n])+    in  counterexample+          (unlines+            [ "failed det/transpose:"+            , "m:  " ++ show m+            , "mT: " ++ show (transpose m)+            , show a ++ " /= " ++ show b+              ++ " (tolerance: " ++ show mag ++ ")."+            ]+          ) $ abs (a - b) <= mag -prop_inverse :: Matrix '[Float, Float] (XN 2) (XN 2) -> Bool-prop_inverse (XFrame (x :*: y :*: Z))-  | -- infer KnownDim for both dimensions of matrix x (and y)-    (KnownDims :: Dims ns) <- dims `inSpaceOf` x-    -- cumbersose inverse instance requires PrimBytes (Vector t n)-  , E <- inferASing' @Float @'[Head ns]-  , E <- inferPrim' @Float @'[Head ns]-  = let m = diag base + x %* transpose y-        mi = inverse m-        err a b = ewfoldl max 0 (abs (b - a)) / base-        base = ewfoldl max 0.5 (abs x) + ewfoldl max 0.5 (abs y)-    in   err eye (m %* mi) <= eps-      && err eye (mi %* m) <= eps+prop_inverse :: SomeSquareMatrix NonSingular TestElem -> Property+prop_inverse (SSM m)+  = let mi = inverse m+        aeq a b = maxElem (b - a) <= eps * maxRows m+    in  counterexample ("failed inverse:" +++                            show (m, mi, m %* mi, mi %* m)) $+         aeq eye (m %* mi) && aeq eye (mi %* m) -prop_LU :: Matrix '[Float, Float] (XN 2) (XN 2) -> Bool-prop_LU (XFrame (x :*: y :*: Z))-  | -- infer KnownDim for both dimensions of matrix x (and y)-    (KnownDims :: Dims ns) <- dims `inSpaceOf` x-    -- cumbersose inverse instance requires PrimBytes (Vector t n)-  , E <- inferASing' @Float @'[Head ns]-  , E <- inferPrim' @Float @'[Head ns]-  = let m = diag base + x %* transpose y-        f = lu m-        err a b = ewfoldl max 0 (abs (b - a)) / base-        base = ewfoldl max 0.5 (abs x) + ewfoldl max 0.5 (abs y)-    in err (luPerm f %* m) (luLower f %* luUpper f) <= eps+-- TODO: improve lu!+-- lu factorization is very unstable in some cases+--+-- >>> m = unsafeFromFlatList (Dims @'[4,4]) 0 [1,0,1,-2, 0,-1,1,2, 2,-4,2,-2, 4,-8,-2,2 ] :: Mat44f+-- >>> det m == 0+-- >>> det (transpose m) == 60+prop_LU :: SomeSquareMatrix NonSingular TestElem -> Bool+prop_LU (SSM m)+  = let f = lu m+        aeq a b = maxElem (b - a) <= eps * maxRows m+    in aeq (luPerm f %* m) (luLower f %* luUpper f) -prop_translate3vs4 :: Vector Float 4 -> Bool+prop_translate3vs4 :: Vector TestElem 4 -> Bool prop_translate3vs4 v = translate4 v == translate3 (dropW v)-  -prop_translate4 :: Vector Float 4 -> Vector Float 3 -> Bool-prop_translate4 a b = translate4 a %* toHomPoint b == toHomPoint (dropW a + b) -prop_translate3 :: Vector Float 3 -> Vector Float 3 -> Bool-prop_translate3 a b = translate3 a %* toHomPoint b == toHomPoint (a + b)+prop_translate4 :: Vector TestElem 4 -> Vector TestElem 3 -> Bool+prop_translate4 a b = toHomPoint b %* translate4 a == toHomPoint (dropW a + b) -prop_rotateX :: Vector Float 4 -> Bool-prop_rotateX v | (x,y,z,w) <- unpackV4 v =-  and [-    rotateX (-2 * pi)   %* v `approxEq` v,-    rotateX (-1.5 * pi) %* v `approxEq` vec4 x (-z) y w,-    rotateX (-pi)       %* v `approxEq` vec4 x (-y) (-z) w,-    rotateX (-0.5 * pi) %* v `approxEq` vec4 x z (-y) w,-    rotateX 0           %* v `approxEq` v,-    rotateX (0.5 * pi)  %* v `approxEq` vec4 x (-z) y w,-    rotateX pi          %* v `approxEq` vec4 x (-y) (-z) w,-    rotateX (1.5 * pi)  %* v `approxEq` vec4 x z (-y) w,-    rotateX (2 * pi)    %* v `approxEq` v+prop_translate3 :: Vector TestElem 3 -> Vector TestElem 3 -> Bool+prop_translate3 a b = toHomPoint b %* translate3 a == toHomPoint (a + b)++prop_rotateX :: Vector TestElem 4 -> Property+prop_rotateX v@(Vec4 x y z w) =+  conjoin [+    v %* rotateX (-2 * pi)   `approxEq` v,+    v %* rotateX (-1.5 * pi) `approxEq` vec4 x (-z) y w,+    v %* rotateX (-pi)       `approxEq` vec4 x (-y) (-z) w,+    v %* rotateX (-0.5 * pi) `approxEq` vec4 x z (-y) w,+    v %* rotateX 0           `approxEq` v,+    v %* rotateX (0.5 * pi)  `approxEq` vec4 x (-z) y w,+    v %* rotateX pi          `approxEq` vec4 x (-y) (-z) w,+    v %* rotateX (1.5 * pi)  `approxEq` vec4 x z (-y) w,+    v %* rotateX (2 * pi)    `approxEq` v   ] -prop_rotateY :: Vector Float 4 -> Bool-prop_rotateY v | (x,y,z,w) <- unpackV4 v =-  and [-    rotateY (-2 * pi)   %* v `approxEq` v,-    rotateY (-1.5 * pi) %* v `approxEq` vec4 z y (-x) w,-    rotateY (-pi)       %* v `approxEq` vec4 (-x) y (-z) w,-    rotateY (-0.5 * pi) %* v `approxEq` vec4 (-z) y x w,-    rotateY 0           %* v `approxEq` v,-    rotateY (0.5 * pi)  %* v `approxEq` vec4 z y (-x) w,-    rotateY pi          %* v `approxEq` vec4 (-x) y (-z) w,-    rotateY (1.5 * pi)  %* v `approxEq` vec4 (-z) y x w,-    rotateY (2 * pi)    %* v `approxEq` v+prop_rotateY :: Vector TestElem 4 -> Property+prop_rotateY v@(Vec4 x y z w) =+  conjoin [+    v %* rotateY (-2 * pi)   `approxEq` v,+    v %* rotateY (-1.5 * pi) `approxEq` vec4 z y (-x) w,+    v %* rotateY (-pi)       `approxEq` vec4 (-x) y (-z) w,+    v %* rotateY (-0.5 * pi) `approxEq` vec4 (-z) y x w,+    v %* rotateY 0           `approxEq` v,+    v %* rotateY (0.5 * pi)  `approxEq` vec4 z y (-x) w,+    v %* rotateY pi          `approxEq` vec4 (-x) y (-z) w,+    v %* rotateY (1.5 * pi)  `approxEq` vec4 (-z) y x w,+    v %* rotateY (2 * pi)    `approxEq` v   ] -prop_rotateZ :: Vector Float 4 -> Bool-prop_rotateZ v | (x,y,z,w) <- unpackV4 v =-  and [-    rotateZ (-2 * pi)   %* v `approxEq` v,-    rotateZ (-1.5 * pi) %* v `approxEq` vec4 (-y) x z w,-    rotateZ (-pi)       %* v `approxEq` vec4 (-x) (-y) z w,-    rotateZ (-0.5 * pi) %* v `approxEq` vec4 y (-x) z w,-    rotateZ 0           %* v `approxEq` v,-    rotateZ (0.5 * pi)  %* v `approxEq` vec4 (-y) x z w,-    rotateZ pi          %* v `approxEq` vec4 (-x) (-y) z w,-    rotateZ (1.5 * pi)  %* v `approxEq` vec4 y (-x) z w,-    rotateZ (2 * pi)    %* v `approxEq` v+prop_rotateZ :: Vector TestElem 4 -> Property+prop_rotateZ v@(Vec4 x y z w) =+  conjoin [+    v %* rotateZ (-2 * pi)   `approxEq` v,+    v %* rotateZ (-1.5 * pi) `approxEq` vec4 (-y) x z w,+    v %* rotateZ (-pi)       `approxEq` vec4 (-x) (-y) z w,+    v %* rotateZ (-0.5 * pi) `approxEq` vec4 y (-x) z w,+    v %* rotateZ 0           `approxEq` v,+    v %* rotateZ (0.5 * pi)  `approxEq` vec4 (-y) x z w,+    v %* rotateZ pi          `approxEq` vec4 (-x) (-y) z w,+    v %* rotateZ (1.5 * pi)  `approxEq` vec4 y (-x) z w,+    v %* rotateZ (2 * pi)    `approxEq` v   ] -prop_rotate :: Float -> Bool+prop_rotate :: TestElem -> Property prop_rotate a =-  and [+  conjoin [     rotate (vec3 1 0 0) a `approxEq` rotateX a,     rotate (vec3 0 1 0) a `approxEq` rotateY a,     rotate (vec3 0 0 1) a `approxEq` rotateZ a   ] -prop_rotateEuler :: Float -> Float -> Float -> Bool-prop_rotateEuler pitch yaw roll = rotateEuler pitch yaw roll `approxEq` rotateX pitch %* rotateY yaw %* rotateZ roll+prop_rotateEuler :: TestElem -> TestElem -> TestElem -> Bool+prop_rotateEuler pitch yaw roll =+  rotateEuler pitch yaw roll `approxEq` rotateZ roll %* rotateY yaw %* rotateX pitch -prop_lookAt :: Vector Float 3 -> Vector Float 3 -> Vector Float 3 -> Bool+prop_lookAt :: Vector TestElem 3 -> Vector TestElem 3 -> Vector TestElem 3 -> Property prop_lookAt up cam foc =-  and [-    (normalized . fromHom $ m %* toHomPoint foc) `approxEq` vec3 0 0 (-1),-    fromHom (m %* toHomPoint cam) `approxEq` 0,-    fromHom (m %* toHomVector xb) `approxEq` vec3 1 0 0,-    fromHom (m %* toHomVector yb) `approxEq` vec3 0 1 0,-    fromHom (m %* toHomVector zb) `approxEq` vec3 0 0 1+  (apart cam foc && apart up cam) ==>+  conjoin [+    (normalized . fromHom $ toHomPoint foc %* m) `approxEq` vec3 0 0 (-1),+    fromHom (toHomPoint cam %* m) `approxEq` 0,+    fromHom (toHomVector xb %* m) `approxEq` vec3 1 0 0,+    fromHom (toHomVector yb %* m) `approxEq` vec3 0 1 0,+    fromHom (toHomVector zb %* m) `approxEq` vec3 0 0 1   ]   where+    apart :: Vector TestElem 3 -> Vector TestElem 3 -> Bool+    apart a b = maxElem (a - b) > 0.01 * (maxElem a `max` maxElem b)     m = lookAt up cam foc     zb = normalized $ cam - foc     xb = normalized $ up `cross` zb     yb = zb `cross` xb -prop_perspective :: Float -> Float -> Float -> Float -> Bool+prop_perspective :: TestElem -> TestElem -> TestElem -> TestElem -> Bool prop_perspective a b c d =   and [     projectTo 0 0 n       `approxEq` vec3 0 0 (-1),@@ -171,9 +192,9 @@     hpd = tan (fovy * 0.5) -- height/distance     wpd = aspect * hpd -- width/distance     m = perspective n f fovy aspect-    projectTo x' y' z = fromHom $ m %* vec4 (x' * wpd * z) (y' * hpd * z) (-z) 1+    projectTo x' y' z = fromHom $ vec4 (x' * wpd * z) (y' * hpd * z) (-z) 1 %* m -prop_orthogonal :: Float -> Float -> Float -> Float -> Bool+prop_orthogonal :: TestElem -> TestElem -> TestElem -> TestElem -> Bool prop_orthogonal a b c d =   and [     projectTo 0 0 n       `approxEq` vec3 0 0 (-1),@@ -193,20 +214,21 @@     w = 1.0 + mod' c 9999.0 -- Width in range [1, 10000)     h = 1.0 + mod' d 9999.0 -- Height in range [1, 10000)     m = orthogonal n f w h-    projectTo x' y' z = fromHom $ m %* vec4 (x' * w * 0.5) (y' * h * 0.5) (-z) 1+    projectTo x' y' z = fromHom $ vec4 (x' * w * 0.5) (y' * h * 0.5) (-z) 1 %* m -prop_toHomPoint :: Vector Float 3 -> Bool-prop_toHomPoint v | (x,y,z) <- unpackV3 v = toHomPoint v == vec4 x y z 1+prop_toHomPoint :: Vector TestElem 3 -> Bool+prop_toHomPoint v@(Vec3 x y z) = toHomPoint v == vec4 x y z 1 -prop_toHomVector :: Vector Float 3 -> Bool-prop_toHomVector v | (x,y,z) <- unpackV3 v = toHomVector v == vec4 x y z 0+prop_toHomVector :: Vector TestElem 3 -> Bool+prop_toHomVector v@(Vec3 x y z) = toHomVector v == vec4 x y z 0 -prop_fromHom :: Vector Float 4 -> Bool-prop_fromHom v | (x,y,z,w) <- unpackV4 v =+prop_fromHom :: Vector TestElem 4 -> Bool+prop_fromHom v@(Vec4 x y z w) =   case w of     0 -> fromHom v == vec3 x y z     _ -> fromHom v `approxEq` vec3 (x/w) (y/w) (z/w)  return []-runTests :: IO Bool-runTests = $quickCheckAll+runTests :: Int -> IO Bool+runTests n = $forAllProperties+  $ quickCheckWithResult stdArgs { maxSuccess = n }
+ test/Numeric/PrimBytesTest.hs view
@@ -0,0 +1,411 @@+{-# LANGUAGE AllowAmbiguousTypes   #-}+{-# LANGUAGE DataKinds             #-}+{-# LANGUAGE DefaultSignatures     #-}+{-# LANGUAGE DeriveGeneric         #-}+{-# LANGUAGE EmptyDataDeriving     #-}+{-# LANGUAGE FlexibleContexts      #-}+{-# LANGUAGE FlexibleInstances     #-}+{-# LANGUAGE GADTs                 #-}+{-# LANGUAGE InstanceSigs          #-}+{-# LANGUAGE LambdaCase            #-}+{-# LANGUAGE MagicHash             #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE ScopedTypeVariables   #-}+{-# LANGUAGE StandaloneDeriving    #-}+{-# LANGUAGE TemplateHaskell       #-}+{-# LANGUAGE TypeApplications      #-}+{-# LANGUAGE TypeFamilies          #-}+{-# LANGUAGE TypeOperators         #-}+{-# LANGUAGE UnboxedTuples         #-}+module Numeric.PrimBytesTest (runTests) where++import           Data.Int+import           Data.Type.Lits+import           Data.Word+import           Foreign.Marshal+import           Foreign.Ptr+import           Foreign.Storable+import           GHC.Exts+import           GHC.Generics+import           GHC.Word+import           Numeric.DataFrame.Arbitraries ()+import           Numeric.Dimensions+import           Numeric.PrimBytes+import qualified Numeric.Tuple.Lazy            as LT+import qualified Numeric.Tuple.Strict          as ST+import           Spec.Util+import           Test.QuickCheck++data Dummy+  deriving (Generic, Show, Read, Eq, Ord)++data Vertex a b c+  = Vertex+  { pos         :: (a, a, a, a)+  , norm        :: (b, b, b)+  , tex         :: Either (b, b) (c, c, c)+  , extraFloats :: (Float, Double)+  } deriving (Generic, Show, Read, Eq, Ord)++data ManyAlternatives a b c+  = EmptyAlt+  | FirstAlt a b b c+  | SecondAlt a c+  | AltN (Either a b)+  | AltM (Maybe a) (Maybe b) (Maybe c)+  | SecondEmptyAlt+  | SomeWeirdChoice Word8 Word64 Int8 Char Word32 Int16 a+  deriving (Generic, Show, Read, Eq, Ord)++data MyUnboxedType a+  = VeryUnboxed Word# Char# Int# Addr# Float# Double#+  | NotSoUnboxed a a+  | JustABitUnboxed Double# a Char# a+  deriving (Generic, Eq, Ord)++instance Show a => Show (MyUnboxedType a) where+  show (VeryUnboxed w c i a f d)+    = unwords [ "VeryUnboxed", show (W# w), show (I# i)+              , show (C# c), show (Ptr a), show (F# f), show (D# d)]+  show (NotSoUnboxed a b)+    = unwords [ "NotSoUnboxed", show a, show b]+  show (JustABitUnboxed d x c y)+    = unwords [ "JustABitUnboxed ", show (D# d), show x, show (C# c), show y]+++instance (PrimBytes a, PrimBytes b, PrimBytes c)+      => PrimBytes (Vertex a b c)+instance (PrimBytes a, PrimBytes b, PrimBytes c)+      => PrimBytes (ManyAlternatives a b c)+instance (PrimBytes a)+      => PrimBytes (MyUnboxedType a)+instance (PrimBytes a, PrimBytes b, PrimBytes c) => Storable (Vertex a b c) where+    sizeOf = bSizeOf+    alignment = bAlignOf+    peekElemOff = bPeekElemOff+    pokeElemOff = bPokeElemOff+    peekByteOff = bPeekByteOff+    pokeByteOff = bPokeByteOff+    peek = bPeek+    poke = bPoke+instance (PrimBytes a, PrimBytes b, PrimBytes c) => Storable (ManyAlternatives a b c) where+    sizeOf = bSizeOf+    alignment = bAlignOf+    peekElemOff = bPeekElemOff+    pokeElemOff = bPokeElemOff+    peekByteOff = bPeekByteOff+    pokeByteOff = bPokeByteOff+    peek = bPeek+    poke = bPoke+instance PrimBytes a => Storable (MyUnboxedType a) where+    sizeOf = bSizeOf+    alignment = bAlignOf+    peekElemOff = bPeekElemOff+    pokeElemOff = bPokeElemOff+    peekByteOff = bPeekByteOff+    pokeByteOff = bPokeByteOff+    peek = bPeek+    poke = bPoke++instance Arbitrary (Ptr Dummy) where+    arbitrary = intPtrToPtr . IntPtr <$> arbitrary++instance (Arbitrary a, Arbitrary b, Arbitrary c) => Arbitrary (Vertex a b c) where+    arbitrary = Vertex <$> arbitrary <*> arbitrary <*> arbitrary <*> arbitrary++instance (Arbitrary a, Arbitrary b, Arbitrary c) => Arbitrary (ManyAlternatives a b c) where+    arbitrary = choose (1, 7 :: Int) >>= \case+      1 -> pure EmptyAlt+      2 -> FirstAlt <$> arbitrary <*> arbitrary <*> arbitrary <*> arbitrary+      3 -> SecondAlt <$> arbitrary <*> arbitrary+      4 -> AltN <$> arbitrary+      5 -> AltM <$> arbitrary <*> arbitrary <*> arbitrary+      6 -> pure SecondEmptyAlt+      _ -> SomeWeirdChoice <$> arbitrary <*> arbitrary <*> arbitrary <*> arbitrary+                                         <*> arbitrary <*> arbitrary <*> arbitrary++instance Arbitrary a => Arbitrary (MyUnboxedType a) where+    arbitrary = choose (1, 3 :: Int) >>= \case+      1 -> do+        W# w <- arbitrary+        C# c <- arbitrary+        I# i <- arbitrary+        Ptr a <- arbitrary :: Gen (Ptr Dummy)+        F# f <- arbitrary+        D# d <- arbitrary+        return $ VeryUnboxed w c i a f d+      2 -> NotSoUnboxed <$> arbitrary <*> arbitrary+      _ -> do+        C# c <- arbitrary+        D# d <- arbitrary+        x <- arbitrary+        y <- arbitrary+        return $ JustABitUnboxed d x c y++showByteArray :: Int# -> ByteArray# -> [Word8]+showByteArray size ba = go 0#+  where+    go i+      | isTrue# (i <# size) = W8# (indexWord8Array# ba i) : go (i +# 1#)+      | otherwise = []++showMutableByteArray :: Int# -> MutableByteArray# s+                     -> State# s -> (# State# s, [Word8] #)+showMutableByteArray size mba = go 0#+  where+    go i s0+      | isTrue# (i <# size)+      , (# s1, w  #) <- readWord8Array# mba i s0+      , (# s2, ws #) <- go (i +# 1#) s1+                  = (# s2, W8# w : ws #)+      | otherwise = (# s0, [] #)++-- | The most basic property+fromToBytesId :: (PrimBytes a, Eq a, Show a) => a -> Property+fromToBytesId v = counterexample msg $+    v === fromBytes (byteOffset v) bytes+  where+    bytes = getBytes v+    byteList  = showByteArray (byteOffset v +# byteSize v) bytes+    msg = unlines+      [ "byteOffset:    " ++ show (I# (byteOffset v))+      , "byteAlign:     " ++ show (I# (byteAlign v))+      , "byteSize:      " ++ show (I# (byteSize v))+      , "Array content: " ++ show byteList+      ]++-- | Pointers+fromToPtrId :: (PrimBytes a, Eq a, Show a) => a -> Property+fromToPtrId v = ioProperty . allocaBytes (bSizeOf v) $ \ptr -> do+  bPoke ptr v+  v1 <- bPeek ptr+  return (v === v1)++-- | Byte offsets+readWriteBytesId :: (PrimBytes a, Eq a, Show a) => Int -> a -> Property+readWriteBytesId off' v = case runRW# go of (# _, r #) -> r+  where+    -- reasonably small offset aligned to a multiple of @byteAlign v@+    off = case abs off' `mod` 100 of I# i -> i *# byteAlign v+    -- write and read the value from an array by a specified offset+    go :: forall s . State# s -> (# State# s, Property #)+    go s0+      | (# s1, mba #) <- newByteArray# (byteSize v +# off) s0+      , s2            <- writeBytes mba off v s1+      , (# s3, w #)   <- readBytes mba off s2+      , (# s4, byteList #) <- showMutableByteArray (byteSize v +# off) mba s3+      , (# s5, ba #)  <- unsafeFreezeByteArray# mba s4+      , u <- fromBytes off ba+      , msg <- unlines+              [ "Offset 'off':  " ++ show (I# off)+              , "byteOffset:    " ++ show (I# (byteOffset v))+              , "byteAlign:     " ++ show (I# (byteAlign v))+              , "byteSize:      " ++ show (I# (byteSize v))+              , "Array content: " ++ show byteList+              ]+         = (# s5, counterexample msg (v === w .&&. v == u) #)++-- | Elem offsets+readWriteArrayId :: (PrimBytes a, Eq a, Show a) => Int -> Int -> a -> Property+readWriteArrayId n' i' v = case runRW# go of (# _, r #) -> r+  where+    -- allocate reasonably small number of elements+    n = case abs n' `mod` 30 of I# x -> x +# 1#+    i = case abs i' `mod` I# n of I# x -> x+    -- write and read the value from an array by a specified offset+    go :: forall s . State# s -> (# State# s, Property #)+    go s0+      | (# s1, mba #) <- newByteArray# (n *# byteSize v) s0+      , s2            <- writeArray mba i v s1+      , (# s3, w #)   <- readArray mba i s2+      , (# s4, byteList #) <- showMutableByteArray (n *# byteSize v) mba s3+      , (# s5, ba #)  <- unsafeFreezeByteArray# mba s4+      , u <- indexArray ba i+      , msg <- unlines+              [ "Array size:    " ++ show (I# n)+              , "Array index:   " ++ show (I# i)+              , "byteOffset:    " ++ show (I# (byteOffset v))+              , "byteAlign:     " ++ show (I# (byteAlign v))+              , "byteSize:      " ++ show (I# (byteSize v))+              , "Array content: " ++ show byteList+              ]+         = (# s5, counterexample msg (v === w .&&. v == u) #)+++-- | Working this elem offsets and byte offsets together+mixedTransformsId :: (PrimBytes a, Eq a, Show a) => Int -> Int -> a -> Property+mixedTransformsId n' i' v = case runRW# go of (# _, r #) -> r+  where+    -- allocate reasonably small number of elements+    n = case abs n' `mod` 30 of I# x -> x +# 2#+    i = case abs i' `mod` (I# n - 1) of I# x -> x -- i+1 is always a valid index+    i1 = i +# 1#+    -- write and read the value from an array by a specified offset+    go :: forall s . State# s -> (# State# s, Property #)+    go s0+      | (# s1, mba #) <- newByteArray# (n *# byteSize v) s0+      , s2            <- writeArray mba i1 v s1+      , s3            <- writeBytes mba (i *# byteSize v) v s2+      , (# s4, w #)   <- readArray mba i s3+      , (# s5, u #)   <- readBytes mba (i1 *# byteSize v) s4+      , (# s6, byteList #) <- showMutableByteArray (n *# byteSize v) mba s5+      , msg <- unlines+              [ "Array size:    " ++ show (I# n)+              , "Array index:   " ++ show (I# i)+              , "byteOffset:    " ++ show (I# (byteOffset v))+              , "byteAlign:     " ++ show (I# (byteAlign v))+              , "byteSize:      " ++ show (I# (byteSize v))+              , "Array content: " ++ show byteList+              ]+         = (# s6, counterexample msg (v === w .&&. v == u) #)+++class SamePrimRep a b where+  convert :: a -> b++-- | Some times should have the same PrimBytes representation+samePrimRepId :: forall a b+               . ( PrimBytes a, PrimBytes b, Eq b, Show b, SamePrimRep a b)+              => Int -> a -> b -> Property+samePrimRepId off' a b = case runRW# go of (# _, r #) -> r+  where+    f = convert @a @b -- monomorphise it to avoid type errors+    -- reasonably small offset aligned to a multiple of @byteAlign a@+    off = case abs off' `mod` 100 of I# i -> i *# byteAlign a+    -- write and read the value from an array by a specified offset+    go :: forall s . State# s -> (# State# s, Property #)+    go s0+      | (# s1, mba #) <- newByteArray# (off +# byteSize a +# byteSize b) s0+      , s2            <- writeBytes mba off a s1+      , s3            <- writeBytes mba (off +# byteSize a) b s2+      , (# s4, a' #)  <- readBytes mba off s3+      , (# s5, b' #)  <- readBytes mba (off +# byteSize b) s4+      , (# s6, bl #)  <- showMutableByteArray (off +# byteSize a +# byteSize b) mba s5+      , msg <- unlines+              [ "Offset 'off':  " ++ show (I# off)+              , "byteOffset:    " ++ show (I# (byteOffset a), I# (byteOffset b))+              , "byteAlign:     " ++ show (I# (byteAlign a), I# (byteAlign b))+              , "byteSize:      " ++ show (I# (byteSize a), I# (byteSize b))+              , "Array content: " ++ show bl+              ]+         = (# s6, counterexample msg (f a === a' .&&. b === f b') #)++-- Check whether @byteFieldOffset@ calculates correct field offsets+vertexFields :: ( PrimBytes a, Eq a, Show a+                , PrimBytes b, Eq b, Show b+                , PrimBytes c, Eq c, Show c)+             => Vertex a b c -> Property+vertexFields v+  | ba <- getBytes v+  , off <- byteOffset v+    = conjoin+    [ counterexample "pos" $ pos v === fromBytes+        (off +# byteFieldOffset (proxy# @Symbol @"pos") v) ba+    , counterexample "norm" $ norm v === fromBytes+       (off +# byteFieldOffset (proxy# @Symbol @"norm") v) ba+    , counterexample "tex" $ tex v === fromBytes+       (off +# byteFieldOffset (proxy# @Symbol @"tex") v) ba+    , counterexample "extraFloats" $ extraFloats v === fromBytes+       (off +# byteFieldOffset (proxy# @Symbol @"extraFloats") v) ba+    ]++++-- a list of types to test the properties against+type SingleVarTypes =+   '[ Word8, Word16, Word32, Word64, Word+    , Int8, Int16, Int32, Int64, Int+    , Char, Double, Float+    , Vertex Double Float Char+    , Vertex Word8 Double Int16+    , Vertex Word16 Word32 Word64+    , Vertex Int64 Int8 Int32+    , ManyAlternatives Word8 Double Double+    , ManyAlternatives Float Double Int16+    , Maybe Int+    , Either Int32 Double+    , MyUnboxedType (Either (Either () Char) Float)+    , MyUnboxedType ()+    , Ptr Dummy+    , Idx 7+    , Idxs ('[] :: [Nat])+    , Idxs '[5, 3, 12]+    , ST.Tuple '[Double, Word8, Word8, Word8, Maybe Float]+    , LT.Tuple '[]+    , LT.Tuple '[Int, Int8, Either Float Double]+    ]++-- I can substitute these in place of parameters of Vertex or ManyAlternatives+type TypeTriples =+  '[ '(Double, Float, Char)+   , '(Word8, Double, Int16)+   , '(Word16, Word32, Word64)+   , '(Word16, Word32, Word64)+   , '(Int64, Int8, Int32)+   , '(Float, Char, Char)+   ]++instance SamePrimRep a (ST.Tuple '[a]) where+  convert a = a ST.:$ U+instance SamePrimRep (a,b) (ST.Tuple '[a,b]) where+  convert (a, b) = a ST.:$ b ST.:$ U+instance SamePrimRep (a,b,c) (ST.Tuple '[a,b,c]) where+  convert (a, b, c) = a ST.:$ b ST.:$ c ST.:$ U+instance SamePrimRep (a,b,c,d) (ST.Tuple '[a,b,c,d]) where+  convert (a, b, c, d) = a ST.:$ b ST.:$ c ST.:$ d ST.:$ U+instance SamePrimRep (a,b,c,d,e) (ST.Tuple '[a,b,c,d,e]) where+  convert (a, b, c, d, e) = a ST.:$ b ST.:$ c ST.:$ d ST.:$ e ST.:$ U++instance SamePrimRep a (LT.Tuple '[a]) where+  convert a = a LT.:$ U+instance SamePrimRep (a,b) (LT.Tuple '[a,b]) where+  convert (a, b) = a LT.:$ b LT.:$ U+instance SamePrimRep (a,b,c) (LT.Tuple '[a,b,c]) where+  convert (a, b, c) = a LT.:$ b LT.:$ c LT.:$ U+instance SamePrimRep (a,b,c,d) (LT.Tuple '[a,b,c,d]) where+  convert (a, b, c, d) = a LT.:$ b LT.:$ c LT.:$ d LT.:$ U+instance SamePrimRep (a,b,c,d,e) (LT.Tuple '[a,b,c,d,e]) where+  convert (a, b, c, d, e) = a LT.:$ b LT.:$ c LT.:$ d LT.:$ e LT.:$ U++instance SamePrimRep (Maybe a) (Either () a) where+  convert (Just a) = Right a+  convert Nothing  = Left ()++type SamePrimRepTypes =+  '[ '( (Word, Double), ST.Tuple '[Word, Double] )+   , '( (Double, Word8, Word8, Word8, Maybe Float)+      , ST.Tuple '[Double, Word8, Word8, Word8, Maybe Float] )+   , '( (Word8, Int16, Word32, Either (Either Double Float) Int)+      , LT.Tuple '[Word8, Int16, Word32, Either (Either Double Float) Int] )+   , '( Maybe Float, Either () Float)+   , '( Maybe Double, Either () Double)+   ]++return [] -- this is for $testWithTypes++prop_fromToBytesId :: Property+prop_fromToBytesId = $(testWithTypes 'fromToBytesId ''SingleVarTypes)++prop_fromToPtrId :: Property+prop_fromToPtrId = $(testWithTypes 'fromToPtrId ''SingleVarTypes)++prop_readWriteBytesId :: Property+prop_readWriteBytesId = $(testWithTypes 'readWriteBytesId ''SingleVarTypes)++prop_readWriteArrayId :: Property+prop_readWriteArrayId = $(testWithTypes 'readWriteArrayId ''SingleVarTypes)++prop_mixedTransformsId :: Property+prop_mixedTransformsId = $(testWithTypes 'mixedTransformsId ''SingleVarTypes)++prop_samePrimRepId :: Property+prop_samePrimRepId = $(testWithTypes 'samePrimRepId ''SamePrimRepTypes)++prop_vertexFields :: Property+prop_vertexFields = $(testWithTypes 'vertexFields ''TypeTriples)+++return [] -- this is for $forAllProperties+runTests :: Int -> IO Bool+runTests n = $forAllProperties+  $ quickCheckWithResult stdArgs { maxSuccess = n }
+ test/Numeric/QuaterDoubleTest.hs view
@@ -0,0 +1,152 @@+{-# LANGUAGE DataKinds       #-}+{-# LANGUAGE TemplateHaskell #-}+module Numeric.QuaterDoubleTest (runTests) where++import Numeric.DataFrame.Arbitraries ()+import Numeric.Quaternion+import Numeric.Scalar+import Numeric.Vector+import Test.QuickCheck++type T = Double++eps :: T+eps = 1e-7++-- | Some non-linear function are very unstable;+--   it would be a downting task to determine the uncertainty precisely.+--   Instead, I just make sure the numbers are not so big to find at least+--   the most obvious bugs.+smaller :: Quater T -> Quater T+smaller q@(Quater x y z w)+  = if square q >= 1 then Quater (f x) (f y) (f z) (f w) else q+  where+    f :: T -> T+    f a | abs a > 2 = signum a * log (abs a)+        | otherwise = a++(=~=) :: Quater T -> Quater T -> Property+(=~=) = approxEq eps+infix 4 =~=++-- Even lower precision - for naturally fragile operations+approxEq :: T -> Quater T -> Quater T -> Property+approxEq e a b = property $ err <= c * scalar e+    where+      v1 = toVec4 a+      v2 = toVec4 b+      c = 1 `max` normL1 v1 `max` normL1 v2+      err = normL1 $ v1 - v2++prop_Eq :: Quater T -> Bool+prop_Eq q = and+    [ q == q+    , Quater (takei q) (takej q) (takek q) (taker q) == q+    , fromVecNum (imVec q) (taker q)                 == q+    , im q + re q                                    == q+    , fromVec4 (toVec4 q)                            == q+    ]++prop_DoubleConjugate :: Quater T -> Property+prop_DoubleConjugate q = property $ conjugate (conjugate q) == q++prop_Square :: Quater T -> Property+prop_Square q = q * conjugate q  =~= realToFrac (square q)++prop_RotScale :: Quater T -> Vector T 3 -> Property+prop_RotScale q v = fromVecNum (rotScale q v) 0 =~= q * fromVecNum v 0 * conjugate q++prop_GetRotScale :: Vector T 3 -> Vector T 3 -> Property+prop_GetRotScale a b+  = a /= 0 ==> approxEq eps' (fromVecNum (rotScale q a) 0) (fromVecNum b 0)+  where+    q = getRotScale a b+    -- when a and b are almost opposite, precision of getRotScale suffers a lot+    -- compensate it by increasing eps:+    eps' = if cross a b == 0+           then eps+           else eps / (max eps . min 1 . unScalar $+                         1 + normalized a `dot` normalized b)++prop_InverseRotScale :: Quater T -> Vector T 3 -> Property+prop_InverseRotScale q v+  = square q > eps ==> fromVecNum (rotScale (1/q) (rotScale q v)) 0 =~= fromVecNum v 0++prop_NegateToMatrix33 :: Quater T -> Bool+prop_NegateToMatrix33 q = toMatrix33 q == toMatrix33 (negate q)++prop_NegateToMatrix44 :: Quater T -> Bool+prop_NegateToMatrix44 q = toMatrix44 q == toMatrix44 (negate q)++prop_FromToMatrix33 :: Quater T -> Property+prop_FromToMatrix33 q+  = q /= 0 ==> fromMatrix33 (toMatrix33 q) =~= q+          .||. fromMatrix33 (toMatrix33 q) =~= negate q++prop_FromToMatrix44 :: Quater T -> Property+prop_FromToMatrix44 q+  = q /= 0 ==> fromMatrix44 (toMatrix44 q) =~= q+          .||. fromMatrix44 (toMatrix44 q) =~= negate q+++prop_RotationArg :: Quater T -> Property+prop_RotationArg q | q == 0 = axisRotation (imVec q) (qArg q) =~= 1+                   | otherwise = axisRotation (imVec q) (qArg q) =~= signum q++prop_UnitQ :: Quater T -> Property+prop_UnitQ q+  = square q > eps ==> realToFrac (square (q / q)) =~= 1+++prop_ExpLog :: Quater T -> Property+prop_ExpLog q | square q < eps = log (exp q) =~= q+              | otherwise = exp (log q) =~= q++prop_SinAsin :: Quater T -> Property+prop_SinAsin q = sin (asin q') =~= q'+    where+      q' = signum q++prop_CosAcos :: Quater T -> Property+prop_CosAcos q = cos (acos q') =~= q'+    where+      q' = signum q++prop_TanAtan :: Quater T -> Property+prop_TanAtan q = tan (atan q') =~= q'+    where+      q' = sqrt (smaller q) -- because this inverse fun is fragile++prop_SinhAsinh :: Quater T -> Property+prop_SinhAsinh q = sinh (asinh q') =~= q'+    where+      q' = sqrt (smaller q) -- because this inverse fun is fragile++prop_CoshAcosh :: Quater T -> Property+prop_CoshAcosh q = cosh (acosh q) =~= q++prop_TanhAtanh :: Quater T -> Property+prop_TanhAtanh q = tanh (atanh q') =~= q'+    where+      q' = sqrt (smaller q) -- because this inverse fun is fragile++prop_SqrtSqr :: Quater T -> Property+prop_SqrtSqr q = sqrt q * sqrt q =~= q++prop_SinCos :: Quater T -> Property+prop_SinCos q = sin q' * sin q' + cos q' * cos q' =~= 1+    where+      q' = sqrt (smaller q) -- because it involves exponents++prop_SinhCosh :: Quater T -> Property+prop_SinhCosh q = cosh q' * cosh q' - sinh q' * sinh q' =~= 1+    where+      q' = sqrt (smaller q) -- because it involves exponents++prop_ReadShow :: Quater T -> Bool+prop_ReadShow q = q == read (show q)++return []+runTests :: Int -> IO Bool+runTests n = $forAllProperties+  $ quickCheckWithResult stdArgs { maxSuccess = n }
+ test/Numeric/QuaterFloatTest.hs view
@@ -0,0 +1,152 @@+{-# LANGUAGE DataKinds       #-}+{-# LANGUAGE TemplateHaskell #-}+module Numeric.QuaterFloatTest (runTests) where++import Numeric.DataFrame.Arbitraries ()+import Numeric.Quaternion+import Numeric.Scalar+import Numeric.Vector+import Test.QuickCheck++type T = Float++eps :: T+eps = 1e-3++-- | Some non-linear function are very unstable;+--   it would be a downting task to determine the uncertainty precisely.+--   Instead, I just make sure the numbers are not so big to find at least+--   the most obvious bugs.+smaller :: Quater T -> Quater T+smaller q@(Quater x y z w)+  = if square q >= 1 then Quater (f x) (f y) (f z) (f w) else q+  where+    f :: T -> T+    f a | abs a > 2 = signum a * log (abs a)+        | otherwise = a++(=~=) :: Quater T -> Quater T -> Property+(=~=) = approxEq eps+infix 4 =~=++-- Even lower precision - for naturally fragile operations+approxEq :: T -> Quater T -> Quater T -> Property+approxEq e a b = property $ err <= c * scalar e+    where+      v1 = toVec4 a+      v2 = toVec4 b+      c = 1 `max` normL1 v1 `max` normL1 v2+      err = normL1 $ v1 - v2++prop_Eq :: Quater T -> Bool+prop_Eq q = and+    [ q == q+    , Quater (takei q) (takej q) (takek q) (taker q) == q+    , fromVecNum (imVec q) (taker q)                 == q+    , im q + re q                                    == q+    , fromVec4 (toVec4 q)                            == q+    ]++prop_DoubleConjugate :: Quater T -> Property+prop_DoubleConjugate q = property $ conjugate (conjugate q) == q++prop_Square :: Quater T -> Property+prop_Square q = q * conjugate q  =~= realToFrac (square q)++prop_RotScale :: Quater T -> Vector T 3 -> Property+prop_RotScale q v = fromVecNum (rotScale q v) 0 =~= q * fromVecNum v 0 * conjugate q++prop_GetRotScale :: Vector T 3 -> Vector T 3 -> Property+prop_GetRotScale a b+  = a /= 0 ==> approxEq eps' (fromVecNum (rotScale q a) 0) (fromVecNum b 0)+  where+    q = getRotScale a b+    -- when a and b are almost opposite, precision of getRotScale suffers a lot+    -- compensate it by increasing eps:+    eps' = if cross a b == 0+           then eps+           else eps / (max eps . min 1 . unScalar $+                         1 + normalized a `dot` normalized b)++prop_InverseRotScale :: Quater T -> Vector T 3 -> Property+prop_InverseRotScale q v+  = square q > eps ==> fromVecNum (rotScale (1/q) (rotScale q v)) 0 =~= fromVecNum v 0++prop_NegateToMatrix33 :: Quater T -> Bool+prop_NegateToMatrix33 q = toMatrix33 q == toMatrix33 (negate q)++prop_NegateToMatrix44 :: Quater T -> Bool+prop_NegateToMatrix44 q = toMatrix44 q == toMatrix44 (negate q)++prop_FromToMatrix33 :: Quater T -> Property+prop_FromToMatrix33 q+  = q /= 0 ==> fromMatrix33 (toMatrix33 q) =~= q+          .||. fromMatrix33 (toMatrix33 q) =~= negate q++prop_FromToMatrix44 :: Quater T -> Property+prop_FromToMatrix44 q+  = q /= 0 ==> fromMatrix44 (toMatrix44 q) =~= q+          .||. fromMatrix44 (toMatrix44 q) =~= negate q+++prop_RotationArg :: Quater T -> Property+prop_RotationArg q | q == 0 = axisRotation (imVec q) (qArg q) =~= 1+                   | otherwise = axisRotation (imVec q) (qArg q) =~= signum q++prop_UnitQ :: Quater T -> Property+prop_UnitQ q+  = square q > eps ==> realToFrac (square (q / q)) =~= 1+++prop_ExpLog :: Quater T -> Property+prop_ExpLog q | square q < eps = log (exp q) =~= q+              | otherwise = exp (log q) =~= q++prop_SinAsin :: Quater T -> Property+prop_SinAsin q = sin (asin q') =~= q'+    where+      q' = signum q++prop_CosAcos :: Quater T -> Property+prop_CosAcos q = cos (acos q') =~= q'+    where+      q' = signum q++prop_TanAtan :: Quater T -> Property+prop_TanAtan q = tan (atan q') =~= q'+    where+      q' = sqrt (smaller q) -- because this inverse fun is fragile++prop_SinhAsinh :: Quater T -> Property+prop_SinhAsinh q = sinh (asinh q') =~= q'+    where+      q' = sqrt (smaller q) -- because this inverse fun is fragile++prop_CoshAcosh :: Quater T -> Property+prop_CoshAcosh q = cosh (acosh q) =~= q++prop_TanhAtanh :: Quater T -> Property+prop_TanhAtanh q = tanh (atanh q') =~= q'+    where+      q' = sqrt (smaller q) -- because this inverse fun is fragile++prop_SqrtSqr :: Quater T -> Property+prop_SqrtSqr q = sqrt q * sqrt q =~= q++prop_SinCos :: Quater T -> Property+prop_SinCos q = sin q' * sin q' + cos q' * cos q' =~= 1+    where+      q' = sqrt (smaller q) -- because it involves exponents++prop_SinhCosh :: Quater T -> Property+prop_SinhCosh q = cosh q' * cosh q' - sinh q' * sinh q' =~= 1+    where+      q' = sqrt (smaller q) -- because it involves exponents++prop_ReadShow :: Quater T -> Bool+prop_ReadShow q = q == read (show q)++return []+runTests :: Int -> IO Bool+runTests n = $forAllProperties+  $ quickCheckWithResult stdArgs { maxSuccess = n }
− test/Numeric/QuaternionTest.hs
@@ -1,124 +0,0 @@-{-# LANGUAGE TemplateHaskell #-}-{-# LANGUAGE FlexibleContexts #-}-{-# LANGUAGE TypeSynonymInstances #-}-{-# LANGUAGE FlexibleInstances #-}-{-# OPTIONS_GHC -fno-warn-orphans  #-}-module Numeric.QuaternionTest (runTests) where--import Test.QuickCheck-import Numeric.Quaternion-import Numeric.Vector---instance (Quaternion t, Arbitrary t) => Arbitrary (Quater t) where-  arbitrary = packQ <$> arbitrary <*> arbitrary <*> arbitrary <*> arbitrary-  shrink q | (x,y,z,t) <- unpackQ q = packQ <$> shrink x <*> shrink y  <*> shrink z <*> shrink t--instance Arbitrary Vec3d where-  arbitrary = vec3 <$> arbitrary <*> arbitrary <*> arbitrary-  shrink v | (x,y,z) <- unpackV3 v = vec3 <$> shrink x <*> shrink y  <*> shrink z---(=~=) :: (Quaternion a, Num a, Ord a, Num (Quater a), Fractional a) => Quater a -> Quater a -> Bool-(=~=) a b = taker (abs (a - b)) <= eps-    where-      s = max 1e-6 $ max (taker (abs a)) (taker (abs b))-      eps = s * 1e-6-infix 4 =~=---prop_Eq :: QDouble -> Bool-prop_Eq q = and-    [ (\(x,y,z,t) -> packQ x y z t) (unpackQ q)     == q-    , packQ (takei q) (takej q) (takek q) (taker q) == q-    , fromVecNum (imVec q) (taker q)                == q-    , im q + re q                                   == q-    ]---prop_DoubleConjugate :: QDouble -> Bool-prop_DoubleConjugate q = conjugate (conjugate q) == q--prop_Square :: QDouble -> Bool-prop_Square q = q * conjugate q  =~= realToFrac (square q)---prop_RotScale :: QDouble -> Vec3d -> Bool-prop_RotScale q v = fromVecNum (rotScale q v) 0 =~= q * fromVecNum v 0 * conjugate q--prop_GetRotScale :: Vec3d -> Vec3d -> Bool-prop_GetRotScale a b = fromVecNum (rotScale q a) 0 =~= fromVecNum b 0-  where-    q = getRotScale a b---prop_InverseRotScale :: QDouble -> Vec3d -> Bool-prop_InverseRotScale q v | q /= 0    = fromVecNum (rotScale (1/q) (rotScale q v)) 0 =~= fromVecNum v 0-                         | otherwise = True--prop_FromToMatrix33 :: QDouble -> Bool-prop_FromToMatrix33 q | q == 0 = True-                      | otherwise = fromMatrix33 (toMatrix33 (signum q)) =~= signum q * signum (re q)--prop_FromToMatrix44 :: QDouble -> Bool-prop_FromToMatrix44 q | q == 0 = True-                      | otherwise = fromMatrix44 (toMatrix44 (signum q)) =~= signum q * signum (re q)--prop_RotationArg :: QDouble -> Bool-prop_RotationArg q | q == 0 = axisRotation (imVec q) (qArg q) =~= 1-                   | otherwise = axisRotation (imVec q) (qArg q) =~= signum q---prop_UnitQ :: QDouble -> Bool-prop_UnitQ q | q == 0 = True-             | otherwise = realToFrac (square (q / q)) =~= (1 :: QDouble)---prop_ExpLog :: QDouble -> Bool-prop_ExpLog q | q == 0 = log (exp q) == q-              | otherwise = exp (log q) =~= q--prop_SinAsin :: QDouble -> Bool-prop_SinAsin q = sin (asin q') =~= q'-    where-      q' = signum q--prop_CosAcos :: QDouble -> Bool-prop_CosAcos q = cos (acos q') =~= q'-    where-      q' = signum q--prop_TanAtan :: QDouble -> Bool-prop_TanAtan q = tan (atan q') =~= q'-    where -- protect agains big numbers and rounding errors-      q' = if square q >= 1e6 then signum q else q---prop_SinhAsinh :: QDouble -> Bool-prop_SinhAsinh q = sinh (asinh q') =~= q'-    where -- protect agains big numbers and rounding errors-      q' = if square q >= 1e6 then signum q else q--prop_CoshAcosh :: QDouble -> Bool-prop_CoshAcosh q = cosh (acosh q') =~= q'-    where -- protect agains big numbers and rounding errors-      q' = if square q >= 1e6 then signum q else q--prop_TanhAtanh :: QDouble -> Bool-prop_TanhAtanh q = tanh (atanh q') =~= q'-    where -- protect agains big numbers and rounding errors-      q' = if square q >= 1e6 then signum q else q--prop_SinCos :: QDouble -> Bool-prop_SinCos q = sin q' * sin q' + cos q' * cos q' =~= 1-    where-      q' = signum q--prop_SinhCosh :: QDouble -> Bool-prop_SinhCosh q = cosh q' * cosh q' - sinh q' * sinh q' =~= 1-    where-      q' = signum q--return []-runTests :: IO Bool-runTests = $quickCheckAll
test/Spec.hs view
@@ -1,24 +1,30 @@ module Main (tests, main) where -import           Distribution.TestSuite-import           System.Exit+import Distribution.TestSuite+import System.Exit  import qualified Numeric.DataFrame.BasicTest import qualified Numeric.DataFrame.SubSpaceTest import qualified Numeric.MatrixDoubleTest import qualified Numeric.MatrixFloatTest-import qualified Numeric.QuaternionTest+import qualified Numeric.PrimBytesTest+import qualified Numeric.QuaterDoubleTest+import qualified Numeric.QuaterFloatTest   -- | Collection of tests in detailed-0.9 format tests :: IO [Test] tests = return-  [ test "DataFrame.Basic"    Numeric.DataFrame.BasicTest.runTests-  , test "DataFrame.SubSpace" Numeric.DataFrame.SubSpaceTest.runTests-  , test "MatrixDouble"       Numeric.MatrixDoubleTest.runTests-  , test "MatrixFloat"        Numeric.MatrixFloatTest.runTests-  , test "Quaternion"         Numeric.QuaternionTest.runTests+  [ test "DataFrame.Basic"    $ Numeric.DataFrame.BasicTest.runTests n+  , test "DataFrame.SubSpace" $ Numeric.DataFrame.SubSpaceTest.runTests n+  , test "MatrixDouble"       $ Numeric.MatrixDoubleTest.runTests n+  , test "MatrixFloat"        $ Numeric.MatrixFloatTest.runTests n+  , test "QuaterDouble"       $ Numeric.QuaterDoubleTest.runTests n+  , test "QuaterFloat"        $ Numeric.QuaterFloatTest.runTests n+  , test "PrimBytes"          $ Numeric.PrimBytesTest.runTests n   ]+  where+    n = 1000 :: Int   @@ -26,16 +32,17 @@ -- | Run tests as exitcode-stdio-1.0 main :: IO () main = do+    putStrLn ""     ts <- tests-    trs <- mapM (\(Test ti) ->(,) (name ti) <$> run ti) ts-    case filter (not . isGood) trs of+    trs <- mapM (\(Test ti) -> (,) (name ti) <$> run ti) ts+    case filter (not . isGood . snd) trs of        [] -> exitSuccess        xs -> do         putStrLn $ "Failed tests: " ++ unwords (fmap fst xs)         exitFailure   where-    isGood (_, Finished Pass) = True-    isGood _                  = False+    isGood (Finished Pass) = True+    isGood _               = False   -- | Convert QuickCheck props into Cabal tests
+ test/Spec/Util.hs view
@@ -0,0 +1,154 @@+{-# LANGUAGE QuasiQuotes     #-}+{-# LANGUAGE TemplateHaskell #-}++module Spec.Util (propWithTypes, testWithTypes) where++import Control.Applicative+import Control.Monad+import Data.Monoid+import Language.Haskell.TH+import Test.QuickCheck+-- import Language.Haskell.TH.Syntax++-- | Test a property with several types.+--+--   The first argument is the name of a @Testable@ function+--+--   The second argument is expected to be a type synonym of kind [k] --+--     the variants of type arguments to apply to a fun+--+--   Kind @k@ here should match the kind of type variable of the testable function,+--    (or a promoted n-tuple or a promoted list of such variables.)+testWithTypes :: Name -- ^ Function with a few type variables+              -> Name -- ^ Name of a type with kind [k]+              -> ExpQ+testWithTypes fName tyNames = do+    typeLists <- getTypes tyNames+    let props = (\ts -> mkProp ts $ foldl AppTypeE (VarE fName) ts) <$> typeLists+    [e| conjoin $(listE props) |]+  where+    mkProp :: [Type] -> Exp -> ExpQ+    mkProp ts ex+     = let qe = pure ex :: ExpQ+           qs = litE . stringL $ unlines ["Tested with types:", pprint ts]+       in [e| property ( counterexample $qs $qe ) |]++-- | Assuming the argument is a type synonym for a list of types, unpack it.+getTypes :: Name -> Q [[Type]]+getTypes tyNames =+    reify tyNames >>= unpackTyConI >>= unpackFamList >>= traverse unpackAppType+  where+    unpackTyConI :: Info -> Q Type+    unpackTyConI (TyConI (TySynD _ [] t)) = pure t+    unpackTyConI i = error $+      "getTypes/unpackTyConI:"+      ++ "Expected a type synonym with no arguments, but got something else "+      ++ show i+    unpackFamList :: Type -> Q [Type]+    unpackFamList t+      | Just ts <- unpackPList t = pure ts+      | otherwise                = error $+      "getTypes/unpackFamList:"+      ++ "Expected a promoted (type) list inside the type synonym, but got "+      ++ show t+    unpackAppType :: Type -> Q [Type]+    unpackAppType t+      | Just ts <- unpackPList t  = pure ts+      | Just ts <- unpackPTuple t = pure ts+      | otherwise                 = pure [t]+    unpackPTuple :: Type -> Maybe [Type]+    unpackPTuple (PromotedTupleT _) = pure []+    unpackPTuple (AppT t r)         = (++ [r]) <$> unpackPTuple t+    unpackPTuple (ParensT t)        = unpackPTuple t+    unpackPTuple (SigT t _)         = unpackPTuple t+    unpackPTuple _                  = Nothing+    unpackPList :: Type -> Maybe [Type]+    unpackPList PromotedNilT                    = pure []+    unpackPList (AppT (AppT PromotedConsT r) t) = (r:) <$> unpackPList t+    unpackPList (ParensT t)                     = unpackPList t+    unpackPList (SigT t _)                      = unpackPList t+    unpackPList _                               = Nothing+++-- | Make several properties by applying types+propWithTypes :: Name -- ^ Function with a few type variables+              -> [[Name]] -- ^ All specific types to test it on.+              -> DecsQ+propWithTypes fName tyNames+    = fmap join . sequence+    $ zipWith3 mkDecl funNames funTypes appliedExpressions+  where+    appliedExpressions :: [ExpQ]+    appliedExpressions+      = foldl (\e -> appTypeE e . conT) (varE fName) <$> tyNames+    funNames :: [Q Name]+    funNames+      = newName . foldl (\n -> (n ++) . nameBase) ("prop_" ++ nameBase fName) <$> tyNames+    funTypes :: [TypeQ]+    funTypes+      = (\ns -> fmap (subtTyVars (map ConT ns)) ) <$> tyNames <*> [infoType <$> reify fName]+    mkDecl qn qt qe = do+      n <- qn+      sequence+        [ sigD n qt+        , funD n [(\e -> Clause [] (NormalB e) []) <$> qe]+        ]+++-- | Get a type of something at the term level (e.g. function, var, constructor).+infoType :: Info -> Type+infoType (ClassOpI _ t _) = t+infoType (DataConI _ t _) = t+infoType (VarI _ t _)     = t+infoType _                = undefined++-- | Substitute at most as many type variables as given types in the list.+--+--   For every type in a list @ts@, the function looks for the first occurrence+--   of any type variable and substitutes all its occurrences in the target type.+--+--   Returns the original type if it has no type variables.+subtTyVars :: [Type] -> Type -> Type+subtTyVars = flip (foldl f)+  where+    f t x+      | Just v <- findFirstTyVar t+        = substTyVar v x t+      | otherwise = t++-- | Substitute all occurrences of a type variable+substTyVar :: Name -- ^ TyVar name+           -> Type -- ^ Substitution+           -> Type -- ^ Original type+           -> Type+substTyVar x y (ForallT vs ctx t)+    = ForallT (remVar vs) (ctx >>= substOrRemove) (substTyVar x y t)+  where+    thisVar :: TyVarBndr -> Bool+    thisVar (PlainTV n)    = n == x+    thisVar (KindedTV n _) = n == x+    remVar :: [TyVarBndr] -> [TyVarBndr]+    remVar = filter (not . thisVar)+    substOrRemove p+      = let p' = substTyVar x y p+        in if findFirstTyVar p' == Nothing then [] else [p]+substTyVar x y (AppT t1 t2) = AppT (substTyVar x y t1) (substTyVar x y t2)+substTyVar x y (SigT t1 t2) = SigT (substTyVar x y t1) (substTyVar x y t2)+substTyVar x y v@(VarT n) = if n == x then y else v+substTyVar x y (InfixT t1 n t2) = InfixT (substTyVar x y t1) n (substTyVar x y t2)+substTyVar x y (UInfixT t1 n t2) = UInfixT (substTyVar x y t1) n (substTyVar x y t2)+substTyVar x y (ParensT t) = ParensT (substTyVar x y t)+substTyVar _ _ t = t++findFirstTyVar :: Type -> Maybe Name+findFirstTyVar (ForallT (PlainTV n:_) _ _) = Just n+findFirstTyVar (ForallT (KindedTV n _:_) _ _) = Just n+findFirstTyVar (ForallT [] ctx t)+  = getFirst (foldMap (First . findFirstTyVar) ctx) <|> findFirstTyVar t+findFirstTyVar (AppT t1 t2) = findFirstTyVar t1 <|> findFirstTyVar t2+findFirstTyVar (SigT t1 k1) = findFirstTyVar t1 <|> findFirstTyVar k1+findFirstTyVar (VarT n) = Just n+findFirstTyVar (InfixT t1 _ t2) = findFirstTyVar t1 <|> findFirstTyVar t2+findFirstTyVar (UInfixT t1 _ t2) = findFirstTyVar t1 <|> findFirstTyVar t2+findFirstTyVar (ParensT t) = findFirstTyVar t+findFirstTyVar _ = Nothing