# HG changeset patch # User John W. Eaton # Date 1289294666 18000 # Node ID ce27d6f4e134416a2f030341c5ea00cfc8fbc0dc # Parent 2554b4a0806e7faac456e20f712aedf1c6b02fcc use templates and inline for more lo-mappers functionos diff --git a/liboctave/ChangeLog b/liboctave/ChangeLog --- a/liboctave/ChangeLog +++ b/liboctave/ChangeLog @@ -1,10 +1,17 @@ 2010-11-09 John W. Eaton - * lo-mappers.cc, lo-mappers.h (xmod, xrem): Move definitions + * lo-mappers.cc, lo-mappers.h (xisnan, xisinf, xfinite, xmod, + xrem, floor, ceil, xround, xroundb, signum): Move definitions from lo-mappers.cc to lo-mappers.h and convert to templates. (xtrunc): Move definitions from lo-mappers.cc to lo-mappers.h. - * lo-mappers.cc (fix): Use xtrunc. - * lo-mappers.h (xfloor): New functions. + * lo-mappers.cc (fix): Use xtrunc. Move definitions to + lo-mappers.cc from lo-mappers.h. + (real, imag, conj) Move definitions to lo-mappers.h and declare inline. + (round): Move definitions to lo-mappers.h and declare inline. + Use roundf for float version. + (arg): Move definitions to lo-mappers.h and declare inline. + Use atan2f for float version. + * lo-mappers.h (xceil): New functions. (X_NINT): New template function. (D_NINT, F_NINT): Define in terms of X_NINT. * lo-utils.h, lo-utils.cc (D_NINT, F_NINT): Delete. diff --git a/liboctave/lo-mappers.cc b/liboctave/lo-mappers.cc --- a/liboctave/lo-mappers.cc +++ b/liboctave/lo-mappers.cc @@ -40,42 +40,6 @@ // double -> double mappers. -double -arg (double x) -{ - return atan2 (0.0, x); -} - -double -conj (double x) -{ - return x; -} - -double -fix (double x) -{ - return xtrunc (x); -} - -double -imag (double) -{ - return 0.0; -} - -double -real (double x) -{ - return x; -} - -double -xround (double x) -{ - return gnulib::round (x); -} - double xroundb (double x) { @@ -242,44 +206,6 @@ return log ((1.0 + x) / (1.0 - x)) / 2.0; } -Complex -ceil (const Complex& x) -{ - return Complex (ceil (real (x)), ceil (imag (x))); -} - -Complex -fix (const Complex& x) -{ - return Complex (fix (real (x)), fix (imag (x))); -} - -Complex -floor (const Complex& x) -{ - return Complex (floor (real (x)), floor (imag (x))); -} - -Complex -xround (const Complex& x) -{ - return Complex (xround (real (x)), xround (imag (x))); -} - -Complex -xroundb (const Complex& x) -{ - return Complex (xroundb (real (x)), xroundb (imag (x))); -} - -Complex -signum (const Complex& x) -{ - double tmp = abs (x); - - return tmp == 0 ? 0.0 : x / tmp; -} - // complex -> bool mappers. bool @@ -313,48 +239,12 @@ // float -> float mappers. -float -arg (float x) -{ - return atan2 (0.0f, x); -} - -float -conj (float x) -{ - return x; -} - -float -fix (float x) -{ - return xtrunc (x); -} - -float -imag (float) -{ - return 0.0; -} - -float -real (float x) -{ - return x; -} - -float -xround (float x) -{ - return gnulib::round (x); -} - float xroundb (float x) { float t = xround (x); - if (fabs (x - t) == 0.5) + if (fabsf (x - t) == 0.5) t = 2 * xtrunc (0.5 * t); return t; @@ -515,44 +405,6 @@ return log ((static_cast(1.0) + x) / (static_cast(1.0) - x)) / static_cast(2.0); } -FloatComplex -ceil (const FloatComplex& x) -{ - return FloatComplex (ceil (real (x)), ceil (imag (x))); -} - -FloatComplex -fix (const FloatComplex& x) -{ - return FloatComplex (fix (real (x)), fix (imag (x))); -} - -FloatComplex -floor (const FloatComplex& x) -{ - return FloatComplex (floor (real (x)), floor (imag (x))); -} - -FloatComplex -xround (const FloatComplex& x) -{ - return FloatComplex (xround (real (x)), xround (imag (x))); -} - -FloatComplex -xroundb (const FloatComplex& x) -{ - return FloatComplex (xroundb (real (x)), xroundb (imag (x))); -} - -FloatComplex -signum (const FloatComplex& x) -{ - float tmp = abs (x); - - return tmp == 0 ? 0.0 : x / tmp; -} - // complex -> bool mappers. bool @@ -595,87 +447,107 @@ return fabsf (x) > 1.0f ? acos (FloatComplex (x)) : FloatComplex (acosf (x)); } -Complex rc_acosh (double x) +Complex +rc_acosh (double x) { return x < 1.0 ? acosh (Complex (x)) : Complex (acosh (x)); } -FloatComplex rc_acosh (float x) +FloatComplex +rc_acosh (float x) { return x < 1.0f ? acosh (FloatComplex (x)) : FloatComplex (acoshf (x)); } -Complex rc_asin (double x) +Complex +rc_asin (double x) { return fabs (x) > 1.0 ? asin (Complex (x)) : Complex (asin (x)); } -FloatComplex rc_asin (float x) +FloatComplex +rc_asin (float x) { return fabsf (x) > 1.0f ? asin (FloatComplex (x)) : FloatComplex (asinf (x)); } -Complex rc_atanh (double x) +Complex +rc_atanh (double x) { return fabs (x) > 1.0 ? atanh (Complex (x)) : Complex (atanh (x)); } -FloatComplex rc_atanh (float x) +FloatComplex +rc_atanh (float x) { return fabsf (x) > 1.0f ? atanh (FloatComplex (x)) : FloatComplex (atanhf (x)); } -Complex rc_log (double x) +Complex +rc_log (double x) { const double pi = 3.14159265358979323846; return x < 0.0 ? Complex (log (-x), pi) : Complex (log (x)); } -FloatComplex rc_log (float x) +FloatComplex +rc_log (float x) { const float pi = 3.14159265358979323846f; return x < 0.0f ? FloatComplex (logf (-x), pi) : FloatComplex (logf (x)); } -Complex rc_log2 (double x) +Complex +rc_log2 (double x) { const double pil2 = 4.53236014182719380962; // = pi / log(2) return x < 0.0 ? Complex (xlog2 (-x), pil2) : Complex (xlog2 (x)); } -FloatComplex rc_log2 (float x) +FloatComplex +rc_log2 (float x) { const float pil2 = 4.53236014182719380962f; // = pi / log(2) return x < 0.0f ? FloatComplex (xlog2 (-x), pil2) : FloatComplex (xlog2 (x)); } -Complex rc_log10 (double x) +Complex +rc_log10 (double x) { const double pil10 = 1.36437635384184134748; // = pi / log(10) return x < 0.0 ? Complex (log10 (-x), pil10) : Complex (log10 (x)); } -FloatComplex rc_log10 (float x) +FloatComplex +rc_log10 (float x) { const float pil10 = 1.36437635384184134748f; // = pi / log(10) return x < 0.0f ? FloatComplex (log10 (-x), pil10) : FloatComplex (log10f (x)); } -Complex rc_sqrt (double x) +Complex +rc_sqrt (double x) { return x < 0.0 ? Complex (0.0, sqrt (-x)) : Complex (sqrt (x)); } -FloatComplex rc_sqrt (float x) +FloatComplex +rc_sqrt (float x) { return x < 0.0f ? FloatComplex (0.0f, sqrtf (-x)) : FloatComplex (sqrtf (x)); } -bool xnegative_sign (double x) -{ return __lo_ieee_signbit (x); } +bool +xnegative_sign (double x) +{ + return __lo_ieee_signbit (x); +} -bool xnegative_sign (float x) -{ return __lo_ieee_float_signbit (x); } +bool +xnegative_sign (float x) +{ + return __lo_ieee_float_signbit (x); +} // Convert X to the nearest integer value. Should not pass NaN to // this function. diff --git a/liboctave/lo-mappers.h b/liboctave/lo-mappers.h --- a/liboctave/lo-mappers.h +++ b/liboctave/lo-mappers.h @@ -33,14 +33,15 @@ // Double Precision inline double xtrunc (double x) { return gnulib::trunc (x); } inline double xcopysign (double x, double y) { return copysignf (x, y); } +inline double xceil (double x) { return ceil (x); } inline double xfloor (double x) { return floor (x); } -extern OCTAVE_API double arg (double x); -extern OCTAVE_API double conj (double x); -extern OCTAVE_API double fix (double x); -extern OCTAVE_API double imag (double x); -extern OCTAVE_API double real (double x); -extern OCTAVE_API double xround (double x); +inline double arg (double x) { return atan2 (0.0, x); } +inline double conj (double x) { return x; } +inline double fix (double x) { return xtrunc (x); } +inline double imag (double) { return 0.0; } +inline double real (double x) { return x; } +inline double xround (double x) { return gnulib::round (x); } extern OCTAVE_API double xroundb (double x); extern OCTAVE_API double signum (double x); extern OCTAVE_API double xlog2 (double x); @@ -78,18 +79,30 @@ // Generic xmin, xmax definitions template inline T xmin (T x, T y) -{ return x <= y ? x : y; } +{ + return x <= y ? x : y; +} + template inline T xmax (T x, T y) -{ return x >= y ? x : y; } +{ + return x >= y ? x : y; +} -// This form is favorable. GCC will translate (x <= y ? x : y) without a jump, -// hence the only conditional jump involved will be the first (xisnan), infrequent -// and hence friendly to branch prediction. -inline double xmin (double x, double y) -{ return xisnan (y) ? x : (x <= y ? x : y);; } -inline double xmax (double x, double y) -{ return xisnan (y) ? x : (x >= y ? x : y);; } +// This form is favorable. GCC will translate (x <= y ? x : y) without a +// jump, hence the only conditional jump involved will be the first +// (xisnan), infrequent and hence friendly to branch prediction. +inline double +xmin (double x, double y) +{ + return xisnan (y) ? x : (x <= y ? x : y); +} + +inline double +xmax (double x, double y) +{ + return xisnan (y) ? x : (x >= y ? x : y); +} extern OCTAVE_API Complex acos (const Complex& x); extern OCTAVE_API Complex acosh (const Complex& x); @@ -98,23 +111,6 @@ extern OCTAVE_API Complex atan (const Complex& x); extern OCTAVE_API Complex atanh (const Complex& x); -extern OCTAVE_API Complex ceil (const Complex& x); -extern OCTAVE_API Complex fix (const Complex& x); -extern OCTAVE_API Complex floor (const Complex& x); -extern OCTAVE_API Complex xround (const Complex& x); -extern OCTAVE_API Complex xroundb (const Complex& x); -extern OCTAVE_API Complex signum (const Complex& x); - -inline bool -xisnan (const Complex& x) -{ return (xisnan (real (x)) || xisnan (imag (x))); } -inline bool -xfinite (const Complex& x) -{ return (xfinite (real (x)) && xfinite (imag (x))); } -inline bool -xisinf (const Complex& x) -{ return (xisinf (real (x)) || xisinf (imag (x))); } - extern OCTAVE_API bool octave_is_NA (const Complex& x); extern OCTAVE_API bool octave_is_NaN_or_NA (const Complex& x); @@ -124,14 +120,15 @@ // Single Precision inline float xtrunc (float x) { return gnulib::truncf (x); } inline float xcopysign (float x, float y) { return copysignf (x, y); } +inline float xceil (float x) { return ceilf (x); } inline float xfloor (float x) { return floorf (x); } -extern OCTAVE_API float arg (float x); -extern OCTAVE_API float conj (float x); -extern OCTAVE_API float fix (float x); -extern OCTAVE_API float imag (float x); -extern OCTAVE_API float real (float x); -extern OCTAVE_API float xround (float x); +inline float arg (float x) { return atan2f (0.0f, x); } +inline float conj (float x) { return x; } +inline float fix (float x) { return xtrunc (x); } +inline float imag (float) { return 0.0f; } +inline float real (float x) { return x; } +inline float xround (float x) { return gnulib::round (x); } extern OCTAVE_API float xroundb (float x); extern OCTAVE_API float signum (float x); extern OCTAVE_API float xlog2 (float x); @@ -159,14 +156,20 @@ extern OCTAVE_API bool xisinf (float x); #endif - extern OCTAVE_API bool octave_is_NA (float x); extern OCTAVE_API bool octave_is_NaN_or_NA (float x) GCC_ATTR_DEPRECATED; -inline float xmin (float x, float y) -{ return xisnan (y) ? x : (x <= y ? x : y);; } -inline float xmax (float x, float y) -{ return xisnan (y) ? x : (x >= y ? x : y);; } +inline float +xmin (float x, float y) +{ + return xisnan (y) ? x : (x <= y ? x : y); +} + +inline float +xmax (float x, float y) +{ + return xisnan (y) ? x : (x >= y ? x : y); +} extern OCTAVE_API FloatComplex acos (const FloatComplex& x); extern OCTAVE_API FloatComplex acosh (const FloatComplex& x); @@ -175,23 +178,6 @@ extern OCTAVE_API FloatComplex atan (const FloatComplex& x); extern OCTAVE_API FloatComplex atanh (const FloatComplex& x); -extern OCTAVE_API FloatComplex ceil (const FloatComplex& x); -extern OCTAVE_API FloatComplex fix (const FloatComplex& x); -extern OCTAVE_API FloatComplex floor (const FloatComplex& x); -extern OCTAVE_API FloatComplex xround (const FloatComplex& x); -extern OCTAVE_API FloatComplex xroundb (const FloatComplex& x); -extern OCTAVE_API FloatComplex signum (const FloatComplex& x); - -inline bool -xisnan (const FloatComplex& x) -{ return (xisnan (real (x)) || xisnan (imag (x))); } -inline bool -xfinite (const FloatComplex& x) -{ return (xfinite (real (x)) && xfinite (imag (x))); } -inline bool -xisinf (const FloatComplex& x) -{ return (xisinf (real (x)) || xisinf (imag (x))); } - extern OCTAVE_API bool octave_is_NA (const FloatComplex& x); extern OCTAVE_API bool octave_is_NaN_or_NA (const FloatComplex& x); @@ -219,15 +205,24 @@ // Some useful tests, that are commonly repeated. // Test for a finite integer. -inline bool xisinteger (double x) -{ return xfinite (x) && x == xround (x); } -inline bool xisinteger (float x) -{ return xfinite (x) && x == xround (x); } +inline bool +xisinteger (double x) +{ + return xfinite (x) && x == xround (x); +} + +inline bool +xisinteger (float x) +{ + return xfinite (x) && x == xround (x); +} // Test for negative sign. extern OCTAVE_API bool xnegative_sign (double x); extern OCTAVE_API bool xnegative_sign (float x); +// Some old rounding functions. + extern OCTAVE_API octave_idx_type NINTbig (double x); extern OCTAVE_API octave_idx_type NINTbig (float x); @@ -248,6 +243,71 @@ // Template functions can have either float or double arguments. template +bool +xisnan (const std::complex& x) +{ + return (xisnan (real (x)) || xisnan (imag (x))); +} + +template +bool +xfinite (const std::complex& x) +{ + return (xfinite (real (x)) && xfinite (imag (x))); +} + +template +bool +xisinf (const std::complex& x) +{ + return (xisinf (real (x)) || xisinf (imag (x))); +} + +template +std::complex +fix (const std::complex& x) +{ + return std::complex (fix (real (x)), fix (imag (x))); +} + +template +std::complex +ceil (const std::complex& x) +{ + return std::complex (xceil (real (x)), xceil (imag (x))); +} + +template +std::complex +floor (const std::complex& x) +{ + return std::complex (xfloor (real (x)), xfloor (imag (x))); +} + +template +std::complex +xround (const std::complex& x) +{ + return std::complex (xround (real (x)), xround (imag (x))); +} + +template +std::complex +xroundb (const std::complex& x) +{ + return std::complex (xroundb (real (x)), xroundb (imag (x))); +} + +template +std::complex +signum (const std::complex& x) +{ + T tmp = abs (x); + + return tmp == 0 ? 0.0 : x / tmp; +} + +template OCTAVE_API T xmod (T x, T y)