26#if defined (HAVE_CONFIG_H)
76 bool execution_error =
false;
80 retval = interp.
feval (fcn, inputlist, nargout);
91 execution_error =
true;
107 static_cast<double> (count
113 retval = interp.
feval (error_handler, errlist, nargout);
124 std::string fcn_name = args(0).string_value ();
130 if (fcn_name ==
"isempty")
134 "cellfun: accelerated function must be called with only one argument");
140 else if (fcn_name ==
"islogical")
144 "cellfun: accelerated function must be called with only one argument");
150 else if (fcn_name ==
"isnumeric")
154 "cellfun: accelerated function must be called with only one argument");
160 else if (fcn_name ==
"isreal")
164 "cellfun: accelerated function must be called with only one argument");
170 else if (fcn_name ==
"length")
174 "cellfun: accelerated function must be called with only one argument");
177 result(count) =
static_cast<double> (f_arg.
xelem (count).
length ());
180 else if (fcn_name ==
"ndims")
184 "cellfun: accelerated function must be called with only one argument");
187 result(count) =
static_cast<double> (f_arg.
xelem (count).
ndims ());
190 else if (fcn_name ==
"numel" || fcn_name ==
"prodofsize")
194 "cellfun: accelerated function must be called with only one argument");
197 result(count) =
static_cast<double> (f_arg.
xelem (count).
numel ());
200 else if (fcn_name ==
"size")
204 "cellfun: accelerated function 'size' must be called with exactly two arguments");
206 int d = args(2).strict_int_value () - 1;
210 "cellfun: K must be a positive integer");
218 result(count) =
static_cast<double> (dv(
d));
225 else if (fcn_name ==
"isclass")
229 "cellfun: accelerated function 'isclass' must be called with exactly two arguments");
231 std::string class_name = args(2).xstring_value (
"cellfun: CLASS argument to 'isclass' must be a string");
244 int& nargin,
bool& uniform_output,
octave_value& error_handler)
246 while (nargin > 3 && args(nargin-2).is_string ())
248 std::string arg = args(nargin-2).string_value ();
250 std::size_t compare_len = std::max (arg.length (),
251 static_cast<std::size_t
> (2));
253 if (string::strncmpi (arg,
"uniformoutput", compare_len))
254 uniform_output = args(nargin-1).xbool_value (
"cellfun: UniformOutput value must be boolean");
255 else if (string::strncmpi (arg,
"errorhandler", compare_len))
257 if (args(nargin-1).is_function_handle ()
258 || args(nargin-1).is_inline_function ())
260 error_handler = args(nargin-1);
262 else if (args(nargin-1).is_string ())
264 std::string err_name = args(nargin-1).string_value ();
270 "cellfun: invalid function NAME: %s",
275 "cellfun: invalid value for 'ErrorHandler' function");
279 "cellfun: unrecognized parameter %s", arg.c_str ());
287DEFMETHOD (cellfun, interp, args, nargout,
444 int nargin = args.
length ();
449 if (! args(1).iscell ())
451 "cellfun: C must be a cell array");
460 retval = try_cellfun_accelfcns (args, nargin);
462 if (! retval.
empty ())
473 std::string name = args(0).string_value ();
483 "cellfun: invalid function NAME: %s",
491 "cellfun: argument NAME must be a string or function handle");
494 bool uniform_output =
true;
496 int nargout1 = (nargout < 1 ? 1 : nargout);
498 parse_options (symtab, args, nargin, uniform_output, error_handler);
523 const Cell *cinputs = inputs;
530 for (
int j = 0; j < nargin; j++)
532 if (! args(j+1).iscell ())
534 "cellfun: arguments must be cells");
537 isarray[j] = (inputs[j].numel () != 1);
540 nel = inputs[j].numel ();
541 if (inputdims.
numel () == 1)
542 inputdims = inputs[j].dims ();
543 else if (inputs[j].dims () != inputdims)
544 error (
"cellfun: input cell dimensions mismatch");
547 inputovl(j) = cinputs[j](0);
555 int expected_nargout;
559 for (
int j = 0; j < nargin; j++)
562 inputovl.
xelem (j) = cinputs[j](count);
567 = fcn_eval (interp, count, nargout, inputovl, fcn, error_handler);
577 expected_nargout = (y_nel > 0 && y(0).is_defined ()) ? 1 : 0;
579 expected_nargout = nargout;
581 if (y_nel < expected_nargout)
582 error (
"cellfun: function returned fewer than nargout values");
583 else if (expected_nargout == 0 && y_nel > 0 && y(0).is_defined ())
584 error (
"cellfun: function returned unexpected number of values");
587 if (expected_nargout > 0)
594 for (
int j = 0; j < expected_nargout; j++)
596 if (y(j).is_undefined ())
597 error (
"cellfun: function returned fewer than nargout values");
600 if (val.
numel () != 1)
601 error (
"cellfun: all values must be scalars when UniformOutput = true");
603 results[j] = val.
resize (inputdims);
608 for (
int j = 0; j < expected_nargout; j++)
610 if (y(j).is_undefined ())
611 error (
"cellfun: function returned fewer than nargout values");
614 if (! results[j].fast_elem_insert (count, val))
616 if (val.
numel () != 1)
617 error (
"cellfun: all values must be scalars when UniformOutput = true");
619 error (
"cellfun: all values should be of the same type when UniformOutput = true");
628 for (
int j = 0; j < nargout1; j++)
630 if (nargout > 0 && results[j].is_undefined ())
631 retval(j) =
NDArray (inputdims);
633 retval(j) = results[j];
640 for (
int j = 0; j < nargout1; j++)
641 results[j].resize (inputdims);
643 bool have_output =
false;
647 for (
int j = 0; j < nargin; j++)
650 inputovl.
xelem (j) = cinputs[j](count);
654 = fcn_eval (interp, count, nargout, inputovl, fcn, error_handler);
658 if (nargout > 0 && y_nel < nargout)
659 error (
"cellfun: function returned fewer than nargout values");
662 || (nargout == 0 && y_nel > 0 && y(0).is_defined ()))
666 int num_to_copy = std::min (y_nel, nargout1);
668 for (
int j = 0; j < num_to_copy; j++)
670 if (y(j).is_undefined ())
671 error (
"cellfun: function returned fewer than nargout values");
672 results[j](count) = y(j);
677 if (have_output || inputdims.
any_zero ())
680 for (
int j = 0; j < nargout1; j++)
681 retval(j) = results[j];
1147DEFMETHOD (arrayfun, interp, args, nargout,
1267 int nargin = args.
length ();
1273 int nargout1 = (nargout < 1 ? 1 : nargout);
1274 bool symbol_table_lookup =
false;
1282 std::string name = args(0).string_value ();
1292 "arrayfun: invalid function NAME: %s",
1295 symbol_table_lookup =
true;
1306 if (! symbol_table_lookup)
1322 if (
f.is_defined ())
1328 bool uniform_output =
true;
1331 parse_options (symtab, args, nargin, uniform_output, error_handler);
1344 for (
int j = 0; j < nargin; j++)
1346 inputs[j] = args(j+1);
1347 mask[j] = inputs[j].numel () != 1;
1350 inputlist(j) = inputs[j];
1353 for (
int j = 0; j < nargin; j++)
1357 fdims = inputs[j].dims ();
1358 k = inputs[j].numel ();
1360 for (
int i = j+1; i < nargin; i++)
1362 if (mask[i] && inputs[i].dims () != fdims)
1364 "arrayfun: dimensions mismatch");
1374 std::list<octave_value_list> idx_list (1);
1375 idx_list.front ().resize (1);
1376 std::string idx_type =
"(";
1383 int expected_nargout = 0;
1386 idx_list.front ()(0) = count + 1.0;
1388 for (
int j = 0; j < nargin; j++)
1395 = fcn_eval (interp, count, nargout, inputlist, fcn,
1405 expected_nargout = (y_nel > 0 && y(0).is_defined ())
1408 expected_nargout = nargout;
1410 if (y_nel < expected_nargout)
1412 "arrayfun: function returned fewer than nargout values");
1413 else if (expected_nargout == 0 && y_nel > 0 && y(0).is_defined ())
1414 error (
"cellfun: function returned unexpected number of values");
1416 if (expected_nargout > 0)
1420 for (
int j = 0; j < expected_nargout; j++)
1422 if (y(j).is_defined ())
1426 if (val.
numel () == 1)
1427 retv[j] = val.
resize (fdims);
1430 "arrayfun: all values must be scalars when UniformOutput = true");
1433 error (
"arrayfun: function returned fewer than nargout values");
1438 for (
int j = 0; j < expected_nargout; j++)
1440 if (y(j).is_defined ())
1444 if (! retv[j].fast_elem_insert (count, val))
1446 if (val.
numel () == 1)
1448 idx_list.front ()(0) = count + 1.0;
1450 idx_type, idx_list, val);
1454 "arrayfun: all values must be scalars when UniformOutput = true");
1458 error (
"arrayfun: function returned fewer than nargout values");
1464 retval.
resize (nargout1);
1466 for (
int j = 0; j < nargout1; j++)
1468 if (nargout > 0 && retv[j].is_undefined ())
1471 retval(j) = retv[j];
1476 std::list<octave_value_list> idx_list (1);
1477 idx_list.front ().resize (1);
1478 std::string idx_type =
"(";
1482 for (
int j = 0; j < nargout1; j++)
1483 results[j].resize (fdims,
Matrix ());
1485 bool have_some_output =
false;
1489 idx_list.front ()(0) = count + 1.0;
1491 for (
int j = 0; j < nargin; j++)
1498 = fcn_eval (interp, count, nargout, inputlist, fcn,
1501 if (nargout > 0 && y.
length () < nargout)
1503 "arrayfun: function returned fewer than nargout values");
1507 && y.
length () > 0 && y(0).is_defined ()))
1509 int num_to_copy = y.
length ();
1511 if (num_to_copy > nargout1)
1512 num_to_copy = nargout1;
1514 if (num_to_copy > 0)
1515 have_some_output =
true;
1517 for (
int j = 0; j < num_to_copy; j++)
1519 if (y(j).is_undefined ())
1520 error (
"arrayfun: function returned fewer than nargout values");
1521 results[j](count) = y(j);
1526 if (have_some_output || fdims.
any_zero ())
1528 retval.
resize (nargout1);
1530 for (
int j = 0; j < nargout1; j++)
1531 retval(j) = results[j];
1537 "arrayfun: argument NAME must be a string or function handle");
1838 int dvl = dimv.
numel ();
1839 int maxd = dv.
ndims ();
1841 for (
int i = 0; i < dvl; i++)
1842 maxd = std::max (maxd, dimv(i));
1843 if (maxd > dv.
ndims ())
1849 perm.
clear (maxd, 1);
1850 for (
int i = 0; i < dvl; i++)
1852 int k = dimv(i) - 1;
1854 error (
"num2cell: dimension indices must be positive");
1856 if (i > 0 && k < dimv(i-1) - 1)
1857 error (
"num2cell: dimension indices must be strictly increasing");
1863 for (
int k = 0, i = dvl; k < maxd; k++)
1867 for (
int i = 0; i < maxd; i++)
1874template <
typename NDA>
1875static inline typename NDA::element_type
1881{
return Cell (array(i)); }
1883template <
typename NDA>
1885do_num2cell (
const NDA& array,
const Array<int>& dimv)
1889 Cell retval (array.dims ());
1892 retval.
xelem (i) = do_num2cell_elem (array, i);
1900 do_num2cell_helper (array.dims (), dimv, celldv, arraydv, perm);
1902 NDA parray = array.permute (perm);
1906 parray = parray.reshape (
dim_vector (nela, nelc));
1908 Cell retval (celldv);
1911 retval.
xelem (i) = NDA (parray.column (i).reshape (arraydv));
1933 for (
int i = 0; i < n; i++)
1949 error (
"num2cell (A, dim) not implemented for class objects");
1951 const dim_vector& dv = get_object_dims (array);
1969DEFUN (num2cell, args, ,
2033 int nargin = args.
length ();
2035 if (nargin < 1 || nargin > 2)
2044 dimv = args(1).int_vector_value (
true);
2083 retval = do_num2cell (array.
array_value (), dimv);
2087 retval = do_object2cell (array, dimv);
2089 retval = do_num2cell (array.
map_value (), dimv);
2090 else if (array.
iscell ())
2091 retval = do_num2cell (array.
cell_value (), dimv);
2108 for (
int i = 0; i < nd; i++)
2117 error (
"mat2cell: mismatch on dimension %d (%" OCTAVE_IDX_TYPE_FORMAT
2118 " != %" OCTAVE_IDX_TYPE_FORMAT
")", i+1, r, s);
2124template <
typename container>
2126prepare_idx (container *idx,
int idim,
int nd,
2147template <
typename Array2D>
2156 if (mat2cell_mismatch (a.dims (),
d, nd))
2161 retval.
clear (nridx, ncidx);
2164 if (a.rows () > 1 && a.cols () == 1 && ncidx == 1)
2166 else if (a.rows () == 1 && nridx == 1 && nd == 2)
2177 if constexpr (std::is_same_v<Array2D, Cell>)
2188 prepare_idx (ridx, 0, nd,
d);
2191 prepare_idx (cidx, 1, nd,
d);
2198 if constexpr (std::is_same_v<Array2D, Cell>)
2199 retval.
xelem (i, j) =
Cell (a.index (ridx[i], cidx[j]));
2201 retval.
xelem (i, j) = a.index (ridx[i], cidx[j]);
2211template <
typename ArrayND>
2219 if (mat2cell_mismatch (a.dims (),
d, nd))
2228 for (
int i = 0; i < nd; i++)
2230 retdv(i) = nidx[i] =
d[i].
numel ();
2236 retval.
clear (retdv);
2246 for (
int i = 0; i < nd; i++)
2248 idx[i] = xidx + idxtot;
2249 prepare_idx (idx[i], i, nd,
d);
2266 for (
int i = 0; i < nd; i++)
2267 ra_idx.xelem (i) = idx[i][ridx[i]];
2270 if constexpr (std::is_same_v<ArrayND, Cell>)
2277 if (j < (retnumel - 1))
2285template <
typename ArrayND>
2289 if (a.ndims () == 2 && nd <= 2)
2290 return do_mat2cell_2d (a,
d, nd);
2305 if (mat2cell_mismatch (a.
dims (),
d, nd))
2311 for (
int i = 0; i < nd; i++)
2313 rdv(i) = nidx[i] =
d[i].
numel ();
2323 for (
int i = 0; i < nd; i++)
2325 idx[i] = xidx + idxtot;
2326 prepare_idx (idx[i], i, nd,
d);
2338 for (
int i = 0; i < nd; i++)
2339 ra_idx(i) = idx[i][ridx[i]];
2349DEFUN (mat2cell, args, ,
2438 int nargin = args.
length ();
2448 for (
int i = 1; i < nargin; i++)
2449 d[i-1] = args(i).octave_idx_type_vector_value (
true);
2453 if (sparse && nargin > 3)
2454 error (
"mat2cell: sparse arguments only support 2-D indexing");
2477#define BTYP_BRANCH(X, Y) \
2479 retval = do_mat2cell (a.Y ## _value (), d, nargin - 1); \
2536template <
typename NDA>
2538do_cellslices_nda (
const NDA& array,
2545 if (array.isvector () && (dim == -1
2546 || (dim == 0 && array.columns () == 1)
2547 || (dim == 1 && array.rows () == 1)))
2555 int ndims = dv.
ndims ();
2558 ndims = std::max (ndims, dim + 1);
2565 retval.
xelem (i) = array.index (idx);
2572DEFUN (cellslices, args, ,
2596 int nargin = args.
length ();
2598 if (nargin < 3 || nargin > 4)
2607 dim = args(3).int_value () - 1;
2609 error (
"cellslices: DIM must be a valid dimension");
2613 error (
"cellslices: the lengths of LB and UB must match");
2616 if (!
x.issparse () &&
x.is_matrix_type ())
2620 retcell = do_cellslices_nda (
x.bool_array_value (),
2622 else if (
x.is_char_matrix ())
2623 retcell = do_cellslices_nda (
x.char_array_value (),
2625 else if (
x.isinteger ())
2627 if (
x.is_int8_type ())
2628 retcell = do_cellslices_nda (
x.int8_array_value (),
2630 else if (
x.is_int16_type ())
2631 retcell = do_cellslices_nda (
x.int16_array_value (),
2633 else if (
x.is_int32_type ())
2634 retcell = do_cellslices_nda (
x.int32_array_value (),
2636 else if (
x.is_int64_type ())
2637 retcell = do_cellslices_nda (
x.int64_array_value (),
2639 else if (
x.is_uint8_type ())
2640 retcell = do_cellslices_nda (
x.uint8_array_value (),
2642 else if (
x.is_uint16_type ())
2643 retcell = do_cellslices_nda (
x.uint16_array_value (),
2645 else if (
x.is_uint32_type ())
2646 retcell = do_cellslices_nda (
x.uint32_array_value (),
2648 else if (
x.is_uint64_type ())
2649 retcell = do_cellslices_nda (
x.uint64_array_value (),
2652 else if (
x.iscomplex ())
2654 if (
x.is_single_type ())
2655 retcell = do_cellslices_nda (
x.float_complex_array_value (),
2658 retcell = do_cellslices_nda (
x.complex_array_value (),
2663 if (
x.is_single_type ())
2664 retcell = do_cellslices_nda (
x.float_array_value (),
2667 retcell = do_cellslices_nda (
x.array_value (),
2675 retcell =
Cell (1, n);
2677 int ndims = dv.
ndims ();
2680 ndims = std::max (ndims, dim + 1);
2689 return ovl (retcell);
2699DEFUN (cellindexmat, args, ,
2724 const Cell x = args(0).xcell_value (
"cellindexmat: X must be a cell");
2742OCTAVE_END_NAMESPACE(octave)
Cell do_mat2cell(const ArrayND &a, const Array< octave_idx_type > *d, int nd)
#define BTYP_BRANCH(X, Y)
Cell do_mat2cell_nd(const ArrayND &a, const Array< octave_idx_type > *d, int nd)
N Dimensional Array with copy-on-write semantics.
const dim_vector & dims() const
Return a const-reference so that dims ()(i) works efficiently.
T & xelem(octave_idx_type n)
Size of the specified dimension.
void resize(const dim_vector &dv, const T &rfv)
Size of the specified dimension.
bool isempty() const
Size of the specified dimension.
octave_idx_type numel() const
Number of elements in the array.
Vector representing the dimensions (size) of an Array.
octave_idx_type numel(int n=0) const
Number of elements that a matrix with this dimensions would have.
void resize(int n, int fill_value=0)
static dim_vector alloc(int n)
int increment_index(octave_idx_type *idx, int start=0) const
Increment a multi-dimensional index tuple, optionally starting from an offset position and return the...
octave_idx_type ndims() const
Number of dimensions.
int first_non_singleton(int def=0) const
octave_value last_error_id(const octave_value_list &args, int nargout)
void save_exception(const execution_exception &ee)
octave_value last_error_message(const octave_value_list &args, int nargout)
static const idx_vector colon
error_system & get_error_system()
octave_value_list feval(const char *name, const octave_value_list &args=octave_value_list(), int nargout=0)
Evaluate an Octave function (built-in or interpreted) and return the list of result values.
void recover_from_exception()
symbol_table & get_symbol_table()
void assign(const std::string &k, const octave_value &val)
void resize(octave_idx_type n, const octave_value &rfv=octave_value())
octave_value & xelem(octave_idx_type i)
octave_value_list slice(octave_idx_type offset, octave_idx_type len, bool tags=false) const
octave_idx_type length() const
octave_value_list & prepend(const octave_value &val)
bool is_function_handle() const
bool is_undefined() const
bool is_uint32_type() const
boolNDArray bool_array_value(bool warn=false) const
SparseMatrix sparse_matrix_value(bool frc_str_conv=false) const
std::string class_name() const
bool is_inline_function() const
octave_function * function_value(bool silent=false) const
int32NDArray int32_array_value() const
uint16NDArray uint16_array_value() const
octave_value index_op(const octave_value_list &idx, bool resize_ok=false)
int16NDArray int16_array_value() const
int8NDArray int8_array_value() const
bool is_int8_type() const
ComplexNDArray complex_array_value(bool frc_str_conv=false) const
bool is_single_type() const
charNDArray char_array_value(bool frc_str_conv=false) const
bool is_uint8_type() const
bool is_uint64_type() const
bool is_uint16_type() const
uint64NDArray uint64_array_value() const
bool is_int16_type() const
bool is_char_matrix() const
octave_idx_type numel() const
octave_map map_value() const
bool is_int64_type() const
octave_value single_subsref(const std::string &type, const octave_value_list &idx)
int64NDArray int64_array_value() const
NDArray array_value(bool frc_str_conv=false) const
octave_idx_type length() const
bool is_int32_type() const
uint8NDArray uint8_array_value() const
FloatComplexNDArray float_complex_array_value(bool frc_str_conv=false) const
octave_value resize(const dim_vector &dv, bool fill=false) const
FloatNDArray float_array_value(bool frc_str_conv=false) const
uint32NDArray uint32_array_value() const
builtin_type_t builtin_type() const
SparseComplexMatrix sparse_complex_matrix_value(bool frc_str_conv=false) const
octave_value find_function(const std::string &name, const symbol_scope &search_scope=symbol_scope::invalid())
OCTAVE_BEGIN_NAMESPACE(octave) static octave_value daspk_fcn
#define DEFMETHOD(name, interp_name, args_name, nargout_name, doc)
Macro to define a builtin method.
#define DEFUN(name, args_name, nargout_name, doc)
Macro to define a builtin function.
void error_with_id(const char *id, const char *fmt,...)
void error(const char *fmt,...)
void err_wrong_type_arg(const char *name, const char *s)
octave_value get_function_handle(interpreter &interp, const octave_value &arg, const std::string ¶meter_name)
#define OCTAVE_LOCAL_BUFFER(T, buf, size)
#define OCTAVE_LOCAL_BUFFER_INIT(T, buf, size, value)
const octave_base_value const Array< octave_idx_type > & ra_idx
octave_value_list ovl(const OV_Args &... args)
Construct an octave_value_list with less typing.
#define panic_unless(cond)
F77_RET_T const F77_DBLE const F77_DBLE F77_DBLE * d
F77_RET_T const F77_DBLE * x
F77_RET_T const F77_DBLE const F77_DBLE * f
bool valid_identifier(const char *s)