changeset 17001:234519448e76

make cell2mat.m more efficient for large arrays (bug #39387). * cell2mat.m: Correct sort order of dimensions to descending. Use single cat() call in special case of only scalar elements.
author Olaf Till <i7tiol@t-online.de>
date Mon, 01 Jul 2013 19:29:10 +0200
parents 45165d6c4738
children dd783018709b
files scripts/general/cell2mat.m
diffstat 1 files changed, 26 insertions(+), 20 deletions(-) [+]
line wrap: on
line diff
--- a/scripts/general/cell2mat.m	Thu Jul 18 08:36:01 2013 -0700
+++ b/scripts/general/cell2mat.m	Mon Jul 01 19:29:10 2013 +0200
@@ -53,27 +53,33 @@
       error ("cell2mat: wrong type elements or mixed cells, structs and matrices");
     endif
 
-    ## The goal is to minimize the total number of cat() calls.
-    ## The dimensions can be concatenated along in arbitrary order.
-    ## The numbers of concatenations are:
-    ## n / d1
-    ## n / (d1 * d2)
-    ## n / (d1 * d2 * d3)
-    ## etc.
-    ## This is minimized if d1 >= d2 >= d3...
+    sc = size (c);
+    if (all (cellfun ("numel", c)(:) == 1))
+      m = reshape (cat (1, c{:}), sc);
+    else
+
+      ## The goal is to minimize the total number of cat() calls.
+      ## The dimensions can be concatenated along in arbitrary order.
+      ## The numbers of concatenations are:
+      ## n / d1
+      ## n / (d1 * d2)
+      ## n / (d1 * d2 * d3)
+      ## etc.
+      ## This is minimized if d1 >= d2 >= d3...
 
-    sc = size (c);
-    nd = ndims (c);
-    [~, isc] = sort (sc);
-    for idim = isc
-      if (sc(idim) == 1)
-        continue;
-      endif
-      xdim = [1:idim-1, idim+1:nd];
-      cc = num2cell (c, xdim);
-      c = cellfun ("cat", {idim}, cc{:}, "uniformoutput", false);
-    endfor
-    m = c{1};
+      nd = ndims (c);
+      [~, isc] = sort (sc, "descend");
+      for idim = isc
+        if (sc(idim) == 1)
+          continue;
+        endif
+        xdim = [1:idim-1, idim+1:nd];
+        cc = num2cell (c, xdim);
+        c = cellfun ("cat", {idim}, cc{:}, "uniformoutput", false);
+      endfor
+      m = c{1};
+
+    endif
   endif
 
 endfunction