changeset 9025:484756d558d6

add Array<T>::find
author Jaroslav Hajek <highegg@gmail.com>
date Thu, 26 Mar 2009 13:05:00 +0100
parents 15774d99f4cc
children 6890d411a0b8
files liboctave/Array.cc liboctave/Array.h liboctave/ChangeLog
diffstat 3 files changed, 75 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/liboctave/Array.cc	Wed Mar 25 23:42:12 2009 -0400
+++ b/liboctave/Array.cc	Thu Mar 26 13:05:00 2009 +0100
@@ -2487,6 +2487,69 @@
   return idx;
 }
 
+template <class T>
+Array<octave_idx_type> 
+Array<T>::find (octave_idx_type n, bool backward) const
+{
+  Array<octave_idx_type> retval;
+  const T *src = data ();
+  octave_idx_type nel = nelem ();
+  const T zero = T ();
+  if (n < 0)
+    {
+      // We want all elements, which means we'll almost surely need
+      // to resize. So count first, then allocate array of exact size.
+      octave_idx_type cnt = 0;
+      for (octave_idx_type i = 0; i < nel; i++)
+        cnt += src[i] != zero;
+
+      retval = Array<octave_idx_type> (cnt);
+      octave_idx_type *dest = retval.fortran_vec ();
+      for (octave_idx_type i = 0; i < nel; i++)
+        if (src[i] != zero) *dest++ = i;
+    }
+  else
+    {
+      // We want a fixed max number of elements, usually small. So be
+      // optimistic, alloc the array in advance, and then resize if
+      // needed.
+      retval = Array<octave_idx_type> (n);
+      if (backward)
+        {
+          // Do the search as a series of successive single-element searches.
+          octave_idx_type k = 0, l = nel - 1;
+          for (; k < n; k++)
+            {
+              for (;l >= 0 && src[l] == zero; l--) ;
+              if (l >= 0)
+                retval(k) = l--;
+              else
+                break;
+            }
+          if (k < n)
+            retval.resize (k);
+        }
+      else
+        {
+          // Do the search as a series of successive single-element searches.
+          octave_idx_type k = 0, l = 0;
+          for (; k < n; k++)
+            {
+              for (;l != nel && src[l] == zero; l++) ;
+              if (l != n)
+                retval(k) = l++;
+              else
+                break;
+            }
+          if (k < n)
+            retval.resize (k);
+        }
+    }
+
+  return retval;
+}
+
+
 #define INSTANTIATE_ARRAY_SORT(T) template class octave_sort<T>;
 
 #define NO_INSTANTIATE_ARRAY_SORT(T) \
@@ -2520,7 +2583,9 @@
 template <> Array<octave_idx_type>  \
 Array<T>::lookup (const Array<T>&, sortmode, bool, bool) const \
 { return Array<octave_idx_type> (); } \
-
+template <> Array<octave_idx_type> \
+Array<T>::find (octave_idx_type, bool) const\
+{ return Array<octave_idx_type> (); } \
 
 
 template <class T>
--- a/liboctave/Array.h	Wed Mar 25 23:42:12 2009 -0400
+++ b/liboctave/Array.h	Thu Mar 26 13:05:00 2009 +0100
@@ -579,6 +579,10 @@
   Array<octave_idx_type> lookup (const Array<T>& values, sortmode mode = UNSORTED, 
                                  bool linf = false, bool rinf = false) const;
 
+  // Find indices of (at most n) nonzero elements. If n is specified, backward
+  // specifies search from backward.
+  Array<octave_idx_type> find (octave_idx_type n = -1, bool backward = false) const;
+
   Array<T> diag (octave_idx_type k = 0) const;
 
   template <class U, class F>
--- a/liboctave/ChangeLog	Wed Mar 25 23:42:12 2009 -0400
+++ b/liboctave/ChangeLog	Thu Mar 26 13:05:00 2009 +0100
@@ -1,3 +1,8 @@
+2009-03-26  Jaroslav Hajek  <highegg@gmail.com>
+
+	* Array.cc (Array<T>::find): New method.
+	* Array.h: Declare it.
+
 2009-03-25  John W. Eaton  <jwe@octave.org>
 
 	* EIG.cc (EIG::init (const Matrix&, bool),