changeset 10414:2a8b1db1e2ca

implement built-in cbrt
author Jaroslav Hajek <highegg@gmail.com>
date Tue, 16 Mar 2010 15:16:32 +0100
parents 271c5262975b
children 976e76b77fa0
files configure.ac liboctave/ChangeLog liboctave/lo-specfun.cc liboctave/lo-specfun.h src/ChangeLog src/mappers.cc src/ov-base.cc src/ov-base.h src/ov-float.cc src/ov-flt-re-mat.cc src/ov-re-mat.cc src/ov-re-sparse.cc src/ov-scalar.cc src/ov.h
diffstat 14 files changed, 94 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/configure.ac	Tue Mar 16 12:29:49 2010 +0100
+++ b/configure.ac	Tue Mar 16 15:16:32 2010 +0100
@@ -1690,7 +1690,7 @@
 ### Check for nonstandard but common math functions that we need.
 
 AC_CHECK_FUNCS(acosh acoshf asinh asinhf atanh atanhf erf erff erfc erfcf exp2f log2 log2f)
-AC_CHECK_FUNCS(hypotf _hypotf)
+AC_CHECK_FUNCS(hypotf _hypotf cbrt cbrtf)
 
 ### Checks for OS specific cruft.
 
--- a/liboctave/ChangeLog	Tue Mar 16 12:29:49 2010 +0100
+++ b/liboctave/ChangeLog	Tue Mar 16 15:16:32 2010 +0100
@@ -1,3 +1,9 @@
+2010-03-16  Jaroslav Hajek  <highegg@gmail.com>
+
+	* lo-specfun.cc: Substitute cbrt and cbrtf if needed.
+	* lo-specfun.h: Declare cbrt and cbrtf if needed.
+	* configure.ac: Check for cbrt and cbrtf.
+
 2010-03-15  John W. Eaton  <jwe@octave.org>
 
 	* oct-glob.cc (octave_glob): Tag calls to glob and globfree with
--- a/liboctave/lo-specfun.cc	Tue Mar 16 12:29:49 2010 +0100
+++ b/liboctave/lo-specfun.cc	Tue Mar 16 15:16:32 2010 +0100
@@ -560,6 +560,22 @@
   return retval;
 }
 
+#if !defined (HAVE_CBRT)
+double cbrt (double x)
+{
+  static const double one_third = 0.3333333333333333333;
+  if (xfinite (x))
+    {
+      // Use pow.
+      double y = std::pow (std::abs (x), one_third) * signum (x);
+      // Correct for better accuracy.
+      return (x / (y*y) + y + y) / 3;
+    }
+  else
+    return x;
+}
+#endif
+
 #if !defined (HAVE_LOG1PF)
 float
 log1pf (float x)
@@ -603,6 +619,22 @@
   return retval;
 }
 
+#if !defined (HAVE_CBRTF)
+float cbrtf (float x)
+{
+  static const float one_third = 0.3333333333333333333f;
+  if (xfinite (x))
+    {
+      // Use pow.
+      float y = std::pow (std::abs (x), one_third) * signum (x);
+      // Correct for better accuracy.
+      return (x / (y*y) + y + y) / 3;
+    }
+  else
+    return x;
+}
+#endif
+
 static inline Complex
 zbesj (const Complex& z, double alpha, int kode, octave_idx_type& ierr);
 
--- a/liboctave/lo-specfun.h	Tue Mar 16 12:29:49 2010 +0100
+++ b/liboctave/lo-specfun.h	Tue Mar 16 15:16:32 2010 +0100
@@ -101,6 +101,14 @@
 #endif
 extern OCTAVE_API FloatComplex log1p (const FloatComplex& x);
 
+#if !defined (HAVE_CBRT)
+extern OCTAVE_API double cbrt (double x);
+#endif
+
+#if !defined (HAVE_CBRTF)
+extern OCTAVE_API float cbrtf (float x);
+#endif
+
 extern OCTAVE_API double xgamma (double x);
 extern OCTAVE_API double xlgamma (double x);
 extern OCTAVE_API Complex rc_lgamma (double x);
--- a/src/ChangeLog	Tue Mar 16 12:29:49 2010 +0100
+++ b/src/ChangeLog	Tue Mar 16 15:16:32 2010 +0100
@@ -1,3 +1,13 @@
+2010-03-16  Jaroslav Hajek  <highegg@gmail.com>
+
+	* ov-base.h (unary_mapper_t::umap_cbrt): New enum member.
+	* ov.h (octave_value::cbrt): New forwarder method.
+	* ov-scalar.cc (octave_scalar::map): Handle cbrt.
+	* ov-float.cc (octave_float_scalar::map): Ditto.
+	* ov-re-mat.cc (octave_matrix::map): Ditto.
+	* ov-flt-re-mat.cc (octave_float_matrix::map): Ditto.
+	* ov-re-sparse.cc (octave_sparse_matrix::map): Ditto.
+
 2010-03-15  John W. Eaton  <jwe@octave.org>
 
 	* oct-parse.yy, lex.ll: Undefine GNULIB_NAMESPACE immediately
--- a/src/mappers.cc	Tue Mar 16 12:29:49 2010 +0100
+++ b/src/mappers.cc	Tue Mar 16 15:16:32 2010 +0100
@@ -351,6 +351,35 @@
 
 */
 
+DEFUN (cbrt, args, ,
+    "-*- texinfo -*-\n\
+@deftypefn {Mapping Function} {} cbrt (@var{x})\n\
+Return the real cube root of @var{x}. Unlike @code{@var{x}^(1/3)},\n\
+the result will be negative if @var{x} is negative.\n\
+@end deftypefn")
+{
+  octave_value retval;
+  if (args.length () == 1)
+    retval = args(0).cbrt ();
+  else
+    print_usage ();
+
+  return retval;
+}
+
+/*
+
+%!assert (cbrt (64), 4)
+%!assert (cbrt (-125), -5)
+%!assert (cbrt (0), 0)
+%!assert (cbrt (Inf), Inf)
+%!assert (cbrt (-Inf), -Inf)
+%!assert (cbrt (NaN), NaN)
+%!assert (cbrt (2^300), 2^100)
+%!assert (cbrt (125*2^300), 5*2^100)
+
+*/
+
 DEFUN (ceil, args, ,
     "-*- texinfo -*-\n\
 @deftypefn {Mapping Function} {} ceil (@var{x})\n\
--- a/src/ov-base.cc	Tue Mar 16 12:29:49 2010 +0100
+++ b/src/ov-base.cc	Tue Mar 16 15:16:32 2010 +0100
@@ -1150,6 +1150,7 @@
       "asinh",
       "atan",
       "atanh",
+      "cbrt",
       "ceil",
       "conj",
       "cos",
--- a/src/ov-base.h	Tue Mar 16 12:29:49 2010 +0100
+++ b/src/ov-base.h	Tue Mar 16 15:16:32 2010 +0100
@@ -658,6 +658,7 @@
       umap_asinh,
       umap_atan,
       umap_atanh,
+      umap_cbrt,
       umap_ceil,
       umap_conj,
       umap_cos,
--- a/src/ov-float.cc	Tue Mar 16 12:29:49 2010 +0100
+++ b/src/ov-float.cc	Tue Mar 16 15:16:32 2010 +0100
@@ -290,6 +290,7 @@
       SCALAR_MAPPER (erfcx, ::erfcx);
       SCALAR_MAPPER (gamma, xgamma);
       SCALAR_MAPPER (lgamma, rc_lgamma);
+      SCALAR_MAPPER (cbrt, ::cbrtf);
       SCALAR_MAPPER (ceil, ::ceilf);
       SCALAR_MAPPER (cos, ::cosf);
       SCALAR_MAPPER (cosh, ::coshf);
--- a/src/ov-flt-re-mat.cc	Tue Mar 16 12:29:49 2010 +0100
+++ b/src/ov-flt-re-mat.cc	Tue Mar 16 15:16:32 2010 +0100
@@ -770,6 +770,7 @@
       ARRAY_MAPPER (erfcx, float, ::erfcx);
       ARRAY_MAPPER (gamma, float, xgamma);
       RC_ARRAY_MAPPER (lgamma, FloatComplex, rc_lgamma);
+      ARRAY_MAPPER (cbrt, float, ::cbrtf);
       ARRAY_MAPPER (ceil, float, ::ceilf);
       ARRAY_MAPPER (cos, float, ::cosf);
       ARRAY_MAPPER (cosh, float, ::coshf);
--- a/src/ov-re-mat.cc	Tue Mar 16 12:29:49 2010 +0100
+++ b/src/ov-re-mat.cc	Tue Mar 16 15:16:32 2010 +0100
@@ -893,6 +893,7 @@
       ARRAY_MAPPER (erfcx, double, ::erfcx);
       ARRAY_MAPPER (gamma, double, xgamma);
       RC_ARRAY_MAPPER (lgamma, Complex, rc_lgamma);
+      ARRAY_MAPPER (cbrt, double, ::cbrt);
       ARRAY_MAPPER (ceil, double, ::ceil);
       ARRAY_MAPPER (cos, double, ::cos);
       ARRAY_MAPPER (cosh, double, ::cosh);
--- a/src/ov-re-sparse.cc	Tue Mar 16 12:29:49 2010 +0100
+++ b/src/ov-re-sparse.cc	Tue Mar 16 15:16:32 2010 +0100
@@ -913,6 +913,7 @@
       ARRAY_MAPPER (erfc, double, ::erfc);
       ARRAY_MAPPER (gamma, double, xgamma);
       ARRAY_MAPPER (lgamma, Complex, rc_lgamma);
+      ARRAY_MAPPER (cbrt, double, ::cbrt);
       ARRAY_MAPPER (ceil, double, ::ceil);
       ARRAY_MAPPER (cos, double, ::cos);
       ARRAY_MAPPER (cosh, double, ::cosh);
--- a/src/ov-scalar.cc	Tue Mar 16 12:29:49 2010 +0100
+++ b/src/ov-scalar.cc	Tue Mar 16 15:16:32 2010 +0100
@@ -306,6 +306,7 @@
       SCALAR_MAPPER (erfcx, ::erfcx);
       SCALAR_MAPPER (gamma, xgamma);
       SCALAR_MAPPER (lgamma, rc_lgamma);
+      SCALAR_MAPPER (cbrt, ::cbrt);
       SCALAR_MAPPER (ceil, ::ceil);
       SCALAR_MAPPER (cos, ::cos);
       SCALAR_MAPPER (cosh, ::cosh);
--- a/src/ov.h	Tue Mar 16 12:29:49 2010 +0100
+++ b/src/ov.h	Tue Mar 16 15:16:32 2010 +0100
@@ -1082,6 +1082,7 @@
   MAPPER_FORWARD (asinh)
   MAPPER_FORWARD (atan)
   MAPPER_FORWARD (atanh)
+  MAPPER_FORWARD (cbrt)
   MAPPER_FORWARD (ceil)
   MAPPER_FORWARD (conj)
   MAPPER_FORWARD (cos)