Mercurial > hg > octave-avbm
changeset 11010:9478b216752e
simplify more array tests
author | Jaroslav Hajek <highegg@gmail.com> |
---|---|
date | Wed, 22 Sep 2010 07:06:25 +0200 |
parents | 064aaf82222f |
children | a046d03e2417 |
files | liboctave/Array.h liboctave/ChangeLog liboctave/dMatrix.cc liboctave/dNDArray.cc liboctave/fMatrix.cc liboctave/fNDArray.cc liboctave/lo-mappers.cc liboctave/lo-mappers.h liboctave/lo-utils.cc liboctave/lo-utils.h |
diffstat | 10 files changed, 155 insertions(+), 242 deletions(-) [+] |
line wrap: on
line diff
--- a/liboctave/Array.h +++ b/liboctave/Array.h @@ -623,6 +623,58 @@ map (U (&fcn) (const T&)) const { return map<U, U (&) (const T&)> (fcn); } + // Generic any/all test functionality with arbitrary predicate. + template <class F, bool zero> + bool test (F fcn) const + { + octave_idx_type len = length (); + + const T *m = data (); + + octave_idx_type i; + for (i = 0; i < len - 3; i += 4) + { + octave_quit (); + + if (fcn (m[i]) != zero + || fcn (m[i+1]) != zero + || fcn (m[i+2]) != zero + || fcn (m[i+3]) != zero) + return ! zero; + + } + + octave_quit (); + + for (; i < len; i++) + if (fcn (m[i]) != zero) + return ! zero; + + return zero; + } + + // Simpler calls. + template <class F> + bool test_any (F fcn) const + { return test<F, false> (fcn); } + + template <class F> + bool test_all (F fcn) const + { return test<F, true> (fcn); } + + // Overloads for function references. + bool test_any (bool (&fcn) (T)) const + { return test<bool (&) (T), false> (fcn); } + + bool test_any (bool (&fcn) (const T&)) const + { return test<bool (&) (const T&), false> (fcn); } + + bool test_all (bool (&fcn) (T)) const + { return test<bool (&) (T), true> (fcn); } + + bool test_all (bool (&fcn) (const T&)) const + { return test<bool (&) (const T&), true> (fcn); } + template <class U> friend class Array; // Returns true if this->dims () == dv, and if so, replaces this->dimensions
--- a/liboctave/ChangeLog +++ b/liboctave/ChangeLog @@ -1,3 +1,28 @@ +2010-09-21 Jaroslav Hajek <highegg@gmail.com> + + * Array.h (Array::test, Array::test_all, Array::test_any): New + overloaded template methods. + * lo-mappers.h (xisinteger, xnegative_sign): New bool mappers. + * dNDArray.cc (NDArray::any_element_is_negative, + NDArray::all_integers): Simplify. + * fNDArray.cc (FloatNDArray::any_element_is_negative, + FloatNDArray::all_integers): Simplify. + + * lo-utils.cc (xis_int_or_inf_or_nan, xis_one_or_zero, + xis_zero, xtoo_large_for_float): New utility functions. + + * dNDArray.cc (NDArray::any_element_is_negative, + NDArray::all_integers, NDArray::all_elements_are_zero, + NDArray::all_elements_are_int_or_inf_or_nan, + NDArray::any_element_not_one_or_zero, + NDArray::too_large_for_float): Simplify. + + * fNDArray.cc (FloatNDArray::any_element_is_negative, + FloatNDArray::all_integers, FloatNDArray::all_elements_are_zero, + FloatNDArray::all_elements_are_int_or_inf_or_nan, + FloatNDArray::any_element_not_one_or_zero, + FloatNDArray::too_large_for_float): Simplify. + 2010-09-21 Jaroslav Hajek <highegg@gmail.com> * dNDArray.cc (NDArray::any_element_is_negative,
--- a/liboctave/dMatrix.cc +++ b/liboctave/dMatrix.cc @@ -2621,80 +2621,32 @@ bool Matrix::any_element_is_negative (bool neg_zero) const { - octave_idx_type nel = nelem (); - - if (neg_zero) - { - for (octave_idx_type i = 0; i < nel; i++) - if (lo_ieee_signbit (elem (i))) - return true; - } - else - return do_mx_check<double> (*this, mx_inline_any_negative); - - return false; + return (neg_zero ? test_all (xnegative_sign) + : do_mx_check<double> (*this, mx_inline_any_negative)); } bool Matrix::any_element_is_nan (void) const { - octave_idx_type nel = nelem (); - - for (octave_idx_type i = 0; i < nel; i++) - { - double val = elem (i); - if (xisnan (val)) - return true; - } - - return false; + return do_mx_check<double> (*this, mx_inline_any_nan); } bool Matrix::any_element_is_inf_or_nan (void) const { - octave_idx_type nel = nelem (); - - for (octave_idx_type i = 0; i < nel; i++) - { - double val = elem (i); - if (xisinf (val) || xisnan (val)) - return true; - } - - return false; + return ! do_mx_check<double> (*this, mx_inline_all_finite); } bool Matrix::any_element_not_one_or_zero (void) const { - octave_idx_type nel = nelem (); - - for (octave_idx_type i = 0; i < nel; i++) - { - double val = elem (i); - if (val != 0 && val != 1) - return true; - } - - return false; + return ! test_all (xis_one_or_zero); } bool Matrix::all_elements_are_int_or_inf_or_nan (void) const { - octave_idx_type nel = nelem (); - - for (octave_idx_type i = 0; i < nel; i++) - { - double val = elem (i); - if (xisnan (val) || D_NINT (val) == val) - continue; - else - return false; - } - - return true; + return test_all (xis_int_or_inf_or_nan); } // Return nonzero if any element of M is not an integer. Also extract @@ -2723,7 +2675,7 @@ if (val < min_val) min_val = val; - if (D_NINT (val) != val) + if (! xisinteger (val)) return false; } @@ -2733,18 +2685,7 @@ bool Matrix::too_large_for_float (void) const { - octave_idx_type nel = nelem (); - - for (octave_idx_type i = 0; i < nel; i++) - { - double val = elem (i); - - if (! (xisnan (val) || xisinf (val)) - && fabs (val) > FLT_MAX) - return true; - } - - return false; + return test_all (xtoo_large_for_float); } // FIXME Do these really belong here? Maybe they should be
--- a/liboctave/dNDArray.cc +++ b/liboctave/dNDArray.cc @@ -547,18 +547,8 @@ bool NDArray::any_element_is_negative (bool neg_zero) const { - octave_idx_type nel = nelem (); - - if (neg_zero) - { - for (octave_idx_type i = 0; i < nel; i++) - if (lo_ieee_signbit (elem (i))) - return true; - } - else - return do_mx_check<double> (*this, mx_inline_any_negative); - - return false; + return (neg_zero ? test_all (xnegative_sign) + : do_mx_check<double> (*this, mx_inline_any_negative)); } bool @@ -576,45 +566,19 @@ bool NDArray::any_element_not_one_or_zero (void) const { - octave_idx_type nel = nelem (); - - for (octave_idx_type i = 0; i < nel; i++) - { - double val = elem (i); - if (val != 0 && val != 1) - return true; - } - - return false; + return ! test_all (xis_one_or_zero); } bool NDArray::all_elements_are_zero (void) const { - octave_idx_type nel = nelem (); - - for (octave_idx_type i = 0; i < nel; i++) - if (elem (i) != 0) - return false; - - return true; + return test_all (xis_zero); } bool NDArray::all_elements_are_int_or_inf_or_nan (void) const { - octave_idx_type nel = nelem (); - - for (octave_idx_type i = 0; i < nel; i++) - { - double val = elem (i); - if (xisnan (val) || D_NINT (val) == val) - continue; - else - return false; - } - - return true; + return test_all (xis_int_or_inf_or_nan); } // Return nonzero if any element of M is not an integer. Also extract @@ -643,7 +607,7 @@ if (val < min_val) min_val = val; - if (D_NINT (val) != val) + if (! xisinteger (val)) return false; } @@ -653,34 +617,13 @@ bool NDArray::all_integers (void) const { - octave_idx_type nel = nelem (); - - for (octave_idx_type i = 0; i < nel; i++) - { - double val = elem (i); - - if (D_NINT (val) != val) - return false; - } - - return true; + return test_all (xisinteger); } bool NDArray::too_large_for_float (void) const { - octave_idx_type nel = nelem (); - - for (octave_idx_type i = 0; i < nel; i++) - { - double val = elem (i); - - if (! (xisnan (val) || xisinf (val)) - && fabs (val) > FLT_MAX) - return true; - } - - return false; + return test_all (xtoo_large_for_float); } // FIXME -- this is not quite the right thing.
--- a/liboctave/fMatrix.cc +++ b/liboctave/fMatrix.cc @@ -2620,18 +2620,8 @@ bool FloatMatrix::any_element_is_negative (bool neg_zero) const { - octave_idx_type nel = nelem (); - - if (neg_zero) - { - for (octave_idx_type i = 0; i < nel; i++) - if (lo_ieee_signbit (elem (i))) - return true; - } - else - return do_mx_check<float> (*this, mx_inline_any_negative); - - return false; + return (neg_zero ? test_all (xnegative_sign) + : do_mx_check<float> (*this, mx_inline_any_negative)); } bool @@ -2649,33 +2639,13 @@ bool FloatMatrix::any_element_not_one_or_zero (void) const { - octave_idx_type nel = nelem (); - - for (octave_idx_type i = 0; i < nel; i++) - { - float val = elem (i); - if (val != 0 && val != 1) - return true; - } - - return false; + return ! test_all (xis_one_or_zero); } bool FloatMatrix::all_elements_are_int_or_inf_or_nan (void) const { - octave_idx_type nel = nelem (); - - for (octave_idx_type i = 0; i < nel; i++) - { - float val = elem (i); - if (xisnan (val) || D_NINT (val) == val) - continue; - else - return false; - } - - return true; + return test_all (xis_int_or_inf_or_nan); } // Return nonzero if any element of M is not an integer. Also extract @@ -2704,7 +2674,7 @@ if (val < min_val) min_val = val; - if (D_NINT (val) != val) + if (! xisinteger (val)) return false; } @@ -2714,17 +2684,6 @@ bool FloatMatrix::too_large_for_float (void) const { - octave_idx_type nel = nelem (); - - for (octave_idx_type i = 0; i < nel; i++) - { - float val = elem (i); - - if (! (xisnan (val) || xisinf (val)) - && fabs (val) > FLT_MAX) - return true; - } - return false; }
--- a/liboctave/fNDArray.cc +++ b/liboctave/fNDArray.cc @@ -505,18 +505,8 @@ bool FloatNDArray::any_element_is_negative (bool neg_zero) const { - octave_idx_type nel = nelem (); - - if (neg_zero) - { - for (octave_idx_type i = 0; i < nel; i++) - if (lo_ieee_signbit (elem (i))) - return true; - } - else - return do_mx_check<float> (*this, mx_inline_any_negative); - - return false; + return (neg_zero ? test_all (xnegative_sign) + : do_mx_check<float> (*this, mx_inline_any_negative)); } bool @@ -534,45 +524,19 @@ bool FloatNDArray::any_element_not_one_or_zero (void) const { - octave_idx_type nel = nelem (); - - for (octave_idx_type i = 0; i < nel; i++) - { - float val = elem (i); - if (val != 0 && val != 1) - return true; - } - - return false; + return ! test_all (xis_one_or_zero); } bool FloatNDArray::all_elements_are_zero (void) const { - octave_idx_type nel = nelem (); - - for (octave_idx_type i = 0; i < nel; i++) - if (elem (i) != 0) - return false; - - return true; + return test_all (xis_zero); } bool FloatNDArray::all_elements_are_int_or_inf_or_nan (void) const { - octave_idx_type nel = nelem (); - - for (octave_idx_type i = 0; i < nel; i++) - { - float val = elem (i); - if (xisnan (val) || D_NINT (val) == val) - continue; - else - return false; - } - - return true; + return test_all (xis_int_or_inf_or_nan); } // Return nonzero if any element of M is not an integer. Also extract @@ -601,7 +565,7 @@ if (val < min_val) min_val = val; - if (D_NINT (val) != val) + if (! xisinteger (val)) return false; } @@ -611,33 +575,12 @@ bool FloatNDArray::all_integers (void) const { - octave_idx_type nel = nelem (); - - for (octave_idx_type i = 0; i < nel; i++) - { - double val = elem (i); - - if (D_NINT (val) != val) - return false; - } - - return true; + return test_all (xisinteger); } bool FloatNDArray::too_large_for_float (void) const { - octave_idx_type nel = nelem (); - - for (octave_idx_type i = 0; i < nel; i++) - { - float val = elem (i); - - if (! (xisnan (val) || xisinf (val)) - && fabs (val) > FLT_MAX) - return true; - } - return false; }
--- a/liboctave/lo-mappers.cc +++ b/liboctave/lo-mappers.cc @@ -702,3 +702,9 @@ { 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 (float x) +{ return __lo_ieee_float_signbit (x); }
--- a/liboctave/lo-mappers.h +++ b/liboctave/lo-mappers.h @@ -211,4 +211,16 @@ extern OCTAVE_API Complex rc_sqrt (double); extern OCTAVE_API FloatComplex rc_sqrt (float); +// 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); } + +// Test for negative sign. +extern OCTAVE_API bool xnegative_sign (double x); +extern OCTAVE_API bool xnegative_sign (float x); + + #endif
--- a/liboctave/lo-utils.cc +++ b/liboctave/lo-utils.cc @@ -30,6 +30,7 @@ #include <cstdlib> #include <cstdio> #include <cstring> +#include <cfloat> #include <limits> #include <string> @@ -111,6 +112,27 @@ return floor (x + 0.5); } +bool xis_int_or_inf_or_nan (double x) +{ return ! (xisnan (x) || D_NINT (x) == x); } + +bool xis_one_or_zero (double x) +{ return x == 0 || x == 1; } + +bool xis_zero (double x) +{ return x == 0; } + +bool xtoo_large_for_float (double x) +{ return (! (xisnan (x) || xisinf (x)) && fabs (x) > FLT_MAX); } + +bool xis_int_or_inf_or_nan (float x) +{ return ! (xisnan (x) || D_NINT (x) == x); } + +bool xis_one_or_zero (float x) +{ return x == 0 || x == 1; } + +bool xis_zero (float x) +{ return x == 0; } + // Save a string. char *
--- a/liboctave/lo-utils.h +++ b/liboctave/lo-utils.h @@ -39,6 +39,16 @@ extern OCTAVE_API double D_NINT (double x); extern OCTAVE_API float F_NINT (float x); +extern OCTAVE_API bool xis_int_or_inf_or_nan (double x); +extern OCTAVE_API bool xis_one_or_zero (double x); +extern OCTAVE_API bool xis_zero (double x); +extern OCTAVE_API bool xtoo_large_for_float (double x); + +extern OCTAVE_API bool xis_int_or_inf_or_nan (float x); +extern OCTAVE_API bool xis_one_or_zero (float x); +extern OCTAVE_API bool xis_zero (float x); +extern OCTAVE_API bool xtoo_large_for_float (float x); + extern OCTAVE_API char *strsave (const char *); extern OCTAVE_API void