changeset 9894:83bd7f34f9da

improve idx_vector->octave_value conversion
author Jaroslav Hajek <highegg@gmail.com>
date Tue, 01 Dec 2009 10:41:52 +0100
parents 609726a25877
children 5a4f8d52bb0e
files liboctave/ChangeLog liboctave/idx-vector.cc liboctave/idx-vector.h src/ChangeLog src/DLD-FUNCTIONS/find.cc src/ov-bool-mat.h src/ov-re-mat.h src/ov.cc
diffstat 8 files changed, 89 insertions(+), 23 deletions(-) [+]
line wrap: on
line diff
--- a/liboctave/ChangeLog	Mon Nov 30 16:17:04 2009 -0800
+++ b/liboctave/ChangeLog	Tue Dec 01 10:41:52 2009 +0100
@@ -1,3 +1,12 @@
+2009-12-01  Jaroslav Hajek  <highegg@gmail.com>
+
+	* idx-vector.cc (idx_vector::idx_range_rep::unconvert,
+	idx_vector::idx_scalar_rep::unconvert,
+	idx_vector::idx_vector_rep::unconvert,
+	idx_vector::idx_mask_rep::unconvert): New methods.
+	(idx_vector::unconvert): Use them here. Add mask output.
+	* idx-vector.h: Update decls.
+
 2009-11-28  Jaroslav Hajek  <highegg@gmail.com>
 
 	* dim-vector.h (dim_vector::zero_by_zero): New method.
--- a/liboctave/idx-vector.cc	Mon Nov 30 16:17:04 2009 -0800
+++ b/liboctave/idx-vector.cc	Tue Dec 01 10:41:52 2009 +0100
@@ -168,6 +168,13 @@
   return os;
 }
 
+Range
+idx_vector::idx_range_rep::unconvert (void) const
+{
+  return Range (static_cast<double> (start+1), 
+                static_cast<double> (step), len);
+}
+
 inline octave_idx_type
 convert_index (octave_idx_type i, bool& conv_error, 
                octave_idx_type& ext)
@@ -235,6 +242,12 @@
   return os << data;
 }
 
+double
+idx_vector::idx_scalar_rep::unconvert (void) const
+{
+  return data + 1;
+}
+
 DEFINE_OCTAVE_ALLOCATOR(idx_vector::idx_vector_rep);
 
 template <class T>
@@ -394,6 +407,15 @@
   return os;
 }
 
+Array<double>
+idx_vector::idx_vector_rep::unconvert (void) const
+{
+  Array<double> retval (orig_dims);
+  for (octave_idx_type i = 0; i < len; i++)
+    retval.xelem (i) = data[i] + 1;
+  return retval;
+}
+
 DEFINE_OCTAVE_ALLOCATOR(idx_vector::idx_mask_rep);
 
 idx_vector::idx_mask_rep::idx_mask_rep (bool b)
@@ -481,6 +503,20 @@
   return os;
 }
 
+Array<bool>
+idx_vector::idx_mask_rep::unconvert (void) const
+{
+  if (aowner)
+    return *aowner;
+  else
+    {
+      Array<bool> retval (orig_dims);
+      for (octave_idx_type i = 0; i < len; i++)
+        retval.xelem (i) = data[i];
+      return retval;
+    }
+}
+
 const idx_vector idx_vector::colon (new idx_vector::idx_colon_rep ());
 
 idx_vector::idx_vector (const Array<bool>& bnda)
@@ -833,7 +869,8 @@
 }
 
 void idx_vector::unconvert (idx_class_type& iclass,
-                            double& scalar, Range& range, Array<double>& array)
+                            double& scalar, Range& range, 
+                            Array<double>& array, Array<bool>& mask) const
 {
   iclass = idx_class ();
   switch (iclass)
@@ -843,32 +880,25 @@
     case class_range:
         {
           idx_range_rep * r = dynamic_cast<idx_range_rep *> (rep);
-          double start = r->get_start (), step = r->get_step ();
-          range = Range (start+1, step, r->length (0));
+          range = r->unconvert ();
         }
       break;
     case class_scalar:
         {
           idx_scalar_rep * r = dynamic_cast<idx_scalar_rep *> (rep);
-          scalar = r->get_data () + 1;
+          scalar = r->unconvert ();
         }
       break;
     case class_vector:
         {
           idx_vector_rep * r = dynamic_cast<idx_vector_rep *> (rep);
-          const octave_idx_type *data = r->get_data ();
-          array = Array<double> (r->orig_dimensions ());
-          octave_idx_type len = r->length (0);
-          for (octave_idx_type i = 0; i < len; i++)
-            array.xelem (i) = data[i] + 1;
+          array = r->unconvert ();
         }
       break;
     case class_mask:
         {
-          // This is done because we don't want a logical index be cached for a
-          // numeric array.
-          *this = unmask ();
-          unconvert (iclass, scalar, range, array);
+          idx_mask_rep * r = dynamic_cast<idx_mask_rep *> (rep);
+          mask = r->unconvert ();
         }
       break;
     default:
--- a/liboctave/idx-vector.h	Mon Nov 30 16:17:04 2009 -0800
+++ b/liboctave/idx-vector.h	Tue Dec 01 10:41:52 2009 +0100
@@ -195,6 +195,8 @@
 
     std::ostream& print (std::ostream& os) const;
 
+    Range unconvert (void) const;
+
   private:
 
     DECLARE_OCTAVE_ALLOCATOR
@@ -248,6 +250,8 @@
 
     std::ostream& print (std::ostream& os) const;
 
+    double unconvert (void) const;
+
   private:
 
     DECLARE_OCTAVE_ALLOCATOR
@@ -308,6 +312,8 @@
 
     std::ostream& print (std::ostream& os) const;
 
+    Array<double> unconvert (void) const;
+
   private:
 
     DECLARE_OCTAVE_ALLOCATOR
@@ -373,6 +379,8 @@
 
     std::ostream& print (std::ostream& os) const;
 
+    Array<bool> unconvert (void) const;
+
   private:
 
     DECLARE_OCTAVE_ALLOCATOR
@@ -927,10 +935,10 @@
   // If the index is a mask, convert it to index vector.
   idx_vector unmask (void) const;
 
-  // Unconverts the index to a scalar, Range or double array.
-  // Note that the index class can be changed, if it's a mask index.
+  // Unconverts the index to a scalar, Range, double array or a mask.
   void unconvert (idx_class_type& iclass,
-                  double& scalar, Range& range, Array<double>& array);
+                  double& scalar, Range& range, 
+                  Array<double>& array, Array<bool>& mask) const;
     
   // FIXME -- these are here for compatibility.  They should be removed
   // when no longer in use.
--- a/src/ChangeLog	Mon Nov 30 16:17:04 2009 -0800
+++ b/src/ChangeLog	Tue Dec 01 10:41:52 2009 +0100
@@ -1,3 +1,13 @@
+2009-12-01  Jaroslav Hajek  <highegg@gmail.com>
+
+	* ov-bool-mat.h (octave_bool_matrix::octave_bool_matrix (const
+	boolNDArray&, const idx_vector&)): New constructor.
+	* ov-re-mat.h (octave_bool_matrix::octave_bool_matrix (const
+	NDArray&, const idx_vector&)): Simplify.
+	 * ov.cc (octave_value::octave_value (const idx_vector&)): Allow the
+	 mask case.
+	 * DLD-FUNCTIONS/find.cc (Ffind): Explicitly call unmask ().
+
 2009-11-30  Kacper Kowalik <xarthisius.kk@gmail.com>
 
 	* oct-hdf5.h: Drop force the use of the v1.6 API
--- a/src/DLD-FUNCTIONS/find.cc	Mon Nov 30 16:17:04 2009 -0800
+++ b/src/DLD-FUNCTIONS/find.cc	Tue Dec 01 10:41:52 2009 +0100
@@ -483,8 +483,8 @@
       else if (nargout <= 1 && n_to_find == -1 && direction == 1)
         {
           // This case is equivalent to extracting indices from a logical
-          // matrix. Try to reuse the possibly cached index vector.
-          retval(0) = arg.index_vector ();
+          // matrix. Try to reuse the possibly cached index vector. 
+          retval(0) = arg.index_vector ().unmask ();
         }
       else
         {
--- a/src/ov-bool-mat.h	Mon Nov 30 16:17:04 2009 -0800
+++ b/src/ov-bool-mat.h	Tue Dec 01 10:41:52 2009 +0100
@@ -65,6 +65,12 @@
   octave_bool_matrix (const boolMatrix& bm, const MatrixType& t)
     : octave_base_matrix<boolNDArray> (bm, t) { }
 
+  octave_bool_matrix (const boolNDArray& bm, const idx_vector& cache)
+    : octave_base_matrix<boolNDArray> (bm) 
+    { 
+      set_idx_cache (cache);
+    }
+
   octave_bool_matrix (const octave_bool_matrix& bm)
     : octave_base_matrix<boolNDArray> (bm) { }
 
--- a/src/ov-re-mat.h	Mon Nov 30 16:17:04 2009 -0800
+++ b/src/ov-re-mat.h	Tue Dec 01 10:41:52 2009 +0100
@@ -93,7 +93,7 @@
   octave_matrix (const NDArray& nda, const idx_vector& cache)
     : octave_base_matrix<NDArray> (nda) 
     { 
-      set_idx_cache (idx_vector (cache));
+      set_idx_cache (cache);
     }
 
   ~octave_matrix (void) { }
--- a/src/ov.cc	Mon Nov 30 16:17:04 2009 -0800
+++ b/src/ov.cc	Tue Dec 01 10:41:52 2009 +0100
@@ -1051,10 +1051,10 @@
   double scalar;
   Range range;
   NDArray array;
+  boolNDArray mask;
   idx_vector::idx_class_type idx_class;
 
-  idx_vector jdx = idx; // Unconvert may potentially modify the class.
-  jdx.unconvert (idx_class, scalar, range, array);
+  idx.unconvert (idx_class, scalar, range, array, mask);
 
   switch (idx_class)
     {
@@ -1062,13 +1062,16 @@
       rep = new octave_magic_colon ();
       break;
     case idx_vector::class_range:
-      rep = new octave_range (range, jdx);
+      rep = new octave_range (range, idx);
       break;
     case idx_vector::class_scalar:
       rep = new octave_scalar (scalar);
       break;
     case idx_vector::class_vector:
-      rep = new octave_matrix (array, jdx);
+      rep = new octave_matrix (array, idx);
+      break;
+    case idx_vector::class_mask:
+      rep = new octave_bool_matrix (mask, idx);
       break;
     default:
       assert (false);