diff liboctave/Array.cc @ 9920:56fbe170d354

fix issorted with NaNs in middle
author Jaroslav Hajek <highegg@gmail.com>
date Fri, 04 Dec 2009 14:02:15 +0100
parents cddd5c3d5f04
children 7c8392a034e6
line wrap: on
line diff
--- a/liboctave/Array.cc	Fri Dec 04 15:33:51 2009 -0800
+++ b/liboctave/Array.cc	Fri Dec 04 14:02:15 2009 +0100
@@ -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>  \