changeset 15213:4bbd3bbb8912

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<T>::test): Call any_all_test. * Sparse.h (Sparse<T>::test, Sparse<T>::test_any, Sparse<T>::test_all, Sparse<T>::test_any, Sparse<T>::test_any, Sparse<T>::test_all, Sparse<T>::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.
author John W. Eaton <jwe@octave.org>
date Wed, 22 Aug 2012 16:16:31 -0400
parents efd2024c7d56
children 336f42406671
files liboctave/Array.h liboctave/CMatrix.cc liboctave/CNDArray.cc liboctave/CSparse.cc liboctave/Sparse.h liboctave/dMatrix.cc liboctave/dNDArray.cc liboctave/dSparse.cc liboctave/fCMatrix.cc liboctave/fCNDArray.cc liboctave/lo-utils.cc liboctave/lo-utils.h
diffstat 12 files changed, 74 insertions(+), 124 deletions(-) [+]
line wrap: on
line diff
--- a/liboctave/Array.h
+++ b/liboctave/Array.h
@@ -646,30 +646,7 @@
   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;
+    return any_all_test<F, T, zero> (fcn, data (), length ());
   }
 
   // Simpler calls.
--- 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
--- 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
--- 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
--- a/liboctave/Sparse.h
+++ b/liboctave/Sparse.h
@@ -584,6 +584,35 @@
 
   Array<T> array_value (void) const;
 
+  // Generic any/all test functionality with arbitrary predicate.
+  template <class F, bool zero>
+  bool test (F fcn) const
+  {
+    return any_all_test<F, T, zero> (fcn, data (), nnz ());
+  }
+
+  // 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, class F>
   Sparse<U>
   map (F fcn) const
--- 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
--- 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.
--- 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
--- 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;
 }
 
--- 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;
 }
 
--- 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; }
 
--- a/liboctave/lo-utils.h
+++ b/liboctave/lo-utils.h
@@ -28,14 +28,46 @@
 #include <iostream>
 #include <string>
 
+#include "quit.h"
+
 #include "lo-cutils.h"
 #include "oct-cmplx.h"
 
+// Generic any/all test functionality with arbitrary predicate.
+
+template <class F, class T, bool zero>
+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);