changeset 9920:56fbe170d354

fix issorted with NaNs in middle
author Jaroslav Hajek <highegg@gmail.com>
date Fri, 04 Dec 2009 14:02:15 +0100
parents a463aa0aa0ab
children 7c8392a034e6
files liboctave/Array-C.cc liboctave/Array-d.cc liboctave/Array-f.cc liboctave/Array-fC.cc liboctave/Array.cc liboctave/ChangeLog
diffstat 6 files changed, 54 insertions(+), 56 deletions(-) [+]
line wrap: on
line diff
--- a/liboctave/Array-C.cc
+++ b/liboctave/Array-C.cc
@@ -60,7 +60,7 @@
 }
 
 Array<Complex>::compare_fcn_type
-sortrows_comparator (sortmode mode, const Array<Complex>& a , bool allow_chk)
+safe_comparator (sortmode mode, const Array<Complex>& a , bool allow_chk)
 {
   Array<Complex>::compare_fcn_type result = 0;
 
--- a/liboctave/Array-d.cc
+++ b/liboctave/Array-d.cc
@@ -56,7 +56,7 @@
 }
 
 Array<double>::compare_fcn_type
-sortrows_comparator (sortmode mode, const Array<double>& a , bool allow_chk)
+safe_comparator (sortmode mode, const Array<double>& a , bool allow_chk)
 {
   Array<double>::compare_fcn_type result = 0;
 
--- a/liboctave/Array-f.cc
+++ b/liboctave/Array-f.cc
@@ -56,7 +56,7 @@
 }
 
 Array<float>::compare_fcn_type
-sortrows_comparator (sortmode mode, const Array<float>& a , bool allow_chk)
+safe_comparator (sortmode mode, const Array<float>& a , bool allow_chk)
 {
   Array<float>::compare_fcn_type result = 0;
 
--- a/liboctave/Array-fC.cc
+++ b/liboctave/Array-fC.cc
@@ -60,7 +60,7 @@
 }
 
 Array<FloatComplex>::compare_fcn_type
-sortrows_comparator (sortmode mode, const Array<FloatComplex>& a,
+safe_comparator (sortmode mode, const Array<FloatComplex>& a,
 		     bool allow_chk)
 {
   Array<FloatComplex>::compare_fcn_type result = 0;
--- a/liboctave/Array.cc
+++ b/liboctave/Array.cc
@@ -2189,55 +2189,9 @@
 }
 
 template <class T>
-sortmode
-Array<T>::is_sorted (sortmode mode) const
-{
-  if (nelem () <= 1)
-    return ASCENDING;
-
-  const T *lo = data (), *hi = data () + nelem () - 1;
-
-  // Check for NaNs at the beginning and end.
-  if (mode != ASCENDING && sort_isnan<T> (*lo))
-    {
-      mode = DESCENDING;
-      do
-        ++lo;
-      while (lo < hi && sort_isnan<T> (*lo));
-    }
-  else if (mode != DESCENDING && sort_isnan<T> (*hi))
-    {
-      mode = ASCENDING;
-      do
-        --hi;
-      while (lo < hi && sort_isnan<T> (*hi));
-    }
-  
-  octave_sort<T> lsort;
-
-  // If mode is still unknown, compare lo and hi
-  if (! mode)
-    {
-      if (lsort.descending_compare (*lo, *hi))
-        mode = DESCENDING;
-      else if (lsort.ascending_compare (*lo, *hi))
-        mode = ASCENDING;
-      else
-        mode = ASCENDING;
-    }
-
-  lsort.set_compare (mode);
-
-  if (! lsort.is_sorted (lo, hi - lo + 1))
-    mode = UNSORTED;
-
-  return mode;
-}
-
-template <class T>
 typename Array<T>::compare_fcn_type
-sortrows_comparator (sortmode mode, const Array<T>& /* a */,
-		     bool /* allow_chk */)
+safe_comparator (sortmode mode, const Array<T>& /* a */,
+                 bool /* allow_chk */)
 {
   if (mode == ASCENDING)
     return octave_sort<T>::ascending_compare;
@@ -2248,6 +2202,41 @@
 }
 
 template <class T>
+sortmode
+Array<T>::is_sorted (sortmode mode) const
+{
+  octave_sort<T> lsort;
+
+  octave_idx_type n = numel ();
+
+  if (n <= 1)
+    return mode ? mode : ASCENDING;
+
+  if (! mode)
+    {
+      // Auto-detect mode.
+      compare_fcn_type compare
+	= safe_comparator (ASCENDING, *this, false);
+
+      if (compare (elem (n-1), elem (0)))
+        mode = DESCENDING;
+      else
+        mode = ASCENDING;
+    }
+
+  if (mode)
+    {
+      lsort.set_compare (safe_comparator (mode, *this, false));
+
+      if (! lsort.is_sorted (data (), n))
+        mode = UNSORTED;
+    }
+
+  return mode;
+
+}
+
+template <class T>
 Array<octave_idx_type>
 Array<T>::sort_rows_idx (sortmode mode) const
 {
@@ -2255,7 +2244,7 @@
 
   octave_sort<T> lsort;
 
-  lsort.set_compare (sortrows_comparator (mode, *this, true));
+  lsort.set_compare (safe_comparator (mode, *this, true));
 
   octave_idx_type r = rows (), c = cols ();
 
@@ -2282,7 +2271,7 @@
     {
       // Auto-detect mode.
       compare_fcn_type compare
-	= sortrows_comparator (ASCENDING, *this, false);
+	= safe_comparator (ASCENDING, *this, false);
 
       octave_idx_type i;
       for (i = 0; i < cols (); i++)
@@ -2315,7 +2304,7 @@
 
   if (mode)
     {
-      lsort.set_compare (sortrows_comparator (mode, *this, false));
+      lsort.set_compare (safe_comparator (mode, *this, false));
 
       if (! lsort.is_sorted_rows (data (), r, c))
         mode = UNSORTED;
@@ -2696,7 +2685,7 @@
 { return UNSORTED; } \
  \
 Array<T>::compare_fcn_type \
-sortrows_comparator (sortmode, const Array<T>&, bool) \
+safe_comparator (sortmode, const Array<T>&, bool) \
 { return 0; } \
  \
 template <> Array<octave_idx_type>  \
--- a/liboctave/ChangeLog
+++ b/liboctave/ChangeLog
@@ -1,3 +1,12 @@
+2009-12-05  Jaroslav Hajek  <highegg@gmail.com>
+
+	* Array.cc (sortrows_comparator): Rename to safe_comparator.
+	(Array<T>::is_sorted): Use it here.
+	* Array-d.cc: Update.
+	* Array-f.cc: Update.
+	* Array-C.cc: Update.
+	* Array-fC.cc: Update.
+
 2009-12-03  John W. Eaton  <jwe@octave.org>
 
 	* Makefile.am (BUILT_NODISTFILES): New variable.