# HG changeset patch # User John W. Eaton # Date 1345666591 14400 # Node ID 4bbd3bbb89126cff32bd1b572728a8c5c6c57d37 # Parent efd2024c7d56e159f9ae422a327932acd9d9a712 reduce code duplication in too_large_for_float array functions * lo-utils.h (any_all_test): New function. * lo-utils.h, lo-utils.cc (xtoo_large_for_float (const Complex&)): New function. * Array.h (Array::test): Call any_all_test. * Sparse.h (Sparse::test, Sparse::test_any, Sparse::test_all, Sparse::test_any, Sparse::test_any, Sparse::test_all, Sparse::test_all): New functions. * CMatrix.cc (ComplexMatrix::too_large_for_float): Simplify with test_any and xtoo_large_for_float. * CNDArray.cc (ComplexNDArray::too_large_for_float): Likewise. * CSparse.cc (SparseComplexMatrix::too_large_for_float): Likewise. * dSparse.cc (SparseMatrix::too_large_for_float): Likewise. * dMatrix.cc (Matrix::too_large_for_float): Use test_any, not test_all. * dNDArray.cc (NDArray::too_large_for_float): Likewise. * fCMatrix.cc (FloatComplexMatrix::too_large_for_float): Unconditionlly return false. * fCNDArray.cc (FloatComplexNDArray::too_large_for_float): Likewise. diff --git a/liboctave/Array.h b/liboctave/Array.h --- a/liboctave/Array.h +++ b/liboctave/Array.h @@ -646,30 +646,7 @@ template 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; + return any_all_test (fcn, data (), length ()); } // Simpler calls. diff --git a/liboctave/CMatrix.cc b/liboctave/CMatrix.cc --- a/liboctave/CMatrix.cc +++ b/liboctave/CMatrix.cc @@ -3162,25 +3162,7 @@ bool ComplexMatrix::too_large_for_float (void) const { - octave_idx_type nr = rows (); - octave_idx_type nc = cols (); - - for (octave_idx_type j = 0; j < nc; j++) - for (octave_idx_type i = 0; i < nr; i++) - { - Complex val = elem (i, j); - - double r_val = std::real (val); - double i_val = std::imag (val); - - if ((! (xisnan (r_val) || xisinf (r_val)) - && fabs (r_val) > FLT_MAX) - || (! (xisnan (i_val) || xisinf (i_val)) - && fabs (i_val) > FLT_MAX)) - return true; - } - - return false; + return test_any (xtoo_large_for_float); } // FIXME Do these really belong here? Maybe they should be diff --git a/liboctave/CNDArray.cc b/liboctave/CNDArray.cc --- a/liboctave/CNDArray.cc +++ b/liboctave/CNDArray.cc @@ -584,23 +584,7 @@ bool ComplexNDArray::too_large_for_float (void) const { - octave_idx_type nel = nelem (); - - for (octave_idx_type i = 0; i < nel; i++) - { - Complex val = elem (i); - - double r_val = std::real (val); - double i_val = std::imag (val); - - if ((! (xisnan (r_val) || xisinf (r_val)) - && fabs (r_val) > FLT_MAX) - || (! (xisnan (i_val) || xisinf (i_val)) - && fabs (i_val) > FLT_MAX)) - return true; - } - - return false; + return test_any (xtoo_large_for_float); } boolNDArray diff --git a/liboctave/CSparse.cc b/liboctave/CSparse.cc --- a/liboctave/CSparse.cc +++ b/liboctave/CSparse.cc @@ -7299,23 +7299,7 @@ bool SparseComplexMatrix::too_large_for_float (void) const { - octave_idx_type nel = nnz (); - - for (octave_idx_type i = 0; i < nel; i++) - { - Complex val = data (i); - - double r_val = std::real (val); - double i_val = std::imag (val); - - if (r_val > FLT_MAX - || i_val > FLT_MAX - || r_val < FLT_MIN - || i_val < FLT_MIN) - return true; - } - - return false; + return test_any (xtoo_large_for_float); } // FIXME Do these really belong here? Maybe they should be diff --git a/liboctave/Sparse.h b/liboctave/Sparse.h --- a/liboctave/Sparse.h +++ b/liboctave/Sparse.h @@ -584,6 +584,35 @@ Array array_value (void) const; + // Generic any/all test functionality with arbitrary predicate. + template + bool test (F fcn) const + { + return any_all_test (fcn, data (), nnz ()); + } + + // Simpler calls. + template + bool test_any (F fcn) const + { return test (fcn); } + + template + bool test_all (F fcn) const + { return test (fcn); } + + // Overloads for function references. + bool test_any (bool (&fcn) (T)) const + { return test (fcn); } + + bool test_any (bool (&fcn) (const T&)) const + { return test (fcn); } + + bool test_all (bool (&fcn) (T)) const + { return test (fcn); } + + bool test_all (bool (&fcn) (const T&)) const + { return test (fcn); } + template Sparse map (F fcn) const diff --git a/liboctave/dMatrix.cc b/liboctave/dMatrix.cc --- a/liboctave/dMatrix.cc +++ b/liboctave/dMatrix.cc @@ -2723,7 +2723,7 @@ bool Matrix::too_large_for_float (void) const { - return test_all (xtoo_large_for_float); + return test_any (xtoo_large_for_float); } // FIXME Do these really belong here? Maybe they should be diff --git a/liboctave/dNDArray.cc b/liboctave/dNDArray.cc --- a/liboctave/dNDArray.cc +++ b/liboctave/dNDArray.cc @@ -632,7 +632,7 @@ bool NDArray::too_large_for_float (void) const { - return test_all (xtoo_large_for_float); + return test_any (xtoo_large_for_float); } // FIXME -- this is not quite the right thing. diff --git a/liboctave/dSparse.cc b/liboctave/dSparse.cc --- a/liboctave/dSparse.cc +++ b/liboctave/dSparse.cc @@ -7418,17 +7418,7 @@ bool SparseMatrix::too_large_for_float (void) const { - octave_idx_type nel = nnz (); - - for (octave_idx_type i = 0; i < nel; i++) - { - double val = data (i); - - if (val > FLT_MAX || val < FLT_MIN) - return true; - } - - return false; + return test_any (xtoo_large_for_float); } SparseBoolMatrix diff --git a/liboctave/fCMatrix.cc b/liboctave/fCMatrix.cc --- a/liboctave/fCMatrix.cc +++ b/liboctave/fCMatrix.cc @@ -3158,24 +3158,6 @@ bool FloatComplexMatrix::too_large_for_float (void) const { - octave_idx_type nr = rows (); - octave_idx_type nc = cols (); - - for (octave_idx_type j = 0; j < nc; j++) - for (octave_idx_type i = 0; i < nr; i++) - { - FloatComplex val = elem (i, j); - - float r_val = std::real (val); - float i_val = std::imag (val); - - if ((! (xisnan (r_val) || xisinf (r_val)) - && fabs (r_val) > FLT_MAX) - || (! (xisnan (i_val) || xisinf (i_val)) - && fabs (i_val) > FLT_MAX)) - return true; - } - return false; } diff --git a/liboctave/fCNDArray.cc b/liboctave/fCNDArray.cc --- a/liboctave/fCNDArray.cc +++ b/liboctave/fCNDArray.cc @@ -581,22 +581,6 @@ bool FloatComplexNDArray::too_large_for_float (void) const { - octave_idx_type nel = nelem (); - - for (octave_idx_type i = 0; i < nel; i++) - { - FloatComplex val = elem (i); - - float r_val = std::real (val); - float i_val = std::imag (val); - - if ((! (xisnan (r_val) || xisinf (r_val)) - && fabs (r_val) > FLT_MAX) - || (! (xisnan (i_val) || xisinf (i_val)) - && fabs (i_val) > FLT_MAX)) - return true; - } - return false; } diff --git a/liboctave/lo-utils.cc b/liboctave/lo-utils.cc --- a/liboctave/lo-utils.cc +++ b/liboctave/lo-utils.cc @@ -56,6 +56,12 @@ bool xtoo_large_for_float (double x) { return (! (xisnan (x) || xisinf (x)) && fabs (x) > FLT_MAX); } +bool xtoo_large_for_float (const Complex& x) +{ + return (xtoo_large_for_float (x.real ()) + || xtoo_large_for_float (x.imag ())); +} + bool xis_int_or_inf_or_nan (float x) { return xisnan (x) || D_NINT (x) == x; } diff --git a/liboctave/lo-utils.h b/liboctave/lo-utils.h --- a/liboctave/lo-utils.h +++ b/liboctave/lo-utils.h @@ -28,14 +28,46 @@ #include #include +#include "quit.h" + #include "lo-cutils.h" #include "oct-cmplx.h" +// Generic any/all test functionality with arbitrary predicate. + +template +bool +any_all_test (F fcn, const T *m, octave_idx_type len) +{ + 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; +} + 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 xtoo_large_for_float (const Complex& 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);