{-# LANGUAGE CPP #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MagicHash #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE TypeApplications #-}
{-# 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
import Unsafe.Coerce (unsafeCoerce)
data FloatX4 = FloatX4# Float# Float# Float# Float#
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 #-}
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 #-}
#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# #-}
withArrayContent# _ g x = g (CumulDims [ELEM_N, 1]) 0# (getBytes x)
{-# INLINE withArrayContent# #-}
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# #-}
getIdxOffset :: Idxs '[4] -> Int#
getIdxOffset is = case unsafeCoerce is of
~[w] -> case w of W# i -> word2Int# i
{-# INLINE getIdxOffset #-}
{-# RULES
"index/FloatX4" forall i . index @Float @'[4] @'[] @'[4] i
= unsafeCoerce (ix# @Float @FloatX4 (getIdxOffset i))
#-}