changeset 10125:82ed1b4c3011

improve cellslices
author Jaroslav Hajek <highegg@gmail.com>
date Sun, 17 Jan 2010 22:09:05 +0100
parents e5c6600e3400
children 8687ce1c56da
files src/ChangeLog src/DLD-FUNCTIONS/cellfun.cc
diffstat 2 files changed, 56 insertions(+), 34 deletions(-) [+]
line wrap: on
line diff
--- a/src/ChangeLog	Sun Jan 17 15:13:53 2010 +0100
+++ b/src/ChangeLog	Sun Jan 17 22:09:05 2010 +0100
@@ -1,3 +1,8 @@
+2010-01-17  Jaroslav Hajek  <highegg@gmail.com>
+
+	* DLD-FUNCTIONS/cellfun.cc (Fcellslices): Support dim argument, make
+	consistent with rest of functions.
+
 2010-01-17  Thorsten Meyer  <thorsten.meyier@gmx.de>
 
 	* ov-cell.cc (Fstruct2cell): Add example, add test.
--- a/src/DLD-FUNCTIONS/cellfun.cc	Sun Jan 17 15:13:53 2010 +0100
+++ b/src/DLD-FUNCTIONS/cellfun.cc	Sun Jan 17 22:09:05 2010 +0100
@@ -1454,27 +1454,32 @@
 static Cell 
 do_cellslices_nda (const NDA& array, 
                    const Array<octave_idx_type>& lb, 
-                   const Array<octave_idx_type>& ub)
+                   const Array<octave_idx_type>& ub,
+                   int dim = -1)
 {
   octave_idx_type n = lb.length ();
   Cell retval (1, n);
-  if (array.is_vector ())
+  if (array.is_vector () && (dim == -1 
+                             || (dim == 0 && array.columns () == 1) 
+                             || (dim == 1 && array.rows () == 1)))
     {
       for (octave_idx_type i = 0; i < n && ! error_state; i++)
         retval(i) = array.index (idx_vector (lb(i) - 1, ub(i)));
     }
   else
     {
-      dim_vector dv = array.dims ();
-      octave_idx_type nl = 1;
-      for (int i = 0; i < dv.length () - 1; i++) nl *= dv(i);
+      const dim_vector dv = array.dims ();
+      int ndims = dv.length ();
+      if (dim < 0)
+        dim = dv.first_non_singleton ();
+      ndims = std::max (ndims, dim + 1);
+
+      Array<idx_vector> idx (ndims, idx_vector::colon);
+
       for (octave_idx_type i = 0; i < n && ! error_state; i++)
         {
-          // Do it with a single index to speed things up.
-          dv = array.dims ();
-          dv(dv.length () - 1) = ub(i) + 1 - lb(i);
-          dv.chop_trailing_singletons ();
-          retval(i) = array.index (idx_vector (nl*(lb(i) - 1), nl*ub(i))).reshape (dv);
+          idx(dim) = idx_vector (lb(i) - 1, ub(i));
+          retval(i) = array.index (idx);
         }
     }
 
@@ -1483,8 +1488,8 @@
 
 DEFUN_DLD (cellslices, args, ,
   "-*- texinfo -*-\n\
-@deftypefn {Loadable Function} {@var{sl} =} cellslices (@var{x}, @var{lb}, @var{ub})\n\
-Given a vector @var{x}, this function produces a cell array of slices from the vector\n\
+@deftypefn {Loadable Function} {@var{sl} =} cellslices (@var{x}, @var{lb}, @var{ub}, @var{dim})\n\
+Given an array @var{x}, this function produces a cell array of slices from the array\n\
 determined by the index vectors @var{lb}, @var{ub}, for lower and upper bounds, respectively.\n\
 In other words, it is equivalent to the following code:\n\
 \n\
@@ -1493,22 +1498,30 @@
 n = length (lb);\n\
 sl = cell (1, n);\n\
 for i = 1:length (lb)\n\
-  sl@{i@} = x(lb(i):ub(i));\n\
+  sl@{i@} = x(:,@dots{},lb(i):ub(i),@dots{},:);\n\
 endfor\n\
 @end group\n\
 @end example\n\
 \n\
-If @var{X} is a matrix or array, indexing is done along the last dimension.\n\
-@seealso{mat2cell}\n\
+The position of the index is determined by @var{dim}. If not specified, slicing\n\
+is done along the first non-singleton dimension.\n\
 @end deftypefn")
 {
   octave_value retval;
   int nargin = args.length ();
-  if (nargin == 3)
+  if (nargin == 3 || nargin == 4)
     {
       octave_value x = args(0);
       Array<octave_idx_type> lb = args(1).octave_idx_type_vector_value ();
       Array<octave_idx_type> ub = args(2).octave_idx_type_vector_value ();
+      int dim = -1;
+      if (nargin == 4)
+        {
+          dim = args(3).int_value () - 1;
+          if (dim < 0)
+            error ("cellslices: dim must be a valid dimension");
+        }
+
       if (! error_state)
         {
           if (lb.length () != ub.length ())
@@ -1520,41 +1533,41 @@
                 {
                   // specialize for some dense arrays.
                   if (x.is_bool_type ())
-                    retcell = do_cellslices_nda (x.bool_array_value (), lb, ub);
+                    retcell = do_cellslices_nda (x.bool_array_value (), lb, ub, dim);
                   else if (x.is_char_matrix ())
-                    retcell = do_cellslices_nda (x.char_array_value (), lb, ub);
+                    retcell = do_cellslices_nda (x.char_array_value (), lb, ub, dim);
                   else if (x.is_integer_type ())
                     {
                       if (x.is_int8_type ())
-                        retcell = do_cellslices_nda (x.int8_array_value (), lb, ub);
+                        retcell = do_cellslices_nda (x.int8_array_value (), lb, ub, dim);
                       else if (x.is_int16_type ())
-                        retcell = do_cellslices_nda (x.int16_array_value (), lb, ub);
+                        retcell = do_cellslices_nda (x.int16_array_value (), lb, ub, dim);
                       else if (x.is_int32_type ())
-                        retcell = do_cellslices_nda (x.int32_array_value (), lb, ub);
+                        retcell = do_cellslices_nda (x.int32_array_value (), lb, ub, dim);
                       else if (x.is_int64_type ())
-                        retcell = do_cellslices_nda (x.int64_array_value (), lb, ub);
+                        retcell = do_cellslices_nda (x.int64_array_value (), lb, ub, dim);
                       else if (x.is_uint8_type ())
-                        retcell = do_cellslices_nda (x.uint8_array_value (), lb, ub);
+                        retcell = do_cellslices_nda (x.uint8_array_value (), lb, ub, dim);
                       else if (x.is_uint16_type ())
-                        retcell = do_cellslices_nda (x.uint16_array_value (), lb, ub);
+                        retcell = do_cellslices_nda (x.uint16_array_value (), lb, ub, dim);
                       else if (x.is_uint32_type ())
-                        retcell = do_cellslices_nda (x.uint32_array_value (), lb, ub);
+                        retcell = do_cellslices_nda (x.uint32_array_value (), lb, ub, dim);
                       else if (x.is_uint64_type ())
-                        retcell = do_cellslices_nda (x.uint64_array_value (), lb, ub);
+                        retcell = do_cellslices_nda (x.uint64_array_value (), lb, ub, dim);
                     }
                   else if (x.is_complex_type ())
                     {
                       if (x.is_single_type ())
-                        retcell = do_cellslices_nda (x.float_complex_array_value (), lb, ub);
+                        retcell = do_cellslices_nda (x.float_complex_array_value (), lb, ub, dim);
                       else
-                        retcell = do_cellslices_nda (x.complex_array_value (), lb, ub);
+                        retcell = do_cellslices_nda (x.complex_array_value (), lb, ub, dim);
                     }
                   else
                     {
                       if (x.is_single_type ())
-                        retcell = do_cellslices_nda (x.float_array_value (), lb, ub);
+                        retcell = do_cellslices_nda (x.float_array_value (), lb, ub, dim);
                       else
-                        retcell = do_cellslices_nda (x.array_value (), lb, ub);
+                        retcell = do_cellslices_nda (x.array_value (), lb, ub, dim);
                     }
                 }
               else
@@ -1562,11 +1575,15 @@
                   // generic code.
                   octave_idx_type n = lb.length ();
                   retcell = Cell (1, n);
-                  octave_idx_type nind = x.dims ().is_vector () ? 1 : x.ndims ();
-                  octave_value_list idx (nind, octave_value::magic_colon_t);
+                  const dim_vector dv = x.dims ();
+                  int ndims = dv.length ();
+                  if (dim < 0)
+                    dim = dv.first_non_singleton ();
+                  ndims = std::max (ndims, dim + 1);
+                  octave_value_list idx (ndims, octave_value::magic_colon_t);
                   for (octave_idx_type i = 0; i < n && ! error_state; i++)
                     {
-                      idx(nind-1) = Range (lb(i), ub(i));
+                      idx(dim) = Range (lb(i), ub(i));
                       retcell(i) = x.do_index_op (idx);
                     }
                 }
@@ -1584,7 +1601,7 @@
 /*
 %!test
 %! m = [1, 2, 3, 4; 5, 6, 7, 8; 9, 10, 11, 12];
-%! c = cellslices (m, [1, 2], [2, 3]);
+%! c = cellslices (m, [1, 2], [2, 3], 2);
 %! assert (c, {[1, 2; 5, 6; 9, 10], [2, 3; 6, 7; 10, 11]});
 */