changeset 10498:8615b55b5caf

fix & improve cat (bug #29465)
author Jaroslav Hajek <highegg@gmail.com>
date Thu, 08 Apr 2010 12:50:15 +0200
parents cb7ffe7288f0
children fabed15083a4
files liboctave/ChangeLog liboctave/dim-vector.h src/ChangeLog src/DLD-FUNCTIONS/conv2.cc src/data.cc
diffstat 5 files changed, 83 insertions(+), 73 deletions(-) [+]
line wrap: on
line diff
--- a/liboctave/ChangeLog	Thu Apr 08 10:29:57 2010 +0200
+++ b/liboctave/ChangeLog	Thu Apr 08 12:50:15 2010 +0200
@@ -1,3 +1,8 @@
+2010-04-08  Jaroslav Hajek  <highegg@gmail.com>
+
+	* dim-vector.h (dim_vector::concat): Ignore zero_by_zero, but not
+	all_zero arrays in concatenation (like Matlab).
+
 2010-04-07  Jaroslav Hajek  <highegg@gmail.com>
 
 	* Sparse.cc (Sparse<T>::index (const idx_vector&, bool)): Use shallow
--- a/liboctave/dim-vector.h	Thu Apr 08 10:29:57 2010 +0200
+++ b/liboctave/dim-vector.h	Thu Apr 08 12:50:15 2010 +0200
@@ -473,15 +473,15 @@
 
   bool concat (const dim_vector& dvb, int dim = 0)
   {
-    if (all_zero ())
+    if (dvb.zero_by_zero ())
+      return true;
+
+    if (zero_by_zero ())
       {
         *this = dvb;
         return true;
       }
 
-    if (dvb.all_zero ())
-      return true;
-
     int na = length ();
     int nb = dvb.length ();
   
--- a/src/ChangeLog	Thu Apr 08 10:29:57 2010 +0200
+++ b/src/ChangeLog	Thu Apr 08 12:50:15 2010 +0200
@@ -1,3 +1,11 @@
+2010-04-08  Jaroslav Hajek  <highegg@gmail.com>
+
+	* data.cc (SINGLE_TYPE_CONCAT, DO_SINGLE_TYPE_CONCAT): Replace by
+	templates.
+	(single_type_concat, do_single_type_concat): New static template
+	funcs. Correctly skip 0x0 matrices.
+	(Fcat): Call them here. Add tests.
+
 2010-04-07  Jaroslav Hajek  <highegg@gmail.com>
 
 	* oct-parse.yy (feval): Use do_multi_index_op on handles.
--- a/src/DLD-FUNCTIONS/conv2.cc	Thu Apr 08 10:29:57 2010 +0200
+++ b/src/DLD-FUNCTIONS/conv2.cc	Thu Apr 08 12:50:15 2010 +0200
@@ -2,6 +2,7 @@
 
 Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
               Andy Adler
+Copyright (C) 2010 VZLU Prague
 
 This file is part of Octave.
 
--- a/src/data.cc	Thu Apr 08 10:29:57 2010 +0200
+++ b/src/data.cc	Thu Apr 08 12:50:15 2010 +0200
@@ -1345,50 +1345,49 @@
 
  */
 
-#define SINGLE_TYPE_CONCAT(TYPE, EXTRACTOR) \
-  do \
-    { \
-      int dv_len = dv.length (); \
-      Array<octave_idx_type> ra_idx (dv_len > 1 ? dv_len : 2, 1, 0); \
-      \
-      for (int j = 1; j < n_args; j++) \
-        { \
-          octave_quit (); \
-          \
-          TYPE ra = args(j).EXTRACTOR ();       \
-          \
-          if (! error_state) \
-            { \
-              result.insert (ra, ra_idx); \
-              \
-              if (error_state) \
-                return retval; \
-              \
-              dim_vector dv_tmp = args (j).dims (); \
-              \
-              if (dim >= dv_len) \
-                { \
-                  if (j > 1) \
-                    error ("%s: indexing error", fname.c_str ()); \
-                  break; \
-                } \
-              else \
-                ra_idx (dim) += (dim < dv_tmp.length () ? dv_tmp (dim) : 1); \
-            } \
-        } \
-    } \
- while (0)
-
-#define DO_SINGLE_TYPE_CONCAT(TYPE, EXTRACTOR) \
-  do \
-    { \
-      TYPE result (dv); \
-      \
-      SINGLE_TYPE_CONCAT(TYPE, EXTRACTOR); \
-      \
-      retval = result; \
-    } \
- while (0)
+template<class TYPE>
+static void 
+single_type_concat (TYPE& 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++)
+    {
+      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);
+    }
+}
+
+template<class TYPE>
+static octave_value 
+do_single_type_concat (const dim_vector& dv,
+                       const octave_value_list& args,
+                       int dim)
+{
+  TYPE result (dv);
+
+  single_type_concat (result, args, dim);
+
+  return result;
+}
+
 
 static octave_value
 do_cat (const octave_value_list& args, std::string fname)
@@ -1452,25 +1451,24 @@
               if (any_sparse_p)
                 {           
                   if (all_real_p)
-                    DO_SINGLE_TYPE_CONCAT (SparseMatrix, sparse_matrix_value);
+                    retval = do_single_type_concat<SparseMatrix> (dv, args, dim);
                   else
-                    DO_SINGLE_TYPE_CONCAT (SparseComplexMatrix, sparse_complex_matrix_value);
+                    retval = do_single_type_concat<SparseComplexMatrix> (dv, args, dim);
                 }
               else
                 {
                   if (all_real_p)
-                    DO_SINGLE_TYPE_CONCAT (NDArray, array_value);
+                    retval = do_single_type_concat<NDArray> (dv, args, dim);
                   else
-                    DO_SINGLE_TYPE_CONCAT (ComplexNDArray, complex_array_value);
+                    retval = do_single_type_concat<ComplexNDArray> (dv, args, dim);
                 }
             }
           else if (result_type == "single")
             {
               if (all_real_p)
-                DO_SINGLE_TYPE_CONCAT (FloatNDArray, float_array_value);
+                retval = do_single_type_concat<FloatNDArray> (dv, args, dim);
               else
-                DO_SINGLE_TYPE_CONCAT (FloatComplexNDArray, 
-                                       float_complex_array_value);
+                retval = do_single_type_concat<FloatComplexNDArray> (dv, args, dim);
             }
           else if (result_type == "char")
             {
@@ -1480,33 +1478,33 @@
 
               charNDArray result (dv, Vstring_fill_char);
 
-              SINGLE_TYPE_CONCAT (charNDArray, char_array_value);
+              single_type_concat<charNDArray> (result, args, dim);
 
               retval = octave_value (result, type);
             }
           else if (result_type == "logical")
             {
               if (any_sparse_p)
-                DO_SINGLE_TYPE_CONCAT (SparseBoolMatrix, sparse_bool_matrix_value);
+                retval = do_single_type_concat<SparseBoolMatrix> (dv, args, dim);
               else
-                DO_SINGLE_TYPE_CONCAT (boolNDArray, bool_array_value);
+                retval = do_single_type_concat<boolNDArray> (dv, args, dim);
             }
           else if (result_type == "int8")
-            DO_SINGLE_TYPE_CONCAT (int8NDArray, int8_array_value);
+            retval = do_single_type_concat<int8NDArray> (dv, args, dim);
           else if (result_type == "int16")
-            DO_SINGLE_TYPE_CONCAT (int16NDArray, int16_array_value);
+            retval = do_single_type_concat<int16NDArray> (dv, args, dim);
           else if (result_type == "int32")
-            DO_SINGLE_TYPE_CONCAT (int32NDArray, int32_array_value);
+            retval = do_single_type_concat<int32NDArray> (dv, args, dim);
           else if (result_type == "int64")
-            DO_SINGLE_TYPE_CONCAT (int64NDArray, int64_array_value);
+            retval = do_single_type_concat<int64NDArray> (dv, args, dim);
           else if (result_type == "uint8")
-            DO_SINGLE_TYPE_CONCAT (uint8NDArray, uint8_array_value);
+            retval = do_single_type_concat<uint8NDArray> (dv, args, dim);
           else if (result_type == "uint16")
-            DO_SINGLE_TYPE_CONCAT (uint16NDArray, uint16_array_value);
+            retval = do_single_type_concat<uint16NDArray> (dv, args, dim);
           else if (result_type == "uint32")
-            DO_SINGLE_TYPE_CONCAT (uint32NDArray, uint32_array_value);
+            retval = do_single_type_concat<uint32NDArray> (dv, args, dim);
           else if (result_type == "uint64")
-            DO_SINGLE_TYPE_CONCAT (uint64NDArray, uint64_array_value);
+            retval = do_single_type_concat<uint64NDArray> (dv, args, dim);
           else
             {
               // The lines below might seem crazy, since we take a copy
@@ -1556,13 +1554,6 @@
                 }
               retval = tmp;
             }
-
-          if (! error_state)
-            {
-              // Reshape, chopping trailing singleton dimensions
-              dv.chop_trailing_singletons ();
-              retval = retval.reshape (dv);
-            }
         }
       else
         error ("%s: invalid dimension argument", fname.c_str ());
@@ -1789,6 +1780,11 @@
 %!assert (testcat('uint64', 'single', 'uint64', false));
 %!assert (testcat('uint64', 'uint64', 'uint64', false));
 
+%! assert (cat (3, [], [1,2;3,4]), [1,2;3,4]);
+%! assert (cat (3, [1,2;3,4], []), [1,2;3,4]);
+%! assert (cat (3, [], [1,2;3,4], []), [1,2;3,4]);
+%! assert (cat (3, [], [], []), []);
+
 */
 
 static octave_value