77 catch (octave_execution_exception)
91 static_cast<double> (count
92 + static_cast<octave_idx_type>(1)));
118 template<
typename BNDA,
typename NDA>
124 std::string name = args(0).string_value ();
130 if (name ==
"isempty")
132 BNDA result (f_args.
dims ());
137 else if (name ==
"islogical")
139 BNDA result (f_args.
dims ());
144 else if (name ==
"isnumeric")
146 BNDA result (f_args.
dims ());
151 else if (name ==
"isreal")
153 BNDA result (f_args.
dims ());
158 else if (name ==
"length")
160 NDA result (f_args.
dims ());
162 result(count) =
static_cast<double> (f_args.
elem (count).
length ());
165 else if (name ==
"ndims")
167 NDA result (f_args.
dims ());
169 result(count) =
static_cast<double> (f_args.
elem (count).
ndims ());
172 else if (name ==
"numel" || name ==
"prodofsize")
174 NDA result (f_args.
dims ());
176 result(count) =
static_cast<double> (f_args.
elem (count).
numel ());
179 else if (name ==
"size")
183 int d = args(2).nint_value () - 1;
186 error (
"cellfun: K must be a positive integer");
190 NDA result (f_args.
dims ());
195 result(count) =
static_cast<double> (dv(d));
203 error (
"cellfun: not enough arguments for \"size\"");
205 else if (name ==
"isclass")
209 std::string class_name = args(2).string_value ();
210 BNDA result (f_args.
dims ());
212 result(count) = (f_args.
elem (count).
class_name () == class_name);
217 error (
"cellfun: not enough arguments for \"isclass\"");
227 while (nargin > 3 && args(nargin-2).is_string ())
231 size_t compare_len =
std::max (arg.length (),
static_cast<size_t> (2));
233 if (arg.
compare (
"uniformoutput", compare_len))
234 uniform_output = args(nargin-1).bool_value ();
235 else if (arg.
compare (
"errorhandler", compare_len))
237 if (args(nargin-1).is_function_handle ()
238 || args(nargin-1).is_inline_function ())
240 error_handler = args(nargin-1);
242 else if (args(nargin-1).is_string ())
244 std::string err_name = args(nargin-1).string_value ();
250 error (
"cellfun: invalid function NAME: %s",
257 error (
"cellfun: invalid value for 'ErrorHandler' function");
263 error (
"cellfun: unrecognized parameter %s",
274 DEFUN (cellfun, args, nargout,
276 @deftypefn {Built-in Function} {} cellfun (@var{name}, @var{C})\n\
277 @deftypefnx {Built-in Function} {} cellfun (\"size\", @var{C}, @var{k})\n\
278 @deftypefnx {Built-in Function} {} cellfun (\"isclass\", @var{C}, @var{class})\n\
279 @deftypefnx {Built-in Function} {} cellfun (@var{func}, @var{C})\n\
280 @deftypefnx {Built-in Function} {} cellfun (@var{func}, @var{C}, @var{D})\n\
281 @deftypefnx {Built-in Function} {[@var{a}, @dots{}] =} cellfun (@dots{})\n\
282 @deftypefnx {Built-in Function} {} cellfun (@dots{}, \"ErrorHandler\", @var{errfunc})\n\
283 @deftypefnx {Built-in Function} {} cellfun (@dots{}, \"UniformOutput\", @var{val})\n\
285 Evaluate the function named @var{name} on the elements of the cell array\n\
286 @var{C}. Elements in @var{C} are passed on to the named function\n\
287 individually. The function @var{name} can be one of the functions\n\
291 Return 1 for empty elements.\n\
294 Return 1 for logical elements.\n\
297 Return 1 for numeric elements.\n\
300 Return 1 for real elements.\n\
303 Return a vector of the lengths of cell elements.\n\
306 Return the number of dimensions of each element.\n\
310 Return the number of elements contained within each cell element. The\n\
311 number is the product of the dimensions of the object at each cell element.\n\
314 Return the size along the @var{k}-th dimension.\n\
317 Return 1 for elements of @var{class}.\n\
320 Additionally, @code{cellfun} accepts an arbitrary function @var{func}\n\
321 in the form of an inline function, function handle, or the name of a\n\
322 function (in a character string). The function can take one or more arguments,\n\
323 with the inputs arguments given by @var{C}, @var{D}, etc. Equally the\n\
324 function can return one or more output arguments. For example:\n\
328 cellfun (\"atan2\", @{1, 0@}, @{0, 1@})\n\
329 @result{} [ 1.57080 0.00000 ]\n\
333 The number of output arguments of @code{cellfun} matches the number of output\n\
334 arguments of the function. The outputs of the function will be collected\n\
335 into the output arguments of @code{cellfun} like this:\n\
339 function [a, b] = twoouts (x)\n\
343 [aa, bb] = cellfun (@@twoouts, @{1, 2, 3@})\n\
352 Note that per default the output argument(s) are arrays of the same size as\n\
353 the input arguments. Input arguments that are singleton (1x1) cells will be\n\
354 automatically expanded to the size of the other arguments.\n\
356 If the parameter @qcode{\"UniformOutput\"} is set to true (the default),\n\
357 then the function must return scalars which will be concatenated into the\n\
358 return array(s). If @qcode{\"UniformOutput\"} is false, the outputs are\n\
359 concatenated into a cell array (or cell arrays). For example:\n\
363 cellfun (\"tolower\", @{\"Foo\", \"Bar\", \"FooBar\"@},\n\
364 \"UniformOutput\", false)\n\
365 @result{} @{\"foo\", \"bar\", \"foobar\"@}\n\
369 Given the parameter @qcode{\"ErrorHandler\"}, then @var{errfunc} defines a\n\
370 function to call in case @var{func} generates an error. The form of the\n\
374 function [@dots{}] = errfunc (@var{s}, @dots{})\n\
378 where there is an additional input argument to @var{errfunc} relative to\n\
379 @var{func}, given by @var{s}. This is a structure with the elements\n\
380 @qcode{\"identifier\"}, @qcode{\"message\"} and @qcode{\"index\"}, giving\n\
381 respectively the error identifier, the error message, and the index into the\n\
382 input arguments of the element that caused the error. For example:\n\
386 function y = foo (s, x), y = NaN; endfunction\n\
387 cellfun (\"factorial\", @{-1,2@}, \"ErrorHandler\", @@foo)\n\
392 Use @code{cellfun} intelligently. The @code{cellfun} function is a\n\
393 useful tool for avoiding loops. It is often used with anonymous\n\
394 function handles; however, calling an anonymous function involves an\n\
395 overhead quite comparable to the overhead of an m-file function.\n\
396 Passing a handle to a built-in function is faster, because the\n\
397 interpreter is not involved in the internal loop. For example:\n\
402 v = cellfun (@@(x) det (x), a); # compute determinants\n\
403 v = cellfun (@@det, a); # faster\n\
407 @seealso{arrayfun, structfun, spfun}\n\
411 int nargin = args.
length ();
412 int nargout1 = (nargout < 1 ? 1 : nargout);
416 error (
"cellfun: function requires at least 2 arguments");
423 if (! args(1).is_cell ())
425 error (
"cellfun: C must be a cell array");
432 retval = try_cellfun_internal_ops<boolNDArray,NDArray>(args, nargin);
439 std::string name = args(0).string_value ();
444 std::string fname =
"function y = " + fcn_name +
"(x) y = ";
448 fname,
"; endfunction");
458 error (
"cellfun: invalid function NAME: %s", name.c_str ());
469 bool uniform_output =
true;
486 if (f -> is_overloaded ())
496 if (name !=
"size" && name !=
"class")
504 try_cellfun_internal_ops<boolNDArray, NDArray> (tmp_args,
508 try_cellfun_internal_ops<Cell, Cell> (tmp_args, nargin);
533 const Cell *cinputs = inputs;
542 for (
int j = 0; j < nargin; j++)
544 if (! args(j+1).is_cell ())
546 error (
"cellfun: arguments must be cells");
550 inputs[j] = args(j+1).cell_value ();
551 mask[j] = inputs[j].numel () != 1;
553 inputlist(j) = cinputs[j](0);
556 for (
int j = 0; j < nargin; j++)
560 fdims = inputs[j].dims ();
561 k = inputs[j].numel ();
562 for (
int i = j+1; i < nargin; i++)
564 if (mask[i] && inputs[i].dims () != fdims)
566 error (
"cellfun: dimensions mismatch");
584 std::list<octave_value_list> idx_list (1);
585 idx_list.front ().resize (1);
586 std::string idx_type =
"(";
592 for (
int j = 0; j < nargin; j++)
595 inputlist.
xelem (j) = cinputs[j](count);
605 if (nargout > 0 && tmp.
length () < nargout)
607 error (
"cellfun: function returned fewer than nargout values");
613 && tmp.
length () > 0 && tmp(0).is_defined ()))
615 int num_to_copy = tmp.
length ();
617 if (num_to_copy > nargout1)
618 num_to_copy = nargout1;
622 for (
int j = 0; j < num_to_copy; j++)
624 if (tmp(j).is_defined ())
628 if (val.
numel () == 1)
629 retv[j] = val.
resize (fdims);
632 error (
"cellfun: all values must be scalars when UniformOutput = true");
640 for (
int j = 0; j < num_to_copy; j++)
642 if (tmp(j).is_defined ())
646 if (! retv[j].fast_elem_insert (count, val))
648 if (val.
numel () == 1)
650 idx_list.front ()(0) = count + 1.0;
652 idx_type, idx_list, val);
659 error (
"cellfun: all values must be scalars when UniformOutput = true");
674 for (
int j = 0; j < nargout1; j++)
676 if (nargout > 0 && retv[j].is_undefined ())
686 for (
int j = 0; j < nargout1; j++)
689 bool have_some_output =
false;
693 for (
int j = 0; j < nargin; j++)
696 inputlist.
xelem (j) = cinputs[j](count);
706 if (nargout > 0 && tmp.
length () < nargout)
708 error (
"cellfun: function returned fewer than nargout values");
714 && tmp.
length () > 0 && tmp(0).is_defined ()))
716 int num_to_copy = tmp.
length ();
718 if (num_to_copy > nargout1)
719 num_to_copy = nargout1;
722 have_some_output =
true;
724 for (
int j = 0; j < num_to_copy; j++)
725 results[j](count) = tmp(j);
729 if (have_some_output || fdims.
any_zero ())
733 for (
int j = 0; j < nargout1; j++)
734 retval(j) = results[j];
739 error (
"cellfun: argument NAME must be a string or function handle");
1060 DEFUN (arrayfun, args, nargout,
1062 @deftypefn {Function File} {} arrayfun (@var{func}, @var{A})\n\
1063 @deftypefnx {Function File} {@var{x} =} arrayfun (@var{func}, @var{A})\n\
1064 @deftypefnx {Function File} {@var{x} =} arrayfun (@var{func}, @var{A}, @var{b}, @dots{})\n\
1065 @deftypefnx {Function File} {[@var{x}, @var{y}, @dots{}] =} arrayfun (@var{func}, @var{A}, @dots{})\n\
1066 @deftypefnx {Function File} {} arrayfun (@dots{}, \"UniformOutput\", @var{val})\n\
1067 @deftypefnx {Function File} {} arrayfun (@dots{}, \"ErrorHandler\", @var{errfunc})\n\
1069 Execute a function on each element of an array. This is useful for\n\
1070 functions that do not accept array arguments. If the function does\n\
1071 accept array arguments it is better to call the function directly.\n\
1073 The first input argument @var{func} can be a string, a function\n\
1074 handle, an inline function, or an anonymous function. The input\n\
1075 argument @var{A} can be a logic array, a numeric array, a string\n\
1076 array, a structure array, or a cell array. By a call of the function\n\
1077 @command{arrayfun} all elements of @var{A} are passed on to the named\n\
1078 function @var{func} individually.\n\
1080 The named function can also take more than two input arguments, with\n\
1081 the input arguments given as third input argument @var{b}, fourth\n\
1082 input argument @var{c}, @dots{} If given more than one array input\n\
1083 argument then all input arguments must have the same sizes, for\n\
1088 arrayfun (@@atan2, [1, 0], [0, 1])\n\
1089 @result{} [ 1.5708 0.0000 ]\n\
1093 If the parameter @var{val} after a further string input argument\n\
1094 @qcode{\"UniformOutput\"} is set @code{true} (the default), then the named\n\
1095 function @var{func} must return a single element which then will be\n\
1096 concatenated into the return value and is of type matrix. Otherwise,\n\
1097 if that parameter is set to @code{false}, then the outputs are\n\
1098 concatenated in a cell array. For example:\n\
1102 arrayfun (@@(x,y) x:y, \"abc\", \"def\", \"UniformOutput\", false)\n\
1112 If more than one output arguments are given then the named function\n\
1113 must return the number of return values that also are expected, for\n\
1118 [A, B, C] = arrayfun (@@find, [10; 0], \"UniformOutput\", false)\n\
1138 If the parameter @var{errfunc} after a further string input argument\n\
1139 @qcode{\"ErrorHandler\"} is another string, a function handle, an inline\n\
1140 function, or an anonymous function, then @var{errfunc} defines a\n\
1141 function to call in the case that @var{func} generates an error.\n\
1142 The definition of the function must be of the form\n\
1145 function [@dots{}] = errfunc (@var{s}, @dots{})\n\
1149 where there is an additional input argument to @var{errfunc}\n\
1150 relative to @var{func}, given by @var{s}. This is a structure with\n\
1151 the elements @qcode{\"identifier\"}, @qcode{\"message\"}, and\n\
1152 @qcode{\"index\"} giving, respectively, the error identifier, the error\n\
1153 message, and the index of the array elements that caused the error. The\n\
1154 size of the output argument of @var{errfunc} must have the same size as the\n\
1155 output argument of @var{func}, otherwise a real error is thrown. For\n\
1160 function y = ferr (s, x), y = \"MyString\"; endfunction\n\
1161 arrayfun (@@str2num, [1234],\n\
1162 \"UniformOutput\", false, \"ErrorHandler\", @@ferr)\n\
1170 @seealso{spfun, cellfun, structfun}\n\
1174 int nargin = args.
length ();
1175 int nargout1 = (nargout < 1 ? 1 : nargout);
1180 "arrayfun: function requires at least 2 arguments");
1186 bool symbol_table_lookup =
false;
1192 std::string name = args(0).string_value ();
1197 std::string fname =
"function y = " + fcn_name +
"(x) y = ";
1201 fname,
"; endfunction");
1212 "arrayfun: invalid function NAME: %s",
1215 symbol_table_lookup =
true;
1230 if (! symbol_table_lookup )
1240 if (f -> is_overloaded ())
1251 bool uniform_output =
true;
1271 for (
int j = 0; j < nargin; j++)
1273 inputs[j] = args(j+1);
1274 mask[j] = inputs[j].numel () != 1;
1277 inputlist(j) = inputs[j];
1280 for (
int j = 0; j < nargin; j++)
1284 fdims = inputs[j].dims ();
1285 k = inputs[j].numel ();
1287 for (
int i = j+1; i < nargin; i++)
1289 if (mask[i] && inputs[i].dims () != fdims)
1292 "arrayfun: dimensions mismatch");
1311 std::list<octave_value_list> idx_list (1);
1312 idx_list.front ().resize (1);
1313 std::string idx_type =
"(";
1319 idx_list.front ()(0) = count + 1.0;
1321 for (
int j = 0; j < nargin; j++)
1337 if (nargout > 0 && tmp.
length () < nargout)
1340 "arrayfun: function returned fewer than nargout values");
1346 && tmp.
length () > 0 && tmp(0).is_defined ()))
1348 int num_to_copy = tmp.
length ();
1350 if (num_to_copy > nargout1)
1351 num_to_copy = nargout1;
1355 for (
int j = 0; j < num_to_copy; j++)
1357 if (tmp(j).is_defined ())
1361 if (val.
numel () == 1)
1362 retv[j] = val.
resize (fdims);
1366 "arrayfun: all values must be scalars when UniformOutput = true");
1374 for (
int j = 0; j < num_to_copy; j++)
1376 if (tmp(j).is_defined ())
1380 if (! retv[j].fast_elem_insert (count, val))
1382 if (val.
numel () == 1)
1384 idx_list.front ()(0) = count + 1.0;
1386 idx_type, idx_list, val);
1394 "arrayfun: all values must be scalars when UniformOutput = true");
1407 retval.
resize (nargout1);
1409 for (
int j = 0; j < nargout1; j++)
1411 if (nargout > 0 && retv[j].is_undefined ())
1414 retval(j) = retv[j];
1419 std::list<octave_value_list> idx_list (1);
1420 idx_list.front ().resize (1);
1421 std::string idx_type =
"(";
1425 for (
int j = 0; j < nargout1; j++)
1428 bool have_some_output =
false;
1432 idx_list.front ()(0) = count + 1.0;
1434 for (
int j = 0; j < nargin; j++)
1450 if (nargout > 0 && tmp.
length () < nargout)
1453 "arrayfun: function returned fewer than nargout values");
1459 && tmp.
length () > 0 && tmp(0).is_defined ()))
1461 int num_to_copy = tmp.
length ();
1463 if (num_to_copy > nargout1)
1464 num_to_copy = nargout1;
1466 if (num_to_copy > 0)
1467 have_some_output =
true;
1469 for (
int j = 0; j < num_to_copy; j++)
1470 results[j](count) = tmp(j);
1474 if (have_some_output || fdims.
any_zero ())
1476 retval.
resize (nargout1);
1478 for (
int j = 0; j < nargout1; j++)
1479 retval(j) = results[j];
1485 "arrayfun: argument NAME must be a string or function handle");
1712 int dvl = dimv.
length ();
1715 for (
int i = 0; i < dvl; i++)
1723 perm.
clear (maxd, 1);
1724 for (
int i = 0; i < dvl; i++)
1726 int k = dimv(i) - 1;
1729 error (
"num2cell: dimension indices must be positive");
1732 else if (i > 0 && k < dimv(i-1) - 1)
1734 error (
"num2cell: dimension indices must be strictly increasing");
1742 for (
int k = 0, i = dvl; k < maxd; k++)
1746 for (
int i = 0; i < maxd; i++)
1754 static inline typename NDA::element_type
1756 {
return array(i); }
1760 {
return Cell (array(i)); }
1769 Cell retval (array.dims ());
1784 NDA parray = array.permute (perm);
1787 parray = parray.reshape (
dim_vector (nela, nelc));
1789 Cell retval (celldv);
1792 retval.
xelem (i) = NDA (parray.column (i).reshape (arraydv));
1814 for (
int i = 0; i < n; i++)
1854 error (
"num2cell (A, dim) not implemented for class objects");
1860 DEFUN (num2cell, args, ,
1862 @deftypefn {Built-in Function} {@var{C} =} num2cell (@var{A})\n\
1863 @deftypefnx {Built-in Function} {@var{C} =} num2cell (@var{A}, @var{dim})\n\
1864 Convert the numeric matrix @var{A} to a cell array. If @var{dim} is\n\
1865 defined, the value @var{C} is of dimension 1 in this dimension and the\n\
1866 elements of @var{A} are placed into @var{C} in slices. For example:\n\
1870 num2cell ([1,2;3,4])\n\
1878 num2cell ([1,2;3,4],1)\n\
1891 @seealso{mat2cell}\n\
1894 int nargin = args.length ();
1897 if (nargin < 1 || nargin > 2)
1904 dimv = args (1).int_vector_value (
true);
1950 else if (array.
is_map ())
1973 for (
int i = 0; i < nd; i++)
1983 error (
"mat2cell: mismatch on %d-th dimension (%d != %d)",
1992 template<
class container>
2015 template <
class Array2D>
2020 assert (nd == 1 || nd == 2);
2021 assert (a.ndims () == 2);
2028 retval.clear (nridx, ncidx);
2031 if (a.rows () > 1 && a.cols () == 1 && ncidx == 1)
2033 else if (a.rows () == 1 && nridx == 1 && nd == 2)
2061 retval(i,j) = a.index (ridx[i], cidx[j]);
2071 template <
class ArrayND>
2084 for (
int i = 0; i < nd; i++)
2086 rdv(i) = nidx[i] = d[i].
length ();
2096 for (
int i = 0; i < nd; i++)
2098 idx[i] = xidx + idxtot;
2111 for (
int i = 0; i < nd; i++)
2112 ra_idx(i) = idx[i][ridx[i]];
2114 retval(j) = a.index (ra_idx);
2123 template <
class ArrayND>
2127 if (a.ndims () == 2 && nd <= 2)
2148 for (
int i = 0; i < nd; i++)
2150 rdv(i) = nidx[i] = d[i].
length ();
2160 for (
int i = 0; i < nd; i++)
2162 idx[i] = xidx + idxtot;
2175 for (
int i = 0; i < nd; i++)
2176 ra_idx(i) = idx[i][ridx[i]];
2189 DEFUN (mat2cell, args, ,
2191 @deftypefn {Built-in Function} {@var{C} =} mat2cell (@var{A}, @var{m}, @var{n})\n\
2192 @deftypefnx {Built-in Function} {@var{C} =} mat2cell (@var{A}, @var{d1}, @var{d2}, @dots{})\n\
2193 @deftypefnx {Built-in Function} {@var{C} =} mat2cell (@var{A}, @var{r})\n\
2194 Convert the matrix @var{A} to a cell array. If @var{A} is 2-D, then\n\
2195 it is required that @code{sum (@var{m}) == size (@var{A}, 1)} and\n\
2196 @code{sum (@var{n}) == size (@var{A}, 2)}. Similarly, if @var{A} is\n\
2197 multi-dimensional and the number of dimensional arguments is equal\n\
2198 to the dimensions of @var{A}, then it is required that @code{sum (@var{di})\n\
2199 == size (@var{A}, i)}.\n\
2201 Given a single dimensional argument @var{r}, the other dimensional\n\
2202 arguments are assumed to equal @code{size (@var{A},@var{i})}.\n\
2204 An example of the use of mat2cell is\n\
2207 mat2cell (reshape (1:16,4,4), [3,1], [3,1])\n\
2229 @seealso{num2cell, cell2mat}\n\
2232 int nargin = args.length ();
2242 for (
int i = 1; i < nargin; i++)
2244 d[i-1] = args(i).octave_idx_type_vector_value (
true);
2251 if (sparse && nargin > 3)
2253 error (
"mat2cell: sparse arguments only support 2-D indexing");
2276 #define BTYP_BRANCH(X,Y) \
2278 retval = do_mat2cell (a.Y ## _value (), d, nargin - 1); \
2324 template <
class NDA>
2333 if (array.is_vector () && (dim == -1
2334 || (dim == 0 && array.columns () == 1)
2335 || (dim == 1 && array.rows () == 1)))
2343 int ndims = dv.
length ();
2353 retval(i) = array.
index (idx);
2360 DEFUN (cellslices, args, ,
2362 @deftypefn {Built-in Function} {@var{sl} =} cellslices (@var{x}, @var{lb}, @var{ub}, @var{dim})\n\
2363 Given an array @var{x}, this function produces a cell array of slices from\n\
2364 the array determined by the index vectors @var{lb}, @var{ub}, for lower and\n\
2365 upper bounds, respectively. In other words, it is equivalent to the\n\
2371 sl = cell (1, n);\n\
2372 for i = 1:length (lb)\n\
2373 sl@{i@} = x(:,@dots{},lb(i):ub(i),@dots{},:);\n\
2378 The position of the index is determined by @var{dim}. If not specified,\n\
2379 slicing is done along the first non-singleton dimension.\n\
2380 @seealso{cell2mat, cellindexmat, cellfun}\n\
2384 int nargin = args.
length ();
2385 if (nargin == 3 || nargin == 4)
2393 dim = args(3).int_value () - 1;
2395 error (
"cellslices: DIM must be a valid dimension");
2401 error (
"cellslices: the lengths of LB and UB must match");
2464 retcell =
Cell (1, n);
2466 int ndims = dv.
length ();
2473 idx(dim) =
Range (lb(i), ub(i));
2495 DEFUN (cellindexmat, args, ,
2497 @deftypefn {Built-in Function} {@var{y} =} cellindexmat (@var{x}, @var{varargin})\n\
2498 Given a cell array of matrices @var{x}, this function computes\n\
2502 Y = cell (size (X));\n\
2503 for i = 1:numel (X)\n\
2504 Y@{i@} = X@{i@}(varargin@{:@});\n\
2508 @seealso{cellslices, cellfun}\n\
2512 if (args.length () >= 1)
2514 if (args(0).is_cell ())
2516 const Cell x = args(0).cell_value ();
2533 error (
"cellindexmat: X must be a cell");