summaryrefslogtreecommitdiffstats
path: root/mathfuncs_log.h
diff options
context:
space:
mode:
Diffstat (limited to 'mathfuncs_log.h')
-rw-r--r--mathfuncs_log.h137
1 files changed, 63 insertions, 74 deletions
diff --git a/mathfuncs_log.h b/mathfuncs_log.h
index cd71eb3..fa517ba 100644
--- a/mathfuncs_log.h
+++ b/mathfuncs_log.h
@@ -7,93 +7,82 @@
#include <cmath>
+namespace vecmathlib {
+template <typename realvec_t>
+realvec_t mathfuncs<realvec_t>::vml_log2(realvec_t x) {
+ // Algorithm inspired by SLEEF 2.80
-namespace vecmathlib {
-
- template<typename realvec_t>
- realvec_t mathfuncs<realvec_t>::vml_log2(realvec_t x)
- {
- // Algorithm inspired by SLEEF 2.80
-
- // Rescale
- intvec_t ilogb_x = ilogb(x * RV(M_SQRT2));
- x = ldexp(x, -ilogb_x);
- VML_ASSERT(all(x >= RV(M_SQRT1_2) && x <= RV(M_SQRT2)));
-
- realvec_t y = (x - RV(1.0)) / (x + RV(1.0));
- realvec_t y2 = y*y;
-
- realvec_t r;
- switch (sizeof(real_t)) {
- case 4:
- // float, error=7.09807175879142775648452461821e-8
- r = RV(0.59723611417135718739797302426);
- r = mad(r, y2, RV(0.961524413175528426101613434));
- r = mad(r, y2, RV(2.88539097665498228703236701));
- break;
- case 8:
+ // Rescale
+ intvec_t ilogb_x = ilogb(x * RV(M_SQRT2));
+ x = ldexp(x, -ilogb_x);
+ VML_ASSERT(all(x >= RV(M_SQRT1_2) && x <= RV(M_SQRT2)));
+
+ realvec_t y = (x - RV(1.0)) / (x + RV(1.0));
+ realvec_t y2 = y * y;
+
+ realvec_t r;
+ switch (sizeof(real_t)) {
+ case 4:
+ // float, error=7.09807175879142775648452461821e-8
+ r = RV(0.59723611417135718739797302426);
+ r = mad(r, y2, RV(0.961524413175528426101613434));
+ r = mad(r, y2, RV(2.88539097665498228703236701));
+ break;
+ case 8:
#ifdef VML_HAVE_FP_CONTRACT
- // double, error=1.48294180185938512675770096324e-16
- r = RV(0.243683403415639178527756320773);
- r = mad(r, y2, RV(0.26136626803870009948502658));
- r = mad(r, y2, RV(0.320619429891299265439389));
- r = mad(r, y2, RV(0.4121983452028499242926));
- r = mad(r, y2, RV(0.577078017761894161436));
- r = mad(r, y2, RV(0.96179669392233355927));
- r = mad(r, y2, RV(2.8853900817779295236));
+ // double, error=1.48294180185938512675770096324e-16
+ r = RV(0.243683403415639178527756320773);
+ r = mad(r, y2, RV(0.26136626803870009948502658));
+ r = mad(r, y2, RV(0.320619429891299265439389));
+ r = mad(r, y2, RV(0.4121983452028499242926));
+ r = mad(r, y2, RV(0.577078017761894161436));
+ r = mad(r, y2, RV(0.96179669392233355927));
+ r = mad(r, y2, RV(2.8853900817779295236));
#else
- // double, error=2.1410114030383689267772704676e-14
- r = RV(0.283751646449323373643963474845);
- r = mad(r, y2, RV(0.31983138095551191299118812));
- r = mad(r, y2, RV(0.412211603844146279666022));
- r = mad(r, y2, RV(0.5770779098948940070516));
- r = mad(r, y2, RV(0.961796694295973716912));
- r = mad(r, y2, RV(2.885390081777562819196));
+ // double, error=2.1410114030383689267772704676e-14
+ r = RV(0.283751646449323373643963474845);
+ r = mad(r, y2, RV(0.31983138095551191299118812));
+ r = mad(r, y2, RV(0.412211603844146279666022));
+ r = mad(r, y2, RV(0.5770779098948940070516));
+ r = mad(r, y2, RV(0.961796694295973716912));
+ r = mad(r, y2, RV(2.885390081777562819196));
#endif
- break;
- default:
- __builtin_unreachable();
- }
- r *= y;
-
- // Undo rescaling
- r += convert_float(ilogb_x);
-
- return r;
- }
-
-
-
- template<typename realvec_t>
- inline
- realvec_t mathfuncs<realvec_t>::vml_log(realvec_t x)
- {
- return log2(x) * RV(M_LN2);
+ break;
+ default:
+ __builtin_unreachable();
}
+ r *= y;
- template<typename realvec_t>
- inline
- realvec_t mathfuncs<realvec_t>::vml_log10(realvec_t x)
- {
- return log(x) * RV(M_LOG10E);
- }
+ // Undo rescaling
+ r += convert_float(ilogb_x);
- template<typename realvec_t>
- inline
- realvec_t mathfuncs<realvec_t>::vml_log1p(realvec_t x)
- {
- // TODO: Check SLEEF 2.80 algorithm
-
- return log(RV(1.0) + x);
+ return r;
+}
+
+template <typename realvec_t>
+inline realvec_t mathfuncs<realvec_t>::vml_log(realvec_t x) {
+ return log2(x) * RV(M_LN2);
+}
+
+template <typename realvec_t>
+inline realvec_t mathfuncs<realvec_t>::vml_log10(realvec_t x) {
+ return log(x) * RV(M_LOG10E);
+}
+
+template <typename realvec_t>
+inline realvec_t mathfuncs<realvec_t>::vml_log1p(realvec_t x) {
+ // TODO: Check SLEEF 2.80 algorithm
+
+ return log(RV(1.0) + x);
#if 0
// Goldberg, theorem 4
realvec_t x1 = RV(1.0) + x;
x1.barrier();
return ifthen(x1 == x, x, x * log(x1) / (x1 - RV(1.0)));
#endif
- }
-
+}
+
}; // namespace vecmathlib
-#endif // #ifndef MATHFUNCS_LOG_H
+#endif // #ifndef MATHFUNCS_LOG_H
OpenPOWER on IntegriCloud