Mercurial > hg > octave-nkf
changeset 17004:19b7c7412a63
cell2mat.m: Re-vamp input validation for 30% speedup
* scripts/general/cell2mat.m: Use if tree to only call cellfun if necessary
to further validate inputs. Add %!error tests for input validation. Use
standard variable name 'sz' for size of object.
* libinterp/corefcn/cellfun.cc(try_cellfun_internal_ops): Put test for 'numel'
ahead of test for 'prodofsize' since it is the more common usage.
author | Rik <rik@octave.org> |
---|---|
date | Thu, 18 Jul 2013 12:05:34 -0700 |
parents | c6a39f7f193d |
children | b3d4edc991c0 |
files | libinterp/corefcn/cellfun.cc scripts/general/cell2mat.m |
diffstat | 2 files changed, 27 insertions(+), 16 deletions(-) [+] |
line wrap: on
line diff
--- a/libinterp/corefcn/cellfun.cc +++ b/libinterp/corefcn/cellfun.cc @@ -161,7 +161,7 @@ result(count) = static_cast<double> (f_args.elem (count).ndims ()); retval(0) = result; } - else if (name == "prodofsize" || name == "numel") + else if (name == "numel" || name == "prodofsize") { NDArray result (f_args.dims ()); for (octave_idx_type count = 0; count < k; count++)
--- a/scripts/general/cell2mat.m +++ b/scripts/general/cell2mat.m @@ -21,8 +21,8 @@ ## @deftypefn {Function File} {@var{m} =} cell2mat (@var{c}) ## Convert the cell array @var{c} into a matrix by concatenating all ## elements of @var{c} into a hyperrectangle. Elements of @var{c} must -## be numeric, logical or char matrices, or cell arrays, and @code{cat} -## must be able to concatenate them together. +## be numeric, logical, or char matrices; or cell arrays; or structs; and +## @code{cat} must be able to concatenate them together. ## @seealso{mat2cell, num2cell} ## @end deftypefn @@ -42,20 +42,24 @@ m = []; else - ## We only want numeric, logical, and char matrices. + ## Check first for valid matrix types valid = cellfun ("isnumeric", c); - valid |= cellfun ("islogical", c); - valid |= cellfun ("isclass", c, "char"); - validc = cellfun ("isclass", c, "cell"); - valids = cellfun ("isclass", c, "struct"); - - if (! all (valid(:)) && ! all (validc(:)) && ! all (valids(:))) - error ("cell2mat: wrong type elements or mixed cells, structs and matrices"); + valid = cellfun ("islogical", c(! valid)); + valid = cellfun ("isclass", c(! valid), "char"); + if (! all (valid(:))) + valid = cellfun ("isclass", c, "cell"); + if (! all (valid(:))) + valid = cellfun ("isclass", c, "struct"); + if (! all (valid(:))) + error ("cell2mat: wrong type elements or mixed cells, structs, and matrices"); + endif + endif endif - sc = size (c); + sz = size (c); if (all (cellfun ("numel", c)(:) == 1)) - m = reshape (cat (1, c{:}), sc); + ## Special case of all scalars + m = reshape (cat (1, c{:}), sz); else ## The goal is to minimize the total number of cat() calls. @@ -68,9 +72,9 @@ ## This is minimized if d1 >= d2 >= d3... nd = ndims (c); - [~, isc] = sort (sc, "descend"); - for idim = isc - if (sc(idim) == 1) + [~, isz] = sort (sz, "descend"); + for idim = isz + if (sz(idim) == 1) continue; endif xdim = [1:idim-1, idim+1:nd]; @@ -109,3 +113,10 @@ %! m = {1, 2, 3}; %! assert (cell2mat (mat2cell (m, 1, [1 1 1])), m); +%!error cell2mat () +%!error cell2mat (1,2) +%!error <C is not a cell array> cell2mat ([1,2]) +%!error <mixed cells, structs, and matrices> cell2mat ({[1], struct()}) +%!error <mixed cells, structs, and matrices> cell2mat ({[1], {1}}) +%!error <mixed cells, structs, and matrices> cell2mat ({struct(), {1}}) +