summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorErik Schnetter <schnetter@gmail.com>2012-12-01 12:53:49 -0500
committerErik Schnetter <schnetter@gmail.com>2012-12-01 12:53:49 -0500
commit1d94d7894b3802497833de2d465529118e1f70c5 (patch)
treef9d9714f4a6a621532c454fb95b2e72cfaf898e0
parent058c31f56befa0b0a9935d5a1a9f904cf6c39afc (diff)
downloadvecmathlib-1d94d7894b3802497833de2d465529118e1f70c5.zip
vecmathlib-1d94d7894b3802497833de2d465529118e1f70c5.tar.gz
Implement asinh and exp
-rw-r--r--mathfuncs.h2
-rw-r--r--mathfuncs_asinh.h35
-rw-r--r--mathfuncs_base.h11
-rw-r--r--mathfuncs_exp.h68
-rw-r--r--test.cc360
-rw-r--r--vec_base.h78
-rw-r--r--vec_double_avx.h61
-rw-r--r--vec_float.h24
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
diff --git a/test.cc b/test.cc
new file mode 100644
index 0000000..dda725e
--- /dev/null
+++ b/test.cc
@@ -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;
+}
diff --git a/vec_base.h b/vec_base.h
index ab4a558..91316a9 100644
--- a/vec_base.h
+++ b/vec_base.h
@@ -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); }
};
OpenPOWER on IntegriCloud