changeset 10758:f3892d8eea9f

optimize horzcat/vertcat for scalars, cells and structs
author Jaroslav Hajek <highegg@gmail.com>
date Mon, 28 Jun 2010 12:06:48 +0200
parents 1cc44f3ec814
children d9e57045b9e1
files liboctave/ChangeLog liboctave/lo-traits.h src/ChangeLog src/data.cc src/pt-mat.cc
diffstat 5 files changed, 104 insertions(+), 10 deletions(-) [+]
line wrap: on
line diff
--- a/liboctave/ChangeLog	Mon Jun 28 09:23:57 2010 +0200
+++ b/liboctave/ChangeLog	Mon Jun 28 12:06:48 2010 +0200
@@ -1,3 +1,8 @@
+2010-06-28  Jaroslav Hajek  <highegg@gmail.com>
+
+	* dim-vector.h (dim_vector::scalar_1x1): New method.
+	* lo-traits.h (equal_types): Fix.
+
 2010-06-21  Jaroslav Hajek  <highegg@gmail.com>
 
 	* Array.cc (Array<T>::cat): Implement the loose horzcat/vertcat rules
--- a/liboctave/lo-traits.h	Mon Jun 28 09:23:57 2010 +0200
+++ b/liboctave/lo-traits.h	Mon Jun 28 12:06:48 2010 +0200
@@ -62,7 +62,7 @@
 {
 public:
 
-  static const bool value = false;
+  static const bool value = true;
 };
 
 // Determine whether a type is an instance of a template.
--- a/src/ChangeLog	Mon Jun 28 09:23:57 2010 +0200
+++ b/src/ChangeLog	Mon Jun 28 12:06:48 2010 +0200
@@ -1,3 +1,11 @@
+2010-06-28  Jaroslav Hajek  <highegg@gmail.com>
+
+	* data.cc (single_type_concat): Optimize all scalars case where
+	applicable.
+	(single_type_concat_map, do_single_type_concat_map): New funcs.
+	* pt-mat.cc (get_concat_class): Handle cell and struct concats.
+
+
 2010-06-25  Jaroslav Hajek  <highegg@gmail.com>
 
 	* DLD-FUNCTIONS/cellfun.cc (Fnum2cell, do_num2cell): Optimize cells
--- a/src/data.cc	Mon Jun 28 09:23:57 2010 +0200
+++ b/src/data.cc	Mon Jun 28 12:06:48 2010 +0200
@@ -1369,6 +1369,17 @@
 
  */
 
+static bool
+all_scalar_1x1 (const octave_value_list& args)
+{
+  int n_args = args.length ();
+  for (int i = 0; i < n_args; i++)
+    if (args(i).numel () != 1)
+      return false;
+
+  return true;
+}
+
 template <class TYPE, class T>
 static void 
 single_type_concat (Array<T>& result,
@@ -1376,17 +1387,41 @@
                     int dim)
 {
   int n_args = args.length ();
-  OCTAVE_LOCAL_BUFFER (Array<T>, array_list, n_args);
-
-  for (int j = 0; j < n_args && ! error_state; j++)
+  if (! (equal_types<T, char>::value
+         || equal_types<T, octave_value>::value)
+      && all_scalar_1x1 (args))
     {
-      octave_quit ();
-
-      array_list[j] = octave_value_extract<TYPE> (args(j));
+      // Optimize all scalars case.
+      dim_vector dv (1, 1);
+      if (dim == -1 || dim == -2)
+        dim = -dim - 1;
+      else if (dim >= 2)
+        dv.resize (dim+1, 1);
+      dv(dim) = n_args;
+
+      result.clear (dv);
+
+      for (int j = 0; j < n_args && ! error_state; j++)
+        {
+          octave_quit ();
+
+          result(j) = octave_value_extract<T> (args(j));
+        }
     }
-
-  if (! error_state)
-    result = Array<T>::cat (dim, n_args, array_list);
+  else
+    {
+      OCTAVE_LOCAL_BUFFER (Array<T>, array_list, n_args);
+
+      for (int j = 0; j < n_args && ! error_state; j++)
+        {
+          octave_quit ();
+
+          array_list[j] = octave_value_extract<TYPE> (args(j));
+        }
+
+      if (! error_state)
+        result = Array<T>::cat (dim, n_args, array_list);
+    }
 }
 
 template <class TYPE, class T>
@@ -1421,6 +1456,44 @@
   return result;
 }
 
+template<class MAP>
+static void 
+single_type_concat_map (octave_map& result,
+                        const octave_value_list& args,
+                        int dim)
+{
+  int n_args = args.length ();
+  OCTAVE_LOCAL_BUFFER (MAP, map_list, n_args);
+
+  for (int j = 0; j < n_args && ! error_state; j++)
+    {
+      octave_quit ();
+
+      map_list[j] = octave_value_extract<MAP> (args(j));
+    }
+
+  if (! error_state)
+    result = octave_map::cat (dim, n_args, map_list);
+}
+
+static octave_map
+do_single_type_concat_map (const octave_value_list& args,
+                           int dim)
+{
+  octave_map result;
+  if (all_scalar_1x1 (args)) // optimize all scalars case.
+    {
+      if (dim < 0)
+        dim = -dim;
+
+      single_type_concat_map<octave_scalar_map> (result, args, dim);
+    }
+  else
+    single_type_concat_map<octave_map> (result, args, dim);
+
+  return result;
+}
+
 static octave_value
 do_cat (const octave_value_list& args, int dim, std::string fname)
 {
@@ -1514,6 +1587,10 @@
         retval = do_single_type_concat<uint32NDArray> (args, dim);
       else if (result_type == "uint64")
         retval = do_single_type_concat<uint64NDArray> (args, dim);
+      else if (result_type == "cell")
+        retval = do_single_type_concat<Cell> (args, dim);
+      else if (result_type == "struct")
+        retval = do_single_type_concat_map (args, dim);
       else
         {
           dim_vector  dv = args(0).dims ();
--- a/src/pt-mat.cc	Mon Jun 28 09:23:57 2010 +0200
+++ b/src/pt-mat.cc	Mon Jun 28 12:06:48 2010 +0200
@@ -249,6 +249,10 @@
         retval = c2;
       else if (c1_is_logical && c2_is_logical)
         retval = c1;
+      else if (c1 == "struct" && c2 == c1)
+        retval = c1;
+      else if (c1 == "cell" && c2 == c1)
+        retval = c1;
     }
 
   return retval;