changeset 10533:f094ac9bc93e

reuse Array<T>::cat and Sparse<T>::cat in cat/horzcat/vertcat
author Jaroslav Hajek <highegg@gmail.com>
date Mon, 19 Apr 2010 15:31:49 +0200
parents 568c7c041fac
children eb55e736060e
files liboctave/Array.cc liboctave/ChangeLog liboctave/Sparse.cc src/ChangeLog src/data.cc
diffstat 5 files changed, 97 insertions(+), 63 deletions(-) [+]
line wrap: on
line diff
--- a/liboctave/Array.cc	Mon Apr 19 07:22:30 2010 -0400
+++ b/liboctave/Array.cc	Mon Apr 19 15:31:49 2010 +0200
@@ -2609,11 +2609,17 @@
         ("cat: dimension mismatch");
 
   Array<T> retval (dv);
-  Array<idx_vector> idxa (dv.length (), 1, idx_vector::colon);
+  int nidx = std::max (dv.length (), dim + 1);
+  Array<idx_vector> idxa (nidx, 1, idx_vector::colon);
   octave_idx_type l = 0;
 
   for (octave_idx_type i = 0; i < n; i++)
     {
+      if (array_list[i].dims ().zero_by_zero ())
+        continue;
+
+      octave_quit ();
+
       octave_idx_type u;
       if (dim < array_list[i].ndims ())
         u = l + array_list[i].dims ()(dim);
@@ -2623,6 +2629,8 @@
       idxa(dim) = idx_vector (l, u);
 
       retval.assign (idxa, array_list[i]);
+
+      l = u;
     }
 
   return retval;
--- a/liboctave/ChangeLog	Mon Apr 19 07:22:30 2010 -0400
+++ b/liboctave/ChangeLog	Mon Apr 19 15:31:49 2010 +0200
@@ -1,3 +1,8 @@
+2010-04-19  Jaroslav Hajek  <highegg@gmail.com>
+
+	* Array.cc (Array<T>::cat): Miscellaneous fixes.
+	* Sparse.cc (Sparse<T>::cat): Ditto.
+
 2010-04-18  Jaroslav Hajek  <highegg@gmail.com>
 
 	* Array.cc (Array<T>::cat): New method.
--- a/liboctave/Sparse.cc	Mon Apr 19 07:22:30 2010 -0400
+++ b/liboctave/Sparse.cc	Mon Apr 19 15:31:49 2010 +0200
@@ -2402,12 +2402,17 @@
         // sparse vertcat. This is not efficiently handled by assignment, so
         // we'll do it directly.
         octave_idx_type l = 0;
-        for (octave_idx_type j = 0; j < n; j++)
+        for (octave_idx_type j = 0; j < dv(1); j++)
           {
+            octave_quit ();
+
             octave_idx_type rcum = 0;
             for (octave_idx_type i = 0; i < n; i++)
               {
                 const Sparse<T>& spi = sparse_list[i];
+                if (spi.dims ().zero_by_zero ())
+                  continue;
+
                 octave_idx_type kl = spi.cidx(j), ku = spi.cidx(j+1);
                 for (octave_idx_type k = kl; k < ku; k++, l++)
                   {
@@ -2425,12 +2430,14 @@
       }
     case 1:
       {
-        octave_idx_type ccum = 0;
+        octave_idx_type l = 0;
         for (octave_idx_type i = 0; i < n; i++)
           {
-            octave_idx_type l = ccum, u = ccum + sparse_list[i].columns ();
+            octave_quit ();
+
+            octave_idx_type u = l + sparse_list[i].columns ();
             retval.assign (idx_vector::colon, idx_vector (l, u), sparse_list[i]);
-            ccum = u;
+            l = u;
           }
 
         break;
--- a/src/ChangeLog	Mon Apr 19 07:22:30 2010 -0400
+++ b/src/ChangeLog	Mon Apr 19 15:31:49 2010 +0200
@@ -1,3 +1,10 @@
+2010-04-19  Jaroslav Hajek  <highegg@gmail.com>
+
+	* data.cc (single_type_concat, do_single_type_concat): Rewrite using
+	new liboctave facilities.
+	(do_cat): Don't compute result dims if the case can be forwarded to
+	liboctave.
+
 2010-04-13  David Bateman  <dbateman@free.fr>
 
 	* graphics.cc (void text::properties::update_text_extent (void)):
--- a/src/data.cc	Mon Apr 19 07:22:30 2010 -0400
+++ b/src/data.cc	Mon Apr 19 15:31:49 2010 +0200
@@ -1345,50 +1345,58 @@
 
  */
 
-template<class TYPE>
+template <class TYPE, class T>
 static void 
-single_type_concat (TYPE& result,
+single_type_concat (Array<T>& result,
+                    const octave_value_list& args,
+                    int dim)
+{
+  int n_args = args.length ();
+  OCTAVE_LOCAL_BUFFER (Array<T>, array_list, n_args - 1);
+
+  for (int j = 1; j < n_args && ! error_state; j++)
+    {
+      octave_quit ();
+
+      array_list[j-1] = octave_value_extract<TYPE> (args(j));
+    }
+
+  if (! error_state)
+    result = Array<T>::cat (dim, n_args-1, array_list);
+}
+
+template <class TYPE, class T>
+static void 
+single_type_concat (Sparse<T>& result,
                     const octave_value_list& args,
                     int dim)
 {
-  int dv_len = result.ndims (), n_args = args.length ();
-  Array<octave_idx_type> ra_idx (dv_len, 1, 0);
-
-  for (int j = 1; j < n_args; j++)
+  int n_args = args.length ();
+  OCTAVE_LOCAL_BUFFER (Sparse<T>, sparse_list, n_args-1);
+
+  for (int j = 1; j < n_args && ! error_state; j++)
     {
       octave_quit ();
 
-      TYPE ra = octave_value_extract<TYPE> (args(j));
-      dim_vector dvra = ra.dims ();
-      if (error_state)
-        break;
-
-      if (dvra.zero_by_zero ())
-        continue;
-
-      result.insert (ra, ra_idx);
-
-      if (error_state)
-        break;
-
-      ra_idx (dim) += (dim < dvra.length () ? dvra(dim) : 1);
+      sparse_list[j-1] = octave_value_extract<TYPE> (args(j));
     }
+
+  if (! error_state)
+    result = Sparse<T>::cat (dim, n_args-1, sparse_list);
 }
 
+// Dispatcher.
 template<class TYPE>
-static octave_value 
-do_single_type_concat (const dim_vector& dv,
-                       const octave_value_list& args,
-                       int dim)
+static TYPE 
+do_single_type_concat (const octave_value_list& args, int dim)
 {
-  TYPE result (dv);
-
-  single_type_concat (result, args, dim);
+  TYPE result;
+
+  single_type_concat<TYPE, typename TYPE::element_type> (result, args, dim);
 
   return result;
 }
 
-
 static octave_value
 do_cat (const octave_value_list& args, std::string fname)
 {
@@ -1413,7 +1421,6 @@
       if (dim >= 0)
         {
           
-          dim_vector  dv = args(1).dims ();
           std::string result_type = args(1).class_name ();
           
           bool all_sq_strings_p = args(1).is_sq_string ();
@@ -1423,16 +1430,6 @@
 
           for (int i = 2; i < args.length (); i++)
             {
-              // add_dims constructs a dimension vector which holds the
-              // dimensions of the final array after concatenation.
-
-              if (! dv.concat (args(i).dims (), dim))
-                {
-                  // Dimensions do not match. 
-                  error ("cat: dimension mismatch");
-                  return retval;
-                }
-              
               result_type = 
                 get_concat_class (result_type, args(i).class_name ());
 
@@ -1451,24 +1448,24 @@
               if (any_sparse_p)
                 {           
                   if (all_real_p)
-                    retval = do_single_type_concat<SparseMatrix> (dv, args, dim);
+                    retval = do_single_type_concat<SparseMatrix> (args, dim);
                   else
-                    retval = do_single_type_concat<SparseComplexMatrix> (dv, args, dim);
+                    retval = do_single_type_concat<SparseComplexMatrix> (args, dim);
                 }
               else
                 {
                   if (all_real_p)
-                    retval = do_single_type_concat<NDArray> (dv, args, dim);
+                    retval = do_single_type_concat<NDArray> (args, dim);
                   else
-                    retval = do_single_type_concat<ComplexNDArray> (dv, args, dim);
+                    retval = do_single_type_concat<ComplexNDArray> (args, dim);
                 }
             }
           else if (result_type == "single")
             {
               if (all_real_p)
-                retval = do_single_type_concat<FloatNDArray> (dv, args, dim);
+                retval = do_single_type_concat<FloatNDArray> (args, dim);
               else
-                retval = do_single_type_concat<FloatComplexNDArray> (dv, args, dim);
+                retval = do_single_type_concat<FloatComplexNDArray> (args, dim);
             }
           else if (result_type == "char")
             {
@@ -1476,37 +1473,47 @@
 
               maybe_warn_string_concat (all_dq_strings_p, all_sq_strings_p);
 
-              charNDArray result (dv, Vstring_fill_char);
-
-              single_type_concat<charNDArray> (result, args, dim);
+              charNDArray result =  do_single_type_concat<charNDArray> (args, dim);
 
               retval = octave_value (result, type);
             }
           else if (result_type == "logical")
             {
               if (any_sparse_p)
-                retval = do_single_type_concat<SparseBoolMatrix> (dv, args, dim);
+                retval = do_single_type_concat<SparseBoolMatrix> (args, dim);
               else
-                retval = do_single_type_concat<boolNDArray> (dv, args, dim);
+                retval = do_single_type_concat<boolNDArray> (args, dim);
             }
           else if (result_type == "int8")
-            retval = do_single_type_concat<int8NDArray> (dv, args, dim);
+            retval = do_single_type_concat<int8NDArray> (args, dim);
           else if (result_type == "int16")
-            retval = do_single_type_concat<int16NDArray> (dv, args, dim);
+            retval = do_single_type_concat<int16NDArray> (args, dim);
           else if (result_type == "int32")
-            retval = do_single_type_concat<int32NDArray> (dv, args, dim);
+            retval = do_single_type_concat<int32NDArray> (args, dim);
           else if (result_type == "int64")
-            retval = do_single_type_concat<int64NDArray> (dv, args, dim);
+            retval = do_single_type_concat<int64NDArray> (args, dim);
           else if (result_type == "uint8")
-            retval = do_single_type_concat<uint8NDArray> (dv, args, dim);
+            retval = do_single_type_concat<uint8NDArray> (args, dim);
           else if (result_type == "uint16")
-            retval = do_single_type_concat<uint16NDArray> (dv, args, dim);
+            retval = do_single_type_concat<uint16NDArray> (args, dim);
           else if (result_type == "uint32")
-            retval = do_single_type_concat<uint32NDArray> (dv, args, dim);
+            retval = do_single_type_concat<uint32NDArray> (args, dim);
           else if (result_type == "uint64")
-            retval = do_single_type_concat<uint64NDArray> (dv, args, dim);
+            retval = do_single_type_concat<uint64NDArray> (args, dim);
           else
             {
+              dim_vector  dv = args(1).dims ();
+
+              for (int i = 2; i < args.length (); i++)
+                {
+                  if (! dv.concat (args(i).dims (), dim))
+                    {
+                      // Dimensions do not match. 
+                      error ("cat: dimension mismatch");
+                      return retval;
+                    }
+                }
+              
               // The lines below might seem crazy, since we take a copy
               // of the first argument, resize it to be empty and then resize
               // it to be full. This is done since it means that there is no