diff options
| -rw-r--r-- | bench/Main.hs | 27 | ||||
| -rw-r--r-- | cbits/arith.c | 130 | ||||
| -rw-r--r-- | cbits/arith_lists.h | 21 | ||||
| -rw-r--r-- | ox-arrays.cabal | 2 | ||||
| -rw-r--r-- | src/Data/Array/Nested/Internal.hs | 56 | ||||
| -rw-r--r-- | src/Data/Array/Nested/Internal/Arith.hs | 63 | 
6 files changed, 259 insertions, 40 deletions
| diff --git a/bench/Main.hs b/bench/Main.hs index 8f3b670..41eb3b3 100644 --- a/bench/Main.hs +++ b/bench/Main.hs @@ -6,7 +6,7 @@ import qualified Numeric.LinearAlgebra as LA  import Test.Tasty.Bench  import Data.Array.Nested -import Data.Array.Nested.Internal (mliftPrim2, arithPromoteRanked2) +import Data.Array.Nested.Internal (mliftPrim, mliftPrim2, arithPromoteRanked, arithPromoteRanked2)  main :: IO () @@ -24,6 +24,14 @@ main = defaultMain        let n = 1_000_000        in nf (\(a, b) -> runScalar (rsumOuter1 (arithPromoteRanked2 (mliftPrim2 (/)) a b)))              (riota @Double n, riota n) +    ,bench "sum(**) Double [1e6]" $ +      let n = 1_000_000 +      in nf (\(a, b) -> runScalar (rsumOuter1 (arithPromoteRanked2 (mliftPrim2 (**)) a b))) +            (riota @Double n, riota n) +    ,bench "sum(sin) Double [1e6]" $ +      let n = 1_000_000 +      in nf (\a -> runScalar (rsumOuter1 (arithPromoteRanked (mliftPrim sin) a))) +            (riota @Double n)      ,bench "sum Double [1e6]" $        let n = 1_000_000        in nf (\a -> runScalar (rsumOuter1 a)) @@ -42,6 +50,14 @@ main = defaultMain        let n = 1_000_000        in nf (\(a, b) -> runScalar (rsumOuter1 (a / b)))              (riota @Double n, riota n) +    ,bench "sum(**) Double [1e6]" $ +      let n = 1_000_000 +      in nf (\(a, b) -> runScalar (rsumOuter1 (a ** b))) +            (riota @Double n, riota n) +    ,bench "sum(sin) Double [1e6]" $ +      let n = 1_000_000 +      in nf (\a -> runScalar (rsumOuter1 (sin a))) +            (riota @Double n)      ,bench "sum Double [1e6]" $        let n = 1_000_000        in nf (\a -> runScalar (rsumOuter1 a)) @@ -63,6 +79,15 @@ main = defaultMain        in nf (\(a, b) -> LA.sumElements (a / b))              (LA.linspace @Double n (0.0, fromIntegral (n - 1))              ,LA.linspace @Double n (0.0, fromIntegral (n - 1))) +    ,bench "sum(**) Double [1e6]" $ +      let n = 1_000_000 +      in nf (\(a, b) -> LA.sumElements (a ** b)) +            (LA.linspace @Double n (0.0, fromIntegral (n - 1)) +            ,LA.linspace @Double n (0.0, fromIntegral (n - 1))) +    ,bench "sum(sin) Double [1e6]" $ +      let n = 1_000_000 +      in nf (\a -> LA.sumElements (sin a)) +            (LA.linspace @Double n (0.0, fromIntegral (n - 1)))      ,bench "sum Double [1e6]" $        let n = 1_000_000        in nf (\a -> LA.sumElements a) diff --git a/cbits/arith.c b/cbits/arith.c index a71c1b9..e20578b 100644 --- a/cbits/arith.c +++ b/cbits/arith.c @@ -18,6 +18,66 @@  typedef int32_t i32;  typedef int64_t i64; +/***************************************************************************** + *                         Additional math functions                         * + *****************************************************************************/ + +#define GEN_ABS(x) \ +  _Generic((x), \ +      int: abs, \ +      long: labs, \ +      long long: llabs, \ +      float: fabsf, \ +      double: fabs)(x) + +// This does not result in multiple loads with GCC 13. +#define GEN_SIGNUM(x) ((x) < 0 ? -1 : (x) > 0 ? 1 : 0) + +#define GEN_POW(x, y) _Generic((x), float: powf, double: pow)(x, y) +#define GEN_LOGBASE(x, y) _Generic((x), float: logf(y) / logf(x), double: log(y) / log(x)) +#define GEN_EXP(x) _Generic((x), float: expf, double: exp)(x) +#define GEN_LOG(x) _Generic((x), float: logf, double: log)(x) +#define GEN_SQRT(x) _Generic((x), float: sqrtf, double: sqrt)(x) +#define GEN_SIN(x) _Generic((x), float: sinf, double: sin)(x) +#define GEN_COS(x) _Generic((x), float: cosf, double: cos)(x) +#define GEN_TAN(x) _Generic((x), float: tanf, double: tan)(x) +#define GEN_ASIN(x) _Generic((x), float: asinf, double: asin)(x) +#define GEN_ACOS(x) _Generic((x), float: acosf, double: acos)(x) +#define GEN_ATAN(x) _Generic((x), float: atanf, double: atan)(x) +#define GEN_SINH(x) _Generic((x), float: sinhf, double: sinh)(x) +#define GEN_COSH(x) _Generic((x), float: coshf, double: cosh)(x) +#define GEN_TANH(x) _Generic((x), float: tanhf, double: tanh)(x) +#define GEN_ASINH(x) _Generic((x), float: asinhf, double: asinh)(x) +#define GEN_ACOSH(x) _Generic((x), float: acoshf, double: acosh)(x) +#define GEN_ATANH(x) _Generic((x), float: atanhf, double: atanh)(x) +#define GEN_LOG1P(x) _Generic((x), float: log1pf, double: log1p)(x) +#define GEN_EXPM1(x) _Generic((x), float: expm1f, double: expm1)(x) + +// Taken from Haskell's implementation: +//   https://hackage.haskell.org/package/ghc-internal-9.1001.0/docs/src//GHC.Internal.Float.html#log1mexpOrd +#define LOG1MEXP_IMPL(x) do { \ +    if (x > _Generic((x), float: logf, double: log)(2)) return GEN_LOG(-GEN_EXPM1(x)); \ +    else return GEN_LOG1P(-GEN_EXP(x)); \ +  } while (0) + +static float log1mexp_float(float x) { LOG1MEXP_IMPL(x); } +static double log1mexp_double(double x) { LOG1MEXP_IMPL(x); } + +#define GEN_LOG1MEXP(x) _Generic((x), float: log1mexp_float, double: log1mexp_double)(x) + +// Taken from Haskell's implementation: +//   https://hackage.haskell.org/package/ghc-internal-9.1001.0/docs/src//GHC.Internal.Float.html#line-595 +#define LOG1PEXP_IMPL(x) do { \ +      if (x <= 18) return GEN_LOG1P(GEN_EXP(x)); \ +      if (x <= 100) return x + GEN_EXP(-x); \ +      return x; \ +  } while (0) + +static float log1pexp_float(float x) { LOG1PEXP_IMPL(x); } +static double log1pexp_double(double x) { LOG1PEXP_IMPL(x); } + +#define GEN_LOG1PEXP(x) _Generic((x), float: log1pexp_float, double: log1pexp_double)(x) +  /*****************************************************************************   *                             Kernel functions                              * @@ -37,22 +97,22 @@ typedef int64_t i64;      for (i64 i = 0; i < n; i++) out[i] = x[i] op y; \    } +#define PREFIX_BINOP(name, op, typ) \ +  static void oxarop_op_ ## name ## _ ## typ ## _sv(i64 n, typ *out, typ x, const typ *y) { \ +    for (i64 i = 0; i < n; i++) out[i] = op(x, y[i]); \ +  } \ +  static void oxarop_op_ ## name ## _ ## typ ## _vv(i64 n, typ *out, const typ *x, const typ *y) { \ +    for (i64 i = 0; i < n; i++) out[i] = op(x[i], y[i]); \ +  } \ +  static void oxarop_op_ ## name ## _ ## typ ## _vs(i64 n, typ *out, const typ *x, typ y) { \ +    for (i64 i = 0; i < n; i++) out[i] = op(x[i], y); \ +  } +  #define UNARY_OP(name, op, typ) \    static void oxarop_op_ ## name ## _ ## typ(i64 n, typ *out, const typ *x) { \      for (i64 i = 0; i < n; i++) out[i] = op(x[i]); \    } -#define GEN_ABS(x) \ -  _Generic((x), \ -      int: abs, \ -      long: labs, \ -      long long: llabs, \ -      float: fabsf, \ -      double: fabs)(x) - -// This does not result in multiple loads with GCC 13. -#define GEN_SIGNUM(x) ((x) < 0 ? -1 : (x) > 0 ? 1 : 0) -  // Walk a orthotope-style strided array, except for the inner dimension. The  // body is run for every "inner vector".  #define TARRAY_WALK_NOINNER(again_label_name, rank, shape, strides, body) \ @@ -161,18 +221,24 @@ enum fbinop_tag_t {    void oxarop_fbinary_ ## typ ## _sv(enum binop_tag_t tag, i64 n, typ *out, typ x, const typ *y) { \      switch (tag) { \        case FB_DIV: oxarop_op_fdiv_ ## typ ## _sv(n, out, x, y); break; \ +      case FB_POW: oxarop_op_pow_ ## typ ## _sv(n, out, x, y); break; \ +      case FB_LOGBASE: oxarop_op_logbase_ ## typ ## _sv(n, out, x, y); break; \        default: wrong_op("binary_sv", tag); \      } \    } \    void oxarop_fbinary_ ## typ ## _vs(enum binop_tag_t tag, i64 n, typ *out, const typ *x, typ y) { \      switch (tag) { \        case FB_DIV: oxarop_op_fdiv_ ## typ ## _vs(n, out, x, y); break; \ +      case FB_POW: oxarop_op_pow_ ## typ ## _vs(n, out, x, y); break; \ +      case FB_LOGBASE: oxarop_op_logbase_ ## typ ## _vs(n, out, x, y); break; \        default: wrong_op("binary_vs", tag); \      } \    } \    void oxarop_fbinary_ ## typ ## _vv(enum binop_tag_t tag, i64 n, typ *out, const typ *x, const typ *y) { \      switch (tag) { \        case FB_DIV: oxarop_op_fdiv_ ## typ ## _vv(n, out, x, y); break; \ +      case FB_POW: oxarop_op_pow_ ## typ ## _vv(n, out, x, y); break; \ +      case FB_LOGBASE: oxarop_op_logbase_ ## typ ## _vv(n, out, x, y); break; \        default: wrong_op("binary_vv", tag); \      } \    } @@ -204,9 +270,28 @@ enum funop_tag_t {  };  #define ENTRY_FUNARY_OPS(typ) \ -  void oxarop_funary_ ## typ(enum unop_tag_t tag, i64 n, typ *out, const typ *x) { \ +  void oxarop_funary_ ## typ(enum funop_tag_t tag, i64 n, typ *out, const typ *x) { \      switch (tag) { \        case FU_RECIP: oxarop_op_recip_ ## typ(n, out, x); break; \ +      case FU_EXP: oxarop_op_exp_ ## typ(n, out, x); break; \ +      case FU_LOG: oxarop_op_log_ ## typ(n, out, x); break; \ +      case FU_SQRT: oxarop_op_sqrt_ ## typ(n, out, x); break; \ +      case FU_SIN: oxarop_op_sin_ ## typ(n, out, x); break; \ +      case FU_COS: oxarop_op_cos_ ## typ(n, out, x); break; \ +      case FU_TAN: oxarop_op_tan_ ## typ(n, out, x); break; \ +      case FU_ASIN: oxarop_op_asin_ ## typ(n, out, x); break; \ +      case FU_ACOS: oxarop_op_acos_ ## typ(n, out, x); break; \ +      case FU_ATAN: oxarop_op_atan_ ## typ(n, out, x); break; \ +      case FU_SINH: oxarop_op_sinh_ ## typ(n, out, x); break; \ +      case FU_COSH: oxarop_op_cosh_ ## typ(n, out, x); break; \ +      case FU_TANH: oxarop_op_tanh_ ## typ(n, out, x); break; \ +      case FU_ASINH: oxarop_op_asinh_ ## typ(n, out, x); break; \ +      case FU_ACOSH: oxarop_op_acosh_ ## typ(n, out, x); break; \ +      case FU_ATANH: oxarop_op_atanh_ ## typ(n, out, x); break; \ +      case FU_LOG1P: oxarop_op_log1p_ ## typ(n, out, x); break; \ +      case FU_EXPM1: oxarop_op_expm1_ ## typ(n, out, x); break; \ +      case FU_LOG1PEXP: oxarop_op_log1pexp_ ## typ(n, out, x); break; \ +      case FU_LOG1MEXP: oxarop_op_log1mexp_ ## typ(n, out, x); break; \        default: wrong_op("unary", tag); \      } \    } @@ -253,7 +338,28 @@ NUM_TYPES_XLIST  #define X(typ) \    NONCOMM_OP(fdiv, /, typ) \ +  PREFIX_BINOP(pow, GEN_POW, typ) \ +  PREFIX_BINOP(logbase, GEN_LOGBASE, typ) \    UNARY_OP(recip, 1.0/, typ) \ +  UNARY_OP(exp, GEN_EXP, typ) \ +  UNARY_OP(log, GEN_LOG, typ) \ +  UNARY_OP(sqrt, GEN_SQRT, typ) \ +  UNARY_OP(sin, GEN_SIN, typ) \ +  UNARY_OP(cos, GEN_COS, typ) \ +  UNARY_OP(tan, GEN_TAN, typ) \ +  UNARY_OP(asin, GEN_ASIN, typ) \ +  UNARY_OP(acos, GEN_ACOS, typ) \ +  UNARY_OP(atan, GEN_ATAN, typ) \ +  UNARY_OP(sinh, GEN_SINH, typ) \ +  UNARY_OP(cosh, GEN_COSH, typ) \ +  UNARY_OP(tanh, GEN_TANH, typ) \ +  UNARY_OP(asinh, GEN_ASINH, typ) \ +  UNARY_OP(acosh, GEN_ACOSH, typ) \ +  UNARY_OP(atanh, GEN_ATANH, typ) \ +  UNARY_OP(log1p, GEN_LOG1P, typ) \ +  UNARY_OP(expm1, GEN_EXPM1, typ) \ +  UNARY_OP(log1pexp, GEN_LOG1PEXP, typ) \ +  UNARY_OP(log1mexp, GEN_LOG1MEXP, typ) \    ENTRY_FBINARY_OPS(typ) \    ENTRY_FUNARY_OPS(typ)  FLOAT_TYPES_XLIST diff --git a/cbits/arith_lists.h b/cbits/arith_lists.h index 1137c18..2e37575 100644 --- a/cbits/arith_lists.h +++ b/cbits/arith_lists.h @@ -3,12 +3,33 @@ LIST_BINOP(BO_SUB, 2, -)  LIST_BINOP(BO_MUL, 3, *)  LIST_FBINOP(FB_DIV, 1, /) +LIST_FBINOP(FB_POW, 2, **) +LIST_FBINOP(FB_LOGBASE, 3, logBase)  LIST_UNOP(UO_NEG, 1,)  LIST_UNOP(UO_ABS, 2,)  LIST_UNOP(UO_SIGNUM, 3,)  LIST_FUNOP(FU_RECIP, 1,) +LIST_FUNOP(FU_EXP, 2,) +LIST_FUNOP(FU_LOG, 3,) +LIST_FUNOP(FU_SQRT, 4,) +LIST_FUNOP(FU_SIN, 5,) +LIST_FUNOP(FU_COS, 6,) +LIST_FUNOP(FU_TAN, 7,) +LIST_FUNOP(FU_ASIN, 8,) +LIST_FUNOP(FU_ACOS, 9,) +LIST_FUNOP(FU_ATAN, 10,) +LIST_FUNOP(FU_SINH, 11,) +LIST_FUNOP(FU_COSH, 12,) +LIST_FUNOP(FU_TANH, 13,) +LIST_FUNOP(FU_ASINH, 14,) +LIST_FUNOP(FU_ACOSH, 15,) +LIST_FUNOP(FU_ATANH, 16,) +LIST_FUNOP(FU_LOG1P, 17,) +LIST_FUNOP(FU_EXPM1, 18,) +LIST_FUNOP(FU_LOG1PEXP, 19,) +LIST_FUNOP(FU_LOG1MEXP, 20,)  LIST_REDOP(RO_SUM1, 1,)  LIST_REDOP(RO_PRODUCT1, 2,) diff --git a/ox-arrays.cabal b/ox-arrays.cabal index 875c54e..d0aed82 100644 --- a/ox-arrays.cabal +++ b/ox-arrays.cabal @@ -5,6 +5,8 @@ author:          Tom Smeding  license:         BSD-3-Clause  build-type:      Simple +extra-source-files: cbits/arith_lists.h +  library    exposed-modules:      Data.Array.Mixed diff --git a/src/Data/Array/Nested/Internal.hs b/src/Data/Array/Nested/Internal.hs index ef2ad6b..f8d16aa 100644 --- a/src/Data/Array/Nested/Internal.hs +++ b/src/Data/Array/Nested/Internal.hs @@ -1048,34 +1048,36 @@ instance (NumElt a, PrimElt a) => Num (Mixed sh a) where    signum = mliftNumElt1 numEltSignum    fromInteger _ = error "Data.Array.Nested.fromIntegral: No singletons available, use explicit mreplicate" -instance (FloatElt a, NumElt a, PrimElt a, Fractional a) => Fractional (Mixed sh a) where +instance (FloatElt a, NumElt a, PrimElt a) => Fractional (Mixed sh a) where    fromRational _ = error "Data.Array.Nested.fromRational: No singletons available, use explicit mreplicate"    recip = mliftNumElt1 floatEltRecip    (/) = mliftNumElt2 floatEltDiv -instance (FloatElt a, NumElt a, PrimElt a, Floating a) => Floating (Mixed sh a) where +instance (FloatElt a, NumElt a, PrimElt a) => Floating (Mixed sh a) where    pi = error "Data.Array.Nested.pi: No singletons available, use explicit mreplicate" -  exp = mliftPrim exp -  log = mliftPrim log -  sqrt = mliftPrim sqrt -  (**) = mliftPrim2 (**) -  logBase = mliftPrim2 logBase -  sin = mliftPrim sin -  cos = mliftPrim cos -  tan = mliftPrim tan -  asin = mliftPrim asin -  acos = mliftPrim acos -  atan = mliftPrim atan -  sinh = mliftPrim sinh -  cosh = mliftPrim cosh -  tanh = mliftPrim tanh -  asinh = mliftPrim asinh -  acosh = mliftPrim acosh -  atanh = mliftPrim atanh -  log1p = mliftPrim GHC.Float.log1p -  expm1 = mliftPrim GHC.Float.expm1 -  log1pexp = mliftPrim GHC.Float.log1pexp -  log1mexp = mliftPrim GHC.Float.log1mexp +  exp = mliftNumElt1 floatEltExp +  log = mliftNumElt1 floatEltLog +  sqrt = mliftNumElt1 floatEltSqrt + +  (**) = mliftNumElt2 floatEltPow +  logBase = mliftNumElt2 floatEltLogbase + +  sin = mliftNumElt1 floatEltSin +  cos = mliftNumElt1 floatEltCos +  tan = mliftNumElt1 floatEltTan +  asin = mliftNumElt1 floatEltAsin +  acos = mliftNumElt1 floatEltAcos +  atan = mliftNumElt1 floatEltAtan +  sinh = mliftNumElt1 floatEltSinh +  cosh = mliftNumElt1 floatEltCosh +  tanh = mliftNumElt1 floatEltTanh +  asinh = mliftNumElt1 floatEltAsinh +  acosh = mliftNumElt1 floatEltAcosh +  atanh = mliftNumElt1 floatEltAtanh +  log1p = mliftNumElt1 floatEltLog1p +  expm1 = mliftNumElt1 floatEltExpm1 +  log1pexp = mliftNumElt1 floatEltLog1pexp +  log1mexp = mliftNumElt1 floatEltLog1mexp  mtoRanked :: forall sh a. Elt a => Mixed sh a -> Ranked (X.Rank sh) a  mtoRanked arr @@ -1367,12 +1369,12 @@ instance (NumElt a, PrimElt a) => Num (Ranked n a) where    signum = arithPromoteRanked signum    fromInteger _ = error "Data.Array.Nested.fromIntegral: No singletons available, use explicit rreplicateScal" -instance (FloatElt a, NumElt a, PrimElt a, Fractional a) => Fractional (Ranked n a) where +instance (FloatElt a, NumElt a, PrimElt a) => Fractional (Ranked n a) where    fromRational _ = error "Data.Array.Nested.fromRational: No singletons available, use explicit rreplicateScal"    recip = arithPromoteRanked recip    (/) = arithPromoteRanked2 (/) -instance (FloatElt a, NumElt a, PrimElt a, Floating a) => Floating (Ranked n a) where +instance (FloatElt a, NumElt a, PrimElt a) => Floating (Ranked n a) where    pi = error "Data.Array.Nested.pi: No singletons available, use explicit rreplicateScal"    exp = arithPromoteRanked exp    log = arithPromoteRanked log @@ -1698,12 +1700,12 @@ instance (NumElt a, PrimElt a) => Num (Shaped sh a) where    signum = arithPromoteShaped signum    fromInteger _ = error "Data.Array.Nested.fromIntegral: No singletons available, use explicit sreplicateScal" -instance (FloatElt a, NumElt a, PrimElt a, Fractional a) => Fractional (Shaped sh a) where +instance (FloatElt a, NumElt a, PrimElt a) => Fractional (Shaped sh a) where    fromRational _ = error "Data.Array.Nested.fromRational: No singletons available, use explicit sreplicateScal"    recip = arithPromoteShaped recip    (/) = arithPromoteShaped2 (/) -instance (FloatElt a, NumElt a, PrimElt a, Floating a) => Floating (Shaped sh a) where +instance (FloatElt a, NumElt a, PrimElt a) => Floating (Shaped sh a) where    pi = error "Data.Array.Nested.pi: No singletons available, use explicit sreplicateScal"    exp = arithPromoteShaped exp    log = arithPromoteShaped log diff --git a/src/Data/Array/Nested/Internal/Arith.hs b/src/Data/Array/Nested/Internal/Arith.hs index 07d5d8a..95fcfcf 100644 --- a/src/Data/Array/Nested/Internal/Arith.hs +++ b/src/Data/Array/Nested/Internal/Arith.hs @@ -361,12 +361,75 @@ instance NumElt CInt where  class FloatElt a where    floatEltDiv :: SNat n -> RS.Array n a -> RS.Array n a -> RS.Array n a +  floatEltPow :: SNat n -> RS.Array n a -> RS.Array n a -> RS.Array n a +  floatEltLogbase :: SNat n -> RS.Array n a -> RS.Array n a -> RS.Array n a    floatEltRecip :: SNat n -> RS.Array n a -> RS.Array n a +  floatEltExp :: SNat n -> RS.Array n a -> RS.Array n a +  floatEltLog :: SNat n -> RS.Array n a -> RS.Array n a +  floatEltSqrt :: SNat n -> RS.Array n a -> RS.Array n a +  floatEltSin :: SNat n -> RS.Array n a -> RS.Array n a +  floatEltCos :: SNat n -> RS.Array n a -> RS.Array n a +  floatEltTan :: SNat n -> RS.Array n a -> RS.Array n a +  floatEltAsin :: SNat n -> RS.Array n a -> RS.Array n a +  floatEltAcos :: SNat n -> RS.Array n a -> RS.Array n a +  floatEltAtan :: SNat n -> RS.Array n a -> RS.Array n a +  floatEltSinh :: SNat n -> RS.Array n a -> RS.Array n a +  floatEltCosh :: SNat n -> RS.Array n a -> RS.Array n a +  floatEltTanh :: SNat n -> RS.Array n a -> RS.Array n a +  floatEltAsinh :: SNat n -> RS.Array n a -> RS.Array n a +  floatEltAcosh :: SNat n -> RS.Array n a -> RS.Array n a +  floatEltAtanh :: SNat n -> RS.Array n a -> RS.Array n a +  floatEltLog1p :: SNat n -> RS.Array n a -> RS.Array n a +  floatEltExpm1 :: SNat n -> RS.Array n a -> RS.Array n a +  floatEltLog1pexp :: SNat n -> RS.Array n a -> RS.Array n a +  floatEltLog1mexp :: SNat n -> RS.Array n a -> RS.Array n a  instance FloatElt Float where    floatEltDiv = divVectorFloat +  floatEltPow = powVectorFloat +  floatEltLogbase = logbaseVectorFloat    floatEltRecip = recipVectorFloat +  floatEltExp = expVectorFloat +  floatEltLog = logVectorFloat +  floatEltSqrt = sqrtVectorFloat +  floatEltSin = sinVectorFloat +  floatEltCos = cosVectorFloat +  floatEltTan = tanVectorFloat +  floatEltAsin = asinVectorFloat +  floatEltAcos = acosVectorFloat +  floatEltAtan = atanVectorFloat +  floatEltSinh = sinhVectorFloat +  floatEltCosh = coshVectorFloat +  floatEltTanh = tanhVectorFloat +  floatEltAsinh = asinhVectorFloat +  floatEltAcosh = acoshVectorFloat +  floatEltAtanh = atanhVectorFloat +  floatEltLog1p = log1pVectorFloat +  floatEltExpm1 = expm1VectorFloat +  floatEltLog1pexp = log1pexpVectorFloat +  floatEltLog1mexp = log1mexpVectorFloat  instance FloatElt Double where    floatEltDiv = divVectorDouble +  floatEltPow = powVectorDouble +  floatEltLogbase = logbaseVectorDouble    floatEltRecip = recipVectorDouble +  floatEltExp = expVectorDouble +  floatEltLog = logVectorDouble +  floatEltSqrt = sqrtVectorDouble +  floatEltSin = sinVectorDouble +  floatEltCos = cosVectorDouble +  floatEltTan = tanVectorDouble +  floatEltAsin = asinVectorDouble +  floatEltAcos = acosVectorDouble +  floatEltAtan = atanVectorDouble +  floatEltSinh = sinhVectorDouble +  floatEltCosh = coshVectorDouble +  floatEltTanh = tanhVectorDouble +  floatEltAsinh = asinhVectorDouble +  floatEltAcosh = acoshVectorDouble +  floatEltAtanh = atanhVectorDouble +  floatEltLog1p = log1pVectorDouble +  floatEltExpm1 = expm1VectorDouble +  floatEltLog1pexp = log1pexpVectorDouble +  floatEltLog1mexp = log1mexpVectorDouble | 
