diff options
author | Erik Schnetter <schnetter@gmail.com> | 2012-12-01 12:53:49 -0500 |
---|---|---|
committer | Erik Schnetter <schnetter@gmail.com> | 2012-12-01 12:53:49 -0500 |
commit | 1d94d7894b3802497833de2d465529118e1f70c5 (patch) | |
tree | f9d9714f4a6a621532c454fb95b2e72cfaf898e0 | |
parent | 058c31f56befa0b0a9935d5a1a9f904cf6c39afc (diff) | |
download | vecmathlib-1d94d7894b3802497833de2d465529118e1f70c5.zip vecmathlib-1d94d7894b3802497833de2d465529118e1f70c5.tar.gz |
Implement asinh and exp
-rw-r--r-- | mathfuncs.h | 2 | ||||
-rw-r--r-- | mathfuncs_asinh.h | 35 | ||||
-rw-r--r-- | mathfuncs_base.h | 11 | ||||
-rw-r--r-- | mathfuncs_exp.h | 68 | ||||
-rw-r--r-- | test.cc | 360 | ||||
-rw-r--r-- | vec_base.h | 78 | ||||
-rw-r--r-- | vec_double_avx.h | 61 | ||||
-rw-r--r-- | vec_float.h | 24 |
8 files changed, 568 insertions, 71 deletions
diff --git a/mathfuncs.h b/mathfuncs.h index e62358b..f693150 100644 --- a/mathfuncs.h +++ b/mathfuncs.h @@ -6,7 +6,9 @@ #include "mathfuncs_base.h" #include "mathfuncs_asin.h" +#include "mathfuncs_asinh.h" #include "mathfuncs_convert.h" +#include "mathfuncs_exp.h" #include "mathfuncs_fabs.h" #include "mathfuncs_log.h" #include "mathfuncs_rcp.h" diff --git a/mathfuncs_asinh.h b/mathfuncs_asinh.h new file mode 100644 index 0000000..6ea7efd --- /dev/null +++ b/mathfuncs_asinh.h @@ -0,0 +1,35 @@ +// -*-C++-*- + +#ifndef MATHFUNCS_ASINH_H +#define MATHFUNCS_ASINH_H + +#include "mathfuncs_base.h" + +#include <cassert> +#include <cmath> + + + +namespace vecmathlib { + + template<typename realvec_t> + realvec_t mathfuncs<realvec_t>::vml_acosh(realvec_t x) + { + return log(x + sqrt(x*x - RV(1.0))); + } + + template<typename realvec_t> + realvec_t mathfuncs<realvec_t>::vml_asinh(realvec_t x) + { + return log(x + sqrt(x*x + RV(1.0))); + } + + template<typename realvec_t> + realvec_t mathfuncs<realvec_t>::vml_atanh(realvec_t x) + { + return RV(0.5) * log((RV(1.0) + x) / (RV(1.0) - x)); + } + +}; // namespace vecmathlib + +#endif // #ifndef MATHFUNCS_ASINH_H diff --git a/mathfuncs_base.h b/mathfuncs_base.h index 0b9f04f..59be31a 100644 --- a/mathfuncs_base.h +++ b/mathfuncs_base.h @@ -37,6 +37,11 @@ namespace vecmathlib { static realvec_t vml_asin(realvec_t x); static realvec_t vml_atan(realvec_t x); + // asinh + static realvec_t vml_acosh(realvec_t x); + static realvec_t vml_asinh(realvec_t x); + static realvec_t vml_atanh(realvec_t x); + // convert static realvec_t vml_convert_float(intvec_t x); static intvec_t vml_convert_int(realvec_t x); @@ -48,6 +53,12 @@ namespace vecmathlib { static realvec_t vml_scalbn(realvec_t x, intvec_t n); static boolvec_t vml_signbit(realvec_t x); + // exp + static realvec_t vml_exp(realvec_t x); + static realvec_t vml_exp10(realvec_t x); + static realvec_t vml_exp2(realvec_t x); + static realvec_t vml_expm1(realvec_t x); + // log static realvec_t vml_log(realvec_t x); static realvec_t vml_log10(realvec_t x); diff --git a/mathfuncs_exp.h b/mathfuncs_exp.h new file mode 100644 index 0000000..bad3959 --- /dev/null +++ b/mathfuncs_exp.h @@ -0,0 +1,68 @@ +// -*-C++-*- + +#ifndef MATHFUNCS_EXP_H +#define MATHFUNCS_EXP_H + +#include "mathfuncs_base.h" + +#include <cassert> +#include <cmath> + + + +namespace vecmathlib { + + template<typename realvec_t> + realvec_t mathfuncs<realvec_t>::vml_exp2(realvec_t x) + { + // Rescale + realvec_t x0 = x; + realvec_t floor_x = floor(x); + x -= floor_x; + intvec_t ifloor_x = convert_int(floor_x); + + // Approximate + assert(all(x >= RV(0.0) && x < RV(1.0))); + // exp(x) = Sum[n=0,nmax] x^n / n! + int const nmax = 15; + x -= RV(0.5); // shift range to increase accuracy + x *= RV(M_LN2); + realvec_t y = RV(M_SQRT2); // x^n / n!, compensated for range shift + realvec_t r = y; + for (int n=1; n<nmax; ++n) { + y *= x * RV(R(1.0) / R(n)); + r += y; + } + + // Undo rescaling + r = ifthen(x0 < RV(R(FP::min_exponent)), RV(0.0), scalbn(r, ifloor_x)); + + return r; + } + + + + template<typename realvec_t> + inline + realvec_t mathfuncs<realvec_t>::vml_exp(realvec_t x) + { + return exp2(RV(M_LOG2E) * x); + } + + template<typename realvec_t> + inline + realvec_t mathfuncs<realvec_t>::vml_exp10(realvec_t x) + { + return exp(RV(M_LN10) * x); + } + + template<typename realvec_t> + inline + realvec_t mathfuncs<realvec_t>::vml_expm1(realvec_t x) + { + return exp(x) - RV(1.0); + } + +}; // namespace vecmathlib + +#endif // #ifndef MATHFUNCS_EXP_H @@ -0,0 +1,360 @@ +// -*-C++-*- + +#include "vecmathlib.h" + +#include <cmath> +#include <cstdio> +#include <cstdlib> +#include <iomanip> +#include <iostream> +#include <typeinfo> + +using namespace std; + + + +int num_errors = 0; + + + +template<typename realvec_t> +struct vecmathlib_test { + + typedef typename realvec_t::boolvec_t boolvec_t; + typedef typename realvec_t::intvec_t intvec_t; + + typedef typename realvec_t::int_t int_t; + typedef typename realvec_t::real_t real_t; + + typedef vecmathlib::floatprops<real_t> FP; + + + + static int const imax = 1000; + static real_t constexpr accuracy = pow(realvec_t::epsilon(), real_t(0.75)); + + + + static realvec_t random(real_t const xmin, real_t const xmax) + { + realvec_t x; + for (int i=0; i<realvec_t::size; ++i) { + x.set_elt(i, xmin + (xmax - xmin) * real_t(rand()) / real_t(RAND_MAX)); + } + return x; + } + + static intvec_t random(int_t const nmin, int_t const nmax) + { + intvec_t n; + for (int i=0; i<intvec_t::size; ++i) { + real_t x = + real_t(nmax - nmin + 1) * + real_t(rand()) / (real_t(RAND_MAX) + real_t(1.0)); + n.set_elt(i, nmin + FP::convert_int(std::floor(x))); + } + return n; + } + + + + template<typename A> + static void check(char const* const func, + real_t fstd(typename A::scalar_t), realvec_t fvml(A), + A const x, + real_t const accuracy) + { + realvec_t rstd; + for (int i=0; i<realvec_t::size; ++i) { + rstd.set_elt(i, fstd(x[i])); + } + realvec_t const rvml = fvml(x); + realvec_t const dr = rstd - rvml; + if (any(fabs(dr) > + realvec_t(accuracy) * (fabs(rstd) + fabs(rvml) + realvec_t(1.0)))) + { + ++ num_errors; + cout << setprecision(realvec_t::digits10+1) + << "Error in " << func << "(" << x << "):\n" + << " fstd(x)=" << rstd << "\n" + << " fvml(x)=" << rvml << "\n"; + } + } + + template<typename A, typename B> + static void check(char const* const func, + real_t fstd(typename A::scalar_t, typename B::scalar_t), + realvec_t fvml(A, B), + A const x, B const y, + real_t const accuracy) + { + realvec_t rstd; + for (int i=0; i<realvec_t::size; ++i) { + rstd.set_elt(i, fstd(x[i], y[i])); + } + realvec_t const rvml = fvml(x, y); + realvec_t const dr = rstd - rvml; + if (any(fabs(dr) > + realvec_t(accuracy) * (fabs(rstd) + fabs(rvml) + realvec_t(1.0)))) + { + ++ num_errors; + cout << setprecision(realvec_t::digits10+1) + << "Error in " << func << "(" << x << "," << y << "):\n" + << " fstd(x,y)=" << rstd << "\n" + << " fvml(x,y)=" << rvml << "\n"; + } + } + + template<typename A> + static void check(char const* const func, + int_t fstd(typename A::scalar_t), intvec_t fvml(A), + A const x) + { + intvec_t rstd; + for (int i=0; i<intvec_t::size; ++i) { + rstd.set_elt(i, fstd(x[i])); + } + intvec_t const rvml = fvml(x); + intvec_t const dr = rstd - rvml; + if (any(convert_bool(dr))) { + cout << setprecision(realvec_t::digits10+1) + << "Error in " << func << "(" << x << "):\n" + << " fstd(x)=" << rstd << "\n" + << " fvml(x)=" << rvml << "\n"; + } + } + + template<typename A, typename B> + static void check(char const* const func, + int fstd(typename A::scalar_t, typename B::scalar_t), + intvec_t fvml(A, B), + A const x, B const y) + { + intvec_t rstd; + for (int i=0; i<intvec_t::size; ++i) { + rstd.set_elt(i, fstd(x[i], y[i])); + } + intvec_t const rvml = fvml(x, y); + intvec_t const dr = rstd - rvml; + if (any(convert_bool(dr))) { + ++ num_errors; + cout << setprecision(realvec_t::digits10+1) + << "Error in " << func << "(" << x << "," << y << "):\n" + << " fstd(x,y)=" << rstd << "\n" + << " fvml(x,y)=" << rvml << "\n"; + } + } + + template<typename A> + static void check(char const* const func, + bool fstd(typename A::scalar_t), boolvec_t fvml(A), + A const x) + { + boolvec_t rstd; + for (int i=0; i<boolvec_t::size; ++i) { + rstd.set_elt(i, fstd(x[i])); + } + boolvec_t const rvml = fvml(x); + boolvec_t const dr = rstd != rvml; + if (any(dr)) { + cout << setprecision(realvec_t::digits10+1) + << "Error in " << func << "(" << x << "):\n" + << " fstd(x)=" << rstd << "\n" + << " fvml(x)=" << rvml << "\n"; + } + } + + + + static int_t ilogb(real_t x) { return std::ilogb(x); } + static real_t scalbn(real_t x, int_t n) { return std::scalbn(x, n); } + static void test_fabs() + { + cout << " testing copysign fabs ilogb scalbn signbit...\n"; + for (int i=0; i<imax; ++i) { + realvec_t const x = random(real_t(-10.0), real_t(+10.0)); + realvec_t const y = random(real_t(-10.0), real_t(+10.0)); + intvec_t const n = random(int_t(-10), int_t(+10)); + check("copysign", copysign, vecmathlib::copysign, x, y, 0.0); + check("fabs", fabs, vecmathlib::fabs, x, 0.0); + check("ilogb", ilogb, vecmathlib::ilogb, x); + check("scalbn", scalbn, vecmathlib::scalbn, x, n, 0.0); + check("signbit", signbit, vecmathlib::signbit, x); + } + } + + static void test_convert() + { + cout << " testing convert_float convert_int...\n"; + for (int i=0; i<imax; ++i) { + realvec_t const x = random(real_t(-10.0), real_t(+10.0)); + intvec_t const n = random(int_t(-10), int_t(+10)); + check("convert_float", + FP::convert_float, vecmathlib::convert_float, n, accuracy); + check("convert_int", FP::convert_int, vecmathlib::convert_int, x); + } + } + + + + static void test_asin() + { + cout << " testing asin acos atan...\n"; + for (int i=0; i<imax; ++i) { + realvec_t const x = random(real_t(-1.0), real_t(+1.0)); + check("asin", asin, vecmathlib::asin, x, accuracy); + check("acos", acos, vecmathlib::acos, x, accuracy); + } + for (int i=0; i<imax; ++i) { + realvec_t const x = random(real_t(-100.0), real_t(+100.0)); + check("atan", atan, vecmathlib::atan, x, accuracy); + } + } + + static void test_asinh() + { + cout << " testing asinh acosh atanh...\n"; + for (int i=0; i<imax; ++i) { + realvec_t const x = random(real_t(-1000.0), real_t(+1000.0)); + // asinh loses accuracy (by definition, not by implementation?) + check("asinh", asinh, vecmathlib::asinh, x, real_t(1.0e+3)*accuracy); + } + for (int i=0; i<imax; ++i) { + realvec_t const x = random(real_t(1.0), real_t(1000.0)); + check("acosh", acosh, vecmathlib::acosh, x, accuracy); + } + for (int i=0; i<imax; ++i) { + realvec_t const x = random(real_t(-1.0), real_t(+1.0)); + check("atanh", atanh, vecmathlib::atanh, x, accuracy); + } + } + + static real_t exp10(real_t x) { return pow(real_t(10.0), x); } + static void test_exp() + { + cout << " testing exp exp10 exp2 expm1...\n"; + for (int i=0; i<imax; ++i) { + realvec_t const x = random(real_t(-100.0), real_t(+100.0)); + check("exp", exp, vecmathlib::exp, x, accuracy); + check("exp10", exp10, vecmathlib::exp10, x, accuracy); + check("exp2", exp2, vecmathlib::exp2, x, accuracy); + check("expm1", expm1, vecmathlib::expm1, x, accuracy); + } + } + + static void test_log() + { + cout << " testing log log10 log1p log2...\n"; + for (int i=0; i<imax; ++i) { + realvec_t const x = random(real_t(1.0e-10), real_t(1.0e+10)); + check("log", log, vecmathlib::log, x, accuracy); + check("log10", log10, vecmathlib::log10, x, accuracy); + check("log1p", log1p, vecmathlib::log1p, x, accuracy); + check("log2", log2, vecmathlib::log2, x, accuracy); + } + } + + // static real_t pown(real_t const x, long long const n) + // { + // return pow(x, real_t(n)); + // } + // void test_pow() + // { + // for (int i=0; i<imax; ++i) { + // real_t const x = random(0.001, 1000.0); + // real_t const y = random(-10.0, +10.0); + // check("pow", pow, vecmathlib::pow, x, y, accuracy); + // } + // for (int i=0; i<imax; ++i) { + // real_t const x = random(-1000.0, +1000.0); + // long long const n = llrandom(-10, +10); + // check("pown", pown, vecmathlib::pown, x, n, accuracy); + // } + // } + + static real_t rcp(real_t x) { return real_t(1.0)/x; } + static void test_rcp() + { + cout << " testing rcp...\n"; + for (int i=0; i<imax; ++i) { + realvec_t const x = random(real_t(-10.0), real_t(+10.0)); + check("rcp", rcp, vecmathlib::rcp, x, accuracy); + } + } + + // void test_sin() + // { + // for (int i=0; i<imax; ++i) { + // real_t const x = random(-10.0, 10.0); + // check("sin", sin, vecmathlib::sin, x, accuracy); + // check("cos", cos, vecmathlib::cos, x, accuracy); + // check("tan", tan, vecmathlib::tan, x, accuracy); + // } + // } + + // void test_sinh() + // { + // for (int i=0; i<imax; ++i) { + // real_t const x = random(-10.0, 10.0); + // check("sinh", sinh, vecmathlib::sinh, x, accuracy); + // check("cosh", cosh, vecmathlib::cosh, x, accuracy); + // check("tanh", tanh, vecmathlib::tanh, x, accuracy); + // } + // } + + static real_t rsqrt(real_t x) { return real_t(1.0)/sqrt(x); } + static void test_sqrt() + { + cout << " testing rsqrt sqrt...\n"; + for (int i=0; i<imax; ++i) { + realvec_t const x = random(real_t(0.0), real_t(1.0e+3)); + check("rsqrt", rsqrt, vecmathlib::rsqrt, x, accuracy); + check("sqrt", sqrt, vecmathlib::sqrt, x, accuracy); + } + } + + + + static void test() + { + cout << "\n" + << "Testing math functions for type " + // << typeid(realvec_t).name() + << realvec_t::name + << ":\n"; + + test_fabs(); + test_convert(); + + test_asin(); + test_asinh(); + test_exp(); + // test_log(); + // test_pow(); + test_rcp(); + // test_sin(); + // test_sinh(); + test_sqrt(); + } +}; + + + +int main(int argc, char** argv) +{ + using namespace vecmathlib; + + cout << "Testing math functions:\n"; + + vecmathlib_test<realvec<float,1>>::test(); + vecmathlib_test<realvec<double,4>>::test(); + + cout << "\n"; + if (num_errors == 0) { + cout << "SUCCESS"; + } else { + cout << "FAILURE"; + } + cout << ": " << num_errors << " errors found\n"; + return num_errors == 0 ? 0 : 1; +} @@ -134,56 +134,76 @@ namespace vecmathlib { template<typename real_t, int size> - inline realvec<real_t, size> copysign(realvec<real_t, size> x, - realvec<real_t, size> y) + inline realvec<real_t, size> acos(realvec<real_t, size> x) { - return x.copysign(y); + return x.acos(); } template<typename real_t, int size> - inline realvec<real_t, size> fabs(realvec<real_t, size> x) + inline realvec<real_t, size> acosh(realvec<real_t, size> x) { - return x.fabs(); + return x.acosh(); } template<typename real_t, int size> - inline intvec<real_t, size> ilogb(realvec<real_t, size> x) + inline realvec<real_t, size> asin(realvec<real_t, size> x) { - return x.ilogb(); + return x.asin(); } template<typename real_t, int size> - inline - realvec<real_t, size> scalbn(realvec<real_t, size> x, - intvec<real_t, size> n) + inline realvec<real_t, size> asinh(realvec<real_t, size> x) { - return x.scalbn(n); + return x.asinh(); } template<typename real_t, int size> - inline boolvec<real_t, size> signbit(realvec<real_t, size> x) + inline realvec<real_t, size> atan(realvec<real_t, size> x) { - return x.signbit(); + return x.atan(); } + template<typename real_t, int size> + inline realvec<real_t, size> atanh(realvec<real_t, size> x) + { + return x.atanh(); + } + template<typename real_t, int size> + inline realvec<real_t, size> copysign(realvec<real_t, size> x, + realvec<real_t, size> y) + { + return x.copysign(y); + } template<typename real_t, int size> - inline realvec<real_t, size> acos(realvec<real_t, size> x) + inline realvec<real_t, size> exp(realvec<real_t, size> x) { - return x.acos(); + return x.exp(); } template<typename real_t, int size> - inline realvec<real_t, size> asin(realvec<real_t, size> x) + inline realvec<real_t, size> exp10(realvec<real_t, size> x) { - return x.asin(); + return x.exp10(); } template<typename real_t, int size> - inline realvec<real_t, size> atan(realvec<real_t, size> x) + inline realvec<real_t, size> exp2(realvec<real_t, size> x) { - return x.atan(); + return x.exp2(); + } + + template<typename real_t, int size> + inline realvec<real_t, size> expm1(realvec<real_t, size> x) + { + return x.expm1(); + } + + template<typename real_t, int size> + inline realvec<real_t, size> fabs(realvec<real_t, size> x) + { + return x.fabs(); } template<typename real_t, int size> @@ -193,6 +213,12 @@ namespace vecmathlib { } template<typename real_t, int size> + inline intvec<real_t, size> ilogb(realvec<real_t, size> x) + { + return x.ilogb(); + } + + template<typename real_t, int size> inline realvec<real_t, size> log(realvec<real_t, size> x) { return x.log(); @@ -229,6 +255,20 @@ namespace vecmathlib { } template<typename real_t, int size> + inline + realvec<real_t, size> scalbn(realvec<real_t, size> x, + intvec<real_t, size> n) + { + return x.scalbn(n); + } + + template<typename real_t, int size> + inline boolvec<real_t, size> signbit(realvec<real_t, size> x) + { + return x.signbit(); + } + + template<typename real_t, int size> inline realvec<real_t, size> sqrt(realvec<real_t, size> x) { return x.sqrt(); diff --git a/vec_double_avx.h b/vec_double_avx.h index cbea5c2..cca990d 100644 --- a/vec_double_avx.h +++ b/vec_double_avx.h @@ -25,7 +25,7 @@ namespace vecmathlib { template<> struct boolvec<double,4>: floatprops<double> { - static const int size = 4; + static int const size = 4; typedef bool scalar_t; typedef __m256d bvector_t; @@ -113,7 +113,7 @@ namespace vecmathlib { template<> struct intvec<double,4>: floatprops<double> { - static const int size = 4; + static int const size = 4; typedef int_t scalar_t; typedef __m256i ivector_t; @@ -356,10 +356,12 @@ namespace vecmathlib { template<> struct realvec<double,4>: floatprops<double> { - static const int size = 4; + static int const size = 4; typedef real_t scalar_t; typedef __m256d vector_t; + static constexpr char const* const name = "<AVX:4*double>"; + static_assert(size * sizeof(real_t) == sizeof(vector_t), "vector size is wrong"); @@ -450,51 +452,20 @@ namespace vecmathlib { -#if 0 - realvec copysign(realvec y) const - { - uint_t signmask = U(1) << (bits-1); - intvec_t value = as_int() & IV(~signmask); - intvec_t sign = y.as_int() & IV(signmask); - return (sign | value).as_float(); - } - - realvec fabs() const - { - uint_t signmask = U(1) << (bits-1); - return (as_int() & IV(~signmask)).as_float(); - } - - intvec_t ilogb() const - { - intvec_t exponent_mask = - ((U(1) << exponent_bits) - U(1)) << mantissa_bits; - return lsr(as_int() & exponent_mask, mantissa_bits) - IV(exponent_offset); - } - - realvec scalbn(intvec_t n) const - { - return *this * ((n + exponent_offset) << mantissa_bits).as_float(); - } - - boolvec_t signbit() const - { - return v; - } -#endif - - realvec copysign(realvec y) const { return MF::vml_copysign(*this, y); } - realvec fabs() const { return MF::vml_fabs(*this); } - intvec_t ilogb() const { return MF::vml_ilogb(*this); } - realvec scalbn(intvec_t n) const { return MF::vml_scalbn(*this, n); } - boolvec_t signbit() const { return v; } - - - realvec acos() const { return MF::vml_acos(*this); } + realvec acosh() const { return MF::vml_acosh(*this); } realvec asin() const { return MF::vml_asin(*this); } + realvec asinh() const { return MF::vml_asinh(*this); } realvec atan() const { return MF::vml_atan(*this); } + realvec atanh() const { return MF::vml_atanh(*this); } + realvec copysign(realvec y) const { return MF::vml_copysign(*this, y); } + realvec exp() const { return MF::vml_exp(*this); } + realvec exp10() const { return MF::vml_exp10(*this); } + realvec exp2() const { return MF::vml_exp2(*this); } + realvec expm1() const { return MF::vml_expm1(*this); } + realvec fabs() const { return MF::vml_fabs(*this); } realvec floor() const { return _mm256_floor_pd(v); } + intvec_t ilogb() const { return MF::vml_ilogb(*this); } realvec log() const { return MF::vml_log(*this); } realvec log10() const { return MF::vml_log10(*this); } realvec log1p() const { return MF::vml_log1p(*this); } @@ -502,6 +473,8 @@ namespace vecmathlib { realvec rcp() const { return _mm256_div_pd(_mm256_set1_pd(1.0), v); } // realvec rcp() const { return MF::vml_rcp(*this); } realvec rsqrt() const { return MF::vml_rsqrt(*this); } + boolvec_t signbit() const { return v; } + realvec scalbn(intvec_t n) const { return MF::vml_scalbn(*this, n); } realvec sqrt() const { return _mm256_sqrt_pd(v); } // realvec sqrt() const { return MF::vml_sqrt(*this); } }; diff --git a/vec_float.h b/vec_float.h index 6025ab7..d89d5e3 100644 --- a/vec_float.h +++ b/vec_float.h @@ -22,7 +22,7 @@ namespace vecmathlib { template<> struct boolvec<float,1>: floatprops<float> { - static const int size = 1; + static int const size = 1; typedef bool scalar_t; typedef bool bvector_t; @@ -87,7 +87,7 @@ namespace vecmathlib { template<> struct intvec<float,1>: floatprops<float> { - static const int size = 1; + static int const size = 1; typedef int_t scalar_t; typedef int_t ivector_t; @@ -176,6 +176,8 @@ namespace vecmathlib { typedef real_t scalar_t; typedef real_t vector_t; + static constexpr char const* const name = "<1*float>"; + typedef boolvec<real_t, size> boolvec_t; typedef intvec<real_t, size> intvec_t; typedef realvec realvec_t; @@ -239,22 +241,28 @@ namespace vecmathlib { - realvec copysign(realvec x) const { return MF::vml_copysign(v, x.v); } - realvec fabs() const { return MF::vml_fabs(v); } - intvec_t ilogb() const { return MF::vml_ilogb(v); } - realvec scalbn(intvec_t n) const { return MF::vml_scalbn(v, n.v); } - boolvec_t signbit() const { return MF::vml_signbit(v); } - realvec acos() const { return MF::vml_acos(*this); } + realvec acosh() const { return MF::vml_acosh(*this); } realvec asin() const { return MF::vml_asin(*this); } + realvec asinh() const { return MF::vml_asinh(*this); } realvec atan() const { return MF::vml_atan(*this); } + realvec atanh() const { return MF::vml_atanh(*this); } + realvec copysign(realvec x) const { return MF::vml_copysign(v, x.v); } + realvec exp() const { return MF::vml_exp(*this); } + realvec exp10() const { return MF::vml_exp10(*this); } + realvec exp2() const { return MF::vml_exp2(*this); } + realvec expm1() const { return MF::vml_expm1(*this); } + realvec fabs() const { return MF::vml_fabs(v); } realvec floor() const { return std::floor(v); } + intvec_t ilogb() const { return MF::vml_ilogb(v); } realvec log() const { return MF::vml_log(*this); } realvec log10() const { return MF::vml_log10(*this); } realvec log1p() const { return MF::vml_log1p(*this); } realvec log2() const { return MF::vml_log2(*this); } realvec rcp() const { return MF::vml_rcp(*this); } realvec rsqrt() const { return MF::vml_rsqrt(*this); } + realvec scalbn(intvec_t n) const { return MF::vml_scalbn(v, n.v); } + boolvec_t signbit() const { return MF::vml_signbit(v); } realvec sqrt() const { return MF::vml_sqrt(*this); } }; |