GNU Octave  9.1.0
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
data.cc
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////
2 //
3 // Copyright (C) 1994-2024 The Octave Project Developers
4 //
5 // See the file COPYRIGHT.md in the top-level directory of this
6 // distribution or <https://octave.org/copyright/>.
7 //
8 // This file is part of Octave.
9 //
10 // Octave is free software: you can redistribute it and/or modify it
11 // under the terms of the GNU General Public License as published by
12 // the Free Software Foundation, either version 3 of the License, or
13 // (at your option) any later version.
14 //
15 // Octave is distributed in the hope that it will be useful, but
16 // WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 // GNU General Public License for more details.
19 //
20 // You should have received a copy of the GNU General Public License
21 // along with Octave; see the file COPYING. If not, see
22 // <https://www.gnu.org/licenses/>.
23 //
24 ////////////////////////////////////////////////////////////////////////
25 
26 #if defined (HAVE_CONFIG_H)
27 # include "config.h"
28 #endif
29 
30 #include <cmath>
31 #include <cstddef>
32 #include <cstdint>
33 #include <ctime>
34 
35 #include <algorithm>
36 #include <limits>
37 #include <string>
38 
39 #include "lo-ieee.h"
40 #include "mx-base.h"
41 #include "oct-base64.h"
42 #include "oct-binmap.h"
43 #include "oct-time.h"
44 #include "quit.h"
45 
46 #include "Cell.h"
47 #include "data.h"
48 #include "defun.h"
49 #include "error.h"
50 #include "errwarn.h"
51 #include "interpreter-private.h"
52 #include "interpreter.h"
53 #include "oct-map.h"
54 #include "ov-class.h"
55 #include "ov-complex.h"
56 #include "ov-cx-mat.h"
57 #include "ov-cx-sparse.h"
58 #include "ov-float.h"
59 #include "ov-flt-complex.h"
60 #include "ov-flt-cx-mat.h"
61 #include "ov.h"
62 #include "ovl.h"
63 #include "pager.h"
64 #include "pt-mat.h"
65 #include "utils.h"
66 #include "variables.h"
67 #include "xnorm.h"
68 
70 
71 DEFUN (all, args, ,
72  doc: /* -*- texinfo -*-
73 @deftypefn {} {@var{tf} =} all (@var{x})
74 @deftypefnx {} {@var{tf} =} all (@var{x}, @var{dim})
75 For a vector argument, return true (logical 1) if all elements of the vector
76 are nonzero.
77 
78 For a matrix argument, return a row vector of logical ones and zeros with each
79 element indicating whether all of the elements of the corresponding column of
80 the matrix are nonzero. For example:
81 
82 @example
83 @group
84 all ([2, 3; 1, 0])
85  @result{} [ 1, 0 ]
86 @end group
87 @end example
88 
89 If the optional argument @var{dim} is supplied, work along dimension @var{dim}.
90 @seealso{any}
91 @end deftypefn */)
92 {
93  int nargin = args.length ();
94 
95  if (nargin < 1 || nargin > 2)
96  print_usage ();
97 
98  int dim = (nargin == 1 ? -1
99  : args(1).xint_value ("all: DIM must be an integer")-1);
100 
101  if (dim < -1)
102  error ("all: invalid dimension argument = %d", dim + 1);
103 
104  return ovl (args(0).all (dim));
105 }
106 
107 /*
108 %!test
109 %! x = ones (3);
110 %! x(1,1) = 0;
111 %! assert (all (all (rand (3) + 1) == [1, 1, 1]) == 1);
112 %! assert (all (all (x) == [0, 1, 1]) == 1);
113 %! assert (all (x, 1) == [0, 1, 1]);
114 %! assert (all (x, 2) == [0; 1; 1]);
115 
116 %!test
117 %! x = ones (3, "single");
118 %! x(1,1) = 0;
119 %! assert (all (all (single (rand (3) + 1)) == [1, 1, 1]) == 1);
120 %! assert (all (all (x) == [0, 1, 1]) == 1);
121 %! assert (all (x, 1) == [0, 1, 1]);
122 %! assert (all (x, 2) == [0; 1; 1]);
123 
124 %!error all ()
125 %!error all (1, 2, 3)
126 */
127 
128 DEFUN (any, args, ,
129  doc: /* -*- texinfo -*-
130 @deftypefn {} {@var{tf} =} any (@var{x})
131 @deftypefnx {} {@var{tf} =} any (@var{x}, @var{dim})
132 For a vector argument, return true (logical 1) if any element of the vector
133 is nonzero.
134 
135 For a matrix argument, return a row vector of logical ones and zeros with each
136 element indicating whether any of the elements of the corresponding column of
137 the matrix are nonzero. For example:
138 
139 @example
140 @group
141 any (eye (2, 4))
142  @result{} [ 1, 1, 0, 0 ]
143 @end group
144 @end example
145 
146 If the optional argument @var{dim} is supplied, work along dimension @var{dim}.
147 For example:
148 
149 @example
150 @group
151 any (eye (2, 4), 2)
152  @result{} [ 1; 1 ]
153 @end group
154 @end example
155 @seealso{all}
156 @end deftypefn */)
157 {
158  int nargin = args.length ();
159 
160  if (nargin < 1 || nargin > 2)
161  print_usage ();
162 
163  int dim = (nargin == 1 ? -1
164  : args(1).xint_value ("any: DIM must be an integer")-1);
165 
166  if (dim < -1)
167  error ("any: invalid dimension argument = %d", dim + 1);
168 
169  return ovl (args(0).any (dim));
170 }
171 
172 /*
173 %!test
174 %! x = zeros (3);
175 %! x(3,3) = 1;
176 %! assert (all (any (x) == [0, 0, 1]) == 1);
177 %! assert (all (any (ones (3)) == [1, 1, 1]) == 1);
178 %! assert (any (x, 1) == [0, 0, 1]);
179 %! assert (any (x, 2) == [0; 0; 1]);
180 
181 %!test
182 %! x = zeros (3, "single");
183 %! x(3,3) = 1;
184 %! assert (all (any (x) == [0, 0, 1]) == 1);
185 %! assert (all (any (ones (3, "single")) == [1, 1, 1]) == 1);
186 %! assert (any (x, 1) == [0, 0, 1]);
187 %! assert (any (x, 2) == [0; 0; 1]);
188 
189 %!error any ()
190 %!error any (1, 2, 3)
191 */
192 
193 // These mapping functions may also be useful in other places, eh?
194 
195 DEFUN (atan2, args, ,
196  doc: /* -*- texinfo -*-
197 @deftypefn {} {@var{angle} =} atan2 (@var{y}, @var{x})
198 Compute atan (@var{y} / @var{x}) for corresponding elements of @var{y} and
199 @var{x}.
200 
201 @var{y} and @var{x} must match in size and orientation. The signs of elements
202 of @var{y} and @var{x} are used to determine the quadrants of each resulting
203 value.
204 
205 This function is equivalent to @code{arg (complex (@var{x}, @var{y}))}.
206 @seealso{tan, tand, tanh, atanh}
207 @end deftypefn */)
208 {
209  if (args.length () != 2)
210  print_usage ();
211 
212  octave_value retval;
213 
214  if (! args(0).isnumeric ())
215  err_wrong_type_arg ("atan2", args(0));
216 
217  if (! args(1).isnumeric ())
218  err_wrong_type_arg ("atan2", args(1));
219 
220  if (args(0).iscomplex () || args(1).iscomplex ())
221  error ("atan2: not defined for complex numbers");
222 
223  if (args(0).is_single_type () || args(1).is_single_type ())
224  {
225  if (args(0).is_scalar_type () && args(1).is_scalar_type ())
226  retval = atan2f (args(0).float_value (), args(1).float_value ());
227  else
228  {
229  FloatNDArray a0 = args(0).float_array_value ();
230  FloatNDArray a1 = args(1).float_array_value ();
231  retval = binmap<float> (a0, a1, std::atan2, "atan2");
232  }
233  }
234  else
235  {
236  if (args(0).is_scalar_type () && args(1).is_scalar_type ())
237  retval = atan2 (args(0).scalar_value (), args(1).scalar_value ());
238  else if (args(0).issparse ())
239  {
240  SparseMatrix m0 = args(0).sparse_matrix_value ();
241  SparseMatrix m1 = args(1).sparse_matrix_value ();
242  retval = binmap<double> (m0, m1, std::atan2, "atan2");
243  }
244  else
245  {
246  NDArray a0 = args(0).array_value ();
247  NDArray a1 = args(1).array_value ();
248  retval = binmap<double> (a0, a1, std::atan2, "atan2");
249  }
250  }
251 
252  return retval;
253 }
254 
255 /*
256 %!assert (size (atan2 (zeros (0, 2), zeros (0, 2))), [0, 2])
257 %!assert (size (atan2 (rand (2, 3, 4), zeros (2, 3, 4))), [2, 3, 4])
258 %!assert (size (atan2 (rand (2, 3, 4), 1)), [2, 3, 4])
259 %!assert (size (atan2 (1, rand (2, 3, 4))), [2, 3, 4])
260 %!assert (size (atan2 (1, 2)), [1, 1])
261 
262 %!test
263 %! rt2 = sqrt (2);
264 %! rt3 = sqrt (3);
265 %! v = [0, pi/6, pi/4, pi/3, -pi/3, -pi/4, -pi/6, 0];
266 %! y = [0, rt3, 1, rt3, -rt3, -1, -rt3, 0];
267 %! x = [1, 3, 1, 1, 1, 1, 3, 1];
268 %! assert (atan2 (y, x), v, sqrt (eps));
269 
270 %!test
271 %! rt2 = sqrt (2);
272 %! rt3 = sqrt (3);
273 %! v = single ([0, pi/6, pi/4, pi/3, -pi/3, -pi/4, -pi/6, 0]);
274 %! y = single ([0, rt3, 1, rt3, -rt3, -1, -rt3, 0]);
275 %! x = single ([1, 3, 1, 1, 1, 1, 3, 1]);
276 %! assert (atan2 (y, x), v, sqrt (eps ("single")));
277 
278 ## Test sparse implementations
279 %!shared xs
280 %! xs = sparse (0:3);
281 %!test
282 %! y = atan2 (1, xs);
283 %! assert (issparse (y), false);
284 %! assert (nnz (y), 4);
285 %! assert (y, atan2 (1, 0:3));
286 %!test
287 %! y = atan2 (0, xs);
288 %! assert (issparse (y), false);
289 %! assert (nnz (y), 0);
290 %! assert (y, zeros (1,4));
291 %!test
292 %! y = atan2 (xs, 1);
293 %! assert (issparse (y));
294 %! assert (nnz (y), 3);
295 %! assert (y, sparse (atan2 (0:3, 1)));
296 %!test
297 %! y = atan2 (xs, 0);
298 %! assert (issparse (y));
299 %! assert (nnz (y), 3);
300 %! assert (y, sparse (atan2 (0:3, 0)));
301 %!test
302 %! y = atan2 (xs, sparse (ones (1, 4)));
303 %! assert (issparse (y));
304 %! assert (nnz (y), 3);
305 %! assert (y, sparse (atan2 (0:3, ones (1,4))));
306 %!test
307 %! y = atan2 (xs, sparse (zeros (1,4)));
308 %! assert (issparse (y));
309 %! assert (nnz (y), 3);
310 %! assert (y, sparse (atan2 (0:3, zeros (1,4))));
311 
312 %!error atan2 ()
313 %!error atan2 (1, 2, 3)
314 */
315 
316 static octave_value
317 do_hypot (const octave_value& x, const octave_value& y)
318 {
319  octave_value retval;
320 
321  octave_value arg0 = x;
322  octave_value arg1 = y;
323  if (! arg0.isnumeric ())
324  err_wrong_type_arg ("hypot", arg0);
325  if (! arg1.isnumeric ())
326  err_wrong_type_arg ("hypot", arg1);
327 
328  if (arg0.iscomplex ())
329  arg0 = arg0.abs ();
330  if (arg1.iscomplex ())
331  arg1 = arg1.abs ();
332 
333  if (arg0.is_single_type () || arg1.is_single_type ())
334  {
335  if (arg0.is_scalar_type () && arg1.is_scalar_type ())
336  retval = hypotf (arg0.float_value (), arg1.float_value ());
337  else
338  {
339  FloatNDArray a0 = arg0.float_array_value ();
340  FloatNDArray a1 = arg1.float_array_value ();
341  retval = binmap<float> (a0, a1, std::hypot, "hypot");
342  }
343  }
344  else
345  {
346  if (arg0.is_scalar_type () && arg1.is_scalar_type ())
347  retval = hypot (arg0.scalar_value (), arg1.scalar_value ());
348  else if (arg0.issparse () || arg1.issparse ())
349  {
350  SparseMatrix m0 = arg0.sparse_matrix_value ();
351  SparseMatrix m1 = arg1.sparse_matrix_value ();
352  retval = binmap<double> (m0, m1, std::hypot, "hypot");
353  }
354  else
355  {
356  NDArray a0 = arg0.array_value ();
357  NDArray a1 = arg1.array_value ();
358  retval = binmap<double> (a0, a1, std::hypot, "hypot");
359  }
360  }
361 
362  return retval;
363 }
364 
365 DEFUN (hypot, args, ,
366  doc: /* -*- texinfo -*-
367 @deftypefn {} {@var{h} =} hypot (@var{x}, @var{y})
368 @deftypefnx {} {@var{h} =} hypot (@var{x}, @var{y}, @var{z}, @dots{})
369 Compute the element-by-element square root of the sum of the squares of
370 @var{x} and @var{y}.
371 
372 This is equivalent to
373 @code{sqrt (@var{x}.^2 + @var{y}.^2)}, but is calculated in a manner that
374 avoids overflows for large values of @var{x} or @var{y}.
375 
376 @code{hypot} can also be called with more than 2 arguments; in this case,
377 the arguments are accumulated from left to right:
378 
379 @example
380 @group
381 hypot (hypot (@var{x}, @var{y}), @var{z})
382 hypot (hypot (hypot (@var{x}, @var{y}), @var{z}), @var{w}), etc.
383 @end group
384 @end example
385 @end deftypefn */)
386 {
387  int nargin = args.length ();
388 
389  if (nargin < 2)
390  print_usage ();
391 
392  octave_value retval;
393 
394  if (nargin == 2)
395  retval = do_hypot (args(0), args(1));
396  else
397  {
398  retval = args(0);
399 
400  for (int i = 1; i < nargin; i++)
401  retval = do_hypot (retval, args(i));
402  }
403 
404  return retval;
405 }
406 
407 /*
408 %!assert (size (hypot (zeros (0, 2), zeros (0, 2))), [0, 2])
409 %!assert (size (hypot (rand (2, 3, 4), zeros (2, 3, 4))), [2, 3, 4])
410 %!assert (size (hypot (rand (2, 3, 4), 1)), [2, 3, 4])
411 %!assert (size (hypot (1, rand (2, 3, 4))), [2, 3, 4])
412 %!assert (size (hypot (1, 2)), [1, 1])
413 %!assert (hypot (1:10, 1:10), sqrt (2) * [1:10], 16*eps)
414 %!assert (hypot (single (1:10), single (1:10)), single (sqrt (2) * [1:10]))
415 
416 ## Test sparse implementations
417 %!shared xs
418 %! xs = sparse (0:3);
419 %!test
420 %! y = hypot (1, xs);
421 %! assert (nnz (y), 4);
422 %! assert (y, sparse (hypot (1, 0:3)));
423 %!test
424 %! y = hypot (0, xs);
425 %! assert (nnz (y), 3);
426 %! assert (y, xs);
427 %!test
428 %! y = hypot (xs, 1);
429 %! assert (nnz (y), 4);
430 %! assert (y, sparse (hypot (0:3, 1)));
431 %!test
432 %! y = hypot (xs, 0);
433 %! assert (nnz (y), 3);
434 %! assert (y, xs);
435 %!test
436 %! y = hypot (sparse ([0 0]), sparse ([0 1]));
437 %! assert (nnz (y), 1);
438 %! assert (y, sparse ([0 1]));
439 %!test
440 %! y = hypot (sparse ([0 1]), sparse ([0 0]));
441 %! assert (nnz (y), 1);
442 %! assert (y, sparse ([0 1]));
443 
444 */
445 
446 template <typename T, typename ET>
447 void
449 {
450  f = Array<T> (x.dims ());
451  e = Array<ET> (x.dims ());
452  for (octave_idx_type i = 0; i < x.numel (); i++)
453  {
454  int exp;
455  f.xelem (i) = math::log2 (x(i), exp);
456  e.xelem (i) = exp;
457  }
458 }
459 
460 DEFUN (log2, args, nargout,
461  doc: /* -*- texinfo -*-
462 @deftypefn {} {@var{y} =} log2 (@var{x})
463 @deftypefnx {} {[@var{f}, @var{e}] =} log2 (@var{x})
464 Compute the base-2 logarithm of each element of @var{x}.
465 
466 If called with one output, compute the base-2 logarithm such that
467 @tex
468 $2^y = x$.
469 @end tex
470 @ifnottex
471 @code{2^@var{y} = @var{x}}.
472 @end ifnottex
473 
474 If called with two output arguments, split @var{x} into binary mantissa
475 (@var{f}) and exponent (@var{e}) such that
476 @tex
477 $x = f \cdot 2^e$
478 @end tex
479 @ifnottex
480 @code{@var{x} = @var{f} * 2^@var{e}}
481 @end ifnottex
482 where
483 @tex
484 ${1 \over 2} \le \left| f \right| < 1$
485 @end tex
486 @ifnottex
487 @w{@code{1/2 <= abs (@var{f}) < 1}}
488 @end ifnottex
489 and @var{e} is an integer. If
490 @tex
491 $x = 0$, $f = e = 0$.
492 @end tex
493 @ifnottex
494 @w{@code{x = 0}}, @w{@code{f = e = 0}}.
495 @end ifnottex
496 @seealso{pow2, log, log10, exp}
497 @end deftypefn */)
498 {
499  if (args.length () != 1)
500  print_usage ();
501 
502  octave_value_list retval;
503 
504  if (nargout < 2)
505  retval = ovl (args(0).log2 ());
506  else if (args(0).is_single_type ())
507  {
508  if (args(0).isreal ())
509  {
510  FloatNDArray f;
511  FloatNDArray x = args(0).float_array_value ();
512  // FIXME: should E be an int value?
513  FloatMatrix e;
514  map_2_xlog2 (x, f, e);
515  retval = ovl (f, e);
516  }
517  else if (args(0).iscomplex ())
518  {
520  FloatComplexNDArray x = args(0).float_complex_array_value ();
521  // FIXME: should E be an int value?
522  FloatNDArray e;
523  map_2_xlog2 (x, f, e);
524  retval = ovl (f, e);
525  }
526  }
527  else if (args(0).isreal ())
528  {
529  NDArray f;
530  NDArray x = args(0).array_value ();
531  // FIXME: should E be an int value?
532  Matrix e;
533  map_2_xlog2 (x, f, e);
534  retval = ovl (f, e);
535  }
536  else if (args(0).iscomplex ())
537  {
539  ComplexNDArray x = args(0).complex_array_value ();
540  // FIXME: should E be an int value?
541  NDArray e;
542  map_2_xlog2 (x, f, e);
543  retval = ovl (f, e);
544  }
545  else
546  err_wrong_type_arg ("log2", args(0));
547 
548  return retval;
549 }
550 
551 /*
552 %!assert (log2 ([1/4, 1/2, 1, 2, 4]), [-2, -1, 0, 1, 2])
553 %!assert (log2 (Inf), Inf)
554 %!assert (isnan (log2 (NaN)))
555 %!assert (log2 (4*i), 2 + log2 (1*i))
556 %!assert (log2 (complex (0,Inf)), Inf + log2 (i))
557 
558 %!test
559 %! [f, e] = log2 ([0,-1; 2,-4; Inf,-Inf]);
560 %! assert (f, [0,-0.5; 0.5,-0.5; Inf,-Inf]);
561 %! assert (e(1:2,:), [0,1;2,3]);
562 
563 %!test
564 %! [f, e] = log2 (complex (zeros (3, 2), [0,-1; 2,-4; Inf,-Inf]));
565 %! assert (f, complex (zeros (3, 2), [0,-0.5; 0.5,-0.5; Inf,-Inf]));
566 %! assert (e(1:2,:), [0,1; 2,3]);
567 
568 %!assert <*42583> (all (log2 (pow2 (-1074:1023)) == -1074:1023))
569 */
570 
571 DEFUN (rem, args, ,
572  doc: /* -*- texinfo -*-
573 @deftypefn {} {@var{r} =} rem (@var{x}, @var{y})
574 Return the remainder of the division @code{@var{x} / @var{y}}.
575 
576 The remainder is computed using the expression
577 
578 @example
579 x - y .* fix (x ./ y)
580 @end example
581 
582 An error message is printed if the dimensions of the arguments do not agree,
583 or if either argument is complex.
584 
585 Programming Notes: When calculating with floating point numbers (double,
586 single), values within a few eps of an integer will be rounded to that
587 integer before computation for compatibility with @sc{matlab}. Any floating
588 point integers greater than @code{flintmax} (2^53 for double) will not compute
589 correctly. For larger integer values convert the input to @code{uint64} before
590 calling this function.
591 
592 By convention,
593 
594 @example
595 @group
596 rem (@var{x}, 0) = NaN if @var{x} is a floating point variable
597 rem (@var{x}, 0) = 0 if @var{x} is an integer variable
598 rem (@var{x}, @var{y}) returns a value with the signbit from @var{x}
599 @end group
600 @end example
601 
602 For the opposite conventions see the @code{mod} function. In general,
603 @code{rem} is best when computing the remainder after division of two
604 @emph{positive} numbers. For negative numbers, or when the values are
605 periodic, @code{mod} is a better choice.
606 @seealso{mod}
607 @end deftypefn */)
608 {
609  if (args.length () != 2)
610  print_usage ();
611 
612  octave_value retval;
613 
614  if (! args(0).isnumeric ())
615  err_wrong_type_arg ("rem", args(0));
616 
617  if (! args(1).isnumeric ())
618  err_wrong_type_arg ("rem", args(1));
619 
620  if (args(0).iscomplex () || args(1).iscomplex ())
621  error ("rem: not defined for complex numbers");
622 
623  if (args(0).isinteger () || args(1).isinteger ())
624  {
625  builtin_type_t btyp0 = args(0).builtin_type ();
626  builtin_type_t btyp1 = args(1).builtin_type ();
627  if (btyp0 == btyp_double || btyp0 == btyp_float)
628  btyp0 = btyp1;
629  if (btyp1 == btyp_double || btyp1 == btyp_float)
630  btyp1 = btyp0;
631 
632  if (btyp0 != btyp1)
633  error ("rem: cannot combine %s and %s",
634  args(0).class_name ().c_str (),
635  args(1).class_name ().c_str ());
636 
637  switch (btyp0)
638  {
639 #define MAKE_INT_BRANCH(X) \
640  case btyp_ ## X: \
641  { \
642  X##NDArray a0 = args(0).X##_array_value (); \
643  X##NDArray a1 = args(1).X##_array_value (); \
644  retval = binmap<octave_##X,octave_##X,octave_##X> (a0, a1, rem, "rem"); \
645  } \
646  break
647 
648  MAKE_INT_BRANCH (int8);
649  MAKE_INT_BRANCH (int16);
650  MAKE_INT_BRANCH (int32);
651  MAKE_INT_BRANCH (int64);
652  MAKE_INT_BRANCH (uint8);
653  MAKE_INT_BRANCH (uint16);
654  MAKE_INT_BRANCH (uint32);
655  MAKE_INT_BRANCH (uint64);
656 
657 #undef MAKE_INT_BRANCH
658 
659  default:
660  panic_impossible ();
661  }
662  }
663  else if (args(0).is_single_type () || args(1).is_single_type ())
664  {
665  if (args(0).is_scalar_type () && args(1).is_scalar_type ())
666  retval = math::rem (args(0).float_value (), args(1).float_value ());
667  else
668  {
669  FloatNDArray a0 = args(0).float_array_value ();
670  FloatNDArray a1 = args(1).float_array_value ();
671  retval = binmap<float> (a0, a1, math::rem<float>, "rem");
672  }
673  }
674  else
675  {
676  if (args(0).is_scalar_type () && args(1).is_scalar_type ())
677  retval = math::rem (args(0).scalar_value (), args(1).scalar_value ());
678  else if (args(0).issparse () || args(1).issparse ())
679  {
680  SparseMatrix m0 = args(0).sparse_matrix_value ();
681  SparseMatrix m1 = args(1).sparse_matrix_value ();
682  retval = binmap<double> (m0, m1, math::rem<double>, "rem");
683  }
684  else
685  {
686  NDArray a0 = args(0).array_value ();
687  NDArray a1 = args(1).array_value ();
688  retval = binmap<double> (a0, a1, math::rem<double>, "rem");
689  }
690  }
691 
692  return retval;
693 }
694 
695 /*
696 %!assert (size (rem (zeros (0, 2), zeros (0, 2))), [0, 2])
697 %!assert (size (rem (rand (2, 3, 4), zeros (2, 3, 4))), [2, 3, 4])
698 %!assert (size (rem (rand (2, 3, 4), 1)), [2, 3, 4])
699 %!assert (size (rem (1, rand (2, 3, 4))), [2, 3, 4])
700 %!assert (size (rem (1, 2)), [1, 1])
701 
702 %!assert (rem ([1, 2, 3; -1, -2, -3], 2), [1, 0, 1; -1, 0, -1])
703 %!assert (rem ([1, 2, 3; -1, -2, -3], 2 * ones (2, 3)),[1, 0, 1; -1, 0, -1])
704 %!assert (rem ([0, 1, 2], [0, 0, 1]), [NaN, NaN, 0])
705 %!assert (rem (uint8 ([1, 2, 3; -1, -2, -3]), uint8 (2)),
706 %! uint8 ([1, 0, 1; -1, 0, -1]))
707 %!assert (uint8 (rem ([1, 2, 3; -1, -2, -3], 2 * ones (2, 3))),
708 %! uint8 ([1, 0, 1; -1, 0, -1]))
709 %!assert (rem (uint8 ([0, 1, 2]), [0, 0, 1]), uint8 ([0, 0, 0]))
710 
711 ## Test sparse implementations
712 %!shared xs
713 %! xs = sparse (0:3);
714 %!test
715 %! y = rem (11, xs);
716 %! assert (isnan (y(1)));
717 %! assert (y, sparse (rem (11, 0:3)));
718 %!test
719 %! y = rem (0, xs);
720 %! assert (nnz (y), 1);
721 %! assert (y, sparse ([NaN 0 0 0]));
722 %!test
723 %! y = rem (xs, 2);
724 %! assert (nnz (y), 2);
725 %! assert (y, sparse (rem (0:3, 2)));
726 %!test
727 %! y = rem (xs, 1);
728 %! assert (nnz (y), 0);
729 %! assert (y, sparse (rem (0:3, 1)));
730 %!test
731 %! y = rem (sparse ([11 11 11 11]), xs);
732 %! assert (nnz (y), 3);
733 %! assert (y, sparse (rem (11, 0:3)));
734 %!test
735 %! y = rem (sparse ([0 0 0 0]), xs);
736 %! assert (nnz (y), 1);
737 %! assert (y, sparse ([NaN 0 0 0]));
738 
739 %!assert <*45587> (signbit (rem (-0, 1)))
740 %!assert <*45587> (! signbit (rem (0, 1)))
741 
742 %!assert <*42627> (rem (0.94, 0.01), 0.0)
743 
744 %!error rem (uint (8), int8 (5))
745 %!error rem (uint8 ([1, 2]), uint8 ([3, 4, 5]))
746 %!error rem ()
747 %!error rem (1, 2, 3)
748 %!error rem ([1, 2], [3, 4, 5])
749 %!error rem (i, 1)
750 */
751 
752 DEFUN (mod, args, ,
753  doc: /* -*- texinfo -*-
754 @deftypefn {} {@var{m} =} mod (@var{x}, @var{y})
755 Compute the modulo of @var{x} and @var{y}.
756 
757 Conceptually this is given by
758 
759 @example
760 x - y .* floor (x ./ y)
761 @end example
762 
763 @noindent
764 and is written such that the correct modulus is returned for integer types.
765 This function handles negative values correctly. That is,
766 @w{@code{mod (-1, 3)}} is 2, not -1, as @w{@code{rem (-1, 3)}} returns.
767 
768 An error results if the dimensions of the arguments do not agree, or if
769 either of the arguments is complex.
770 
771 Programming Notes: When calculating with floating point numbers (double,
772 single), values within a few eps of an integer will be rounded to that
773 integer before computation for compatibility with @sc{matlab}. Any floating
774 point integers greater than @code{flintmax} (2^53 for double) will not compute
775 correctly. For larger integer values convert the input to @code{uint64} before
776 calling this function.
777 
778 By convention,
779 
780 @example
781 @group
782 mod (@var{x}, 0) = @var{x}
783 mod (@var{x}, @var{y}) returns a value with the signbit from @var{y}
784 @end group
785 @end example
786 
787 For the opposite conventions see the @code{rem} function. In general,
788 @code{mod} is a better choice than @code{rem} when any of the inputs are
789 negative numbers or when the values are periodic.
790 @seealso{rem}
791 @end deftypefn */)
792 {
793  if (args.length () != 2)
794  print_usage ();
795 
796  octave_value retval;
797 
798  if (! args(0).isnumeric ())
799  err_wrong_type_arg ("mod", args(0));
800 
801  if (! args(1).isnumeric ())
802  err_wrong_type_arg ("mod", args(1));
803 
804  if (args(0).iscomplex () || args(1).iscomplex ())
805  error ("mod: not defined for complex numbers");
806 
807  if (args(0).isinteger () || args(1).isinteger ())
808  {
809  builtin_type_t btyp0 = args(0).builtin_type ();
810  builtin_type_t btyp1 = args(1).builtin_type ();
811  if (btyp0 == btyp_double || btyp0 == btyp_float)
812  btyp0 = btyp1;
813  if (btyp1 == btyp_double || btyp1 == btyp_float)
814  btyp1 = btyp0;
815 
816  if (btyp0 != btyp1)
817  error ("mod: cannot combine %s and %s",
818  args(0).class_name ().c_str (),
819  args(1).class_name ().c_str ());
820 
821  switch (btyp0)
822  {
823 #define MAKE_INT_BRANCH(X) \
824  case btyp_ ## X: \
825  { \
826  X##NDArray a0 = args(0).X##_array_value (); \
827  X##NDArray a1 = args(1).X##_array_value (); \
828  retval = binmap<octave_##X,octave_##X,octave_##X> (a0, a1, mod, "mod"); \
829  } \
830  break
831 
832  MAKE_INT_BRANCH (int8);
833  MAKE_INT_BRANCH (int16);
834  MAKE_INT_BRANCH (int32);
835  MAKE_INT_BRANCH (int64);
836  MAKE_INT_BRANCH (uint8);
837  MAKE_INT_BRANCH (uint16);
838  MAKE_INT_BRANCH (uint32);
839  MAKE_INT_BRANCH (uint64);
840 
841 #undef MAKE_INT_BRANCH
842 
843  default:
844  panic_impossible ();
845  }
846  }
847  else if (args(0).is_single_type () || args(1).is_single_type ())
848  {
849  if (args(0).is_scalar_type () && args(1).is_scalar_type ())
850  retval = math::mod (args(0).float_value (), args(1).float_value ());
851  else
852  {
853  FloatNDArray a0 = args(0).float_array_value ();
854  FloatNDArray a1 = args(1).float_array_value ();
855  retval = binmap<float> (a0, a1, math::mod<float>, "mod");
856  }
857  }
858  else
859  {
860  if (args(0).is_scalar_type () && args(1).is_scalar_type ())
861  retval = math::mod (args(0).scalar_value (), args(1).scalar_value ());
862  else if (args(0).issparse () || args(1).issparse ())
863  {
864  SparseMatrix m0 = args(0).sparse_matrix_value ();
865  SparseMatrix m1 = args(1).sparse_matrix_value ();
866  retval = binmap<double> (m0, m1, math::mod<double>, "mod");
867  }
868  else
869  {
870  NDArray a0 = args(0).array_value ();
871  NDArray a1 = args(1).array_value ();
872  retval = binmap<double> (a0, a1, math::mod<double>, "mod");
873  }
874  }
875 
876  return retval;
877 }
878 
879 /*
880 ## empty input test
881 %!assert (isempty (mod ([], [])))
882 
883 ## x mod y, y != 0 tests
884 %!assert (mod (5, 3), 2)
885 %!assert (mod (-5, 3), 1)
886 %!assert (mod (0, 3), 0)
887 %!assert (mod ([-5, 5, 0], [3, 3, 3]), [1, 2, 0])
888 %!assert (mod ([-5; 5; 0], [3; 3; 3]), [1; 2; 0])
889 %!assert (mod ([-5, 5; 0, 3], [3, 3 ; 3, 1]), [1, 2 ; 0, 0])
890 
891 ## x mod 0 tests
892 %!assert (mod (5, 0), 5)
893 %!assert (mod (-5, 0), -5)
894 %!assert (mod ([-5, 5, 0], [3, 0, 3]), [1, 5, 0])
895 %!assert (mod ([-5; 5; 0], [3; 0; 3]), [1; 5; 0])
896 %!assert (mod ([-5, 5; 0, 3], [3, 0 ; 3, 1]), [1, 5 ; 0, 0])
897 %!assert (mod ([-5, 5; 0, 3], [0, 0 ; 0, 0]), [-5, 5; 0, 3])
898 
899 ## mixed scalar/matrix tests
900 %!assert (mod ([-5, 5; 0, 3], 0), [-5, 5; 0, 3])
901 %!assert (mod ([-5, 5; 0, 3], 3), [1, 2; 0, 0])
902 %!assert (mod (-5, [0,0; 0,0]), [-5, -5; -5, -5])
903 %!assert (mod (-5, [3,0; 3,1]), [1, -5; 1, 0])
904 %!assert (mod (-5, [3,2; 3,1]), [1, 1; 1, 0])
905 
906 ## integer types
907 %!assert (mod (uint8 (5), uint8 (4)), uint8 (1))
908 %!assert (mod (uint8 ([1:5]), uint8 (4)), uint8 ([1,2,3,0,1]))
909 %!assert (mod (uint8 ([1:5]), uint8 (0)), uint8 ([1:5]))
910 %!error mod (uint8 (5), int8 (4))
911 
912 ## mixed integer/real types
913 %!assert (mod (uint8 (5), 4), uint8 (1))
914 %!assert (mod (5, uint8 (4)), uint8 (1))
915 %!assert (mod (uint8 ([1:5]), 4), uint8 ([1,2,3,0,1]))
916 
917 ## non-integer real numbers
918 %!assert (mod (2.1, 0.1), 0)
919 %!assert (mod (2.1, 0.2), 0.1, eps)
920 
921 %!assert <*45587> (signbit (mod (-0, 0)))
922 %!assert <*45587> (! signbit (mod (0, -0)))
923 
924 %!assert <*42627> (mod (0.94, 0.01), 0.0)
925 
926 %!assert <*54602> (mod (int8 (125), int8 (-25)), int8 (0))
927 %!assert <*54602> (mod (int8 (-125), int8 (-25)), int8 (0))
928 %!assert <*54602> (mod (int8 (-125), int8 (0)), int8 (-125))
929 %!assert <*54602> (mod (int8 (0), int8 (-25)), int8 (0))
930 
931 */
932 
933 #define DATA_REDUCTION(FCN) \
934  \
935  int nargin = args.length (); \
936  \
937  if (nargin < 1 || nargin > 2) \
938  print_usage (); \
939  \
940  octave_value retval; \
941  \
942  octave_value arg = args(0); \
943  \
944  int dim = (nargin == 1 ? -1 : args(1).int_value (true) - 1); \
945  \
946  if (dim < -1) \
947  error (#FCN ": invalid dimension argument = %d", dim + 1); \
948  \
949  if (arg.isreal ()) \
950  { \
951  if (arg.issparse ()) \
952  { \
953  SparseMatrix tmp = arg.sparse_matrix_value (); \
954  \
955  retval = tmp.FCN (dim); \
956  } \
957  else if (arg.is_single_type ()) \
958  { \
959  FloatNDArray tmp = arg.float_array_value (); \
960  \
961  retval = tmp.FCN (dim); \
962  } \
963  else \
964  { \
965  NDArray tmp = arg.array_value (); \
966  \
967  retval = tmp.FCN (dim); \
968  } \
969  } \
970  else if (arg.iscomplex ()) \
971  { \
972  if (arg.issparse ()) \
973  { \
974  SparseComplexMatrix tmp = arg.sparse_complex_matrix_value (); \
975  \
976  retval = tmp.FCN (dim); \
977  } \
978  else if (arg.is_single_type ()) \
979  { \
980  FloatComplexNDArray tmp \
981  = arg.float_complex_array_value (); \
982  \
983  retval = tmp.FCN (dim); \
984  } \
985  else \
986  { \
987  ComplexNDArray tmp = arg.complex_array_value (); \
988  \
989  retval = tmp.FCN (dim); \
990  } \
991  } \
992  else \
993  err_wrong_type_arg (#FCN, arg); \
994  \
995  return retval
996 
997 DEFUN (cumprod, args, ,
998  doc: /* -*- texinfo -*-
999 @deftypefn {} {@var{y} =} cumprod (@var{x})
1000 @deftypefnx {} {@var{y} =} cumprod (@var{x}, @var{dim})
1001 Cumulative product of elements along dimension @var{dim}.
1002 
1003 If @var{dim} is omitted, it defaults to the first non-singleton dimension.
1004 For example:
1005 
1006 @example
1007 @group
1008 cumprod ([1, 2; 3, 4; 5, 6])
1009  @result{} 1 2
1010  3 8
1011  15 48
1012 @end group
1013 @end example
1014 @seealso{prod, cumsum}
1015 @end deftypefn */)
1016 {
1017  DATA_REDUCTION (cumprod);
1018 }
1019 
1020 /*
1021 %!assert (cumprod ([1, 2, 3]), [1, 2, 6])
1022 %!assert (cumprod ([-1; -2; -3]), [-1; 2; -6])
1023 %!assert (cumprod ([i, 2+i, -3+2i, 4]), [i, -1+2i, -1-8i, -4-32i])
1024 %!assert (cumprod ([1, 2, 3; i, 2i, 3i; 1+i, 2+2i, 3+3i]),
1025 %! [1, 2, 3; i, 4i, 9i; -1+i, -8+8i, -27+27i])
1026 
1027 %!assert (cumprod (single ([1, 2, 3])), single ([1, 2, 6]))
1028 %!assert (cumprod (single ([-1; -2; -3])), single ([-1; 2; -6]))
1029 %!assert (cumprod (single ([i, 2+i, -3+2i, 4])),
1030 %! single ([i, -1+2i, -1-8i, -4-32i]))
1031 %!assert (cumprod (single ([1, 2, 3; i, 2i, 3i; 1+i, 2+2i, 3+3i])),
1032 %! single ([1, 2, 3; i, 4i, 9i; -1+i, -8+8i, -27+27i]))
1033 
1034 %!assert (cumprod ([2, 3; 4, 5], 1), [2, 3; 8, 15])
1035 %!assert (cumprod ([2, 3; 4, 5], 2), [2, 6; 4, 20])
1036 
1037 %!assert (cumprod (single ([2, 3; 4, 5]), 1), single ([2, 3; 8, 15]))
1038 %!assert (cumprod (single ([2, 3; 4, 5]), 2), single ([2, 6; 4, 20]))
1039 
1040 %!error cumprod ()
1041 */
1042 
1043 DEFUN (cumsum, args, ,
1044  doc: /* -*- texinfo -*-
1045 @deftypefn {} {@var{y} =} cumsum (@var{x})
1046 @deftypefnx {} {@var{y} =} cumsum (@var{x}, @var{dim})
1047 @deftypefnx {} {@var{y} =} cumsum (@dots{}, "native")
1048 @deftypefnx {} {@var{y} =} cumsum (@dots{}, "double")
1049 Cumulative sum of elements along dimension @var{dim}.
1050 
1051 If @var{dim} is omitted, it defaults to the first non-singleton dimension.
1052 For example:
1053 
1054 @example
1055 @group
1056 cumsum ([1, 2; 3, 4; 5, 6])
1057  @result{} 1 2
1058  4 6
1059  9 12
1060 @end group
1061 @end example
1062 
1063 For an explanation of the optional parameters @qcode{"native"} and
1064 @qcode{"double"}, @pxref{XREFsum,,@code{sum}}.
1065 @seealso{sum, cumprod}
1066 @end deftypefn */)
1067 {
1068  int nargin = args.length ();
1069 
1070  bool isnative = false;
1071  bool isdouble = false;
1072 
1073  if (nargin > 1 && args(nargin - 1).is_string ())
1074  {
1075  std::string str = args(nargin - 1).string_value ();
1076 
1077  if (str == "native")
1078  isnative = true;
1079  else if (str == "double")
1080  isdouble = true;
1081  else
1082  error ("cumsum: unrecognized string argument");
1083 
1084  nargin--;
1085  }
1086 
1087  if (nargin < 1 || nargin > 2)
1088  print_usage ();
1089 
1090  int dim = -1;
1091  if (nargin == 2)
1092  {
1093  dim = args(1).int_value () - 1;
1094  if (dim < 0)
1095  error ("cumsum: invalid dimension argument = %d", dim + 1);
1096  }
1097 
1098  octave_value retval;
1099  octave_value arg = args(0);
1100 
1101  switch (arg.builtin_type ())
1102  {
1103  case btyp_double:
1104  if (arg.issparse ())
1105  retval = arg.sparse_matrix_value ().cumsum (dim);
1106  else
1107  retval = arg.array_value ().cumsum (dim);
1108  break;
1109  case btyp_complex:
1110  if (arg.issparse ())
1111  retval = arg.sparse_complex_matrix_value ().cumsum (dim);
1112  else
1113  retval = arg.complex_array_value ().cumsum (dim);
1114  break;
1115  case btyp_float:
1116  if (isdouble)
1117  retval = arg.array_value ().cumsum (dim);
1118  else
1119  retval = arg.float_array_value ().cumsum (dim);
1120  break;
1121  case btyp_float_complex:
1122  if (isdouble)
1123  retval = arg.complex_array_value ().cumsum (dim);
1124  else
1125  retval = arg.float_complex_array_value ().cumsum (dim);
1126  break;
1127 
1128 #define MAKE_INT_BRANCH(X) \
1129  case btyp_ ## X: \
1130  if (isnative) \
1131  retval = arg.X ## _array_value ().cumsum (dim); \
1132  else \
1133  retval = arg.array_value ().cumsum (dim); \
1134  break;
1135 
1136  MAKE_INT_BRANCH (int8);
1137  MAKE_INT_BRANCH (int16);
1138  MAKE_INT_BRANCH (int32);
1139  MAKE_INT_BRANCH (int64);
1140  MAKE_INT_BRANCH (uint8);
1141  MAKE_INT_BRANCH (uint16);
1142  MAKE_INT_BRANCH (uint32);
1143  MAKE_INT_BRANCH (uint64);
1144 
1145 #undef MAKE_INT_BRANCH
1146 
1147  case btyp_bool:
1148  if (arg.issparse ())
1149  {
1150  SparseMatrix cs = arg.sparse_matrix_value ().cumsum (dim);
1151  if (isnative)
1152  retval = (cs != 0.0);
1153  else
1154  retval = cs;
1155  }
1156  else
1157  {
1158  NDArray cs = arg.array_value ().cumsum (dim);
1159  if (isnative)
1160  retval = (cs != 0.0);
1161  else
1162  retval = cs;
1163  }
1164  break;
1165 
1166  default:
1167  err_wrong_type_arg ("cumsum", arg);
1168  }
1169 
1170  return retval;
1171 }
1172 
1173 /*
1174 %!assert (cumsum ([1, 2, 3]), [1, 3, 6])
1175 %!assert (cumsum ([-1; -2; -3]), [-1; -3; -6])
1176 %!assert (cumsum ([i, 2+i, -3+2i, 4]), [i, 2+2i, -1+4i, 3+4i])
1177 %!assert (cumsum ([1, 2, 3; i, 2i, 3i; 1+i, 2+2i, 3+3i]),
1178 %! [1, 2, 3; 1+i, 2+2i, 3+3i; 2+2i, 4+4i, 6+6i])
1179 
1180 %!assert (cumsum (single ([1, 2, 3])), single ([1, 3, 6]))
1181 %!assert (cumsum (single ([-1; -2; -3])), single ([-1; -3; -6]))
1182 %!assert (cumsum (single ([i, 2+i, -3+2i, 4])),
1183 %! single ([i, 2+2i, -1+4i, 3+4i]))
1184 %!assert (cumsum (single ([1, 2, 3; i, 2i, 3i; 1+i, 2+2i, 3+3i])),
1185 %! single ([1, 2, 3; 1+i, 2+2i, 3+3i; 2+2i, 4+4i, 6+6i]))
1186 
1187 %!assert (cumsum ([1, 2; 3, 4], 1), [1, 2; 4, 6])
1188 %!assert (cumsum ([1, 2; 3, 4], 2), [1, 3; 3, 7])
1189 
1190 %!assert (cumsum (single ([1, 2; 3, 4]), 1), single ([1, 2; 4, 6]))
1191 %!assert (cumsum (single ([1, 2; 3, 4]), 2), single ([1, 3; 3, 7]))
1192 
1193 %!error cumsum ()
1194 */
1195 
1196 DEFUN (diag, args, ,
1197  doc: /* -*- texinfo -*-
1198 @deftypefn {} {@var{M} =} diag (@var{v})
1199 @deftypefnx {} {@var{M} =} diag (@var{v}, @var{k})
1200 @deftypefnx {} {@var{M} =} diag (@var{v}, @var{m}, @var{n})
1201 @deftypefnx {} {@var{v} =} diag (@var{M})
1202 @deftypefnx {} {@var{v} =} diag (@var{M}, @var{k})
1203 Return a diagonal matrix with vector @var{v} on diagonal @var{k}.
1204 
1205 The second argument is optional. If it is positive, the vector is placed on
1206 the @var{k}-th superdiagonal. If it is negative, it is placed on the
1207 @var{-k}-th subdiagonal. The default value of @var{k} is 0, and the vector
1208 is placed on the main diagonal. For example:
1209 
1210 @example
1211 @group
1212 diag ([1, 2, 3], 1)
1213  @result{} 0 1 0 0
1214  0 0 2 0
1215  0 0 0 3
1216  0 0 0 0
1217 @end group
1218 @end example
1219 
1220 @noindent
1221 The 3-input form returns a diagonal matrix with vector @var{v} on the main
1222 diagonal and the resulting matrix being of size @var{m} rows x @var{n}
1223 columns.
1224 
1225 Given a matrix argument, instead of a vector, @code{diag} extracts the
1226 @var{k}-th diagonal of the matrix.
1227 @end deftypefn */)
1228 {
1229  int nargin = args.length ();
1230 
1231  if (nargin < 1 || nargin > 3)
1232  print_usage ();
1233 
1234  octave_value retval;
1235 
1236  if (nargin == 1)
1237  retval = args(0).diag ();
1238  else if (nargin == 2)
1239  {
1240  octave_idx_type k = args(1).xidx_type_value ("diag: invalid argument K");
1241 
1242  retval = args(0).diag (k);
1243  }
1244  else
1245  {
1246  octave_value arg0 = args(0);
1247 
1248  if (arg0.ndims () != 2 || (arg0.rows () != 1 && arg0.columns () != 1))
1249  error ("diag: V must be a vector");
1250 
1251  octave_idx_type m = args(1).xidx_type_value ("diag: invalid dimension M");
1252  octave_idx_type n = args(2).xidx_type_value ("diag: invalid dimension N");
1253 
1254  retval = arg0.diag (m, n);
1255  }
1256 
1257  return retval;
1258 }
1259 
1260 /*
1261 
1262 %!assert (full (diag ([1; 2; 3])), [1, 0, 0; 0, 2, 0; 0, 0, 3])
1263 %!assert (diag ([1; 2; 3], 1), [0, 1, 0, 0; 0, 0, 2, 0; 0, 0, 0, 3; 0, 0, 0, 0])
1264 %!assert (diag ([1; 2; 3], 2),
1265 %! [0 0 1 0 0; 0 0 0 2 0; 0 0 0 0 3; 0 0 0 0 0; 0 0 0 0 0])
1266 %!assert (diag ([1; 2; 3],-1),
1267 %! [0 0 0 0; 1 0 0 0; 0 2 0 0; 0 0 3 0])
1268 %!assert (diag ([1; 2; 3],-2),
1269 %! [0 0 0 0 0; 0 0 0 0 0; 1 0 0 0 0; 0 2 0 0 0; 0 0 3 0 0])
1270 
1271 %!assert (diag ([1, 0, 0; 0, 2, 0; 0, 0, 3]), [1; 2; 3])
1272 %!assert (diag ([0, 1, 0, 0; 0, 0, 2, 0; 0, 0, 0, 3; 0, 0, 0, 0], 1),
1273 %! [1; 2; 3])
1274 %!assert (diag ([0, 0, 0, 0; 1, 0, 0, 0; 0, 2, 0, 0; 0, 0, 3, 0], -1),
1275 %! [1; 2; 3])
1276 %!assert (diag (ones (1, 0), 2), zeros (2))
1277 %!assert (diag (1:3, 4, 2), [1, 0; 0, 2; 0, 0; 0, 0])
1278 
1279 %!assert (full (diag (single ([1; 2; 3]))),
1280 %! single ([1, 0, 0; 0, 2, 0; 0, 0, 3]))
1281 %!assert (diag (single ([1; 2; 3]), 1),
1282 %! single ([0, 1, 0, 0; 0, 0, 2, 0; 0, 0, 0, 3; 0, 0, 0, 0]))
1283 %!assert (diag (single ([1; 2; 3]), 2),
1284 %! single ([0 0 1 0 0; 0 0 0 2 0; 0 0 0 0 3; 0 0 0 0 0; 0 0 0 0 0]))
1285 %!assert (diag (single ([1; 2; 3]),-1),
1286 %! single ([0, 0, 0, 0; 1, 0, 0, 0; 0, 2, 0, 0; 0, 0, 3, 0]))
1287 %!assert (diag (single ([1; 2; 3]),-2),
1288 %! single ([0 0 0 0 0; 0 0 0 0 0; 1 0 0 0 0; 0 2 0 0 0; 0 0 3 0 0]))
1289 
1290 %!assert (diag (single ([1, 0, 0; 0, 2, 0; 0, 0, 3])), single ([1; 2; 3]))
1291 %!assert (diag (single ([0, 1, 0, 0; 0, 0, 2, 0; 0, 0, 0, 3; 0, 0, 0, 0]), 1),
1292 %! single ([1; 2; 3]))
1293 %!assert (diag (single ([0, 0, 0, 0; 1, 0, 0, 0; 0, 2, 0, 0; 0, 0, 3, 0]), -1),
1294 %! single ([1; 2; 3]))
1295 
1296 %!assert (diag (int8 ([1; 2; 3])), int8 ([1, 0, 0; 0, 2, 0; 0, 0, 3]))
1297 %!assert (diag (int8 ([1; 2; 3]), 1),
1298 %! int8 ([0, 1, 0, 0; 0, 0, 2, 0; 0, 0, 0, 3; 0, 0, 0, 0]))
1299 %!assert (diag (int8 ([1; 2; 3]), 2),
1300 %! int8 ([0 0 1 0 0; 0 0 0 2 0; 0 0 0 0 3; 0 0 0 0 0; 0 0 0 0 0]))
1301 %!assert (diag (int8 ([1; 2; 3]),-1),
1302 %! int8 ([0 0 0 0; 1 0 0 0; 0 2 0 0; 0 0 3 0]))
1303 %!assert (diag (int8 ([1; 2; 3]),-2),
1304 %! int8 ([0 0 0 0 0; 0 0 0 0 0; 1 0 0 0 0; 0 2 0 0 0; 0 0 3 0 0]))
1305 
1306 %!assert (diag (int8 ([1, 0, 0; 0, 2, 0; 0, 0, 3])), int8 ([1; 2; 3]))
1307 %!assert (diag (int8 ([0, 1, 0, 0; 0, 0, 2, 0; 0, 0, 0, 3; 0, 0, 0, 0]), 1),
1308 %! int8 ([1; 2; 3]))
1309 %!assert (diag (int8 ([0, 0, 0, 0; 1, 0, 0, 0; 0, 2, 0, 0; 0, 0, 3, 0]), -1),
1310 %! int8 ([1; 2; 3]))
1311 
1312 %!assert (diag (1, 3, 3), diag ([1, 0, 0]))
1313 %!assert (diag (i, 3, 3), diag ([i, 0, 0]))
1314 %!assert (diag (single (1), 3, 3), diag ([single(1), 0, 0]))
1315 %!assert (diag (single (i), 3, 3), diag ([single(i), 0, 0]))
1316 %!assert (diag ([1, 2], 3, 3), diag ([1, 2, 0]))
1317 %!assert (diag ([1, 2]*i, 3, 3), diag ([1, 2, 0]*i))
1318 %!assert (diag (single ([1, 2]), 3, 3), diag (single ([1, 2, 0])))
1319 %!assert (diag (single ([1, 2]*i), 3, 3), diag (single ([1, 2, 0]*i)))
1320 
1321 %!assert <*37411> (diag (diag ([5, 2, 3])(:,1)), diag([5 0 0 ]))
1322 %!assert <*37411> (diag (diag ([5, 2, 3])(:,1), 2), [0 0 5 0 0; zeros(4, 5)])
1323 %!assert <*37411> (diag (diag ([5, 2, 3])(:,1), -2),
1324 %! [[0 0 5 0 0]', zeros(5, 4)])
1325 
1326 ## Test non-square size
1327 %!assert (diag ([1,2,3], 6, 3), [1 0 0; 0 2 0; 0 0 3; 0 0 0; 0 0 0; 0 0 0])
1328 %!assert (diag (1, 2, 3), [1,0,0; 0,0,0])
1329 %!assert (diag ({1}, 2, 3), {1,[],[]; [],[],[]})
1330 %!assert (diag ({1,2}, 3, 4), {1,[],[],[]; [],2,[],[]; [],[],[],[]})
1331 %!assert <*56711> (diag ({1,2,3}, 2, 1), {1; []})
1332 
1333 ## Test out-of-range diagonals
1334 %!assert (diag (ones (3,3), 4), zeros (0, 1))
1335 %!assert (diag (cell (3,3), 4), cell (0, 1))
1336 %!assert (diag (sparse (ones (3,3)), 4), sparse (zeros (0, 1)))
1337 
1338 ## Test input validation
1339 %!error <Invalid call to diag> diag ()
1340 %!error <Invalid call to diag> diag (1,2,3,4)
1341 %!error <V must be a vector> diag (ones (2), 3, 3)
1342 %!error diag (1:3, -4, 3)
1343 %!error diag (1:3, 4, -3)
1344 
1345 */
1346 
1347 DEFUN (prod, args, ,
1348  doc: /* -*- texinfo -*-
1349 @deftypefn {} {@var{y} =} prod (@var{x})
1350 @deftypefnx {} {@var{y} =} prod (@var{x}, @var{dim})
1351 @deftypefnx {} {@var{y} =} prod (@dots{}, "native")
1352 @deftypefnx {} {@var{y} =} prod (@dots{}, "double")
1353 Product of elements along dimension @var{dim}.
1354 
1355 If @var{dim} is omitted, it defaults to the first non-singleton dimension.
1356 
1357 The optional @qcode{"type"} input determines the class of the variable
1358 used for calculations. If the argument @qcode{"native"} is given, then
1359 the operation is performed in the same type as the original argument, rather
1360 than the default double type.
1361 
1362 For example:
1363 
1364 @example
1365 @group
1366 prod ([true, true])
1367  @result{} 1
1368 prod ([true, true], "native")
1369  @result{} true
1370 @end group
1371 @end example
1372 
1373 On the contrary, if @qcode{"double"} is given, the operation is performed
1374 in double precision even for single precision inputs.
1375 @seealso{cumprod, sum}
1376 @end deftypefn */)
1377 {
1378  int nargin = args.length ();
1379 
1380  bool isnative = false;
1381  bool isdouble = false;
1382 
1383  if (nargin > 1 && args(nargin - 1).is_string ())
1384  {
1385  std::string str = args(nargin - 1).string_value ();
1386 
1387  if (str == "native")
1388  isnative = true;
1389  else if (str == "double")
1390  isdouble = true;
1391  else
1392  error ("prod: unrecognized type argument '%s'", str.c_str ());
1393 
1394  nargin--;
1395  }
1396 
1397  if (nargin < 1 || nargin > 2)
1398  print_usage ();
1399 
1400  octave_value retval;
1401 
1402  octave_value arg = args(0);
1403 
1404  int dim = -1;
1405  if (nargin == 2)
1406  {
1407  dim = args(1).int_value () - 1;
1408  if (dim < 0)
1409  error ("prod: invalid dimension DIM = %d", dim + 1);
1410  }
1411 
1412  switch (arg.builtin_type ())
1413  {
1414  case btyp_double:
1415  if (arg.issparse ())
1416  retval = arg.sparse_matrix_value ().prod (dim);
1417  else
1418  retval = arg.array_value ().prod (dim);
1419  break;
1420  case btyp_complex:
1421  if (arg.issparse ())
1422  retval = arg.sparse_complex_matrix_value ().prod (dim);
1423  else
1424  retval = arg.complex_array_value ().prod (dim);
1425  break;
1426  case btyp_float:
1427  if (isdouble)
1428  retval = arg.float_array_value ().dprod (dim);
1429  else
1430  retval = arg.float_array_value ().prod (dim);
1431  break;
1432  case btyp_float_complex:
1433  if (isdouble)
1434  retval = arg.float_complex_array_value ().dprod (dim);
1435  else
1436  retval = arg.float_complex_array_value ().prod (dim);
1437  break;
1438 
1439 #define MAKE_INT_BRANCH(X) \
1440  case btyp_ ## X: \
1441  if (isnative) \
1442  retval = arg.X ## _array_value ().prod (dim); \
1443  else \
1444  retval = arg.array_value ().prod (dim); \
1445  break;
1446 
1447  MAKE_INT_BRANCH (int8);
1448  MAKE_INT_BRANCH (int16);
1449  MAKE_INT_BRANCH (int32);
1450  MAKE_INT_BRANCH (int64);
1451  MAKE_INT_BRANCH (uint8);
1452  MAKE_INT_BRANCH (uint16);
1453  MAKE_INT_BRANCH (uint32);
1454  MAKE_INT_BRANCH (uint64);
1455 
1456 #undef MAKE_INT_BRANCH
1457 
1458  // GAGME: Accursed Matlab compatibility...
1459  case btyp_char:
1460  retval = arg.array_value (true).prod (dim);
1461  break;
1462 
1463  case btyp_bool:
1464  if (arg.issparse ())
1465  {
1466  if (isnative)
1467  retval = arg.sparse_bool_matrix_value ().all (dim);
1468  else
1469  retval = arg.sparse_matrix_value ().prod (dim);
1470  }
1471  else if (isnative)
1472  retval = arg.bool_array_value ().all (dim);
1473  else
1474  retval = NDArray (arg.bool_array_value ().all (dim));
1475  break;
1476 
1477  default:
1478  err_wrong_type_arg ("prod", arg);
1479  }
1480 
1481  return retval;
1482 }
1483 
1484 /*
1485 %!assert (prod ([1, 2, 3]), 6)
1486 %!assert (prod ([-1; -2; -3]), -6)
1487 %!assert (prod ([i, 2+i, -3+2i, 4]), -4 - 32i)
1488 %!assert (prod ([1, 2, 3; i, 2i, 3i; 1+i, 2+2i, 3+3i]), [-1+i, -8+8i, -27+27i])
1489 
1490 %!assert (prod (single ([1, 2, 3])), single (6))
1491 %!assert (prod (single ([-1; -2; -3])), single (-6))
1492 %!assert (prod (single ([i, 2+i, -3+2i, 4])), single (-4 - 32i))
1493 %!assert (prod (single ([1, 2, 3; i, 2i, 3i; 1+i, 2+2i, 3+3i])),
1494 %! single ([-1+i, -8+8i, -27+27i]))
1495 
1496 ## Test sparse
1497 %!assert (prod (sparse ([1, 2, 3])), sparse (6))
1498 %!assert (prod (sparse ([-1; -2; -3])), sparse (-6))
1499 ## Commented out until bug #42290 is fixed
1500 #%!assert (prod (sparse ([i, 2+i, -3+2i, 4])), sparse (-4 - 32i))
1501 #%!assert (prod (sparse ([1, 2, 3; i, 2i, 3i; 1+i, 2+2i, 3+3i])),
1502 #%! sparse ([-1+i, -8+8i, -27+27i]))
1503 
1504 %!assert (prod ([1, 2; 3, 4], 1), [3, 8])
1505 %!assert (prod ([1, 2; 3, 4], 2), [2; 12])
1506 %!assert (prod (zeros (1, 0)), 1)
1507 %!assert (prod (zeros (1, 0), 1), zeros (1, 0))
1508 %!assert (prod (zeros (1, 0), 2), 1)
1509 %!assert (prod (zeros (0, 1)), 1)
1510 %!assert (prod (zeros (0, 1), 1), 1)
1511 %!assert (prod (zeros (0, 1), 2), zeros (0, 1))
1512 %!assert (prod (zeros (2, 0)), zeros (1, 0))
1513 %!assert (prod (zeros (2, 0), 1), zeros (1, 0))
1514 %!assert (prod (zeros (2, 0), 2), [1; 1])
1515 %!assert (prod (zeros (0, 2)), [1, 1])
1516 %!assert (prod (zeros (0, 2), 1), [1, 1])
1517 %!assert (prod (zeros (0, 2), 2), zeros (0, 1))
1518 
1519 %!assert (prod (single ([1, 2; 3, 4]), 1), single ([3, 8]))
1520 %!assert (prod (single ([1, 2; 3, 4]), 2), single ([2; 12]))
1521 %!assert (prod (zeros (1, 0, "single")), single (1))
1522 %!assert (prod (zeros (1, 0, "single"), 1), zeros (1, 0, "single"))
1523 %!assert (prod (zeros (1, 0, "single"), 2), single (1))
1524 %!assert (prod (zeros (0, 1, "single")), single (1))
1525 %!assert (prod (zeros (0, 1, "single"), 1), single (1))
1526 %!assert (prod (zeros (0, 1, "single"), 2), zeros (0, 1, "single"))
1527 %!assert (prod (zeros (2, 0, "single")), zeros (1, 0, "single"))
1528 %!assert (prod (zeros (2, 0, "single"), 1), zeros (1, 0, "single"))
1529 %!assert (prod (zeros (2, 0, "single"), 2), single ([1; 1]))
1530 %!assert (prod (zeros (0, 2, "single")), single ([1, 1]))
1531 %!assert (prod (zeros (0, 2, "single"), 1), single ([1, 1]))
1532 %!assert (prod (zeros (0, 2, "single"), 2), zeros (0, 1, "single"))
1533 
1534 ## Test "double" type argument
1535 %!assert (prod (single ([1, 2, 3]), "double"), 6)
1536 %!assert (prod (single ([-1; -2; -3]), "double"), -6)
1537 %!assert (prod (single ([i, 2+i, -3+2i, 4]), "double"), -4 - 32i)
1538 %!assert (prod (single ([1, 2, 3; i, 2i, 3i; 1+i, 2+2i, 3+3i]), "double"),
1539 %! [-1+i, -8+8i, -27+27i])
1540 
1541 ## Test "native" type argument
1542 %!assert (prod (uint8 ([1, 2, 3]), "native"), uint8 (6))
1543 %!assert (prod (uint8 ([-1; -2; -3]), "native"), uint8 (0))
1544 %!assert (prod (int8 ([1, 2, 3]), "native"), int8 (6))
1545 %!assert (prod (int8 ([-1; -2; -3]), "native"), int8 (-6))
1546 %!assert (prod ([true false; true true], "native"), [true false])
1547 %!assert (prod ([true false; true true], 2, "native"), [false; true])
1548 
1549 ## Test input validation
1550 %!error prod ()
1551 %!error prod (1,2,3)
1552 %!error <unrecognized type argument 'foobar'> prod (1, "foobar")
1553 */
1554 
1555 static bool
1556 all_scalar_1x1 (const octave_value_list& args)
1557 {
1558  int n_args = args.length ();
1559  for (int i = 0; i < n_args; i++)
1560  if (args(i).numel () != 1)
1561  return false;
1562 
1563  return true;
1564 }
1565 
1566 template <typename TYPE, typename T>
1567 static void
1568 single_type_concat (Array<T>& result,
1569  const octave_value_list& args,
1570  int dim)
1571 {
1572  int n_args = args.length ();
1575  && all_scalar_1x1 (args))
1576  {
1577  // Optimize all scalars case.
1578  dim_vector dv (1, 1);
1579  if (dim == -1 || dim == -2)
1580  dim = -dim - 1;
1581  else if (dim >= 2)
1582  dv.resize (dim+1, 1);
1583  dv(dim) = n_args;
1584 
1585  result.clear (dv);
1586 
1587  for (int j = 0; j < n_args; j++)
1588  {
1589  octave_quit ();
1590 
1591  result(j) = octave_value_extract<T> (args(j));
1592  }
1593  }
1594  else
1595  {
1596  OCTAVE_LOCAL_BUFFER (Array<T>, array_list, n_args);
1597 
1598  for (int j = 0; j < n_args; j++)
1599  {
1600  octave_quit ();
1601 
1602  array_list[j] = octave_value_extract<TYPE> (args(j));
1603  }
1604 
1605  result = Array<T>::cat (dim, n_args, array_list);
1606  }
1607 }
1608 
1609 template <typename TYPE, typename T>
1610 static void
1611 single_type_concat (Sparse<T>& result,
1612  const octave_value_list& args,
1613  int dim)
1614 {
1615  octave_idx_type n_args = args.length ();
1616  OCTAVE_LOCAL_BUFFER (Sparse<T>, sparse_list, n_args);
1617 
1618  for (octave_idx_type j = 0; j < n_args; j++)
1619  {
1620  octave_quit ();
1621 
1622  sparse_list[j] = octave_value_extract<TYPE> (args(j));
1623  }
1624 
1625  result = Sparse<T>::cat (dim, n_args, sparse_list);
1626 }
1627 
1628 // Dispatcher.
1629 template <typename TYPE>
1630 static TYPE
1631 do_single_type_concat (const octave_value_list& args, int dim)
1632 {
1633  TYPE result;
1634 
1635  single_type_concat<TYPE, typename TYPE::element_type> (result, args, dim);
1636 
1637  return result;
1638 }
1639 
1640 template <typename MAP>
1641 static void
1642 single_type_concat_map (octave_map& result,
1643  const octave_value_list& args,
1644  int dim)
1645 {
1646  int n_args = args.length ();
1647  OCTAVE_LOCAL_BUFFER (MAP, map_list, n_args);
1648 
1649  for (int j = 0; j < n_args; j++)
1650  {
1651  octave_quit ();
1652 
1653  map_list[j] = octave_value_extract<MAP> (args(j));
1654  }
1655 
1656  result = octave_map::cat (dim, n_args, map_list);
1657 }
1658 
1659 static octave_map
1660 do_single_type_concat_map (const octave_value_list& args,
1661  int dim)
1662 {
1663  octave_map result;
1664  if (all_scalar_1x1 (args)) // optimize all scalars case.
1665  single_type_concat_map<octave_scalar_map> (result, args, dim);
1666  else
1667  single_type_concat_map<octave_map> (result, args, dim);
1668 
1669  return result;
1670 }
1671 
1672 static octave_value
1673 attempt_type_conversion (const octave_value& ov, std::string dtype)
1674 {
1675  octave_value retval;
1676 
1677  // First try to find function in the class of OV that can convert to
1678  // the dispatch type dtype. It will have the name of the dispatch
1679  // type.
1680 
1681  std::string cname = ov.class_name ();
1682 
1683  interpreter& interp = __get_interpreter__ ();
1684 
1685  symbol_table& symtab = interp.get_symbol_table ();
1686 
1687  octave_value fcn = symtab.find_method (dtype, cname);
1688 
1689  if (fcn.is_defined ())
1690  {
1691  octave_value_list result;
1692 
1693  try
1694  {
1695  result = interp.feval (fcn, ovl (ov), 1);
1696  }
1697  catch (execution_exception& ee)
1698  {
1699  error (ee, "conversion from %s to %s failed", dtype.c_str (),
1700  cname.c_str ());
1701  }
1702 
1703  if (result.empty ())
1704  error ("conversion from %s to %s failed", dtype.c_str (),
1705  cname.c_str ());
1706 
1707  retval = result(0);
1708  }
1709  else
1710  {
1711  // No conversion function available. Try the constructor for the
1712  // dispatch type.
1713 
1714  fcn = symtab.find_method (dtype, dtype);
1715 
1716  if (! fcn.is_defined ())
1717  error ("no constructor for %s!", dtype.c_str ());
1718 
1719  octave_value_list result;
1720 
1721  try
1722  {
1723  result = interp.feval (fcn, ovl (ov), 1);
1724  }
1725  catch (execution_exception& ee)
1726  {
1727  error (ee, "%s constructor failed for %s argument", dtype.c_str (),
1728  cname.c_str ());
1729  }
1730 
1731  if (result.empty ())
1732  error ("%s constructor failed for %s argument", dtype.c_str (),
1733  cname.c_str ());
1734 
1735  retval = result(0);
1736  }
1737 
1738  return retval;
1739 }
1740 
1743  const std::string& cattype, int dim)
1744 {
1745  octave_value retval;
1746 
1747  // Get dominant type for list
1748 
1749  std::string dtype = get_dispatch_type (ovl);
1750 
1751  interpreter& interp = __get_interpreter__ ();
1752 
1753  symbol_table& symtab = interp.get_symbol_table ();
1754 
1755  octave_value fcn = symtab.find_method (cattype, dtype);
1756 
1757  if (fcn.is_defined ())
1758  {
1759  // Have method for dominant type. Call it and let it handle conversions.
1760 
1761  octave_value_list tmp2;
1762 
1763  try
1764  {
1765  tmp2 = interp.feval (fcn, ovl, 1);
1766  }
1767  catch (execution_exception& ee)
1768  {
1769  error (ee, "%s/%s method failed", dtype.c_str (), cattype.c_str ());
1770  }
1771 
1772  if (tmp2.empty ())
1773  error ("%s/%s method did not return a value", dtype.c_str (),
1774  cattype.c_str ());
1775 
1776  retval = tmp2(0);
1777  }
1778  else
1779  {
1780  // No method for dominant type, so attempt type conversions for
1781  // all elements that are not of the dominant type, then do the
1782  // default operation for octave_class values.
1783 
1784  octave_idx_type j = 0;
1787  for (octave_idx_type k = 0; k < len; k++)
1788  {
1789  octave_value elt = ovl(k);
1790 
1791  std::string t1_type = elt.class_name ();
1792 
1793  if (t1_type == dtype)
1794  tmp(j++) = elt;
1795  else if (elt.isobject () || ! elt.isempty ())
1796  tmp(j++) = attempt_type_conversion (elt, dtype);
1797  }
1798 
1799  tmp.resize (j);
1800 
1801  octave_map m = do_single_type_concat_map (tmp, dim);
1802 
1803  std::string cname = tmp(0).class_name ();
1804  std::list<std::string> parents = tmp(0).parent_class_name_list ();
1805 
1806  retval = octave_value (new octave_class (m, cname, parents));
1807  }
1808 
1809  return retval;
1810 }
1811 
1812 static octave_value
1813 do_cat (const octave_value_list& xargs, int dim, std::string fname)
1814 {
1815  octave_value retval;
1816 
1817  // We may need to convert elements of the list to cells, so make a copy.
1818  // This should be efficient, it is done mostly by incrementing reference
1819  // counts.
1820  octave_value_list args = xargs;
1821 
1822  int n_args = args.length ();
1823 
1824  if (n_args == 0)
1825  retval = Matrix ();
1826  else if (n_args == 1)
1827  retval = args(0);
1828  else if (n_args > 1)
1829  {
1830  std::string result_type;
1831 
1832  bool all_strings_p = true;
1833  bool all_sq_strings_p = true;
1834  bool all_dq_strings_p = true;
1835  bool all_real_p = true;
1836  bool all_cmplx_p = true;
1837  bool any_sparse_p = false;
1838  bool any_cell_p = false;
1839  bool any_class_p = false;
1840 
1841  bool first_elem_is_struct = false;
1842 
1843  for (int i = 0; i < n_args; i++)
1844  {
1845  if (i == 0)
1846  {
1847  result_type = args(i).class_name ();
1848 
1849  first_elem_is_struct = args(i).isstruct ();
1850  }
1851  else
1852  result_type = get_concat_class (result_type, args(i).class_name ());
1853 
1854  if (all_strings_p && ! args(i).is_string ())
1855  all_strings_p = false;
1856  if (all_sq_strings_p && ! args(i).is_sq_string ())
1857  all_sq_strings_p = false;
1858  if (all_dq_strings_p && ! args(i).is_dq_string ())
1859  all_dq_strings_p = false;
1860  if (all_real_p && ! args(i).isreal ())
1861  all_real_p = false;
1862  if (all_cmplx_p && ! (args(i).iscomplex ()
1863  || args(i).isreal ()))
1864  all_cmplx_p = false;
1865  if (! any_sparse_p && args(i).issparse ())
1866  any_sparse_p = true;
1867  if (! any_cell_p && args(i).iscell ())
1868  any_cell_p = true;
1869  if (! any_class_p && args(i).isobject ())
1870  any_class_p = true;
1871  }
1872 
1873  if (any_cell_p && ! any_class_p && ! first_elem_is_struct)
1874  {
1875  int j = 0;
1876  for (int i = 0; i < n_args; i++)
1877  {
1878  if (args(i).iscell ())
1879  args(j++) = args(i);
1880  else
1881  {
1882  if (args(i).isempty ())
1883  continue; // Delete empty non-cell arg
1884  else
1885  args(j++) = Cell (args(i));
1886  }
1887  }
1888  n_args = j;
1889  args.resize (n_args);
1890  }
1891 
1892  if (any_class_p)
1893  {
1894  retval = do_class_concat (args, fname, dim);
1895  }
1896  else if (result_type == "double")
1897  {
1898  if (any_sparse_p)
1899  {
1900  if (all_real_p)
1901  retval = do_single_type_concat<SparseMatrix> (args, dim);
1902  else
1903  retval = do_single_type_concat<SparseComplexMatrix> (args, dim);
1904  }
1905  else
1906  {
1907  if (all_real_p)
1908  retval = do_single_type_concat<NDArray> (args, dim);
1909  else
1910  retval = do_single_type_concat<ComplexNDArray> (args, dim);
1911  }
1912  }
1913  else if (result_type == "single")
1914  {
1915  if (all_real_p)
1916  retval = do_single_type_concat<FloatNDArray> (args, dim);
1917  else
1918  retval = do_single_type_concat<FloatComplexNDArray> (args, dim);
1919  }
1920  else if (result_type == "char")
1921  {
1922  char type = (all_dq_strings_p ? '"' : '\'');
1923 
1924  if (! all_strings_p)
1925  warn_implicit_conversion ("Octave:num-to-str",
1926  "numeric", result_type);
1927  else
1928  maybe_warn_string_concat (all_dq_strings_p, all_sq_strings_p);
1929 
1930  charNDArray result = do_single_type_concat<charNDArray> (args, dim);
1931 
1932  retval = octave_value (result, type);
1933  }
1934  else if (result_type == "logical")
1935  {
1936  if (any_sparse_p)
1937  retval = do_single_type_concat<SparseBoolMatrix> (args, dim);
1938  else
1939  retval = do_single_type_concat<boolNDArray> (args, dim);
1940  }
1941  else if (result_type == "int8")
1942  retval = do_single_type_concat<int8NDArray> (args, dim);
1943  else if (result_type == "int16")
1944  retval = do_single_type_concat<int16NDArray> (args, dim);
1945  else if (result_type == "int32")
1946  retval = do_single_type_concat<int32NDArray> (args, dim);
1947  else if (result_type == "int64")
1948  retval = do_single_type_concat<int64NDArray> (args, dim);
1949  else if (result_type == "uint8")
1950  retval = do_single_type_concat<uint8NDArray> (args, dim);
1951  else if (result_type == "uint16")
1952  retval = do_single_type_concat<uint16NDArray> (args, dim);
1953  else if (result_type == "uint32")
1954  retval = do_single_type_concat<uint32NDArray> (args, dim);
1955  else if (result_type == "uint64")
1956  retval = do_single_type_concat<uint64NDArray> (args, dim);
1957  else if (result_type == "cell")
1958  retval = do_single_type_concat<Cell> (args, dim);
1959  else if (result_type == "struct")
1960  retval = do_single_type_concat_map (args, dim);
1961  else
1962  {
1963  dim_vector dv = args(0).dims ();
1964 
1965  // Default concatenation.
1966  bool (dim_vector::*concat_rule) (const dim_vector&, int)
1967  = &dim_vector::concat;
1968 
1969  if (dim == -1 || dim == -2)
1970  {
1971  concat_rule = &dim_vector::hvcat;
1972  dim = -dim - 1;
1973  }
1974 
1975  for (int i = 1; i < args.length (); i++)
1976  {
1977  if (! (dv.*concat_rule) (args(i).dims (), dim))
1978  error ("cat: dimension mismatch");
1979  }
1980 
1981  // The lines below might seem crazy, since we take a copy
1982  // of the first argument, resize it to be empty and then resize
1983  // it to be full. This is done since it means that there is no
1984  // recopying of data, as would happen if we used a single resize.
1985  // It should be noted that resize operation is also significantly
1986  // slower than the do_cat_op function, so it makes sense to have
1987  // an empty matrix and copy all data.
1988  //
1989  // We might also start with a empty octave_value using
1990  //
1991  // tmp = type_info::lookup_type (args(1).type_name());
1992  //
1993  // and then directly resize. However, for some types there might
1994  // be some additional setup needed, and so this should be avoided.
1995 
1996  octave_value tmp = args(0);
1997  tmp = tmp.resize (dim_vector (0, 0)).resize (dv);
1998 
1999  int dv_len = dv.ndims ();
2000  Array<octave_idx_type> ra_idx (dim_vector (dv_len, 1), 0);
2001 
2002  for (int j = 0; j < n_args; j++)
2003  {
2004  // Can't fast return here to skip empty matrices as something
2005  // like cat (1,[],single ([])) must return an empty matrix of
2006  // the right type.
2007  tmp = cat_op (tmp, args(j), ra_idx);
2008 
2009  dim_vector dv_tmp = args(j).dims ();
2010 
2011  if (dim >= dv_len)
2012  {
2013  if (j > 1)
2014  error ("%s: indexing error", fname.c_str ());
2015 
2016  break;
2017  }
2018  else
2019  ra_idx(dim) += (dim < dv_tmp.ndims () ? dv_tmp(dim) : 1);
2020  }
2021  retval = tmp;
2022  }
2023  }
2024  else
2025  print_usage ();
2026 
2027  return retval;
2028 }
2029 
2030 DEFUN (horzcat, args, ,
2031  doc: /* -*- texinfo -*-
2032 @deftypefn {} {@var{A} =} horzcat (@var{array1}, @var{array2}, @dots{}, @var{arrayN})
2033 Return the horizontal concatenation of N-D array objects, @var{array1},
2034 @var{array2}, @dots{}, @var{arrayN} along dimension 2.
2035 
2036 Arrays may also be concatenated horizontally using the syntax for creating
2037 new matrices. For example:
2038 
2039 @example
2040 @var{A} = [ @var{array1}, @var{array2}, @dots{} ]
2041 @end example
2042 
2043 This syntax is slightly more efficient because the Octave parser can
2044 concatenate the arrays without the overhead of a function call.
2045 @seealso{cat, vertcat}
2046 @end deftypefn */)
2047 {
2048  return do_cat (args, -2, "horzcat");
2049 }
2050 
2051 /*
2052 ## Test concatenation with all zero matrices
2053 %!test
2054 %! warning ("off", "Octave:num-to-str", "local");
2055 %! assert (horzcat ("", 65* ones (1,10)), "AAAAAAAAAA");
2056 %! assert (horzcat (65* ones (1,10), ""), "AAAAAAAAAA");
2057 
2058 %!assert (class (horzcat (int64 (1), int64 (1))), "int64")
2059 %!assert (class (horzcat (int64 (1), int32 (1))), "int64")
2060 %!assert (class (horzcat (int64 (1), int16 (1))), "int64")
2061 %!assert (class (horzcat (int64 (1), int8 (1))), "int64")
2062 %!assert (class (horzcat (int64 (1), uint64 (1))), "int64")
2063 %!assert (class (horzcat (int64 (1), uint32 (1))), "int64")
2064 %!assert (class (horzcat (int64 (1), uint16 (1))), "int64")
2065 %!assert (class (horzcat (int64 (1), uint8 (1))), "int64")
2066 %!assert (class (horzcat (int64 (1), single (1))), "int64")
2067 %!assert (class (horzcat (int64 (1), double (1))), "int64")
2068 %!assert (class (horzcat (int64 (1), cell (1))), "cell")
2069 %!assert (class (horzcat (int64 (1), true)), "int64")
2070 %!test
2071 %! warning ("off", "Octave:num-to-str", "local");
2072 %! assert (class (horzcat (int64 (1), "a")), "char");
2073 
2074 %!assert (class (horzcat (int32 (1), int64 (1))), "int32")
2075 %!assert (class (horzcat (int32 (1), int32 (1))), "int32")
2076 %!assert (class (horzcat (int32 (1), int16 (1))), "int32")
2077 %!assert (class (horzcat (int32 (1), int8 (1))), "int32")
2078 %!assert (class (horzcat (int32 (1), uint64 (1))), "int32")
2079 %!assert (class (horzcat (int32 (1), uint32 (1))), "int32")
2080 %!assert (class (horzcat (int32 (1), uint16 (1))), "int32")
2081 %!assert (class (horzcat (int32 (1), uint8 (1))), "int32")
2082 %!assert (class (horzcat (int32 (1), single (1))), "int32")
2083 %!assert (class (horzcat (int32 (1), double (1))), "int32")
2084 %!assert (class (horzcat (int32 (1), cell (1))), "cell")
2085 %!assert (class (horzcat (int32 (1), true)), "int32")
2086 %!test
2087 %! warning ("off", "Octave:num-to-str", "local");
2088 %! assert (class (horzcat (int32 (1), "a")), "char");
2089 
2090 %!assert (class (horzcat (int16 (1), int64 (1))), "int16")
2091 %!assert (class (horzcat (int16 (1), int32 (1))), "int16")
2092 %!assert (class (horzcat (int16 (1), int16 (1))), "int16")
2093 %!assert (class (horzcat (int16 (1), int8 (1))), "int16")
2094 %!assert (class (horzcat (int16 (1), uint64 (1))), "int16")
2095 %!assert (class (horzcat (int16 (1), uint32 (1))), "int16")
2096 %!assert (class (horzcat (int16 (1), uint16 (1))), "int16")
2097 %!assert (class (horzcat (int16 (1), uint8 (1))), "int16")
2098 %!assert (class (horzcat (int16 (1), single (1))), "int16")
2099 %!assert (class (horzcat (int16 (1), double (1))), "int16")
2100 %!assert (class (horzcat (int16 (1), cell (1))), "cell")
2101 %!assert (class (horzcat (int16 (1), true)), "int16")
2102 %!test
2103 %! warning ("off", "Octave:num-to-str", "local");
2104 %! assert (class (horzcat (int16 (1), "a")), "char");
2105 
2106 %!assert (class (horzcat (int8 (1), int64 (1))), "int8")
2107 %!assert (class (horzcat (int8 (1), int32 (1))), "int8")
2108 %!assert (class (horzcat (int8 (1), int16 (1))), "int8")
2109 %!assert (class (horzcat (int8 (1), int8 (1))), "int8")
2110 %!assert (class (horzcat (int8 (1), uint64 (1))), "int8")
2111 %!assert (class (horzcat (int8 (1), uint32 (1))), "int8")
2112 %!assert (class (horzcat (int8 (1), uint16 (1))), "int8")
2113 %!assert (class (horzcat (int8 (1), uint8 (1))), "int8")
2114 %!assert (class (horzcat (int8 (1), single (1))), "int8")
2115 %!assert (class (horzcat (int8 (1), double (1))), "int8")
2116 %!assert (class (horzcat (int8 (1), cell (1))), "cell")
2117 %!assert (class (horzcat (int8 (1), true)), "int8")
2118 %!test
2119 %! warning ("off", "Octave:num-to-str", "local");
2120 %! assert (class (horzcat (int8 (1), "a")), "char");
2121 
2122 %!assert (class (horzcat (uint64 (1), int64 (1))), "uint64")
2123 %!assert (class (horzcat (uint64 (1), int32 (1))), "uint64")
2124 %!assert (class (horzcat (uint64 (1), int16 (1))), "uint64")
2125 %!assert (class (horzcat (uint64 (1), int8 (1))), "uint64")
2126 %!assert (class (horzcat (uint64 (1), uint64 (1))), "uint64")
2127 %!assert (class (horzcat (uint64 (1), uint32 (1))), "uint64")
2128 %!assert (class (horzcat (uint64 (1), uint16 (1))), "uint64")
2129 %!assert (class (horzcat (uint64 (1), uint8 (1))), "uint64")
2130 %!assert (class (horzcat (uint64 (1), single (1))), "uint64")
2131 %!assert (class (horzcat (uint64 (1), double (1))), "uint64")
2132 %!assert (class (horzcat (uint64 (1), cell (1))), "cell")
2133 %!assert (class (horzcat (uint64 (1), true)), "uint64")
2134 %!test
2135 %! warning ("off", "Octave:num-to-str", "local");
2136 %! assert (class (horzcat (uint64 (1), "a")), "char");
2137 
2138 %!assert (class (horzcat (uint32 (1), int64 (1))), "uint32")
2139 %!assert (class (horzcat (uint32 (1), int32 (1))), "uint32")
2140 %!assert (class (horzcat (uint32 (1), int16 (1))), "uint32")
2141 %!assert (class (horzcat (uint32 (1), int8 (1))), "uint32")
2142 %!assert (class (horzcat (uint32 (1), uint64 (1))), "uint32")
2143 %!assert (class (horzcat (uint32 (1), uint32 (1))), "uint32")
2144 %!assert (class (horzcat (uint32 (1), uint16 (1))), "uint32")
2145 %!assert (class (horzcat (uint32 (1), uint8 (1))), "uint32")
2146 %!assert (class (horzcat (uint32 (1), single (1))), "uint32")
2147 %!assert (class (horzcat (uint32 (1), double (1))), "uint32")
2148 %!assert (class (horzcat (uint32 (1), cell (1))), "cell")
2149 %!assert (class (horzcat (uint32 (1), true)), "uint32")
2150 %!test
2151 %! warning ("off", "Octave:num-to-str", "local");
2152 %! assert (class (horzcat (uint32 (1), "a")), "char");
2153 
2154 %!assert (class (horzcat (uint16 (1), int64 (1))), "uint16")
2155 %!assert (class (horzcat (uint16 (1), int32 (1))), "uint16")
2156 %!assert (class (horzcat (uint16 (1), int16 (1))), "uint16")
2157 %!assert (class (horzcat (uint16 (1), int8 (1))), "uint16")
2158 %!assert (class (horzcat (uint16 (1), uint64 (1))), "uint16")
2159 %!assert (class (horzcat (uint16 (1), uint32 (1))), "uint16")
2160 %!assert (class (horzcat (uint16 (1), uint16 (1))), "uint16")
2161 %!assert (class (horzcat (uint16 (1), uint8 (1))), "uint16")
2162 %!assert (class (horzcat (uint16 (1), single (1))), "uint16")
2163 %!assert (class (horzcat (uint16 (1), double (1))), "uint16")
2164 %!assert (class (horzcat (uint16 (1), cell (1))), "cell")
2165 %!assert (class (horzcat (uint16 (1), true)), "uint16")
2166 %!test
2167 %! warning ("off", "Octave:num-to-str", "local");
2168 %! assert (class (horzcat (uint16 (1), "a")), "char");
2169 
2170 %!assert (class (horzcat (uint8 (1), int64 (1))), "uint8")
2171 %!assert (class (horzcat (uint8 (1), int32 (1))), "uint8")
2172 %!assert (class (horzcat (uint8 (1), int16 (1))), "uint8")
2173 %!assert (class (horzcat (uint8 (1), int8 (1))), "uint8")
2174 %!assert (class (horzcat (uint8 (1), uint64 (1))), "uint8")
2175 %!assert (class (horzcat (uint8 (1), uint32 (1))), "uint8")
2176 %!assert (class (horzcat (uint8 (1), uint16 (1))), "uint8")
2177 %!assert (class (horzcat (uint8 (1), uint8 (1))), "uint8")
2178 %!assert (class (horzcat (uint8 (1), single (1))), "uint8")
2179 %!assert (class (horzcat (uint8 (1), double (1))), "uint8")
2180 %!assert (class (horzcat (uint8 (1), cell (1))), "cell")
2181 %!assert (class (horzcat (uint8 (1), true)), "uint8")
2182 %!test
2183 %! warning ("off", "Octave:num-to-str", "local");
2184 %! assert (class (horzcat (uint8 (1), "a")), "char");
2185 
2186 %!assert (class (horzcat (single (1), int64 (1))), "int64")
2187 %!assert (class (horzcat (single (1), int32 (1))), "int32")
2188 %!assert (class (horzcat (single (1), int16 (1))), "int16")
2189 %!assert (class (horzcat (single (1), int8 (1))), "int8")
2190 %!assert (class (horzcat (single (1), uint64 (1))), "uint64")
2191 %!assert (class (horzcat (single (1), uint32 (1))), "uint32")
2192 %!assert (class (horzcat (single (1), uint16 (1))), "uint16")
2193 %!assert (class (horzcat (single (1), uint8 (1))), "uint8")
2194 %!assert (class (horzcat (single (1), single (1))), "single")
2195 %!assert (class (horzcat (single (1), double (1))), "single")
2196 %!assert (class (horzcat (single (1), cell (1))), "cell")
2197 %!assert (class (horzcat (single (1), true)), "single")
2198 %!test
2199 %! warning ("off", "Octave:num-to-str", "local");
2200 %! assert (class (horzcat (single (1), "a")), "char");
2201 
2202 %!assert (class (horzcat (double (1), int64 (1))), "int64")
2203 %!assert (class (horzcat (double (1), int32 (1))), "int32")
2204 %!assert (class (horzcat (double (1), int16 (1))), "int16")
2205 %!assert (class (horzcat (double (1), int8 (1))), "int8")
2206 %!assert (class (horzcat (double (1), uint64 (1))), "uint64")
2207 %!assert (class (horzcat (double (1), uint32 (1))), "uint32")
2208 %!assert (class (horzcat (double (1), uint16 (1))), "uint16")
2209 %!assert (class (horzcat (double (1), uint8 (1))), "uint8")
2210 %!assert (class (horzcat (double (1), single (1))), "single")
2211 %!assert (class (horzcat (double (1), double (1))), "double")
2212 %!assert (class (horzcat (double (1), cell (1))), "cell")
2213 %!assert (class (horzcat (double (1), true)), "double")
2214 %!test
2215 %! warning ("off", "Octave:num-to-str", "local");
2216 %! assert (class (horzcat (double (1), "a")), "char");
2217 
2218 %!assert (class (horzcat (cell (1), int64 (1))), "cell")
2219 %!assert (class (horzcat (cell (1), int32 (1))), "cell")
2220 %!assert (class (horzcat (cell (1), int16 (1))), "cell")
2221 %!assert (class (horzcat (cell (1), int8 (1))), "cell")
2222 %!assert (class (horzcat (cell (1), uint64 (1))), "cell")
2223 %!assert (class (horzcat (cell (1), uint32 (1))), "cell")
2224 %!assert (class (horzcat (cell (1), uint16 (1))), "cell")
2225 %!assert (class (horzcat (cell (1), uint8 (1))), "cell")
2226 %!assert (class (horzcat (cell (1), single (1))), "cell")
2227 %!assert (class (horzcat (cell (1), double (1))), "cell")
2228 %!assert (class (horzcat (cell (1), cell (1))), "cell")
2229 %!assert (class (horzcat (cell (1), true)), "cell")
2230 %!assert (class (horzcat (cell (1), "a")), "cell")
2231 
2232 %!assert (class (horzcat (true, int64 (1))), "int64")
2233 %!assert (class (horzcat (true, int32 (1))), "int32")
2234 %!assert (class (horzcat (true, int16 (1))), "int16")
2235 %!assert (class (horzcat (true, int8 (1))), "int8")
2236 %!assert (class (horzcat (true, uint64 (1))), "uint64")
2237 %!assert (class (horzcat (true, uint32 (1))), "uint32")
2238 %!assert (class (horzcat (true, uint16 (1))), "uint16")
2239 %!assert (class (horzcat (true, uint8 (1))), "uint8")
2240 %!assert (class (horzcat (true, single (1))), "single")
2241 %!assert (class (horzcat (true, double (1))), "double")
2242 %!assert (class (horzcat (true, cell (1))), "cell")
2243 %!assert (class (horzcat (true, true)), "logical")
2244 %!test
2245 %! warning ("off", "Octave:num-to-str", "local");
2246 %! assert (class (horzcat (true, "a")), "char");
2247 
2248 %!test
2249 %! warning ("off", "Octave:num-to-str", "local");
2250 %! assert (class (horzcat ("a", int64 (1))), "char");
2251 %! assert (class (horzcat ("a", int32 (1))), "char");
2252 %! assert (class (horzcat ("a", int16 (1))), "char");
2253 %! assert (class (horzcat ("a", int8 (1))), "char");
2254 %! assert (class (horzcat ("a", int64 (1))), "char");
2255 %! assert (class (horzcat ("a", int32 (1))), "char");
2256 %! assert (class (horzcat ("a", int16 (1))), "char");
2257 %! assert (class (horzcat ("a", int8 (1))), "char");
2258 %! assert (class (horzcat ("a", single (1))), "char");
2259 %! assert (class (horzcat ("a", double (1))), "char");
2260 %! assert (class (horzcat ("a", cell (1))), "cell");
2261 %! assert (class (horzcat ("a", true)), "char");
2262 %! assert (class (horzcat ("a", "a")), "char");
2263 
2264 %!assert (class (horzcat (cell (1), struct ("foo", "bar"))), "cell")
2265 
2266 %!error horzcat (struct ("foo", "bar"), cell (1))
2267 
2268 %!test <*39041> assert (class (horzcat (cell (0), struct ())), "cell")
2269 %!test <51086> assert (class (horzcat (struct (), cell (0))), "struct")
2270 */
2271 
2272 DEFUN (vertcat, args, ,
2273  doc: /* -*- texinfo -*-
2274 @deftypefn {} {@var{A} =} vertcat (@var{array1}, @var{array2}, @dots{}, @var{arrayN})
2275 Return the vertical concatenation of N-D array objects, @var{array1},
2276 @var{array2}, @dots{}, @var{arrayN} along dimension 1.
2277 
2278 Arrays may also be concatenated vertically using the syntax for creating
2279 new matrices. For example:
2280 
2281 @example
2282 @var{A} = [ @var{array1}; @var{array2}; @dots{} ]
2283 @end example
2284 
2285 This syntax is slightly more efficient because the Octave parser can
2286 concatenate the arrays without the overhead of a function call.
2287 @seealso{cat, horzcat}
2288 @end deftypefn */)
2289 {
2290  return do_cat (args, -1, "vertcat");
2291 }
2292 
2293 /*
2294 %!test
2295 %! c = {"foo"; "bar"; "bazoloa"};
2296 %! assert (vertcat (c, "a", "bc", "def"),
2297 %! {"foo"; "bar"; "bazoloa"; "a"; "bc"; "def"});
2298 */
2299 
2300 DEFUN (cat, args, ,
2301  doc: /* -*- texinfo -*-
2302 @deftypefn {} {@var{A} =} cat (@var{dim}, @var{array1}, @var{array2}, @dots{}, @var{arrayN})
2303 Return the concatenation of N-D array objects, @var{array1}, @var{array2},
2304 @dots{}, @var{arrayN} along dimension @var{dim}.
2305 
2306 @example
2307 @group
2308 A = ones (2, 2);
2309 B = zeros (2, 2);
2310 cat (2, A, B)
2311  @result{} 1 1 0 0
2312  1 1 0 0
2313 @end group
2314 @end example
2315 
2316 Alternatively, we can concatenate @var{A} and @var{B} along the second
2317 dimension in the following way:
2318 
2319 @example
2320 @group
2321 [A, B]
2322 @end group
2323 @end example
2324 
2325 @var{dim} can be larger than the dimensions of the N-D array objects and the
2326 result will thus have @var{dim} dimensions as the following example shows:
2327 
2328 @example
2329 @group
2330 cat (4, ones (2, 2), zeros (2, 2))
2331  @result{} ans(:,:,1,1) =
2332 
2333  1 1
2334  1 1
2335 
2336  ans(:,:,1,2) =
2337 
2338  0 0
2339  0 0
2340 @end group
2341 @end example
2342 @seealso{horzcat, vertcat}
2343 @end deftypefn */)
2344 {
2345  if (args.length () == 0)
2346  print_usage ();
2347 
2348  int dim = args(0).xint_value ("cat: DIM must be an integer") - 1;
2349 
2350  if (dim < 0)
2351  error ("cat: DIM must be a valid dimension");
2352 
2353  return ovl (do_cat (args.slice (1, args.length () - 1), dim, "cat"));
2354 }
2355 
2356 /*
2357 %!function ret = __testcat (t1, t2, tr, cmplx)
2358 %! assert (cat (1, cast ([], t1), cast ([], t2)), cast ([], tr));
2359 %!
2360 %! assert (cat (1, cast (1, t1), cast (2, t2)), cast ([1; 2], tr));
2361 %! assert (cat (1, cast (1, t1), cast ([2; 3], t2)), cast ([1; 2; 3], tr));
2362 %! assert (cat (1, cast ([1; 2], t1), cast (3, t2)), cast ([1; 2; 3], tr));
2363 %! assert (cat (1, cast ([1; 2], t1), cast ([3; 4], t2)),
2364 %! cast ([1; 2; 3; 4], tr));
2365 %! assert (cat (2, cast (1, t1), cast (2, t2)), cast ([1, 2], tr));
2366 %! assert (cat (2, cast (1, t1), cast ([2, 3], t2)), cast ([1, 2, 3], tr));
2367 %! assert (cat (2, cast ([1, 2], t1), cast (3, t2)), cast ([1, 2, 3], tr));
2368 %! assert (cat (2, cast ([1, 2], t1), cast ([3, 4], t2)),
2369 %! cast ([1, 2, 3, 4], tr));
2370 %!
2371 %! assert ([cast(1, t1); cast(2, t2)], cast ([1; 2], tr));
2372 %! assert ([cast(1, t1); cast([2; 3], t2)], cast ([1; 2; 3], tr));
2373 %! assert ([cast([1; 2], t1); cast(3, t2)], cast ([1; 2; 3], tr));
2374 %! assert ([cast([1; 2], t1); cast([3; 4], t2)], cast ([1; 2; 3; 4], tr));
2375 %! assert ([cast(1, t1), cast(2, t2)], cast ([1, 2], tr));
2376 %! assert ([cast(1, t1), cast([2, 3], t2)], cast ([1, 2, 3], tr));
2377 %! assert ([cast([1, 2], t1), cast(3, t2)], cast ([1, 2, 3], tr));
2378 %! assert ([cast([1, 2], t1), cast([3, 4], t2)], cast ([1, 2, 3, 4], tr));
2379 %!
2380 %! if (nargin == 3 || cmplx)
2381 %! assert (cat (1, cast (1i, t1), cast (2, t2)), cast ([1i; 2], tr));
2382 %! assert (cat (1, cast (1i, t1), cast ([2; 3], t2)), cast ([1i; 2; 3], tr));
2383 %! assert (cat (1, cast ([1i; 2], t1), cast (3, t2)), cast ([1i; 2; 3], tr));
2384 %! assert (cat (1, cast ([1i; 2], t1), cast ([3; 4], t2)),
2385 %! cast ([1i; 2; 3; 4], tr));
2386 %! assert (cat (2, cast (1i, t1), cast (2, t2)), cast ([1i, 2], tr));
2387 %! assert (cat (2, cast (1i, t1), cast ([2, 3], t2)), cast ([1i, 2, 3], tr));
2388 %! assert (cat (2, cast ([1i, 2], t1), cast (3, t2)), cast ([1i, 2, 3], tr));
2389 %! assert (cat (2, cast ([1i, 2], t1), cast ([3, 4], t2)),
2390 %! cast ([1i, 2, 3, 4], tr));
2391 %! assert ([cast(1i, t1); cast(2, t2)], cast ([1i; 2], tr));
2392 %! assert ([cast(1i, t1); cast([2; 3], t2)], cast ([1i; 2; 3], tr));
2393 %! assert ([cast([1i; 2], t1); cast(3, t2)], cast ([1i; 2; 3], tr));
2394 %! assert ([cast([1i; 2], t1); cast([3; 4], t2)], cast ([1i; 2; 3; 4], tr));
2395 %! assert ([cast(1i, t1), cast(2, t2)], cast ([1i, 2], tr));
2396 %! assert ([cast(1i, t1), cast([2, 3], t2)], cast ([1i, 2, 3], tr));
2397 %! assert ([cast([1i, 2], t1), cast(3, t2)], cast ([1i, 2, 3], tr));
2398 %! assert ([cast([1i, 2], t1), cast([3, 4], t2)], cast ([1i, 2, 3, 4], tr));
2399 %!
2400 %! assert (cat (1, cast (1, t1), cast (2i, t2)), cast ([1; 2i], tr));
2401 %! assert (cat (1, cast (1, t1), cast ([2i; 3], t2)), cast ([1; 2i; 3], tr));
2402 %! assert (cat (1, cast ([1; 2], t1), cast (3i, t2)), cast ([1; 2; 3i], tr));
2403 %! assert (cat (1, cast ([1; 2], t1), cast ([3i; 4], t2)),
2404 %! cast ([1; 2; 3i; 4], tr));
2405 %! assert (cat (2, cast (1, t1), cast (2i, t2)), cast ([1, 2i], tr));
2406 %! assert (cat (2, cast (1, t1), cast ([2i, 3], t2)), cast ([1, 2i, 3], tr));
2407 %! assert (cat (2, cast ([1, 2], t1), cast (3i, t2)), cast ([1, 2, 3i], tr));
2408 %! assert (cat (2, cast ([1, 2], t1), cast ([3i, 4], t2)),
2409 %! cast ([1, 2, 3i, 4], tr));
2410 %! assert ([cast(1, t1); cast(2i, t2)], cast ([1; 2i], tr));
2411 %! assert ([cast(1, t1); cast([2i; 3], t2)], cast ([1; 2i; 3], tr));
2412 %! assert ([cast([1; 2], t1); cast(3i, t2)], cast ([1; 2; 3i], tr));
2413 %! assert ([cast([1; 2], t1); cast([3i; 4], t2)], cast ([1; 2; 3i; 4], tr));
2414 %! assert ([cast(1, t1), cast(2i, t2)], cast ([1, 2i], tr));
2415 %! assert ([cast(1, t1), cast([2i, 3], t2)], cast ([1, 2i, 3], tr));
2416 %! assert ([cast([1, 2], t1), cast(3i, t2)], cast ([1, 2, 3i], tr));
2417 %! assert ([cast([1, 2], t1), cast([3i, 4], t2)], cast ([1, 2, 3i, 4], tr));
2418 %!
2419 %! assert (cat (1, cast (1i, t1), cast (2i, t2)), cast ([1i; 2i], tr));
2420 %! assert (cat (1, cast (1i, t1), cast ([2i; 3], t2)),
2421 %! cast ([1i; 2i; 3], tr));
2422 %! assert (cat (1, cast ([1i; 2], t1), cast (3i, t2)),
2423 %! cast ([1i; 2; 3i], tr));
2424 %! assert (cat (1, cast ([1i; 2], t1), cast ([3i; 4], t2)),
2425 %! cast ([1i; 2; 3i; 4], tr));
2426 %! assert (cat (2, cast (1i, t1), cast (2i, t2)), cast ([1i, 2i], tr));
2427 %! assert (cat (2, cast (1i, t1), cast ([2i, 3], t2)),
2428 %! cast ([1i, 2i, 3], tr));
2429 %! assert (cat (2, cast ([1i, 2], t1), cast (3i, t2)),
2430 %! cast ([1i, 2, 3i], tr));
2431 %! assert (cat (2, cast ([1i, 2], t1), cast ([3i, 4], t2)),
2432 %! cast ([1i, 2, 3i, 4], tr));
2433 %!
2434 %! assert ([cast(1i, t1); cast(2i, t2)], cast ([1i; 2i], tr));
2435 %! assert ([cast(1i, t1); cast([2i; 3], t2)], cast ([1i; 2i; 3], tr));
2436 %! assert ([cast([1i; 2], t1); cast(3i, t2)], cast ([1i; 2; 3i], tr));
2437 %! assert ([cast([1i; 2], t1); cast([3i; 4], t2)],
2438 %! cast ([1i; 2; 3i; 4], tr));
2439 %! assert ([cast(1i, t1), cast(2i, t2)], cast ([1i, 2i], tr));
2440 %! assert ([cast(1i, t1), cast([2i, 3], t2)], cast ([1i, 2i, 3], tr));
2441 %! assert ([cast([1i, 2], t1), cast(3i, t2)], cast ([1i, 2, 3i], tr));
2442 %! assert ([cast([1i, 2], t1), cast([3i, 4], t2)],
2443 %! cast ([1i, 2, 3i, 4], tr));
2444 %! endif
2445 %! ret = true;
2446 %!endfunction
2447 
2448 %!assert (__testcat ("double", "double", "double"))
2449 %!assert (__testcat ("single", "double", "single"))
2450 %!assert (__testcat ("double", "single", "single"))
2451 %!assert (__testcat ("single", "single", "single"))
2452 
2453 %!assert (__testcat ("double", "int8", "int8", false))
2454 %!assert (__testcat ("int8", "double", "int8", false))
2455 %!assert (__testcat ("single", "int8", "int8", false))
2456 %!assert (__testcat ("int8", "single", "int8", false))
2457 %!assert (__testcat ("int8", "int8", "int8", false))
2458 %!assert (__testcat ("double", "int16", "int16", false))
2459 %!assert (__testcat ("int16", "double", "int16", false))
2460 %!assert (__testcat ("single", "int16", "int16", false))
2461 %!assert (__testcat ("int16", "single", "int16", false))
2462 %!assert (__testcat ("int16", "int16", "int16", false))
2463 %!assert (__testcat ("double", "int32", "int32", false))
2464 %!assert (__testcat ("int32", "double", "int32", false))
2465 %!assert (__testcat ("single", "int32", "int32", false))
2466 %!assert (__testcat ("int32", "single", "int32", false))
2467 %!assert (__testcat ("int32", "int32", "int32", false))
2468 %!assert (__testcat ("double", "int64", "int64", false))
2469 %!assert (__testcat ("int64", "double", "int64", false))
2470 %!assert (__testcat ("single", "int64", "int64", false))
2471 %!assert (__testcat ("int64", "single", "int64", false))
2472 %!assert (__testcat ("int64", "int64", "int64", false))
2473 
2474 %!assert (__testcat ("double", "uint8", "uint8", false))
2475 %!assert (__testcat ("uint8", "double", "uint8", false))
2476 %!assert (__testcat ("single", "uint8", "uint8", false))
2477 %!assert (__testcat ("uint8", "single", "uint8", false))
2478 %!assert (__testcat ("uint8", "uint8", "uint8", false))
2479 %!assert (__testcat ("double", "uint16", "uint16", false))
2480 %!assert (__testcat ("uint16", "double", "uint16", false))
2481 %!assert (__testcat ("single", "uint16", "uint16", false))
2482 %!assert (__testcat ("uint16", "single", "uint16", false))
2483 %!assert (__testcat ("uint16", "uint16", "uint16", false))
2484 %!assert (__testcat ("double", "uint32", "uint32", false))
2485 %!assert (__testcat ("uint32", "double", "uint32", false))
2486 %!assert (__testcat ("single", "uint32", "uint32", false))
2487 %!assert (__testcat ("uint32", "single", "uint32", false))
2488 %!assert (__testcat ("uint32", "uint32", "uint32", false))
2489 %!assert (__testcat ("double", "uint64", "uint64", false))
2490 %!assert (__testcat ("uint64", "double", "uint64", false))
2491 %!assert (__testcat ("single", "uint64", "uint64", false))
2492 %!assert (__testcat ("uint64", "single", "uint64", false))
2493 %!assert (__testcat ("uint64", "uint64", "uint64", false))
2494 
2495 %!assert (cat (3, [], [1,2;3,4]), [1,2;3,4])
2496 %!assert (cat (3, [1,2;3,4], []), [1,2;3,4])
2497 %!assert (cat (3, [], [1,2;3,4], []), [1,2;3,4])
2498 %!assert (cat (3, [], [], []), zeros (0, 0, 3))
2499 
2500 %!assert (cat (3, [], [], 1, 2), cat (3, 1, 2))
2501 %!assert (cat (3, [], [], [1,2;3,4]), [1,2;3,4])
2502 %!assert (cat (4, [], [], [1,2;3,4]), [1,2;3,4])
2503 
2504 %!assert ([zeros(3,2,2); ones(1,2,2)], repmat ([0;0;0;1],[1,2,2]))
2505 %!assert ([zeros(3,2,2); ones(1,2,2)], vertcat (zeros (3,2,2), ones (1,2,2)))
2506 
2507 %!test <*49759>
2508 %! A = [];
2509 %! B = {1; 2};
2510 %! assert (cat (1, A, B), {1; 2});
2511 %! assert (cat (2, A, B), {1; 2});
2512 
2513 %!error <dimension mismatch> cat (3, cat (3, [], []), [1,2;3,4])
2514 %!error <dimension mismatch> cat (3, zeros (0, 0, 2), [1,2;3,4])
2515 */
2516 
2517 static octave_value
2518 do_permute (const octave_value_list& args, bool inv)
2519 {
2520  if (args.length () != 2 || args(1).length () < args(1).ndims ())
2521  print_usage ();
2522 
2523  Array<int> vec = args(1).int_vector_value ();
2524 
2525  // FIXME: maybe we should create an idx_vector object here
2526  // and pass that to permute?
2527  int n = vec.numel ();
2528  for (int i = 0; i < n; i++)
2529  vec(i)--;
2530 
2531  return octave_value (args(0).permute (vec, inv));
2532 }
2533 
2534 DEFUN (permute, args, ,
2535  doc: /* -*- texinfo -*-
2536 @deftypefn {} {@var{B} =} permute (@var{A}, @var{perm})
2537 Return the generalized transpose for an N-D array object @var{A}.
2538 
2539 The permutation vector @var{perm} must contain the elements
2540 @w{@code{1:ndims (A)}} (in any order, but each element must appear only
2541 once). The @var{N}th dimension of @var{A} gets remapped to dimension
2542 @code{@var{PERM}(@var{N})}. For example:
2543 
2544 @example
2545 @group
2546 @var{x} = zeros ([2, 3, 5, 7]);
2547 size (@var{x})
2548  @result{} 2 3 5 7
2549 
2550 size (permute (@var{x}, [2, 1, 3, 4]))
2551  @result{} 3 2 5 7
2552 
2553 size (permute (@var{x}, [1, 3, 4, 2]))
2554  @result{} 2 5 7 3
2555 
2556 ## The identity permutation
2557 size (permute (@var{x}, [1, 2, 3, 4]))
2558  @result{} 2 3 5 7
2559 @end group
2560 @end example
2561 @seealso{ipermute}
2562 @end deftypefn */)
2563 {
2564  return do_permute (args, false);
2565 }
2566 
2567 DEFUN (ipermute, args, ,
2568  doc: /* -*- texinfo -*-
2569 @deftypefn {} {@var{A} =} ipermute (@var{B}, @var{iperm})
2570 The inverse of the @code{permute} function.
2571 
2572 The expression
2573 
2574 @example
2575 ipermute (permute (A, perm), perm)
2576 @end example
2577 
2578 @noindent
2579 returns the original array @var{A}.
2580 @seealso{permute}
2581 @end deftypefn */)
2582 {
2583  return do_permute (args, true);
2584 }
2585 
2586 DEFUN (length, args, ,
2587  doc: /* -*- texinfo -*-
2588 @deftypefn {} {@var{n} =} length (@var{A})
2589 Return the length of the object @var{A}.
2590 
2591 The length is 0 for empty objects, 1 for scalars, and the number of elements
2592 for vectors. For matrix or N-dimensional objects, the length is the number
2593 of elements along the largest dimension
2594 (equivalent to @w{@code{max (size (@var{A}))}}).
2595 @seealso{numel, size}
2596 @end deftypefn */)
2597 {
2598  if (args.length () != 1)
2599  print_usage ();
2600 
2601  return ovl (args(0).length ());
2602 }
2603 
2604 DEFUN (ndims, args, ,
2605  doc: /* -*- texinfo -*-
2606 @deftypefn {} {@var{n} =} ndims (@var{A})
2607 Return the number of dimensions of @var{A}.
2608 
2609 For any array, the result will always be greater than or equal to 2.
2610 Trailing singleton dimensions are not counted, i.e., trailing dimensions @var{d}
2611 greater than 2 for which @code{size (@var{A}, @var{d}) = 1}.
2612 
2613 @example
2614 @group
2615 ndims (ones (4, 1, 2, 1))
2616  @result{} 3
2617 @end group
2618 @end example
2619 @seealso{size}
2620 @end deftypefn */)
2621 {
2622  if (args.length () != 1)
2623  print_usage ();
2624 
2625  // This function *must* use size() to determine the desired values to be
2626  // compatible with Matlab and to allow user-defined class overloading.
2627  Matrix sz = octave_value (args(0)).size ();
2628 
2629  octave_idx_type ndims = sz.numel ();
2630 
2631  // Don't count trailing ones. Trailing zeros are *not* singleton dimension.
2632  while ((ndims > 2) && (sz(ndims - 1) == 1))
2633  ndims--;
2634 
2635  return ovl (ndims);
2636 }
2637 
2638 /*
2639 %!assert (ndims (1:5), 2)
2640 %!assert (ndims (ones (4, 1, 2, 1)), 3)
2641 %!assert (ndims (ones (4, 1, 2, 0)), 4)
2642 */
2643 
2644 DEFUN (numel, args, ,
2645  doc: /* -*- texinfo -*-
2646 @deftypefn {} {@var{n} =} numel (@var{A})
2647 @deftypefnx {} {@var{n} =} numel (@var{A}, @var{idx1}, @var{idx2}, @dots{})
2648 Return the number of elements in the object @var{A}.
2649 
2650 Optionally, if indices @var{idx1}, @var{idx2}, @dots{} are supplied,
2651 return the number of elements that would result from the indexing
2652 
2653 @example
2654 @var{A}(@var{idx1}, @var{idx2}, @dots{})
2655 @end example
2656 
2657 Note that the indices do not have to be scalar numbers. For example,
2658 
2659 @example
2660 @group
2661 @var{a} = 1;
2662 @var{b} = ones (2, 3);
2663 numel (@var{a}, @var{b})
2664 @end group
2665 @end example
2666 
2667 @noindent
2668 will return 6, as this is the number of ways to index with @var{b}.
2669 Or the index could be the string @qcode{":"} which represents the colon
2670 operator. For example,
2671 
2672 @example
2673 @group
2674 @var{A} = ones (5, 3);
2675 numel (@var{A}, 2, ":")
2676 @end group
2677 @end example
2678 
2679 @noindent
2680 will return 3 as the second row has three column entries.
2681 
2682 This method is also called when an object appears as lvalue with cs-list
2683 indexing, i.e., @code{object@{@dots{}@}} or @code{object(@dots{}).field}.
2684 @seealso{size, length, ndims}
2685 @end deftypefn */)
2686 {
2687  int nargin = args.length ();
2688 
2689  if (nargin == 0)
2690  print_usage ();
2691 
2692  octave_value retval;
2693 
2694  if (nargin == 1)
2695  retval = args(0).numel ();
2696  else if (nargin > 1)
2697  {
2698  // Don't use numel (const octave_value_list&) here as that corresponds to
2699  // an overloaded call, not to builtin!
2700  retval = dims_to_numel (args(0).dims (), args.slice (1, nargin-1));
2701  }
2702 
2703  return retval;
2704 }
2705 
2706 DEFUN (size, args, nargout,
2707  doc: /* -*- texinfo -*-
2708 @deftypefn {} {@var{sz} =} size (@var{A})
2709 @deftypefnx {} {@var{dim_sz} =} size (@var{A}, @var{dim})
2710 @deftypefnx {} {@var{dim_sz} =} size (@var{A}, @var{d1}, @var{d2}, @dots{})
2711 @deftypefnx {} {[@var{rows}, @var{cols}, @dots{}, @var{dim_N_sz}] =} size (@dots{})
2712 Return a row vector with the size (number of elements) of each dimension for
2713 the object @var{A}.
2714 
2715 When given a second argument, @var{dim}, return the size of the corresponding
2716 dimension. If @var{dim} is a vector, return each of the corresponding
2717 dimensions. Multiple dimensions may also be specified as separate arguments.
2718 
2719 With a single output argument, @code{size} returns a row vector. When called
2720 with multiple output arguments, @code{size} returns the size of dimension N
2721 in the Nth argument. The number of rows, dimension 1, is returned in the
2722 first argument, the number of columns, dimension 2, is returned in the
2723 second argument, etc. If there are more dimensions in @var{A} than there are
2724 output arguments, @code{size} returns the total number of elements in the
2725 remaining dimensions in the final output argument. If the requested dimension
2726 @var{dim} is greater than the number of dimensions in @var{A}, @code{size}
2727 returns 1 (not 0).
2728 
2729 Example 1: single row vector output
2730 
2731 @example
2732 @group
2733 size ([1, 2; 3, 4; 5, 6])
2734  @result{} [ 3, 2 ]
2735 @end group
2736 @end example
2737 
2738 Example 2: number of elements in 2nd dimension (columns)
2739 
2740 @example
2741 @group
2742 size ([1, 2; 3, 4; 5, 6], 2)
2743  @result{} 2
2744 @end group
2745 @end example
2746 
2747 Example 3: number of output arguments == number of dimensions
2748 
2749 @example
2750 @group
2751 [nr, nc] = size ([1, 2; 3, 4; 5, 6])
2752  @result{} nr = 3
2753  @result{} nc = 2
2754 @end group
2755 @end example
2756 
2757 Example 4: number of output arguments < number of dimensions
2758 
2759 @example
2760 @group
2761 [nr, remainder] = size (ones (2, 3, 4, 5))
2762  @result{} nr = 2
2763  @result{} remainder = 60
2764 @end group
2765 @end example
2766 
2767 Example 5: number of elements in dimension > number of actual dimensions
2768 
2769 @example
2770 @group
2771 sz4 = size (ones (2, 3), 4)
2772  @result{} sz4 = 1
2773 @end group
2774 @end example
2775 
2776 @seealso{numel, ndims, length, rows, columns, size_equal, common_size}
2777 @end deftypefn */)
2778 {
2779  int nargin = args.length ();
2780 
2781  if (nargin == 0)
2782  print_usage ();
2783 
2784  // For compatibility with Matlab, size returns dimensions as doubles.
2785 
2786  Matrix m;
2787 
2788  dim_vector dimensions = args(0).dims ();
2789  int ndims = dimensions.ndims ();
2790 
2791  if (nargin == 1)
2792  {
2793  if (nargout > 1)
2794  {
2795  dimensions = dimensions.redim (nargout);
2796  ndims = dimensions.ndims ();
2797  }
2798 
2799  m.resize (1, ndims);
2800 
2801  for (octave_idx_type i = 0; i < ndims; i++)
2802  m(i) = dimensions(i);
2803  }
2804  else
2805  {
2806  Array<octave_idx_type> query_dims;
2807 
2808  if (nargin > 2)
2809  {
2810  query_dims.resize (dim_vector (1, nargin-1));
2811 
2812  for (octave_idx_type i = 0; i < nargin-1; i++)
2813  query_dims(i) = args(i+1).idx_type_value (true);
2814  }
2815  else
2816  query_dims = args(1).octave_idx_type_vector_value (true);
2817 
2818  if (nargout > 1 && nargout != query_dims.numel ())
2819  error ("size: nargout > 1 but does not match number of requested dimensions");
2820 
2821  octave_idx_type nidx = query_dims.numel ();
2822 
2823  m.resize (1, nidx);
2824 
2825  for (octave_idx_type i = 0; i < nidx; i++)
2826  {
2827  octave_idx_type nd = query_dims.xelem (i);
2828 
2829  if (nd < 1)
2830  error ("size: requested dimension DIM (= %"
2831  OCTAVE_IDX_TYPE_FORMAT ") out of range", nd);
2832 
2833  m(i) = nd <= ndims ? dimensions (nd-1) : 1;
2834  }
2835  }
2836 
2837  if (nargout > 1)
2838  {
2839  octave_value_list retval (nargout);
2840 
2841  for (octave_idx_type i = 0; i < nargout; i++)
2842  retval(i) = m(i);
2843 
2844  return retval;
2845  }
2846 
2847  return ovl (m);
2848 }
2849 
2850 /*
2851 ## Plain call
2852 
2853 %!assert (size ([1, 2; 3, 4; 5, 6]), [3, 2])
2854 
2855 %!test
2856 %! [nr, nc] = size ([1, 2; 3, 4; 5, 6]);
2857 %! assert (nr, 3)
2858 %! assert (nc, 2)
2859 
2860 %!test
2861 %! [nr, remainder] = size (ones (2, 3, 4, 5));
2862 %! assert (nr, 2)
2863 %! assert (remainder, 60)
2864 
2865 ## Call for single existing dimension
2866 
2867 %!assert (size ([1, 2; 3, 4; 5, 6], 1), 3)
2868 %!assert (size ([1, 2; 3, 4; 5, 6], 2), 2)
2869 
2870 ## Call for single non-existing dimension
2871 
2872 %!assert (size ([1, 2; 3, 4; 5, 6], 3), 1)
2873 %!assert (size ([1, 2; 3, 4; 5, 6], 4), 1)
2874 
2875 ## Call for more than existing dimensions
2876 
2877 %!test
2878 %! [nr, nc, e1, e2] = size ([1, 2; 3, 4; 5, 6]);
2879 %! assert (nr, 3)
2880 %! assert (nc, 2)
2881 %! assert (e1, 1)
2882 %! assert (e2, 1)
2883 
2884 ## Call for two arbitrary dimensions
2885 
2886 %!test
2887 %! dim = [3, 2, 1, 1, 1];
2888 %! for i = 1:5
2889 %! for j = 1:5
2890 %! assert (size ([1, 2; 3, 4; 5, 6], i, j), [dim(i), dim(j)])
2891 %! assert (size ([1, 2; 3, 4; 5, 6], [i, j]), [dim(i), dim(j)])
2892 %! [a, b] = size ([1, 2; 3, 4; 5, 6], i, j);
2893 %! assert (a, dim(i));
2894 %! assert (b, dim(j));
2895 %! [a, b] = size ([1, 2; 3, 4; 5, 6], [i, j]);
2896 %! assert (a, dim(i));
2897 %! assert (b, dim(j));
2898 %! endfor
2899 %! endfor
2900 
2901 ## Call for three arbitrary dimensions
2902 
2903 %!test
2904 %! dim = [3, 2, 1, 1, 1];
2905 %! for i = 1:5
2906 %! for j = 1:5
2907 %! for k = 1:5
2908 %! assert (size ([1, 2; 3, 4; 5, 6], i, j, k), [dim(i), dim(j), dim(k)])
2909 %! assert (size ([1, 2; 3, 4; 5, 6], [i, j, k]), [dim(i), dim(j), dim(k)])
2910 %! [a, b, c] = size ([1, 2; 3, 4; 5, 6], i, j, k);
2911 %! assert (a, dim(i));
2912 %! assert (b, dim(j));
2913 %! assert (c, dim(k));
2914 %! [a, b, c] = size ([1, 2; 3, 4; 5, 6], [i, j, k]);
2915 %! assert (a, dim(i));
2916 %! assert (b, dim(j));
2917 %! assert (c, dim(k));
2918 %! endfor
2919 %! endfor
2920 %! endfor
2921 
2922 %!error <does not match number of requested dimensions>
2923 %! [a, b, c] = size ([1, 2; 3, 4; 5, 6], 1:4)
2924 */
2925 
2926 DEFUN (size_equal, args, ,
2927  doc: /* -*- texinfo -*-
2928 @deftypefn {} {@var{TF} =} size_equal (@var{A}, @var{B})
2929 @deftypefnx {} {@var{TF} =} size_equal (@var{A}, @var{B}, @dots{})
2930 Return true if the dimensions of all arguments agree.
2931 
2932 Trailing singleton dimensions are ignored. When called with a single argument,
2933 or no argument, @code{size_equal} returns true.
2934 @seealso{size, numel, ndims, common_size}
2935 @end deftypefn */)
2936 {
2937  int nargin = args.length ();
2938 
2939  if (nargin >= 1)
2940  {
2941  dim_vector a_dims = args(0).dims ();
2942 
2943  for (int i = 1; i < nargin; ++i)
2944  {
2945  dim_vector b_dims = args(i).dims ();
2946 
2947  if (a_dims != b_dims)
2948  return ovl (false);
2949  }
2950  }
2951 
2952  return ovl (true);
2953 }
2954 
2955 DEFUN (nnz, args, ,
2956  doc: /* -*- texinfo -*-
2957 @deftypefn {} {@var{n} =} nnz (@var{A})
2958 Return the number of nonzero elements in @var{A}.
2959 @seealso{nzmax, nonzeros, find}
2960 @end deftypefn */)
2961 {
2962  if (args.length () != 1)
2963  print_usage ();
2964 
2965  return ovl (args(0).nnz ());
2966 }
2967 
2968 /*
2969 %!assert (nnz (1:5), 5)
2970 %!assert (nnz (-5:-1), 5)
2971 %!assert (nnz (0:5), 5)
2972 %!assert (nnz (-5:0), 5)
2973 %!assert (nnz (-5:5), 10)
2974 %!assert (nnz (-2:1:2), 4)
2975 %!assert (nnz (-2+eps (2):1:2), 5)
2976 %!assert (nnz (-2-eps (2):1:2), 5)
2977 %!assert (nnz (-2:1+eps (1):2), 5)
2978 %!assert (nnz (-2:1-eps (1):2), 5)
2979 %!assert (nnz ([1:5] * 0), 0)
2980 %!assert (nnz ([-5:-1] * 0), 0)
2981 %!assert (nnz ([-1:1] * 0), 0)
2982 */
2983 
2984 DEFUN (nzmax, args, ,
2985  doc: /* -*- texinfo -*-
2986 @deftypefn {} {@var{n} =} nzmax (@var{SM})
2987 Return the amount of storage allocated to the sparse matrix @var{SM}.
2988 
2989 Programming Note: Octave tends to crop unused memory at the first opportunity
2990 for sparse objects. Thus, in general the value of @code{nzmax} will be the
2991 same as @code{nnz}, except for some cases of user-created sparse objects.
2992 
2993 Also, note that Octave always reserves storage for at least one value. Thus,
2994 for empty matrices @code{nnz} will report 0, but @code{nzmax} will report 1.
2995 @seealso{nnz, spalloc, sparse}
2996 @end deftypefn */)
2997 {
2998  if (args.length () != 1)
2999  print_usage ();
3000 
3001  return ovl (args(0).nzmax ());
3002 }
3003 
3004 DEFUN (rows, args, ,
3005  doc: /* -*- texinfo -*-
3006 @deftypefn {} {@var{nr} =} rows (@var{A})
3007 Return the number of rows of @var{A}.
3008 
3009 This is equivalent to @code{size (@var{A}, 1)}.
3010 @seealso{columns, size, length, numel, isscalar, isvector, ismatrix}
3011 @end deftypefn */)
3012 {
3013  if (args.length () != 1)
3014  print_usage ();
3015 
3016  // This function *must* use size() to determine the desired values to
3017  // allow user-defined class overloading.
3018 
3019  return ovl ((octave_value (args(0)).size ())(0));
3020 }
3021 
3022 /*
3023 %!assert (rows (ones (2,5)), 2)
3024 %!assert (rows (ones (5,2)), 5)
3025 %!assert (rows (ones (5,4,3,2)), 5)
3026 %!assert (rows (ones (3,4,5,2)), 3)
3027 
3028 %!assert (rows (cell (2,5)), 2)
3029 %!assert (rows (cell (5,2)), 5)
3030 %!assert (rows (cell (5,4,3,2)), 5)
3031 %!assert (rows (cell (3,4,5,2)), 3)
3032 
3033 %!test
3034 %! x(2,5,3).a = 1;
3035 %! assert (rows (x), 2);
3036 %! y(5,4,3).b = 2;
3037 %! assert (rows (y), 5);
3038 
3039 %!assert (rows ("Hello World"), 1)
3040 
3041 %!assert (rows ([]), 0)
3042 %!assert (rows (zeros (2,0)), 2)
3043 
3044 ## Test input validation
3045 %!error rows ()
3046 %!error rows (1,2)
3047 */
3048 
3049 DEFUN (columns, args, ,
3050  doc: /* -*- texinfo -*-
3051 @deftypefn {} {@var{nc} =} columns (@var{A})
3052 Return the number of columns of @var{A}.
3053 
3054 This is equivalent to @code{size (@var{A}, 2)}.
3055 @seealso{rows, size, length, numel, isscalar, isvector, ismatrix}
3056 @end deftypefn */)
3057 {
3058  if (args.length () != 1)
3059  print_usage ();
3060 
3061  // This function *must* use size() to determine the desired values to
3062  // allow user-defined class overloading.
3063 
3064  return ovl ((octave_value (args(0)).size ())(1));
3065 }
3066 
3067 DEFUN (sum, args, ,
3068  doc: /* -*- texinfo -*-
3069 @deftypefn {} {@var{y} =} sum (@var{x})
3070 @deftypefnx {} {@var{y} =} sum (@var{x}, @var{dim})
3071 @deftypefnx {} {@var{y} =} sum (@dots{}, "native")
3072 @deftypefnx {} {@var{y} =} sum (@dots{}, "double")
3073 @deftypefnx {} {@var{y} =} sum (@dots{}, "extra")
3074 Sum of elements along dimension @var{dim}.
3075 
3076 If @var{dim} is omitted, it defaults to the first non-singleton dimension.
3077 
3078 The optional @qcode{"type"} input determines the class of the variable
3079 used for calculations. By default, operations on floating point inputs (double
3080 or single) are performed in their native data type, while operations on
3081 integer, logical, and character data types are performed using doubles. If the
3082 argument @qcode{"native"} is given, then the operation is performed in the same
3083 type as the original argument.
3084 
3085 For example:
3086 
3087 @example
3088 @group
3089 sum ([true, true])
3090  @result{} 2
3091 sum ([true, true], "native")
3092  @result{} true
3093 @end group
3094 @end example
3095 
3096 If @qcode{"double"} is given the sum is performed in double precision even for
3097 single precision inputs.
3098 
3099 For double precision inputs, the @qcode{"extra"} option will use a more
3100 accurate algorithm than straightforward summation. For single precision
3101 inputs, @qcode{"extra"} is the same as @qcode{"double"}. For all other data
3102 type @qcode{"extra"} has no effect.
3103 @seealso{cumsum, sumsq, prod}
3104 @end deftypefn */)
3105 {
3106  int nargin = args.length ();
3107 
3108  bool isnative = false;
3109  bool isdouble = false;
3110  bool isextra = false;
3111 
3112  if (nargin > 1 && args(nargin - 1).is_string ())
3113  {
3114  std::string str = args(nargin - 1).string_value ();
3115 
3116  if (str == "native")
3117  isnative = true;
3118  else if (str == "double")
3119  isdouble = true;
3120  else if (str == "extra")
3121  isextra = true;
3122  else
3123  error ("sum: unrecognized type argument '%s'", str.c_str ());
3124 
3125  nargin--;
3126  }
3127 
3128  if (nargin < 1 || nargin > 2)
3129  print_usage ();
3130 
3131  int dim = -1;
3132  if (nargin == 2)
3133  {
3134  dim = args(1).int_value () - 1;
3135  if (dim < 0)
3136  error ("sum: invalid dimension DIM = %d", dim + 1);
3137  }
3138 
3139  octave_value retval;
3140  octave_value arg = args(0);
3141 
3142  switch (arg.builtin_type ())
3143  {
3144  case btyp_double:
3145  if (arg.issparse ())
3146  {
3147  if (isextra)
3148  warning ("sum: 'extra' not yet implemented for sparse matrices");
3149  retval = arg.sparse_matrix_value ().sum (dim);
3150  }
3151  else if (isextra)
3152  retval = arg.array_value ().xsum (dim);
3153  else
3154  retval = arg.array_value ().sum (dim);
3155  break;
3156 
3157  case btyp_complex:
3158  if (arg.issparse ())
3159  {
3160  if (isextra)
3161  warning ("sum: 'extra' not yet implemented for sparse matrices");
3162  retval = arg.sparse_complex_matrix_value ().sum (dim);
3163  }
3164  else if (isextra)
3165  retval = arg.complex_array_value ().xsum (dim);
3166  else
3167  retval = arg.complex_array_value ().sum (dim);
3168  break;
3169 
3170  case btyp_float:
3171  if (isdouble || isextra)
3172  retval = arg.float_array_value ().dsum (dim);
3173  else
3174  retval = arg.float_array_value ().sum (dim);
3175  break;
3176 
3177  case btyp_float_complex:
3178  if (isdouble || isextra)
3179  retval = arg.float_complex_array_value ().dsum (dim);
3180  else
3181  retval = arg.float_complex_array_value ().sum (dim);
3182  break;
3183 
3184 #define MAKE_INT_BRANCH(X) \
3185  case btyp_ ## X: \
3186  if (isnative) \
3187  retval = arg.X ## _array_value ().sum (dim); \
3188  else \
3189  retval = arg.X ## _array_value ().dsum (dim); \
3190  break;
3191 
3192  MAKE_INT_BRANCH (int8);
3193  MAKE_INT_BRANCH (int16);
3194  MAKE_INT_BRANCH (int32);
3195  MAKE_INT_BRANCH (int64);
3196  MAKE_INT_BRANCH (uint8);
3197  MAKE_INT_BRANCH (uint16);
3198  MAKE_INT_BRANCH (uint32);
3199  MAKE_INT_BRANCH (uint64);
3200 
3201 #undef MAKE_INT_BRANCH
3202 
3203  // GAGME: Accursed Matlab compatibility...
3204  case btyp_char:
3205  if (isextra)
3206  retval = arg.array_value (true).xsum (dim);
3207  else
3208  retval = arg.array_value (true).sum (dim);
3209  break;
3210 
3211  case btyp_bool:
3212  if (arg.issparse ())
3213  {
3214  if (isnative)
3215  retval = arg.sparse_bool_matrix_value ().any (dim);
3216  else
3217  retval = arg.sparse_bool_matrix_value ().sum (dim);
3218  }
3219  else if (isnative)
3220  retval = arg.bool_array_value ().any (dim);
3221  else
3222  retval = arg.array_value ().sum (dim);
3223  break;
3224 
3225  default:
3226  err_wrong_type_arg ("sum", arg);
3227  }
3228 
3229  return retval;
3230 }
3231 
3232 /*
3233 %!assert (sum ([1, 2, 3]), 6)
3234 %!assert (sum ([-1; -2; -3]), -6)
3235 %!assert (sum ([i, 2+i, -3+2i, 4]), 3+4i)
3236 %!assert (sum ([1, 2, 3; i, 2i, 3i; 1+i, 2+2i, 3+3i]), [2+2i, 4+4i, 6+6i])
3237 
3238 %!assert (sum (single ([1, 2, 3])), single (6))
3239 %!assert (sum (single ([-1; -2; -3])), single (-6))
3240 %!assert (sum (single ([i, 2+i, -3+2i, 4])), single (3+4i))
3241 %!assert (sum (single ([1, 2, 3; i, 2i, 3i; 1+i, 2+2i, 3+3i])),
3242 %! single ([2+2i, 4+4i, 6+6i]))
3243 
3244 %!assert (sum ([1, 2; 3, 4], 1), [4, 6])
3245 %!assert (sum ([1, 2; 3, 4], 2), [3; 7])
3246 %!assert (sum (zeros (1, 0)), 0)
3247 %!assert (sum (zeros (1, 0), 1), zeros (1, 0))
3248 %!assert (sum (zeros (1, 0), 2), 0)
3249 %!assert (sum (zeros (0, 1)), 0)
3250 %!assert (sum (zeros (0, 1), 1), 0)
3251 %!assert (sum (zeros (0, 1), 2), zeros (0, 1))
3252 %!assert (sum (zeros (2, 0)), zeros (1, 0))
3253 %!assert (sum (zeros (2, 0), 1), zeros (1, 0))
3254 %!assert (sum (zeros (2, 0), 2), [0; 0])
3255 %!assert (sum (zeros (0, 2)), [0, 0])
3256 %!assert (sum (zeros (0, 2), 1), [0, 0])
3257 %!assert (sum (zeros (0, 2), 2), zeros (0, 1))
3258 %!assert (sum (zeros (2, 2, 0, 3)), zeros (1, 2, 0, 3))
3259 %!assert (sum (zeros (2, 2, 0, 3), 2), zeros (2, 1, 0, 3))
3260 %!assert (sum (zeros (2, 2, 0, 3), 3), zeros (2, 2, 1, 3))
3261 %!assert (sum (zeros (2, 2, 0, 3), 4), zeros (2, 2, 0))
3262 %!assert (sum (zeros (2, 2, 0, 3), 7), zeros (2, 2, 0, 3))
3263 
3264 %!assert (sum (single ([1, 2; 3, 4]), 1), single ([4, 6]))
3265 %!assert (sum (single ([1, 2; 3, 4]), 2), single ([3; 7]))
3266 %!assert (sum (zeros (1, 0, "single")), single (0))
3267 %!assert (sum (zeros (1, 0, "single"), 1), zeros (1, 0, "single"))
3268 %!assert (sum (zeros (1, 0, "single"), 2), single (0))
3269 %!assert (sum (zeros (0, 1, "single")), single (0))
3270 %!assert (sum (zeros (0, 1, "single"), 1), single (0))
3271 %!assert (sum (zeros (0, 1, "single"), 2), zeros (0, 1, "single"))
3272 %!assert (sum (zeros (2, 0, "single")), zeros (1, 0, "single"))
3273 %!assert (sum (zeros (2, 0, "single"), 1), zeros (1, 0, "single"))
3274 %!assert (sum (zeros (2, 0, "single"), 2), single ([0; 0]))
3275 %!assert (sum (zeros (0, 2, "single")), single ([0, 0]))
3276 %!assert (sum (zeros (0, 2, "single"), 1), single ([0, 0]))
3277 %!assert (sum (zeros (0, 2, "single"), 2), zeros (0, 1, "single"))
3278 %!assert (sum (zeros (2, 2, 0, 3, "single")), zeros (1, 2, 0, 3, "single"))
3279 %!assert (sum (zeros (2, 2, 0, 3, "single"), 2), zeros (2, 1, 0, 3, "single"))
3280 %!assert (sum (zeros (2, 2, 0, 3, "single"), 3), zeros (2, 2, 1, 3, "single"))
3281 %!assert (sum (zeros (2, 2, 0, 3, "single"), 4), zeros (2, 2, 0, "single"))
3282 %!assert (sum (zeros (2, 2, 0, 3, "single"), 7), zeros (2, 2, 0, 3, "single"))
3283 
3284 ## Test "native"
3285 %!assert (sum ([true,true]), 2)
3286 %!assert (sum ([true,true], "native"), true)
3287 %!assert (sum (int8 ([127,10,-20])), 117)
3288 %!assert (sum (int8 ([127,10,-20]), "native"), int8 (107))
3289 
3290 ;-)
3291 %!assert (sum ("Octave") + "8", sumsq (primes (17)))
3292 
3293 %!error sum ()
3294 %!error sum (1,2,3)
3295 %!error <unrecognized type argument 'foobar'> sum (1, "foobar")
3296 */
3297 
3298 DEFUN (sumsq, args, ,
3299  doc: /* -*- texinfo -*-
3300 @deftypefn {} {@var{y} =} sumsq (@var{x})
3301 @deftypefnx {} {@var{y} =} sumsq (@var{x}, @var{dim})
3302 Sum of squares of elements along dimension @var{dim}.
3303 
3304 If @var{dim} is omitted, it defaults to the first non-singleton dimension.
3305 
3306 This function is conceptually equivalent to computing
3307 
3308 @example
3309 sum (x .* conj (x), dim)
3310 @end example
3311 
3312 @noindent
3313 but it uses less memory and avoids calling @code{conj} if @var{x} is real.
3314 @seealso{sum, prod}
3315 @end deftypefn */)
3316 {
3317  DATA_REDUCTION (sumsq);
3318 }
3319 
3320 /*
3321 %!assert (sumsq ([1, 2, 3]), 14)
3322 %!assert (sumsq ([-1; -2; 4i]), 21)
3323 %!assert (sumsq ([1, 2, 3; 2, 3, 4; 4i, 6i, 2]), [21, 49, 29])
3324 
3325 %!assert (sumsq (single ([1, 2, 3])), single (14))
3326 %!assert (sumsq (single ([-1; -2; 4i])), single (21))
3327 %!assert (sumsq (single ([1, 2, 3; 2, 3, 4; 4i, 6i, 2])), single ([21, 49, 29]))
3328 
3329 %!assert (sumsq ([1, 2; 3, 4], 1), [10, 20])
3330 %!assert (sumsq ([1, 2; 3, 4], 2), [5; 25])
3331 
3332 %!assert (sumsq (single ([1, 2; 3, 4]), 1), single ([10, 20]))
3333 %!assert (sumsq (single ([1, 2; 3, 4]), 2), single ([5; 25]))
3334 
3335 %!error sumsq ()
3336 */
3337 
3338 DEFUN (islogical, args, ,
3339  doc: /* -*- texinfo -*-
3340 @deftypefn {} {@var{tf} =} islogical (@var{x})
3341 @deftypefnx {} {@var{tf} =} isbool (@var{x})
3342 Return true if @var{x} is a logical object.
3343 
3344 Programming Note: @code{isbool} is an alias for @code{islogical} and can be
3345 used interchangeably.
3346 @seealso{ischar, isfloat, isinteger, isstring, isnumeric, isa}
3347 @end deftypefn */)
3348 {
3349  if (args.length () != 1)
3350  print_usage ();
3351 
3352  return ovl (args(0).islogical ());
3353 }
3354 
3355 DEFALIAS (isbool, islogical);
3356 
3357 /*
3358 %!assert (islogical (true), true)
3359 %!assert (islogical (false), true)
3360 %!assert (islogical ([true, false]), true)
3361 %!assert (islogical (1), false)
3362 %!assert (islogical (1i), false)
3363 %!assert (islogical ([1,1]), false)
3364 %!assert (islogical (single (1)), false)
3365 %!assert (islogical (single (1i)), false)
3366 %!assert (islogical (single ([1,1])), false)
3367 %!assert (islogical (sparse ([true, false])), true)
3368 %!assert (islogical (sparse ([1, 0])), false)
3369 */
3370 
3371 DEFUN (isinteger, args, ,
3372  doc: /* -*- texinfo -*-
3373 @deftypefn {} {@var{tf} =} isinteger (@var{x})
3374 Return true if @var{x} is an integer object (int8, uint8, int16, etc.).
3375 
3376 Note that @w{@code{isinteger (14)}} is false because numeric constants in
3377 Octave are double precision floating point values.
3378 @seealso{isfloat, ischar, islogical, isstring, isnumeric, isa}
3379 @end deftypefn */)
3380 {
3381  if (args.length () != 1)
3382  print_usage ();
3383 
3384  return ovl (args(0).isinteger ());
3385 }
3386 
3387 /*
3388 %!assert (isinteger (int8 (16)))
3389 %!assert (isinteger (int16 (16)))
3390 %!assert (isinteger (int32 (16)))
3391 %!assert (isinteger (int64 (16)))
3392 
3393 %!assert (isinteger (uint8 (16)))
3394 %!assert (isinteger (uint16 (16)))
3395 %!assert (isinteger (uint32 (16)))
3396 %!assert (isinteger (uint64 (16)))
3397 
3398 %!assert (isinteger (intmax ("int8")))
3399 %!assert (isinteger (intmax ("int16")))
3400 %!assert (isinteger (intmax ("int32")))
3401 %!assert (isinteger (intmax ("int64")))
3402 
3403 %!assert (isinteger (intmax ("uint8")))
3404 %!assert (isinteger (intmax ("uint16")))
3405 %!assert (isinteger (intmax ("uint32")))
3406 %!assert (isinteger (intmax ("uint64")))
3407 
3408 %!assert (isinteger (intmin ("int8")))
3409 %!assert (isinteger (intmin ("int16")))
3410 %!assert (isinteger (intmin ("int32")))
3411 %!assert (isinteger (intmin ("int64")))
3412 
3413 %!assert (isinteger (intmin ("uint8")))
3414 %!assert (isinteger (intmin ("uint16")))
3415 %!assert (isinteger (intmin ("uint32")))
3416 %!assert (isinteger (intmin ("uint64")))
3417 
3418 %!assert (isinteger (uint8 ([1:10])))
3419 %!assert (isinteger (uint8 ([1:10; 1:10])))
3420 
3421 %!assert (! isinteger (16))
3422 %!assert (! isinteger ("parrot"))
3423 %!assert (! isinteger ([1, 2, 3]))
3424 
3425 %!error isinteger ()
3426 %!error isinteger ("multiple", "parameters")
3427 */
3428 
3429 DEFUN (iscomplex, args, ,
3430  doc: /* -*- texinfo -*-
3431 @deftypefn {} {@var{tf} =} iscomplex (@var{x})
3432 Return true if @var{x} is a complex-valued numeric object.
3433 @seealso{isreal, isnumeric, ischar, isfloat, islogical, isstring, isa}
3434 @end deftypefn */)
3435 {
3436  if (args.length () != 1)
3437  print_usage ();
3438 
3439  return ovl (args(0).iscomplex ());
3440 }
3441 
3442 /*
3443 %!assert (iscomplex (4), false)
3444 %!assert (iscomplex (i), true)
3445 %!assert (iscomplex (4+3i), true)
3446 %!assert (iscomplex ([1, 2, 3]), false)
3447 %!assert (iscomplex ([1, 2i, 3]), true)
3448 
3449 %!assert (iscomplex (0j), false)
3450 %!assert (iscomplex (complex (0,0)), true)
3451 %!assert (iscomplex ("4"), false)
3452 %!assert (iscomplex ({i}), false)
3453 
3454 ## Test input validation
3455 %!error iscomplex ()
3456 %!error iscomplex (1, 2)
3457 */
3458 
3459 DEFUN (isfloat, args, ,
3460  doc: /* -*- texinfo -*-
3461 @deftypefn {} {@var{tf} =} isfloat (@var{x})
3462 Return true if @var{x} is a floating-point numeric object.
3463 
3464 Objects of class double or single are floating-point objects.
3465 @seealso{isinteger, ischar, islogical, isnumeric, isstring, isa}
3466 @end deftypefn */)
3467 {
3468  if (args.length () != 1)
3469  print_usage ();
3470 
3471  return ovl (args(0).isfloat ());
3472 }
3473 
3474 // FIXME: perhaps this should be implemented with an
3475 // octave_value member function?
3476 
3477 DEFUN (complex, args, ,
3478  doc: /* -*- texinfo -*-
3479 @deftypefn {} {@var{z} =} complex (@var{x})
3480 @deftypefnx {} {@var{z} =} complex (@var{re}, @var{im})
3481 Return a complex value from real arguments.
3482 
3483 With 1 real argument @var{x}, return the complex result
3484 @w{@code{@var{x} + 0i}}.
3485 
3486 With 2 real arguments, return the complex result
3487 @w{@code{@var{re} + @var{im}i}}.
3488 @code{complex} can often be more convenient than expressions such as
3489 @w{@code{a + b*i}}.
3490 For example:
3491 
3492 @example
3493 @group
3494 complex ([1, 2], [3, 4])
3495  @result{} [ 1 + 3i 2 + 4i ]
3496 @end group
3497 @end example
3498 @seealso{real, imag, iscomplex, abs, arg}
3499 @end deftypefn */)
3500 // Programming Note: Throughout this function the coding pattern
3501 // octave_value (new XXX)) is used. This is done specifically because the
3502 // default octave_value constructor would otherwise perform automatic narrowing
3503 // (i.e., complex values with 0 for the imaginary part would be converted
3504 // to real values). The complex() function *must* return a complex value
3505 // even when the imaginary part is 0.
3506 {
3507  int nargin = args.length ();
3508 
3509  if (nargin < 1 || nargin > 2)
3510  print_usage ();
3511 
3512  octave_value retval;
3513 
3514  if (nargin == 1)
3515  {
3516  octave_value arg = args(0);
3517 
3518  if (arg.iscomplex ())
3519  retval = arg;
3520  else
3521  {
3522  if (arg.issparse ())
3523  {
3524  SparseComplexMatrix val = arg.xsparse_complex_matrix_value ("complex: invalid conversion");
3525 
3526  retval = octave_value (new octave_sparse_complex_matrix (val));
3527  }
3528  else if (arg.is_single_type ())
3529  {
3530  if (arg.numel () == 1)
3531  {
3532  FloatComplex val = arg.xfloat_complex_value ("complex: invalid conversion");
3533 
3534  retval = octave_value (new octave_float_complex (val));
3535  }
3536  else
3537  {
3538  FloatComplexNDArray val = arg.xfloat_complex_array_value ("complex: invalid conversion");
3539 
3540  retval = octave_value (new octave_float_complex_matrix (val));
3541  }
3542  }
3543  else
3544  {
3545  if (arg.numel () == 1)
3546  {
3547  Complex val = arg.xcomplex_value ("complex: invalid conversion");
3548 
3549  retval = octave_value (new octave_complex (val));
3550  }
3551  else
3552  {
3553  ComplexNDArray val = arg.xcomplex_array_value ("complex: invalid conversion");
3554 
3555  retval = octave_value (new octave_complex_matrix (val));
3556  }
3557  }
3558  }
3559  }
3560  else
3561  {
3562  octave_value re = args(0);
3563  octave_value im = args(1);
3564 
3565  if (re.issparse () && im.issparse ())
3566  {
3567  const SparseMatrix re_val = re.sparse_matrix_value ();
3568  const SparseMatrix im_val = im.sparse_matrix_value ();
3569 
3570  if (re.numel () == 1)
3571  {
3572  SparseComplexMatrix result;
3573  if (re_val.nnz () == 0)
3574  result = Complex (0, 1) * SparseComplexMatrix (im_val);
3575  else
3576  {
3577  octave_idx_type nr = im_val.rows ();
3578  octave_idx_type nc = im_val.cols ();
3579  result = SparseComplexMatrix (nr, nc, re_val(0));
3580 
3581  for (octave_idx_type j = 0; j < nc; j++)
3582  {
3583  octave_idx_type off = j * nr;
3584  for (octave_idx_type i = im_val.cidx (j);
3585  i < im_val.cidx (j + 1); i++)
3586  result.data (im_val.ridx (i) + off)
3587  += Complex (0, im_val.data (i));
3588  }
3589  }
3590  retval = octave_value (new octave_sparse_complex_matrix (result));
3591  }
3592  else if (im.numel () == 1)
3593  {
3594  SparseComplexMatrix result;
3595  if (im_val.nnz () == 0)
3596  result = SparseComplexMatrix (re_val);
3597  else
3598  {
3599  octave_idx_type nr = re_val.rows ();
3600  octave_idx_type nc = re_val.cols ();
3601  result = SparseComplexMatrix (nr, nc,
3602  Complex (0, im_val(0)));
3603 
3604  for (octave_idx_type j = 0; j < nc; j++)
3605  {
3606  octave_idx_type off = j * nr;
3607  for (octave_idx_type i = re_val.cidx (j);
3608  i < re_val.cidx (j + 1); i++)
3609  result.data (re_val.ridx (i) + off)
3610  += re_val.data (i);
3611  }
3612  }
3613  retval = octave_value (new octave_sparse_complex_matrix (result));
3614  }
3615  else
3616  {
3617  if (re_val.dims () != im_val.dims ())
3618  error ("complex: dimension mismatch");
3619 
3620  SparseComplexMatrix result;
3621  result = SparseComplexMatrix (re_val)
3622  + Complex (0, 1) * SparseComplexMatrix (im_val);
3623  retval = octave_value (new octave_sparse_complex_matrix (result));
3624  }
3625  }
3626  else if (re.is_single_type () || im.is_single_type ())
3627  {
3628  if (re.numel () == 1)
3629  {
3630  float re_val = re.float_value ();
3631 
3632  if (im.numel () == 1)
3633  {
3634  float im_val = im.double_value ();
3635 
3636  retval = octave_value (new octave_float_complex
3637  (FloatComplex (re_val, im_val)));
3638  }
3639  else
3640  {
3641  const FloatNDArray im_val = im.float_array_value ();
3642 
3643  FloatComplexNDArray result (im_val.dims ());
3644 
3645  for (octave_idx_type i = 0; i < im_val.numel (); i++)
3646  result.xelem (i) = FloatComplex (re_val, im_val.xelem (i));
3647 
3649  (result));
3650  }
3651  }
3652  else
3653  {
3654  const FloatNDArray re_val = re.float_array_value ();
3655 
3656  if (im.numel () == 1)
3657  {
3658  float im_val = im.float_value ();
3659 
3660  FloatComplexNDArray result (re_val.dims ());
3661 
3662  for (octave_idx_type i = 0; i < re_val.numel (); i++)
3663  result.xelem (i) = FloatComplex (re_val.xelem (i), im_val);
3664 
3666  (result));
3667  }
3668  else
3669  {
3670  const FloatNDArray im_val = im.float_array_value ();
3671 
3672  if (re_val.dims () != im_val.dims ())
3673  error ("complex: dimension mismatch");
3674 
3675  FloatComplexNDArray result (re_val.dims ());
3676 
3677  for (octave_idx_type i = 0; i < re_val.numel (); i++)
3678  result.xelem (i) = FloatComplex (re_val.xelem (i),
3679  im_val.xelem (i));
3680 
3682  (result));
3683  }
3684  }
3685  }
3686  else if (re.numel () == 1)
3687  {
3688  double re_val = re.double_value ();
3689 
3690  if (im.numel () == 1)
3691  {
3692  double im_val = im.double_value ();
3693 
3694  retval = octave_value (new octave_complex
3695  (Complex (re_val, im_val)));
3696  }
3697  else
3698  {
3699  const NDArray im_val = im.array_value ();
3700 
3701  ComplexNDArray result (im_val.dims ());
3702 
3703  for (octave_idx_type i = 0; i < im_val.numel (); i++)
3704  result.xelem (i) = Complex (re_val, im_val.xelem (i));
3705 
3706  retval = octave_value (new octave_complex_matrix (result));
3707  }
3708  }
3709  else
3710  {
3711  const NDArray re_val = re.array_value ();
3712 
3713  if (im.numel () == 1)
3714  {
3715  double im_val = im.double_value ();
3716 
3717  ComplexNDArray result (re_val.dims ());
3718 
3719  for (octave_idx_type i = 0; i < re_val.numel (); i++)
3720  result.xelem (i) = Complex (re_val.xelem (i), im_val);
3721 
3722  retval = octave_value (new octave_complex_matrix (result));
3723  }
3724  else
3725  {
3726  const NDArray im_val = im.array_value ();
3727 
3728  if (re_val.dims () != im_val.dims ())
3729  error ("complex: dimension mismatch");
3730 
3731  ComplexNDArray result (re_val.dims (), Complex ());
3732 
3733  for (octave_idx_type i = 0; i < re_val.numel (); i++)
3734  result.xelem (i) = Complex (re_val.xelem (i),
3735  im_val.xelem (i));
3736 
3737  retval = octave_value (new octave_complex_matrix (result));
3738  }
3739  }
3740  }
3741 
3742  return retval;
3743 }
3744 
3745 /*
3746 %!error <undefined> 1+Infj
3747 %!error <undefined> 1+Infi
3748 
3749 %!test <31974>
3750 %! assert (Inf + Inf*i, complex (Inf, Inf))
3751 %!
3752 %! assert (1 + Inf*i, complex (1, Inf))
3753 %! assert (1 + Inf*j, complex (1, Inf))
3754 %!
3755 %! ## whitespace should not affect parsing
3756 %! assert (1+Inf*i, complex (1, Inf))
3757 %! assert (1+Inf*j, complex (1, Inf))
3758 %!
3759 %! assert (NaN*j, complex (0, NaN))
3760 %!
3761 %! assert (Inf * 4j, complex (0, Inf))
3762 
3763 %!test <31974>
3764 %! x = Inf;
3765 %! assert (x * j, complex (0, Inf))
3766 %! j = complex (0, 1);
3767 %! assert (Inf * j, complex (0, Inf))
3768 
3769 %!test <31974>
3770 %! exp = complex (zeros (2, 2), Inf (2, 2));
3771 %! assert (Inf (2, 2) * j, exp)
3772 %! assert (Inf (2, 2) .* j, exp)
3773 %! assert (Inf * (ones (2, 2) * j), exp)
3774 %! assert (Inf (2, 2) .* (ones (2, 2) * j), exp)
3775 
3776 %!test <31974>
3777 %! assert ([Inf; 0] * [i, 0], complex ([NaN NaN; 0 0], [Inf NaN; 0 0]))
3778 %! assert ([Inf, 0] * [i; 0], complex (NaN, Inf))
3779 %! assert ([Inf, 0] .* [i, 0], complex ([0 0], [Inf 0]))
3780 
3781 %!test <31974>
3782 %! m = @(x, y) x * y;
3783 %! d = @(x, y) x / y;
3784 %! assert (m (Inf, i), complex (0, +Inf))
3785 %! assert (d (Inf, i), complex (0, -Inf))
3786 */
3787 
3788 DEFUN (isreal, args, ,
3789  doc: /* -*- texinfo -*-
3790 @deftypefn {} {@var{tf} =} isreal (@var{x})
3791 Return true if @var{x} is a non-complex matrix or scalar.
3792 
3793 For compatibility with @sc{matlab}, this includes logical and character
3794 matrices.
3795 @seealso{iscomplex, isnumeric, isa}
3796 @end deftypefn */)
3797 {
3798  if (args.length () != 1)
3799  print_usage ();
3800 
3801  return ovl (args(0).isreal ());
3802 }
3803 
3804 DEFUN (isempty, args, ,
3805  doc: /* -*- texinfo -*-
3806 @deftypefn {} {@var{tf} =} isempty (@var{A})
3807 Return true if @var{A} is an empty object (any one of its dimensions is
3808 zero).
3809 @seealso{isnull, isa}
3810 @end deftypefn */)
3811 {
3812  if (args.length () != 1)
3813  print_usage ();
3814 
3815  return ovl (args(0).isempty ());
3816 }
3817 
3818 /*
3819 ## Debian bug #706376
3820 %!assert (isempty (speye (2^16)), false)
3821 */
3822 
3823 DEFUN (isnumeric, args, ,
3824  doc: /* -*- texinfo -*-
3825 @deftypefn {} {@var{tf} =} isnumeric (@var{x})
3826 Return true if @var{x} is a numeric object, i.e., an integer, real, or
3827 complex array.
3828 
3829 Logical and character arrays are not considered to be numeric.
3830 @seealso{isinteger, isfloat, isreal, iscomplex, ischar, islogical, isstring,
3831 iscell, isstruct, isa}
3832 @end deftypefn */)
3833 {
3834  if (args.length () != 1)
3835  print_usage ();
3836 
3837  return ovl (args(0).isnumeric ());
3838 }
3839 
3840 /*
3841 %!assert (isnumeric (1), true)
3842 %!assert (isnumeric (1i), true)
3843 %!assert (isnumeric ([1,1]), true)
3844 %!assert (isnumeric (single (1)), true)
3845 %!assert (isnumeric (single (1i)), true)
3846 %!assert (isnumeric (single ([1,1])), true)
3847 %!assert (isnumeric (int8 (1)), true)
3848 %!assert (isnumeric (uint8 ([1,1])), true)
3849 %!assert (isnumeric ("Hello World"), false)
3850 %!assert (isnumeric (true), false)
3851 %!assert (isnumeric (false), false)
3852 %!assert (isnumeric ([true, false]), false)
3853 %!assert (isnumeric (sparse ([true, false])), false)
3854 */
3855 
3856 DEFUN (isscalar, args, ,
3857  doc: /* -*- texinfo -*-
3858 @deftypefn {} {@var{tf} =} isscalar (@var{x})
3859 Return true if @var{x} is a scalar.
3860 
3861 A scalar is a single-element object of any type for which @code{size (@var{x})}
3862 returns @w{@code{[1, 1]}}.
3863 @seealso{isvector, ismatrix, size}
3864 @end deftypefn */)
3865 {
3866  if (args.length () != 1)
3867  print_usage ();
3868 
3869  // This function *must* use size() to determine the desired values to be
3870  // compatible with Matlab and to allow user-defined class overloading.
3871  Matrix sz = octave_value (args(0)).size ();
3872 
3873  return ovl (sz.numel () == 2 && sz(0) == 1 && sz(1) == 1);
3874 }
3875 
3876 /*
3877 %!assert (isscalar (1))
3878 %!assert (isscalar ([1, 2]), false)
3879 %!assert (isscalar ([]), false)
3880 %!assert (isscalar ([1, 2; 3, 4]), false)
3881 
3882 %!assert (isscalar ("t"))
3883 %!assert (isscalar ("test"), false)
3884 %!assert (isscalar (["test"; "ing"]), false)
3885 
3886 %!test
3887 %! s.a = 1;
3888 %! assert (isscalar (s));
3889 
3890 ## Test input validation
3891 %!error isscalar ()
3892 %!error isscalar (1, 2)
3893 */
3894 
3895 DEFUN (isvector, args, ,
3896  doc: /* -*- texinfo -*-
3897 @deftypefn {} {@var{tf} =} isvector (@var{x})
3898 Return true if @var{x} is a vector.
3899 
3900 A vector is a 2-D array of any type where one of the dimensions is equal to 1
3901 (either @nospell{1xN} or @nospell{Nx1}). As a consequence of this definition,
3902 a 1x1 object (a scalar) is also a vector.
3903 @seealso{isscalar, ismatrix, iscolumn, isrow, size}
3904 @end deftypefn */)
3905 {
3906  if (args.length () != 1)
3907  print_usage ();
3908 
3909  // This function *must* use size() to determine the desired values to be
3910  // compatible with Matlab and to allow user-defined class overloading.
3911  Matrix sz = octave_value (args(0)).size ();
3912 
3913  return ovl (sz.numel () == 2 && (sz(0) == 1 || sz(1) == 1));
3914 }
3915 
3916 /*
3917 %!assert (isvector (1), true)
3918 %!assert (isvector ([1; 2; 3]), true)
3919 %!assert (isvector ([1, 2, 3]), true)
3920 %!assert (isvector ([]), false)
3921 %!assert (isvector ([1, 2; 3, 4]), false)
3922 
3923 %!assert (isvector ("t"), true)
3924 %!assert (isvector ("test"), true)
3925 %!assert (isvector (["test"; "ing"]), false)
3926 
3927 %!test
3928 %! s.a = 1;
3929 %! assert (isvector (s), true);
3930 
3931 ## Test input validation
3932 %!error isvector ()
3933 %!error isvector ([1, 2], 2)
3934 */
3935 
3936 DEFUN (isrow, args, ,
3937  doc: /* -*- texinfo -*-
3938 @deftypefn {} {@var{tf} =} isrow (@var{x})
3939 Return true if @var{x} is a row vector.
3940 
3941 A row vector is a 2-D array of any type for which @code{size (@var{x})} returns
3942 @w{@code{[1, N]}} with non-negative N.
3943 @seealso{iscolumn, isscalar, isvector, ismatrix, size}
3944 @end deftypefn */)
3945 {
3946  if (args.length () != 1)
3947  print_usage ();
3948 
3949  // This function *must* use size() to determine the desired values to be
3950  // compatible with Matlab and to allow user-defined class overloading.
3951  Matrix sz = octave_value (args(0)).size ();
3952 
3953  return ovl (sz.numel () == 2 && sz(0) == 1);
3954 }
3955 
3956 /*
3957 %!assert (isrow ([1, 2, 3]))
3958 %!assert (isrow ([1; 2; 3]), false)
3959 %!assert (isrow (1))
3960 %!assert (isrow ([]), false)
3961 %!assert (isrow ([1, 2; 3, 4]), false)
3962 
3963 %!assert (isrow (ones (1, 0)), true)
3964 %!assert (isrow (ones (1, 1)), true)
3965 %!assert (isrow (ones (1, 2)), true)
3966 %!assert (isrow (ones (1, 1, 1)), true)
3967 %!assert (isrow (ones (1, 1, 1, 1)), true)
3968 
3969 %!assert (isrow (ones (0, 0)), false)
3970 %!assert (isrow (ones (1, 1, 0)), false)
3971 
3972 %!assert (isrow ("t"), true)
3973 %!assert (isrow ("test"), true)
3974 %!assert (isrow (["test"; "ing"]), false)
3975 
3976 %!test
3977 %! s.a = 1;
3978 %! assert (isrow (s), true);
3979 
3980 ## Test input validation
3981 %!error isrow ()
3982 %!error isrow ([1, 2], 2)
3983 */
3984 
3985 DEFUN (iscolumn, args, ,
3986  doc: /* -*- texinfo -*-
3987 @deftypefn {} {@var{tf} =} iscolumn (@var{x})
3988 Return true if @var{x} is a column vector.
3989 
3990 A column vector is a 2-D array of any type for which @code{size (@var{x})}
3991 returns @w{@code{[N, 1]}} with non-negative N.
3992 @seealso{isrow, isscalar, isvector, ismatrix, size}
3993 @end deftypefn */)
3994 {
3995  if (args.length () != 1)
3996  print_usage ();
3997 
3998  // This function *must* use size() to determine the desired values to be
3999  // compatible with Matlab and to allow user-defined class overloading.
4000  Matrix sz = octave_value (args(0)).size ();
4001 
4002  return ovl (sz.numel () == 2 && sz(1) == 1);
4003 }
4004 
4005 /*
4006 %!assert (iscolumn ([1, 2, 3]), false)
4007 %!assert (iscolumn ([1; 2; 3]), true)
4008 %!assert (iscolumn (1), true)
4009 %!assert (iscolumn ([]), false)
4010 %!assert (iscolumn ([1, 2; 3, 4]), false)
4011 
4012 %!assert (iscolumn ("t"), true)
4013 %!assert (iscolumn ("test"), false)
4014 %!assert (iscolumn (["test"; "ing"]), false)
4015 
4016 %!assert (iscolumn (ones (0, 1)), true)
4017 %!assert (iscolumn (ones (1, 1)), true)
4018 %!assert (iscolumn (ones (2, 1)), true)
4019 %!assert (iscolumn (ones (1, 1, 1)), true)
4020 %!assert (iscolumn (ones (1, 1, 1, 1)), true)
4021 
4022 %!assert (iscolumn (ones (0, 0)), false)
4023 %!assert (iscolumn (ones (0, 1, 0)), false)
4024 
4025 %!test
4026 %! s.a = 1;
4027 %! assert (iscolumn (s));
4028 
4029 ## Test input validation
4030 %!error iscolumn ()
4031 %!error iscolumn ([1, 2], 2)
4032 */
4033 
4034 DEFUN (ismatrix, args, ,
4035  doc: /* -*- texinfo -*-
4036 @deftypefn {} {@var{tf} =} ismatrix (@var{x})
4037 Return true if @var{x} is a 2-D array.
4038 
4039 A matrix is an array of any type where @code{ndims (@var{x}) == 2} and for
4040 which @code{size (@var{x})} returns @w{@code{[M, N]}} with non-negative M and
4041 N.
4042 @seealso{isscalar, isvector, iscell, isstruct, issparse, isa}
4043 @end deftypefn */)
4044 {
4045  if (args.length () != 1)
4046  print_usage ();
4047 
4048  // This function *must* use size() to determine the desired values to be
4049  // compatible with Matlab and to allow user-defined class overloading.
4050  Matrix sz = octave_value (args(0)).size ();
4051 
4052  return ovl (sz.numel () == 2 && sz(0) >= 0 && sz(1) >= 0);
4053 }
4054 
4055 /*
4056 %!assert (ismatrix ([]), true)
4057 %!assert (ismatrix (1), true)
4058 %!assert (ismatrix ([1, 2, 3]), true)
4059 %!assert (ismatrix ([1, 2; 3, 4]), true)
4060 
4061 %!assert (ismatrix (zeros (0)), true)
4062 %!assert (ismatrix (zeros (0, 0)), true)
4063 %!assert (ismatrix (zeros (0, 0, 0)), false)
4064 %!assert (ismatrix (zeros (3, 2, 4)), false)
4065 
4066 %!assert (ismatrix (single ([])), true)
4067 %!assert (ismatrix (single (1)), true)
4068 %!assert (ismatrix (single ([1, 2, 3])), true)
4069 %!assert (ismatrix (single ([1, 2; 3, 4])), true)
4070 
4071 %!assert (ismatrix ("t"), true)
4072 %!assert (ismatrix ("test"), true)
4073 %!assert (ismatrix (["test"; "ing"]), true)
4074 
4075 %!test
4076 %! s.a = 1;
4077 %! assert (ismatrix (s), true);
4078 
4079 %!error ismatrix ()
4080 %!error ismatrix ([1, 2; 3, 4], 2)
4081 */
4082 
4083 DEFUN (issquare, args, ,
4084  doc: /* -*- texinfo -*-
4085 @deftypefn {} {@var{tf} =} issquare (@var{x})
4086 Return true if @var{x} is a 2-D square array.
4087 
4088 A square array is a 2-D array of any type for which @code{size (@var{x})}
4089 returns @w{@code{[N, N]}} where N is a non-negative integer.
4090 @seealso{isscalar, isvector, ismatrix, size}
4091 @end deftypefn */)
4092 {
4093  if (args.length () != 1)
4094  print_usage ();
4095 
4096  // This function *must* use size() to determine the desired values to
4097  // allow user-defined class overloading.
4098  Matrix sz = octave_value (args(0)).size ();
4099 
4100  return ovl (sz.numel () == 2 && sz(0) == sz(1));
4101 }
4102 
4103 /*
4104 %!assert (issquare ([]))
4105 %!assert (issquare (1))
4106 %!assert (! issquare ([1, 2]))
4107 %!assert (issquare ([1, 2; 3, 4]))
4108 %!assert (! issquare ([1, 2; 3, 4; 5, 6]))
4109 %!assert (! issquare (ones (3,3,3)))
4110 %!assert (issquare ("t"))
4111 %!assert (! issquare ("test"))
4112 %!assert (issquare (["test"; "ing"; "1"; "2"]))
4113 %!test
4114 %! s.a = 1;
4115 %! assert (issquare (s));
4116 %!assert (issquare ({1, 2; 3, 4}))
4117 %!assert (sparse (([1, 2; 3, 4])))
4118 
4119 ## Test input validation
4120 %!error issquare ()
4121 %!error issquare ([1, 2; 3, 4], 2)
4122 */
4123 
4124 static octave_value
4125 fill_matrix (const octave_value_list& args, int val, const char *fcn)
4126 {
4127  octave_value retval;
4128 
4129  int nargin = args.length ();
4130 
4132 
4133  dim_vector dims (1, 1);
4134  bool issparse = false;
4135  bool iscomplex = false;
4136 
4137  if (nargin > 0 && args(nargin-1).is_string ())
4138  {
4139  std::string nm = args(nargin-1).string_value ();
4140  nargin--;
4141 
4143  }
4144 
4145  if (nargin > 1 && args(nargin-2).is_string ()
4146  && args(nargin-2).string_value () == "like")
4147  {
4148  std::string nm = args(nargin-1).class_name ();
4149  issparse = args(nargin-1).issparse ();
4150  iscomplex = args(nargin-1).iscomplex ();
4151  nargin -= 2;
4153  }
4154 
4155  switch (nargin)
4156  {
4157  case 0:
4158  break;
4159 
4160  case 1:
4161  get_dimensions (args(0), fcn, dims);
4162  break;
4163 
4164  default:
4165  {
4166  dims.resize (nargin);
4167 
4168  for (int i = 0; i < nargin; i++)
4169  {
4170  if (args(i).numel () > 1)
4171  error ("%s: dimensions must be scalars.", fcn);
4172 
4173  dims(i) = (args(i).isempty () ? 0 : args(i).idx_type_value (true));
4174  }
4175  }
4176  break;
4177  }
4178 
4179  dims.chop_trailing_singletons ();
4180 
4181  check_dimensions (dims, fcn);
4182 
4183  // FIXME: Perhaps this should be made extensible by using the class name
4184  // to lookup a function to call to create the new value.
4185 
4186  // Note that automatic narrowing will handle conversion from
4187  // NDArray to scalar.
4188 
4189  if (issparse)
4190  {
4191  if (dims.ndims () > 2)
4192  error ("%s: sparse ND arrays not supported.", fcn);
4193 
4194  switch (dt)
4195  {
4197  if (iscomplex)
4198  retval = SparseComplexMatrix (dims(0), dims(1), Complex (val, 0));
4199  else
4200  retval = SparseMatrix (dims(0), dims(1), static_cast<double> (val));
4201  break;
4202 
4204  retval = SparseBoolMatrix (dims(0), dims(1), static_cast<bool> (val));
4205  break;
4206 
4207  default:
4208  // FIXME: It shouldn't be possible to ever reach this.
4209  error ("%s: invalid class name for sparse", fcn);
4210  }
4211 
4212  return retval;
4213  }
4214 
4215  switch (dt)
4216  {
4218  retval = int8NDArray (dims, val);
4219  break;
4220 
4222  retval = uint8NDArray (dims, val);
4223  break;
4224 
4226  retval = int16NDArray (dims, val);
4227  break;
4228 
4230  retval = uint16NDArray (dims, val);
4231  break;
4232 
4234  retval = int32NDArray (dims, val);
4235  break;
4236 
4238  retval = uint32NDArray (dims, val);
4239  break;
4240 
4242  retval = int64NDArray (dims, val);
4243  break;
4244 
4246  retval = uint64NDArray (dims, val);
4247  break;
4248 
4250  if (iscomplex)
4251  retval = FloatComplexNDArray (dims, val);
4252  else
4253  retval = FloatNDArray (dims, val);
4254  break;
4255 
4257  if (iscomplex)
4258  retval = ComplexNDArray (dims, Complex (val, 0));
4259  else
4260  retval = NDArray (dims, val);
4261  break;
4262 
4264  retval = boolNDArray (dims, val);
4265  break;
4266 
4267  default:
4268  error ("%s: invalid class name", fcn);
4269  break;
4270  }
4271 
4272  return retval;
4273 }
4274 
4275 static octave_value
4276 fill_matrix (const octave_value_list& args, double val, float fval,
4277  const char *fcn)
4278 {
4279  octave_value retval;
4280 
4281  int nargin = args.length ();
4282 
4284 
4285  dim_vector dims (1, 1);
4286  bool issparse = false;
4287  bool iscomplex = false;
4288 
4289  if (nargin > 0 && args(nargin-1).is_string ())
4290  {
4291  std::string nm = args(nargin-1).string_value ();
4292  nargin--;
4293 
4295  }
4296 
4297  if (nargin > 1 && args(nargin-2).is_string ()
4298  && args(nargin-2).string_value () == "like"
4299  && (std::string(fcn) == "Inf"
4300  || std::string(fcn) == "NaN" || std::string(fcn) == "NA"))
4301  {
4302  if (! args(nargin-1).isfloat ())
4303  error ("%s: input followed by 'like' must be floating point", fcn);
4304  std::string nm = args(nargin-1).class_name ();
4305  issparse = args(nargin-1).issparse ();
4306  iscomplex = args(nargin-1).iscomplex ();
4307  nargin -= 2;
4309  }
4310 
4311  switch (nargin)
4312  {
4313  case 0:
4314  break;
4315 
4316  case 1:
4317  get_dimensions (args(0), fcn, dims);
4318  break;
4319 
4320  default:
4321  {
4322  dims.resize (nargin);
4323 
4324  for (int i = 0; i < nargin; i++)
4325  {
4326  if (args(i).numel () > 1)
4327  error ("%s: dimensions must be scalars.", fcn);
4328 
4329  dims(i) = (args(i).isempty () ? 0 : args(i).idx_type_value (true));
4330  }
4331  }
4332  break;
4333  }
4334 
4335  dims.chop_trailing_singletons ();
4336 
4337  check_dimensions (dims, fcn);
4338 
4339  // Note that automatic narrowing will handle conversion from
4340  // NDArray to scalar.
4341 
4342  if (issparse)
4343  {
4344  if (dims.ndims () > 2)
4345  error ("%s: sparse ND arrays not supported", fcn);
4346 
4347  if (iscomplex)
4348  retval = SparseComplexMatrix (dims(0), dims(1), Complex (val, 0));
4349  else
4350  retval = SparseMatrix (dims(0), dims(1), static_cast<double> (val));
4351 
4352  return retval;
4353  }
4354 
4355  switch (dt)
4356  {
4358  if (iscomplex)
4359  retval = FloatComplexNDArray (dims, fval);
4360  else
4361  retval = FloatNDArray (dims, fval);
4362  break;
4363 
4365  if (iscomplex)
4366  retval = ComplexNDArray (dims, Complex (val, 0));
4367  else
4368  retval = NDArray (dims, val);
4369  break;
4370 
4371  default:
4372  error ("%s: invalid class name", fcn);
4373  break;
4374  }
4375 
4376  return retval;
4377 }
4378 
4379 static octave_value
4380 fill_matrix (const octave_value_list& args, double val, const char *fcn)
4381 {
4382  octave_value retval;
4383 
4384  int nargin = args.length ();
4385 
4387 
4388  dim_vector dims (1, 1);
4389 
4390  if (nargin > 0 && args(nargin-1).is_string ())
4391  {
4392  std::string nm = args(nargin-1).string_value ();
4393  nargin--;
4394 
4396  }
4397 
4398  switch (nargin)
4399  {
4400  case 0:
4401  break;
4402 
4403  case 1:
4404  get_dimensions (args(0), fcn, dims);
4405  break;
4406 
4407  default:
4408  {
4409  dims.resize (nargin);
4410 
4411  for (int i = 0; i < nargin; i++)
4412  {
4413  if (args(i).numel () > 1)
4414  error ("%s: dimensions must be scalars.", fcn);
4415 
4416  dims(i) = (args(i).isempty () ? 0 : args(i).idx_type_value (true));
4417  }
4418  }
4419  break;
4420  }
4421 
4422  dims.chop_trailing_singletons ();
4423 
4424  check_dimensions (dims, fcn);
4425 
4426  // Note that automatic narrowing will handle conversion from
4427  // NDArray to scalar.
4428 
4429  switch (dt)
4430  {
4432  retval = FloatNDArray (dims, static_cast<float> (val));
4433  break;
4434 
4436  retval = NDArray (dims, val);
4437  break;
4438 
4439  default:
4440  error ("%s: invalid class name", fcn);
4441  break;
4442  }
4443 
4444  return retval;
4445 }
4446 
4447 static octave_value
4448 fill_matrix (const octave_value_list& args, const Complex& val,
4449  const char *fcn)
4450 {
4451  octave_value retval;
4452 
4453  int nargin = args.length ();
4454 
4456 
4457  dim_vector dims (1, 1);
4458 
4459  if (nargin > 0 && args(nargin-1).is_string ())
4460  {
4461  std::string nm = args(nargin-1).string_value ();
4462  nargin--;
4463 
4465  }
4466 
4467  switch (nargin)
4468  {
4469  case 0:
4470  break;
4471 
4472  case 1:
4473  get_dimensions (args(0), fcn, dims);
4474  break;
4475 
4476  default:
4477  {
4478  dims.resize (nargin);
4479 
4480  for (int i = 0; i < nargin; i++)
4481  {
4482  if (args(i).numel () > 1)
4483  error ("%s: dimensions must be scalars.", fcn);
4484 
4485  dims(i) = (args(i).isempty () ? 0 : args(i).idx_type_value (true));
4486  }
4487  }
4488  break;
4489  }
4490 
4491  dims.chop_trailing_singletons ();
4492 
4493  check_dimensions (dims, fcn);
4494 
4495  // Note that automatic narrowing will handle conversion from
4496  // NDArray to scalar.
4497 
4498  switch (dt)
4499  {
4501  retval = FloatComplexNDArray (dims,
4502  static_cast<FloatComplex> (val));
4503  break;
4504 
4506  retval = ComplexNDArray (dims, val);
4507  break;
4508 
4509  default:
4510  error ("%s: invalid class name", fcn);
4511  break;
4512  }
4513 
4514  return retval;
4515 }
4516 
4517 static octave_value
4518 fill_matrix (const octave_value_list& args, bool val, const char *fcn)
4519 {
4520  octave_value retval;
4521 
4522  int nargin = args.length ();
4523 
4524  dim_vector dims (1, 1);
4525 
4526  // The TYPE argument is required to be "logical" if present. This
4527  // feature appears to be undocumented in Matlab.
4528 
4529  if (nargin > 0 && args(nargin-1).is_string ())
4530  {
4531  std::string nm = args(nargin-1).string_value ();
4532  nargin--;
4533 
4535  error ("%s: invalid data type '%s'", fcn, nm.c_str ());
4536  }
4537 
4538  bool issparse = false;
4539 
4540  if (nargin > 1 && args(nargin-2).is_string ()
4541  && args(nargin-2).string_value () == "like")
4542  {
4543  if (! args(nargin-1).islogical ())
4544  error (R"(%s: input followed by "like" must be logical)", fcn);
4545 
4546  issparse = args(nargin-1).issparse ();
4547  nargin -= 2;
4548  }
4549 
4550  switch (nargin)
4551  {
4552  case 0:
4553  break;
4554 
4555  case 1:
4556  get_dimensions (args(0), fcn, dims);
4557  break;
4558 
4559  default:
4560  {
4561  dims.resize (nargin);
4562 
4563  for (int i = 0; i < nargin; i++)
4564  {
4565  if (args(i).numel () > 1)
4566  error ("%s: dimensions must be scalars.", fcn);
4567 
4568  dims(i) = (args(i).isempty () ? 0 : args(i).idx_type_value (true));
4569  }
4570  }
4571  break;
4572  }
4573 
4574  dims.chop_trailing_singletons ();
4575 
4576  check_dimensions (dims, fcn);
4577 
4578  // Note that automatic narrowing will handle conversion from
4579  // NDArray to scalar.
4580 
4581  if (issparse)
4582  {
4583  if (dims.ndims () > 2)
4584  error ("%s: sparse ND arrays not supported", fcn);
4585 
4586  retval = SparseBoolMatrix (dims(0), dims(1), val);
4587  }
4588  else
4589  retval = boolNDArray (dims, val);
4590 
4591  return retval;
4592 }
4593 
4594 DEFUN (ones, args, ,
4595  doc: /* -*- texinfo -*-
4596 @deftypefn {} {@var{val} =} ones (@var{n})
4597 @deftypefnx {} {@var{val} =} ones (@var{m}, @var{n})
4598 @deftypefnx {} {@var{val} =} ones (@var{m}, @var{n}, @var{k}, @dots{})
4599 @deftypefnx {} {@var{val} =} ones ([@var{m} @var{n} @dots{}])
4600 @deftypefnx {} {@var{val} =} ones (@dots{}, "like", @var{var})
4601 @deftypefnx {} {@var{val} =} ones (@dots{}, @var{class})
4602 Return a matrix or N-dimensional array whose elements are all 1.
4603 
4604 If invoked with a single scalar integer argument @var{n}, return a square
4605 @nospell{NxN} matrix.
4606 
4607 If invoked with two or more scalar integer arguments, or a vector of integer
4608 values, return an array with the given dimensions.
4609 
4610 To create a constant matrix whose values are all the same use an expression
4611 such as
4612 
4613 @example
4614 val_matrix = val * ones (m, n)
4615 @end example
4616 
4617 If a variable @var{var} is specified after @qcode{"like"}, the output @var{val}
4618 will have the same data type, complexity, and sparsity as @var{var}.
4619 
4620 The optional argument @var{class} specifies the class of the return array
4621 and defaults to double. For example:
4622 
4623 @example
4624 val = ones (m,n, "uint8")
4625 @end example
4626 @seealso{zeros}
4627 @end deftypefn */)
4628 {
4629  return fill_matrix (args, 1, "ones");
4630 }
4631 
4632 /*
4633 %!assert (ones (3), [1, 1, 1; 1, 1, 1; 1, 1, 1])
4634 %!assert (ones (2, 3), [1, 1, 1; 1, 1, 1])
4635 %!assert (ones (3, 2), [1, 1; 1, 1; 1, 1])
4636 %!assert (size (ones (3, 4, 5)), [3, 4, 5])
4637 
4638 %!assert (ones (3, "single"), single ([1, 1, 1; 1, 1, 1; 1, 1, 1]))
4639 %!assert (ones (2, 3, "single"), single ([1, 1, 1; 1, 1, 1]))
4640 %!assert (ones (3, 2, "single"), single ([1, 1; 1, 1; 1, 1]))
4641 %!assert (size (ones (3, 4, 5, "single")), [3, 4, 5])
4642 
4643 %!assert (ones (3, "int8"), int8 ([1, 1, 1; 1, 1, 1; 1, 1, 1]))
4644 %!assert (ones (2, 3, "int8"), int8 ([1, 1, 1; 1, 1, 1]))
4645 %!assert (ones (3, 2, "int8"), int8 ([1, 1; 1, 1; 1, 1]))
4646 %!assert (size (ones (3, 4, 5, "int8")), [3, 4, 5])
4647 
4648 %!assert (ones (2, 2, "like", double (1)), double ([1, 1; 1, 1]))
4649 %!assert (ones (2, 2, "like", complex (ones (2, 2))), [1, 1; 1, 1])
4650 %!assert (ones (1, 2, "like", single (1)), single ([1, 1]))
4651 %!assert (ones (1, "like", single (1i)), single (1))
4652 %!assert (ones (2, 2, "like", uint8 (8)), uint8 ([1, 1; 1, 1]))
4653 %!assert (ones (2, "like", speye (2)), sparse ([1, 1; 1, 1]))
4654 %!assert (ones (2, "like", sparse (1i)), sparse (complex ([1, 1; 1, 1])))
4655 
4656 ## Note: Matlab compatibility requires using 0 for negative dimensions.
4657 %!assert (size (ones (1, -2, 2)), [1, 0, 2])
4658 
4659 ## Test input validation
4660 %!error <conversion of 1.1 .*failed> ones (1.1)
4661 %!error <conversion of 1.1 .*failed> ones (1, 1.1)
4662 %!error <conversion of 1.1 .*failed> ones ([1, 1.1])
4663 %!error <sparse ND .* not supported> ones (3, 3, 3, "like", speye (1))
4664 %!error <must be scalar> ones (1:3, 1)
4665 %!error <must be scalar> ones (1, 1:3)
4666 %!error <must be scalar> ones (1, 2, 1:3)
4667 %!error <must be scalar> ones (1:3, 1, "like", single (1))
4668 */
4669 
4670 /*
4671 ## Tests for bug #47298
4672 ## Matlab requires the size to be a row vector. In that logic, it supports
4673 ## n to be a 1x0 vector (returns 0x0) but not a 0x1 vector. Octave supports
4674 ## row and column vectors and therefore must support 0x1, 1x0, and 0x1x1.
4675 ## Also any empty input results in a 0x0 output.
4676 %!test <*47298>
4677 %! fcns = {@zeros, @ones, @inf, @nan, @NA, @i, @pi, @e};
4678 %! for idx = 1:numel (fcns)
4679 %! fcn = fcns{idx};
4680 %! assert (fcn (zeros (1, 0)), zeros (0, 0));
4681 %! assert (fcn (zeros (0, 1)), zeros (0, 0));
4682 %! assert (fcn (zeros (0, 1, 1)), zeros (0, 0));
4683 %! assert (fcn (zeros ([])), zeros (0, 0));
4684 %! assert (fcn (zeros (0, 0, 1)), zeros (0, 0));
4685 %! endfor
4686 */
4687 
4688 DEFUN (zeros, args, ,
4689  doc: /* -*- texinfo -*-
4690 @deftypefn {} {@var{val} =} zeros (@var{n})
4691 @deftypefnx {} {@var{val} =} zeros (@var{m}, @var{n})
4692 @deftypefnx {} {@var{val} =} zeros (@var{m}, @var{n}, @var{k}, @dots{})
4693 @deftypefnx {} {@var{val} =} zeros ([@var{m} @var{n} @dots{}])
4694 @deftypefnx {} {@var{val} =} zeros (@dots{}, "like", @var{var})
4695 @deftypefnx {} {@var{val} =} zeros (@dots{}, @var{class})
4696 Return a matrix or N-dimensional array whose elements are all 0.
4697 
4698 If invoked with a single scalar integer argument, return a square
4699 @nospell{NxN} matrix.
4700 
4701 If invoked with two or more scalar integer arguments, or a vector of integer
4702 values, return an array with the given dimensions.
4703 
4704 If a variable @var{var} is specified after @qcode{"like"}, the output @var{val}
4705 will have the same data type, complexity, and sparsity as @var{var}.
4706 
4707 The optional argument @var{class} specifies the class of the return array
4708 and defaults to double. For example:
4709 
4710 @example
4711 val = zeros (m,n, "uint8")
4712 @end example
4713 @seealso{ones}
4714 @end deftypefn */)
4715 {
4716  return fill_matrix (args, 0, "zeros");
4717 }
4718 
4719 /*
4720 %!assert (zeros (3), [0, 0, 0; 0, 0, 0; 0, 0, 0])
4721 %!assert (zeros (2, 3), [0, 0, 0; 0, 0, 0])
4722 %!assert (zeros (3, 2), [0, 0; 0, 0; 0, 0])
4723 %!assert (size (zeros (3, 4, 5)), [3, 4, 5])
4724 
4725 %!assert (zeros (2, 2, "like", double (1)), double ([0, 0; 0, 0]))
4726 %!assert (zeros (2, 2, "like", complex (ones (2, 2))), [0, 0; 0, 0])
4727 %!assert (zeros (1, 2, "like", single (1)), single ([0, 0]))
4728 %!assert (zeros (1, 2, "like", single (1i)), single ([0, 0]))
4729 %!assert (zeros (2, 2, "like", uint8 (8)), uint8 ([0, 0; 0, 0]))
4730 %!assert (zeros (2, "like", speye (2)), sparse ([0, 0; 0, 0]))
4731 
4732 %!assert (zeros (3, "single"), single ([0, 0, 0; 0, 0, 0; 0, 0, 0]))
4733 %!assert (zeros (2, 3, "single"), single ([0, 0, 0; 0, 0, 0]))
4734 %!assert (zeros (3, 2, "single"), single ([0, 0; 0, 0; 0, 0]))
4735 %!assert (size (zeros (3, 4, 5, "single")), [3, 4, 5])
4736 
4737 %!assert (zeros (3, "int8"), int8 ([0, 0, 0; 0, 0, 0; 0, 0, 0]))
4738 %!assert (zeros (2, 3, "int8"), int8 ([0, 0, 0; 0, 0, 0]))
4739 %!assert (zeros (3, 2, "int8"), int8 ([0, 0; 0, 0; 0, 0]))
4740 %!assert (size (zeros (3, 4, 5, "int8")), [3, 4, 5])
4741 
4742 ## Test input validation
4743 %!error <invalid data type specified> zeros (1, 1, "foobar")
4744 %!error <conversion of 1.1 .*failed> zeros (1.1)
4745 %!error <conversion of 1.1 .*failed> zeros (1, 1.1)
4746 %!error <conversion of 1.1 .*failed> zeros ([1, 1.1])
4747 %!error <conversion of 1.1 .*failed> zeros (1, 1.1, 2)
4748 %!error <conversion of 1.1 .*failed> zeros ([1, 1.1, 2])
4749 %!error <sparse ND .* not supported> zeros (3, 3, 3, "like", speye (1))
4750 %!error <must be scalar> zeros (1:3, 1)
4751 %!error <must be scalar> zeros (1, 1:3)
4752 %!error <must be scalar> zeros (1, 2, 1:3)
4753 %!error <must be scalar> zeros (1:3, 1, "like", single (1))
4754 */
4755 
4756 DEFUN (Inf, args, ,
4757  doc: /* -*- texinfo -*-
4758 @c List other form of function in documentation index
4759 @findex inf
4760 
4761 @deftypefn {} {@var{A} =} Inf
4762 @deftypefnx {} {@var{A} =} Inf (@var{n})
4763 @deftypefnx {} {@var{A} =} Inf (@var{n}, @var{m})
4764 @deftypefnx {} {@var{A} =} Inf (@var{n}, @var{m}, @var{k}, @dots{})
4765 @deftypefnx {} {@var{A} =} Inf (@dots{}, @var{class})
4766 Return a scalar, matrix or N-dimensional array whose elements are all equal
4767 to the IEEE representation for positive infinity.
4768 
4769 Infinity is produced when results are too large to be represented using the
4770 IEEE floating point format for numbers. Two common examples which produce
4771 infinity are division by zero and overflow.
4772 
4773 @example
4774 @group
4775 [ 1/0 e^800 ]
4776 @result{} Inf Inf
4777 @end group
4778 @end example
4779 
4780 When called with no arguments, return a scalar with the value @samp{Inf}.
4781 
4782 When called with a single argument, return a square matrix with the
4783 dimension specified.
4784 
4785 When called with more than one scalar argument the first two arguments are
4786 taken as the number of rows and columns and any further arguments specify
4787 additional matrix dimensions.
4788 
4789 The optional argument @var{class} specifies the return type and may be
4790 either @qcode{"double"} or @qcode{"single"}.
4791 @seealso{isinf, NaN}
4792 @end deftypefn */)
4793 {
4794  return fill_matrix (args, lo_ieee_inf_value (),
4795  lo_ieee_float_inf_value (), "Inf");
4796 }
4797 
4798 DEFALIAS (inf, Inf);
4799 
4800 /*
4801 %!assert (Inf (3), [Inf, Inf, Inf; Inf, Inf, Inf; Inf, Inf, Inf])
4802 %!assert (Inf (2, 3), [Inf, Inf, Inf; Inf, Inf, Inf])
4803 %!assert (Inf (3, 2), [Inf, Inf; Inf, Inf; Inf, Inf])
4804 %!assert (size (Inf (3, 4, 5)), [3, 4, 5])
4805 
4806 %!assert (Inf (3, "single"),
4807 %! single ([Inf, Inf, Inf; Inf, Inf, Inf; Inf, Inf, Inf]))
4808 %!assert (Inf (2, 3, "single"), single ([Inf, Inf, Inf; Inf, Inf, Inf]))
4809 %!assert (Inf (3, 2, "single"), single ([Inf, Inf; Inf, Inf; Inf, Inf]))
4810 %!assert (size (inf (3, 4, 5, "single")), [3, 4, 5])
4811 
4812 ## Note: Matlab compatibility requires using 0 for negative dimensions.
4813 %!assert (size (Inf (2, -3, 2)), [2, 0, 2])
4814 
4815 %!assert (Inf (2, 2, "like", speye (2)), sparse ([Inf, Inf; Inf, Inf]))
4816 %!assert (Inf (2, 2, "like", complex (ones (2, 2))), [Inf, Inf; Inf, Inf])
4817 %!assert (Inf (2, 2, "like", double (1)), double ([Inf, Inf; Inf, Inf]))
4818 %!assert (Inf (3, 3, "like", single (1)),
4819 %! single ([Inf, Inf, Inf; Inf, Inf, Inf; Inf, Inf, Inf]))
4820 %!assert (Inf (2, "like", single (1i)), single ([Inf, Inf; Inf, Inf]))
4821 
4822 %!error Inf (3, "like", int8 (1))
4823 
4824 %!error Inf (3, "int8")
4825 %!error Inf (2, 3, "int8")
4826 %!error Inf (3, 2, "int8")
4827 %!error Inf (3, 4, 5, "int8")
4828 %!error <input .* floating> Inf (3, 3, "like", true)
4829 %!error <input .* floating> Inf (2, "like", uint8 (1))
4830 %!error <must be scalar> Inf (1:3, 1)
4831 %!error <must be scalar> Inf (1, 1:3)
4832 %!error <must be scalar> Inf (1, 2, 1:3)
4833 %!error <must be scalar> Inf (1:3, 1, "like", single (1))
4834 */
4835 
4836 DEFUN (NaN, args, ,
4837  doc: /* -*- texinfo -*-
4838 @c List other form of function in documentation index
4839 @findex nan
4840 
4841 @deftypefn {} {@var{val} =} NaN
4842 @deftypefnx {} {@var{val} =} NaN (@var{n})
4843 @deftypefnx {} {@var{val} =} NaN (@var{n}, @var{m})
4844 @deftypefnx {} {@var{val} =} NaN (@var{n}, @var{m}, @var{k}, @dots{})
4845 @deftypefnx {} {@var{val} =} NaN (@dots{}, "like", @var{var})
4846 @deftypefnx {} {@var{val} =} NaN (@dots{}, @var{class})
4847 Return a scalar, matrix, or N-dimensional array whose elements are all equal
4848 to the IEEE symbol NaN (Not a Number).
4849 
4850 NaN is the result of operations which do not produce a well defined
4851 numerical result. Common operations which produce a NaN are arithmetic
4852 with infinity
4853 @tex
4854 ($\infty - \infty$), zero divided by zero ($0/0$),
4855 @end tex
4856 @ifnottex
4857 (Inf - Inf), zero divided by zero (0/0),
4858 @end ifnottex
4859 and any operation involving another NaN value (5 + NaN).
4860 
4861 Note that NaN always compares not equal to NaN (NaN != NaN). This behavior
4862 is specified by the IEEE standard for floating point arithmetic. To find
4863 NaN values, use the @code{isnan} function.
4864 
4865 When called with no arguments, return a scalar with the value @samp{NaN}.
4866 
4867 When called with a single argument, return a square matrix with the
4868 dimension specified.
4869 
4870 When called with more than one scalar argument the first two arguments are
4871 taken as the number of rows and columns and any further arguments specify
4872 additional matrix dimensions.
4873 
4874 If a variable @var{var} is specified after @qcode{"like"}, the output @var{val}
4875 will have the same data type, complexity, and sparsity as @var{var}.
4876 
4877 The optional argument @var{class} specifies the return type and may be
4878 either @qcode{"double"} or @qcode{"single"}.
4879 @seealso{isnan, Inf}
4880 @end deftypefn */)
4881 {
4882  return fill_matrix (args, lo_ieee_nan_value (),
4883  lo_ieee_float_nan_value (), "NaN");
4884 }
4885 
4886 DEFALIAS (nan, NaN);
4887 
4888 /*
4889 %!assert (NaN (3), [NaN, NaN, NaN; NaN, NaN, NaN; NaN, NaN, NaN])
4890 %!assert (NaN (2, 3), [NaN, NaN, NaN; NaN, NaN, NaN])
4891 %!assert (NaN (3, 2), [NaN, NaN; NaN, NaN; NaN, NaN])
4892 %!assert (size (NaN (3, 4, 5)), [3, 4, 5])
4893 
4894 %!assert (NaN (3, "single"),
4895 %! single ([NaN, NaN, NaN; NaN, NaN, NaN; NaN, NaN, NaN]))
4896 %!assert (NaN (2, 3, "single"), single ([NaN, NaN, NaN; NaN, NaN, NaN]))
4897 %!assert (NaN (3, 2, "single"), single ([NaN, NaN; NaN, NaN; NaN, NaN]))
4898 %!assert (size (NaN (3, 4, 5, "single")), [3, 4, 5])
4899 
4900 %!assert (NaN (2, 2, "like", double (1)), double ([NaN, NaN; NaN, NaN]))
4901 %!assert (NaN (2, 2, "like", complex (ones(2, 2))), [NaN, NaN; NaN, NaN])
4902 %!assert (NaN (3, 3, "like", single (1)),
4903 %! single ([NaN, NaN, NaN; NaN, NaN, NaN; NaN, NaN, NaN]))
4904 %!assert (NaN (2, "like", single (1i)), single ([NaN, NaN; NaN, NaN]))
4905 %!assert (NaN (2, 2, "like", speye (2)), sparse ([NaN, NaN; NaN, NaN]))
4906 
4907 %!error NaN (3, 'like', int8 (1))
4908 
4909 %!error NaN (3, "int8")
4910 %!error NaN (2, 3, "int8")
4911 %!error NaN (3, 2, "int8")
4912 %!error NaN (3, 4, 5, "int8")
4913 %!error <input .* floating> NaN (3, 3, "like", true)
4914 %!error <input .* floating> NaN (2, "like", uint8 (1))
4915 %!error <must be scalar> NaN (1:3, 1)
4916 %!error <must be scalar> NaN (1, 1:3)
4917 %!error <must be scalar> NaN (1, 2, 1:3)
4918 %!error <must be scalar> NaN (1:3, 1, "like", single (1))
4919 */
4920 
4921 DEFUN (e, args, ,
4922  doc: /* -*- texinfo -*-
4923 @deftypefn {} {@var{A} =} e
4924 @deftypefnx {} {@var{A} =} e (@var{n})
4925 @deftypefnx {} {@var{A} =} e (@var{n}, @var{m})
4926 @deftypefnx {} {@var{A} =} e (@var{n}, @var{m}, @var{k}, @dots{})
4927 @deftypefnx {} {@var{A} =} e (@dots{}, @var{class})
4928 Return a scalar, matrix, or N-dimensional array whose elements are all equal
4929 to the base of natural logarithms.
4930 
4931 The constant
4932 @tex
4933 $e$ satisfies the equation $\log (e) = 1$.
4934 @end tex
4935 @ifnottex
4936 @samp{e} satisfies the equation @code{log} (e) = 1.
4937 @end ifnottex
4938 
4939 When called with no arguments, return a scalar with the value @math{e}.
4940 
4941 When called with a single argument, return a square matrix with the dimension
4942 specified.
4943 
4944 When called with more than one scalar argument the first two arguments are
4945 taken as the number of rows and columns and any further arguments specify
4946 additional matrix dimensions.
4947 
4948 The optional argument @var{class} specifies the return type and may be either
4949 @qcode{"double"} or @qcode{"single"}.
4950 @seealso{log, exp, pi, I}
4951 @end deftypefn */)
4952 {
4953 #if defined (M_E)
4954  double e_val = M_E;
4955 #else
4956  double e_val = exp (1.0);
4957 #endif
4958 
4959  return fill_matrix (args, e_val, "e");
4960 }
4961 
4962 template <typename T>
4963 T
4964 eps (const T& x)
4965 {
4966  T epsval = x.abs ();
4967  typedef typename T::value_type P;
4968  for (octave_idx_type i = 0; i < x.numel (); i++)
4969  {
4970  P val = epsval.xelem (i);
4971  if (math::isnan (val) || math::isinf (val))
4972  epsval(i) = numeric_limits<P>::NaN ();
4973  else if (val < std::numeric_limits<P>::min ())
4974  epsval(i) = std::numeric_limits<P>::denorm_min ();
4975  else
4976  {
4977  int exponent;
4978  math::frexp (val, &exponent);
4979  const P digits = std::numeric_limits<P>::digits;
4980  epsval(i) = std::pow (static_cast<P> (2.0),
4981  static_cast<P> (exponent - digits));
4982  }
4983  }
4984  return epsval;
4985 }
4986 
4987 DEFUN (eps, args, ,
4988  doc: /* -*- texinfo -*-
4989 @deftypefn {} {@var{d} =} eps
4990 @deftypefnx {} {@var{d} =} eps (@var{x})
4991 @deftypefnx {} {@var{d} =} eps (@var{n}, @var{m})
4992 @deftypefnx {} {@var{d} =} eps (@var{n}, @var{m}, @var{k}, @dots{})
4993 @deftypefnx {} {@var{d} =} eps (@dots{}, @var{class})
4994 Return a scalar, matrix or N-dimensional array whose elements are all eps,
4995 the machine precision.
4996 
4997 More precisely, @code{eps} is the relative spacing between any two adjacent
4998 numbers in the machine's floating point system. This number is obviously
4999 system dependent. On machines that support IEEE floating point arithmetic,
5000 @code{eps} is approximately
5001 @tex
5002 $2.2204\times10^{-16}$ for double precision and $1.1921\times10^{-7}$
5003 @end tex
5004 @ifnottex
5005 2.2204e-16 for double precision and 1.1921e-07
5006 @end ifnottex
5007 for single precision.
5008 
5009 When called with no arguments, return a scalar with the value
5010 @code{eps (1.0)}.
5011 
5012 Given a single argument @var{x}, return the distance between @var{x} and the
5013 next largest value.
5014 
5015 When called with more than one argument the first two arguments are taken as
5016 the number of rows and columns and any further arguments specify additional
5017 matrix dimensions. The optional argument @var{class} specifies the return
5018 type and may be either @qcode{"double"} or @qcode{"single"}.
5019 @seealso{realmax, realmin, intmax, flintmax}
5020 @end deftypefn */)
5021 {
5022  octave_value retval;
5023 
5024  if (args.length () == 1 && ! args(0).is_string ())
5025  {
5026  octave_value arg0 = args(0);
5027  if (arg0.is_single_type ())
5028  {
5029  FloatNDArray epsval = eps (arg0.float_array_value ());
5030  retval = epsval;
5031  }
5032  else if (arg0.is_double_type ())
5033  {
5034  NDArray epsval = eps (arg0.array_value ());
5035  retval = epsval;
5036  }
5037  else
5038  error ("eps: X must be of a floating point type");
5039  }
5040  else
5041  retval = fill_matrix (args, std::numeric_limits<double>::epsilon (),
5042  std::numeric_limits<float>::epsilon (), "eps");
5043 
5044  return retval;
5045 }
5046 
5047 /*
5048 %!assert (eps (1/2), 2^(-53))
5049 %!assert (eps (1), 2^(-52))
5050 %!assert (eps (2), 2^(-51))
5051 %!assert (eps (realmax), 2^971)
5052 %!assert (eps (0), 2^(-1074))
5053 %!assert (eps (realmin/2), 2^(-1074))
5054 %!assert (eps (realmin/16), 2^(-1074))
5055 %!assert (eps (Inf), NaN)
5056 %!assert (eps (NaN), NaN)
5057 %!assert (eps ([1/2 1 2 realmax 0 realmin/2 realmin/16 Inf NaN]),
5058 %! [2^-53 2^-52 2^-51 2^971 2^-1074 2^-1074 2^-1074 NaN NaN])
5059 %!assert (eps (single (1/2)), single (2^(-24)))
5060 %!assert (eps (single (1)), single (2^(-23)))
5061 %!assert (eps (single (2)), single (2^(-22)))
5062 %!assert (eps (realmax ("single")), single (2^104))
5063 %!assert (eps (single (0)), single (2^(-149)))
5064 %!assert (eps (realmin ("single")/2), single (2^(-149)))
5065 %!assert (eps (realmin ("single")/16), single (2^(-149)))
5066 %!assert (eps (single (Inf)), single (NaN))
5067 %!assert (eps (single (NaN)), single (NaN))
5068 %!assert (eps (single ([1/2 1 2 realmax("single") 0 realmin("single")/2 realmin("single")/16 Inf NaN])),
5069 %! single ([2^-24 2^-23 2^-22 2^104 2^-149 2^-149 2^-149 NaN NaN]))
5070 
5071 ## Note: Matlab compatibility requires using 0 for negative dimensions.
5072 %!assert (size (eps (2, -3, 2)), [2, 0, 2])
5073 
5074 %!error <X must be of a floating point type> eps (uint8 ([0 1 2]))
5075 %!error <must be scalar> eps (1:3, 1)
5076 %!error <must be scalar> eps (1, 1:3)
5077 %!error <must be scalar> eps (1, 2, 1:3)
5078 %!error <must be scalar> eps (1:3, 1, "single")
5079 */
5080 
5081 DEFUN (pi, args, ,
5082  doc: /* -*- texinfo -*-
5083 @deftypefn {} {@var{p} =} pi
5084 @deftypefnx {} {@var{p} =} pi (@var{n})
5085 @deftypefnx {} {@var{p} =} pi (@var{n}, @var{m})
5086 @deftypefnx {} {@var{p} =} pi (@var{n}, @var{m}, @var{k}, @dots{})
5087 @deftypefnx {} {@var{p} =} pi (@dots{}, @var{class})
5088 Return a scalar, matrix, or N-dimensional array whose elements are all equal
5089 to the ratio of the circumference of a circle to its
5090 @tex
5091 diameter($\pi$).
5092 @end tex
5093 @ifnottex
5094 diameter.
5095 @end ifnottex
5096 
5097 When called with no arguments, return a scalar with the value of
5098 @tex
5099 $\pi$.
5100 @end tex
5101 @ifnottex
5102 pi.
5103 @end ifnottex
5104 
5105 When called with a single argument, return a square matrix with the dimension
5106 specified.
5107 
5108 When called with more than one scalar argument the first two arguments are
5109 taken as the number of rows and columns and any further arguments specify
5110 additional matrix dimensions.
5111 
5112 The optional argument @var{class} specifies the return type and may be either
5113 @qcode{"double"} or @qcode{"single"}.
5114 @seealso{e, I}
5115 @end deftypefn */)
5116 {
5117 #if defined (M_PI)
5118  double pi_val = M_PI;
5119 #else
5120  double pi_val = 4.0 * atan (1.0);
5121 #endif
5122 
5123  return fill_matrix (args, pi_val, "pi");
5124 }
5125 
5126 DEFUN (realmax, args, ,
5127  doc: /* -*- texinfo -*-
5128 @deftypefn {} {@var{Rmax} =} realmax
5129 @deftypefnx {} {@var{Rmax} =} realmax (@var{n})
5130 @deftypefnx {} {@var{Rmax} =} realmax (@var{n}, @var{m})
5131 @deftypefnx {} {@var{Rmax} =} realmax (@var{n}, @var{m}, @var{k}, @dots{})
5132 @deftypefnx {} {@var{Rmax} =} realmax (@dots{}, @var{class})
5133 Return a scalar, matrix, or N-dimensional array whose elements are all equal
5134 to the largest floating point number that is representable.
5135 
5136 The actual value is system dependent. On machines that support IEEE
5137 floating point arithmetic, @code{realmax} is approximately
5138 @tex
5139 $1.7977\times10^{308}$ for double precision and $3.4028\times10^{38}$
5140 @end tex
5141 @ifnottex
5142 1.7977e+308 for double precision and 3.4028e+38
5143 @end ifnottex
5144 for single precision.
5145 
5146 When called with no arguments, return a scalar with the value
5147 @code{realmax (@qcode{"double"})}.
5148 
5149 When called with a single argument, return a square matrix with the
5150 dimension specified.
5151 
5152 When called with more than one scalar argument the first two arguments are
5153 taken as the number of rows and columns and any further arguments specify
5154 additional matrix dimensions.
5155 
5156 The optional argument @var{class} specifies the return type and may be
5157 either @qcode{"double"} or @qcode{"single"}.
5158 @seealso{realmin, intmax, flintmax, eps}
5159 @end deftypefn */)
5160 {
5161  return fill_matrix (args, std::numeric_limits<double>::max (),
5162  std::numeric_limits<float>::max (), "realmax");
5163 }
5164 
5165 DEFUN (realmin, args, ,
5166  doc: /* -*- texinfo -*-
5167 @deftypefn {} {@var{Rmin} =} realmin
5168 @deftypefnx {} {@var{Rmin} =} realmin (@var{n})
5169 @deftypefnx {} {@var{Rmin} =} realmin (@var{n}, @var{m})
5170 @deftypefnx {} {@var{Rmin} =} realmin (@var{n}, @var{m}, @var{k}, @dots{})
5171 @deftypefnx {} {@var{Rmin} =} realmin (@dots{}, @var{class})
5172 Return a scalar, matrix, or N-dimensional array whose elements are all equal
5173 to the smallest normalized floating point number that is representable.
5174 
5175 The actual value is system dependent. On machines that support IEEE floating
5176 point arithmetic, @code{realmin} is approximately
5177 @tex
5178 $2.2251\times10^{-308}$ for double precision and $1.1755\times10^{-38}$
5179 @end tex
5180 @ifnottex
5181 2.2251e-308 for double precision and 1.1755e-38
5182 @end ifnottex
5183 for single precision.
5184 
5185 When called with no arguments, return a scalar with the value
5186 @code{realmin (@qcode{"double"})}.
5187 
5188 When called with a single argument, return a square matrix with the dimension
5189 specified.
5190 
5191 When called with more than one scalar argument the first two arguments are
5192 taken as the number of rows and columns and any further arguments specify
5193 additional matrix dimensions.
5194 
5195 The optional argument @var{class} specifies the return type and may be either
5196 @qcode{"double"} or @qcode{"single"}.
5197 @seealso{realmax, intmin, eps}
5198 @end deftypefn */)
5199 {
5200  return fill_matrix (args, std::numeric_limits<double>::min (),
5201  std::numeric_limits<float>::min (), "realmin");
5202 }
5203 
5204 DEFUN (I, args, ,
5205  doc: /* -*- texinfo -*-
5206 @c List other forms of function in documentation index
5207 @findex i
5208 @findex j
5209 @findex J
5210 
5211 @deftypefn {} {@var{A} =} I
5212 @deftypefnx {} {@var{A} =} I (@var{n})
5213 @deftypefnx {} {@var{A} =} I (@var{n}, @var{m})
5214 @deftypefnx {} {@var{A} =} I (@var{n}, @var{m}, @var{k}, @dots{})
5215 @deftypefnx {} {@var{A} =} I (@dots{}, @var{class})
5216 Return a scalar, matrix, or N-dimensional array whose elements are all equal
5217 to the pure imaginary unit, defined as
5218 @tex
5219 $\sqrt{-1}$.
5220 @end tex
5221 @ifnottex
5222 @w{@code{sqrt (-1)}}.
5223 @end ifnottex
5224 
5225 I, and its equivalents i, j, and J, are functions so any of the names may
5226 be reused for other purposes (such as i for a counter variable).
5227 
5228 When called with no arguments, return a scalar with the value @math{i}.
5229 
5230 When called with a single argument, return a square matrix with the
5231 dimension specified.
5232 
5233 When called with more than one scalar argument the first two arguments are
5234 taken as the number of rows and columns and any further arguments specify
5235 additional matrix dimensions.
5236 
5237 The optional argument @var{class} specifies the return type and may be
5238 either @qcode{"double"} or @qcode{"single"}.
5239 @seealso{e, pi, log, exp}
5240 @end deftypefn */)
5241 {
5242  return fill_matrix (args, Complex (0.0, 1.0), "I");
5243 }
5244 
5245 DEFALIAS (i, I);
5246 DEFALIAS (J, I);
5247 DEFALIAS (j, I);
5248 
5249 DEFUN (NA, args, ,
5250  doc: /* -*- texinfo -*-
5251 @deftypefn {} {@var{val} =} NA
5252 @deftypefnx {} {@var{val} =} NA (@var{n})
5253 @deftypefnx {} {@var{val} =} NA (@var{n}, @var{m})
5254 @deftypefnx {} {@var{val} =} NA (@var{n}, @var{m}, @var{k}, @dots{})
5255 @deftypefnx {} {@var{val} =} NA (@dots{}, "like", @var{var})
5256 @deftypefnx {} {@var{val} =} NA (@dots{}, @var{class})
5257 Return a scalar, matrix, or N-dimensional array whose elements are all equal
5258 to the special constant used to designate missing values.
5259 
5260 Note that NA always compares not equal to NA (NA != NA).
5261 To find NA values, use the @code{isna} function.
5262 
5263 When called with no arguments, return a scalar with the value @samp{NA}.
5264 
5265 When called with a single argument, return a square matrix with the
5266 dimension specified.
5267 
5268 When called with more than one scalar argument the first two arguments are
5269 taken as the number of rows and columns and any further arguments specify
5270 additional matrix dimensions.
5271 
5272 If a variable @var{var} is specified after @qcode{"like"}, the output @var{val}
5273 will have the same data type, complexity, and sparsity as @var{var}.
5274 
5275 The optional argument @var{class} specifies the return type and may be
5276 either @qcode{"double"} or @qcode{"single"}.
5277 @seealso{isna}
5278 @end deftypefn */)
5279 {
5280  return fill_matrix (args, lo_ieee_na_value (),
5281  lo_ieee_float_na_value (), "NA");
5282 }
5283 
5284 /*
5285 %!assert (single (NA ("double")), NA ("single"))
5286 %!assert (double (NA ("single")), NA ("double"))
5287 */
5288 
5289 DEFUN (false, args, ,
5290  doc: /* -*- texinfo -*-
5291 @deftypefn {} {@var{val} =} false (@var{x})
5292 @deftypefnx {} {@var{val} =} false (@var{n}, @var{m})
5293 @deftypefnx {} {@var{val} =} false (@var{n}, @var{m}, @var{k}, @dots{})
5294 @deftypefnx {} {@var{val} =} false (@dots{}, "like", @var{var})
5295 Return a matrix or N-dimensional array whose elements are all logical 0.
5296 
5297 If invoked with a single scalar integer argument, return a square
5298 matrix of the specified size.
5299 
5300 If invoked with two or more scalar integer arguments, or a vector of integer
5301 values, return an array with given dimensions.
5302 
5303 If a logical variable @var{var} is specified after @qcode{"like"}, the output
5304 @var{val} will have the same sparsity as @var{var}.
5305 @seealso{true}
5306 @end deftypefn */)
5307 {
5308  return fill_matrix (args, false, "false");
5309 }
5310 
5311 /*
5312 %!assert (false (2, 3), logical (zeros (2, 3)))
5313 %!assert (false (2, 3, "logical"), logical (zeros (2, 3)))
5314 %!assert (false (2, 1, "like", true), [false; false])
5315 %!assert (false (2, 1, "like", sparse (true)), sparse ([false; false]))
5316 
5317 %!error false (2, 3, "double")
5318 %!error <input .* logical> false (2, 1, "like", sparse (1))
5319 %!error <must be scalar> false (1:3, 1)
5320 %!error <must be scalar> false (1, 1:3)
5321 %!error <must be scalar> false (1, 2, 1:3)
5322 */
5323 
5324 DEFUN (true, args, ,
5325  doc: /* -*- texinfo -*-
5326 @deftypefn {} {@var{val} =} true (@var{x})
5327 @deftypefnx {} {@var{val} =} true (@var{n}, @var{m})
5328 @deftypefnx {} {@var{val} =} true (@var{n}, @var{m}, @var{k}, @dots{})
5329 @deftypefnx {} {@var{val} =} true (@dots{}, "like", @var{var})
5330 Return a matrix or N-dimensional array whose elements are all logical 1.
5331 
5332 If invoked with a single scalar integer argument, return a square
5333 matrix of the specified size.
5334 
5335 If invoked with two or more scalar integer arguments, or a vector of integer
5336 values, return an array with given dimensions.
5337 
5338 If a logical variable @var{var} is specified after @qcode{"like"}, the output
5339 @var{val} will have the same sparsity as @var{var}.
5340 @seealso{false}
5341 @end deftypefn */)
5342 {
5343  return fill_matrix (args, true, "true");
5344 }
5345 
5346 /*
5347 %!assert (true (2, 3), logical (ones (2, 3)))
5348 %!assert (true (2, 3, "logical"), logical (ones (2, 3)))
5349 %!assert (true (2, 1, "like", false), [true; true])
5350 %!assert (true (2, 1, "like", sparse (true)), sparse ([true; true]))
5351 
5352 %!error true (2, 3, "double")
5353 %!error <input .* logical> true (2, 1, "like", double (1))
5354 %!error <must be scalar> true (1:3, 1)
5355 %!error <must be scalar> true (1, 1:3)
5356 %!error <must be scalar> true (1, 2, 1:3)
5357 */
5358 
5359 template <typename MT>
5361 identity_matrix (int nr, int nc)
5362 {
5363  octave_value retval;
5364 
5365  typename MT::element_type one (1);
5366 
5367  if (nr == 1 && nc == 1)
5368  retval = one;
5369  else
5370  {
5371  dim_vector dims (nr, nc);
5372 
5373  typename MT::element_type zero (0);
5374 
5375  MT m (dims, zero);
5376 
5377  if (nr > 0 && nc > 0)
5378  {
5379  int n = std::min (nr, nc);
5380 
5381  for (int i = 0; i < n; i++)
5382  m(i, i) = one;
5383  }
5384 
5385  retval = m;
5386  }
5387 
5388  return retval;
5389 }
5390 
5391 #define INSTANTIATE_EYE(T) \
5392  template octave_value identity_matrix<T> (int, int)
5393 
5405 
5406 static octave_value
5407 identity_matrix (int nr, int nc, oct_data_conv::data_type dt)
5408 {
5409  octave_value retval;
5410 
5411  // FIXME: Perhaps this should be made extensible by using the class name
5412  // to lookup a function to call to create the new value.
5413 
5414  switch (dt)
5415  {
5417  retval = identity_matrix<int8NDArray> (nr, nc);
5418  break;
5419 
5421  retval = identity_matrix<uint8NDArray> (nr, nc);
5422  break;
5423 
5425  retval = identity_matrix<int16NDArray> (nr, nc);
5426  break;
5427 
5429  retval = identity_matrix<uint16NDArray> (nr, nc);
5430  break;
5431 
5433  retval = identity_matrix<int32NDArray> (nr, nc);
5434  break;
5435 
5437  retval = identity_matrix<uint32NDArray> (nr, nc);
5438  break;
5439 
5441  retval = identity_matrix<int64NDArray> (nr, nc);
5442  break;
5443 
5445  retval = identity_matrix<uint64NDArray> (nr, nc);
5446  break;
5447 
5449  retval = FloatDiagMatrix (nr, nc, 1.0f);
5450  break;
5451 
5453  retval = DiagMatrix (nr, nc, 1.0);
5454  break;
5455 
5457  retval = identity_matrix<boolNDArray> (nr, nc);
5458  break;
5459 
5460  default:
5461  error ("eye: invalid class name");
5462  break;
5463  }
5464 
5465  return retval;
5466 }
5467 
5468 #undef INT_EYE_MATRIX
5469 
5470 DEFUN (eye, args, ,
5471  doc: /* -*- texinfo -*-
5472 @deftypefn {} {@var{I} =} eye (@var{n})
5473 @deftypefnx {} {@var{I} =} eye (@var{m}, @var{n})
5474 @deftypefnx {} {@var{I} =} eye ([@var{m} @var{n}])
5475 @deftypefnx {} {@var{I} =} eye (@dots{}, @var{class})
5476 Return an identity matrix.
5477 
5478 If invoked with a single scalar argument @var{n}, return a square
5479 @nospell{NxN} identity matrix.
5480 
5481 If supplied two scalar arguments (@var{m}, @var{n}), @code{eye} takes them
5482 to be the number of rows and columns. If given a vector with two elements,
5483 @code{eye} uses the values of the elements as the number of rows and
5484 columns, respectively. For example:
5485 
5486 @example
5487 @group
5488 eye (3)
5489  @result{} 1 0 0
5490  0 1 0
5491  0 0 1
5492 @end group
5493 @end example
5494 
5495 The following expressions all produce the same result:
5496 
5497 @example
5498 @group
5499 eye (2)
5500 @equiv{}
5501 eye (2, 2)
5502 @equiv{}
5503 eye (size ([1, 2; 3, 4]))
5504 @end group
5505 @end example
5506 
5507 The optional argument @var{class}, allows @code{eye} to return an array of
5508 the specified type, like
5509 
5510 @example
5511 val = zeros (n,m, "uint8")
5512 @end example
5513 
5514 Calling @code{eye} with no arguments is equivalent to calling it with an
5515 argument of 1. Any negative dimensions are treated as zero. These odd
5516 definitions are for compatibility with @sc{matlab}.
5517 @seealso{speye, ones, zeros}
5518 @end deftypefn */)
5519 {
5520  int nargin = args.length ();
5521 
5523 
5524  // Check for type information.
5525 
5526  if (nargin > 0 && args(nargin-1).is_string ())
5527  {
5528  std::string nm = args(nargin-1).string_value ();
5529  nargin--;
5530 
5532  }
5533 
5534  if (nargin > 2)
5535  print_usage ();
5536 
5537  octave_value retval;
5538 
5539  if (nargin == 0)
5540  retval = identity_matrix (1, 1, dt);
5541  else if (nargin == 1)
5542  {
5543  octave_idx_type nr, nc;
5544  get_dimensions (args(0), "eye", nr, nc);
5545 
5546  retval = identity_matrix (nr, nc, dt);
5547  }
5548  else
5549  {
5550  octave_idx_type nr, nc;
5551  get_dimensions (args(0), args(1), "eye", nr, nc);
5552 
5553  retval = identity_matrix (nr, nc, dt);
5554  }
5555 
5556  return retval;
5557 }
5558 
5559 /*
5560 %!assert (full (eye (3)), [1, 0, 0; 0, 1, 0; 0, 0, 1])
5561 %!assert (full (eye (2, 3)), [1, 0, 0; 0, 1, 0])
5562 
5563 %!assert (full (eye (3, "single")), single ([1, 0, 0; 0, 1, 0; 0, 0, 1]))
5564 %!assert (full (eye (2, 3, "single")), single ([1, 0, 0; 0, 1, 0]))
5565 
5566 %!assert (eye (3, "int8"), int8 ([1, 0, 0; 0, 1, 0; 0, 0, 1]))
5567 %!assert (eye (2, 3, "int8"), int8 ([1, 0, 0; 0, 1, 0]))
5568 
5569 ## Note: Matlab compatibility requires using 0 for negative dimensions.
5570 %!assert (size (eye (2, -3)), [2, 0])
5571 
5572 ## Test input validation
5573 %!error eye (1, 2, 3)
5574 %!error <conversion of 1.1 .*failed> eye (1.1)
5575 %!error <conversion of 1.1 .*failed> eye (1, 1.1)
5576 %!error <conversion of 1.1 .*failed> eye ([1, 1.1])
5577 */
5578 
5579 template <typename MT>
5580 static octave_value
5581 do_linspace (const octave_value& base, const octave_value& limit,
5583 {
5584  typedef typename MT::column_vector_type CVT;
5585  typedef typename MT::element_type T;
5586 
5587  octave_value retval;
5588 
5589  if (base.is_scalar_type ())
5590  {
5591  T bs = octave_value_extract<T> (base);
5592  if (limit.is_scalar_type ())
5593  {
5594  T ls = octave_value_extract<T> (limit);
5595  retval = linspace (bs, ls, n);
5596  }
5597  else
5598  {
5599  CVT lv = octave_value_extract<CVT> (limit);
5600  CVT bv (lv.numel (), bs);
5601  retval = linspace (bv, lv, n);
5602  }
5603  }
5604  else
5605  {
5606  CVT bv = octave_value_extract<CVT> (base);
5607  if (limit.is_scalar_type ())
5608  {
5609  T ls = octave_value_extract<T> (limit);
5610  CVT lv (bv.numel (), ls);
5611  retval = linspace (bv, lv, n);
5612  }
5613  else
5614  {
5615  CVT lv = octave_value_extract<CVT> (limit);
5616  retval = linspace (bv, lv, n);
5617  }
5618  }
5619 
5620  return retval;
5621 }
5622 
5623 DEFUN (linspace, args, ,
5624  doc: /* -*- texinfo -*-
5625 @deftypefn {} {@var{y} =} linspace (@var{start}, @var{end})
5626 @deftypefnx {} {@var{y} =} linspace (@var{start}, @var{end}, @var{n})
5627 Return a row vector with @var{n} linearly spaced elements between @var{start}
5628 and @var{end}.
5629 
5630 If the number of elements @var{n} is greater than one, then the endpoints
5631 @var{start} and @var{end} are always included in the range. If @var{start} is
5632 greater than @var{end}, the elements are stored in decreasing order. If the
5633 number of points @var{n} is not specified, a value of 100 is used.
5634 
5635 The @code{linspace} function returns a row vector when both @var{start} and
5636 @var{end} are scalars. If one, or both, inputs are vectors, then
5637 @code{linspace} transforms them to column vectors and returns a matrix where
5638 each row is an independent sequence between
5639 @w{@code{@var{start}(@var{row_n}), @var{end}(@var{row_n})}}.
5640 
5641 Programming Notes: For compatibility with @sc{matlab}, return the second
5642 argument (@var{end}) when a single value (@var{n} = 1) is requested. If
5643 @var{n} is not an integer then @code{floor (@var{n})} is used to round the
5644 number of elements. If @var{n} is zero or negative then an empty 1x0 matrix
5645 is returned.
5646 @seealso{colon, logspace}
5647 @end deftypefn */)
5648 {
5649  int nargin = args.length ();
5650 
5651  if (nargin != 2 && nargin != 3)
5652  print_usage ();
5653 
5654  octave_idx_type npoints = 100;
5655  if (nargin == 3)
5656  {
5657  // Apparently undocumented Matlab. If the third arg is an empty
5658  // numeric value, the number of points defaults to 1.
5659  octave_value arg_3 = args(2);
5660 
5661  if (arg_3.isnumeric () && arg_3.isempty ())
5662  npoints = 1;
5663  else if (! arg_3.is_scalar_type ())
5664  error ("linspace: N must be a scalar");
5665  else
5666  // Even if third arg is not an integer, it must be cast to int
5667  npoints = arg_3.idx_type_value ();
5668  }
5669 
5670  octave_value arg_1 = args(0);
5671  octave_value arg_2 = args(1);
5672 
5673  dim_vector sz1 = arg_1.dims ();
5674  bool isvector1 = sz1.ndims () == 2 && (sz1(0) == 1 || sz1(1) == 1);
5675  dim_vector sz2 = arg_2.dims ();
5676  bool isvector2 = sz2.ndims () == 2 && (sz2(0) == 1 || sz2(1) == 1);
5677 
5678  if (! isvector1 || ! isvector2)
5679  error ("linspace: START, END must be scalars or vectors");
5680 
5681  octave_value retval;
5682 
5683  if (arg_1.is_single_type () || arg_2.is_single_type ())
5684  {
5685  if (arg_1.iscomplex () || arg_2.iscomplex ())
5686  retval = do_linspace<FloatComplexMatrix> (arg_1, arg_2, npoints);
5687  else
5688  retval = do_linspace<FloatMatrix> (arg_1, arg_2, npoints);
5689  }
5690  else
5691  {
5692  if (arg_1.iscomplex () || arg_2.iscomplex ())
5693  retval = do_linspace<ComplexMatrix> (arg_1, arg_2, npoints);
5694  else
5695  retval = do_linspace<Matrix> (arg_1, arg_2, npoints);
5696  }
5697 
5698  return retval;
5699 }
5700 
5701 /*
5702 %!test
5703 %! x1 = linspace (1, 2);
5704 %! x2 = linspace (1, 2, 10);
5705 %! x3 = linspace (1, -2, 10);
5706 %! assert (size (x1) == [1, 100] && x1(1) == 1 && x1(100) == 2);
5707 %! assert (x1(2) - x1(1), (2 - 1)/ (100 - 1), eps);
5708 %! assert (size (x2) == [1, 10] && x2(1) == 1 && x2(10) == 2);
5709 %! assert (x2(2) - x2(1), (2 - 1)/ (10 - 1), eps);
5710 %! assert (size (x3) == [1, 10] && x3(1) == 1 && x3(10) == -2);
5711 %! assert (x3(2) - x3(1), (-2 - 1)/ (10 - 1), eps);
5712 
5713 ## Test complex values
5714 %!test
5715 %! exp = [1+0i, 2-1.25i, 3-2.5i, 4-3.75i, 5-5i];
5716 %! obs = linspace (1, 5-5i, 5);
5717 %! assert (obs, exp);
5718 
5719 ## Test support for vectors in START and END
5720 %!assert (linspace ([1 2 3], [7 8 9]),
5721 %! [linspace(1, 7); linspace(2, 8); linspace(3, 9)], 10*eps)
5722 %!assert (linspace ([1 2 3]', [7 8 9]'),
5723 %! [linspace(1, 7); linspace(2, 8); linspace(3, 9)], 10*eps)
5724 %!assert (linspace ([1 2 3], 9),
5725 %! [linspace(1, 9); linspace(2, 9); linspace(3, 9)], 10*eps)
5726 %!assert (linspace ([1 2 3]', 9),
5727 %! [linspace(1, 9); linspace(2, 9); linspace(3, 9)], 10*eps)
5728 %!assert (linspace (1, [7 8 9]),
5729 %! [linspace(1, 7); linspace(1, 8); linspace(1, 9)], 10*eps)
5730 %!assert (linspace (1, [7 8 9]'),
5731 %! [linspace(1, 7); linspace(1, 8); linspace(1, 9)], 10*eps)
5732 
5733 ## Test class of output
5734 %!assert (class (linspace (1, 2)), "double")
5735 %!assert (class (linspace (single (1), 2)), "single")
5736 %!assert (class (linspace (1, single (2))), "single")
5737 
5738 ## Test symmetry
5739 %!test <*56659>
5740 %! x = linspace (-1, 1, 10);
5741 %! assert (all (x == -fliplr (x)));
5742 %! x = linspace (-1, 1, 11);
5743 %! assert (all (x == -fliplr (x)));
5744 
5745 %!test <*56659>
5746 %! x = linspace (-1-1i, 1+1i, 10);
5747 %! assert (all (x == -fliplr (x)));
5748 %! x = linspace (-1-1i, 1+1i, 11);
5749 %! assert (all (x == -fliplr (x)));
5750 
5751 %!test <*56659>
5752 %! x = linspace (single (-1), 1, 10);
5753 %! assert (all (x == -fliplr (x)));
5754 %! x = linspace (single (-1), 1, 11);
5755 %! assert (all (x == -fliplr (x)));
5756 
5757 %!test <*56659>
5758 %! x = linspace (single (-1-1i), 1+1i, 10);
5759 %! assert (all (x == -fliplr (x)));
5760 %! x = linspace (single (-1-1i), 1+1i, 11);
5761 %! assert (all (x == -fliplr (x)));
5762 
5763 ## Test obscure Matlab compatibility options
5764 %!assert (linspace (0, 1, []), 1)
5765 %!assert (linspace (10, 20, 2), [10 20])
5766 %!assert (linspace (10, 20, 1), [20])
5767 %!assert (linspace (10, 20, 0), zeros (1, 0))
5768 %!assert (linspace (10, 20, -1), zeros (1, 0))
5769 %!assert (numel (linspace (0, 1, 2+eps)), 2)
5770 %!assert (numel (linspace (0, 1, 2-eps)), 1)
5771 %!assert (linspace (10, 20, 2.1), [10 20])
5772 %!assert (linspace (10, 20, 2.9), [10 20])
5773 %!assert (linspace (Inf, Inf, 3), [Inf, Inf, Inf])
5774 %!assert (linspace (-Inf, -Inf, 3), [-Inf, -Inf, -Inf])
5775 %!assert (linspace (-Inf, Inf, 3), [-Inf, 0, Inf])
5776 ## Octave prefers to return NaN which indicates failure of algorithm.
5777 %!assert (linspace (-Inf, Inf, 4), [-Inf, NaN, NaN, Inf])
5778 %!assert (linspace (-Inf, 0, 3), [-Inf, NaN, 0])
5779 %!assert (linspace (-Inf, 0, 4), [-Inf, NaN, NaN, 0])
5780 %!assert (linspace (Inf + 1i, Inf + 1i, 3), [Inf + 1i, Inf + 1i, Inf + 1i])
5781 %!assert (linspace (-Inf - 1i, Inf + 1i, 3), [-Inf - 1i, 0 + 0i, Inf + 1i])
5782 %!assert (linspace (-Inf - 1i, Inf + 2i, 3), [-Inf - 1i, NaN + 0.5i, Inf + 2i])
5783 %!assert (linspace (-Inf - 3i, Inf + 0i, 4),
5784 %! [-Inf - 3i, NaN - 2i, NaN - 1i, Inf + 0i])
5785 %!assert (linspace (complex (-1, -Inf), complex (1, Inf), 3),
5786 %! [complex(-1, -Inf), 0 + 0i, complex(1, Inf)])
5787 %!assert (linspace (complex (-1, -Inf), complex (2, Inf), 3),
5788 %! [complex(-1, -Inf), complex(0.5, NaN), complex(2, Inf)])
5789 %!assert (linspace (complex (-3, -Inf), complex (0, Inf), 4),
5790 %! [complex(-3, -Inf), complex(-2, NaN), complex(-1, NaN), complex(0, Inf)])
5791 
5792 ## FIXME: Octave is not fully Matlab-compatible for some combinations of
5793 ## Inf/-Inf endpoints. See bug #56933. This was dubbed "Won't Fix"
5794 ## as Octave prefers to return NaN for some of these conditions to
5795 ## better reflect that the algorithm has failed. If the behavior in
5796 ## the future is made compatible these tests can be re-instated.
5797 ##%!assert <56933> (linspace (-Inf, Inf, 4), [-Inf, -Inf, Inf, Inf])
5798 ##%!assert <56933> (linspace (-Inf, Inf, 5), [-Inf, -Inf, 0, Inf, Inf])
5799 ##%!assert <56933> (linspace (0, Inf, 4), [0, Inf, Inf, Inf])
5800 ##%!assert <56933> (linspace (0, -Inf, 4), [0, -Inf, -Inf, -Inf])
5801 ##%!assert <56933> (linspace (-Inf, 0, 4), [-Inf, NaN, NaN, 0])
5802 ##%!assert <56933> (linspace (Inf, 0, 4), [Inf, NaN, NaN, 0])
5803 ##%!assert (1 ./ linspace (-0, 0, 4), [-Inf, Inf, Inf, Inf])
5804 
5805 ## Test input validation
5806 %!error <Invalid call> linspace ()
5807 %!error <Invalid call> linspace (1, 2, 3, 4)
5808 %!error <N must be a scalar> linspace (1, 2, [3, 4])
5809 %!error <START, END must be scalars or vectors> linspace (ones (2,2), 2, 3)
5810 %!error <START, END must be scalars or vectors> linspace (2, ones (2,2), 3)
5811 %!error <START, END must be scalars or vectors> linspace (1, [], 3)
5812 */
5813 
5814 // FIXME: should accept dimensions as separate args for N-D
5815 // arrays as well as 1-D and 2-D arrays.
5816 
5817 DEFUN (resize, args, ,
5818  doc: /* -*- texinfo -*-
5819 @deftypefn {} {@var{B} =} resize (@var{A}, @var{m})
5820 @deftypefnx {} {@var{B} =} resize (@var{A}, @var{m}, @var{n}, @dots{})
5821 @deftypefnx {} {@var{B} =} resize (@var{A}, [@var{m} @var{n} @dots{}])
5822 Resize @var{A} cutting off elements as necessary.
5823 
5824 In the result, element with certain indices is equal to the corresponding
5825 element of @var{A} if the indices are within the bounds of @var{A}; otherwise,
5826 the element is set to zero.
5827 
5828 In other words, the statement
5829 
5830 @example
5831 B = resize (A, dv)
5832 @end example
5833 
5834 @noindent
5835 is equivalent to the following code:
5836 
5837 @example
5838 @group
5839 B = zeros (dv, class (A));
5840 sz = min (dv, size (A));
5841 for i = 1:length (sz)
5842  idx@{i@} = 1:sz(i);
5843 endfor
5844 B(idx@{:@}) = A(idx@{:@});
5845 @end group
5846 @end example
5847 
5848 @noindent
5849 but is performed more efficiently.
5850 
5851 If only @var{m} is supplied, and it is a scalar, the dimension of the result is
5852 @var{m}-by-@var{m}. If @var{m}, @var{n}, @dots{} are all scalars, then the
5853 dimensions of the result are @var{m}-by-@var{n}-by-@dots{}. If given a vector
5854 as input, then the dimensions of the result are given by the elements of that
5855 vector.
5856 
5857 An object can be resized to more dimensions than it has; in such case the
5858 missing dimensions are assumed to be 1. Resizing an object to fewer dimensions
5859 is not possible.
5860 @seealso{reshape, postpad, prepad, cat}
5861 @end deftypefn */)
5862 {
5863  int nargin = args.length ();
5864 
5865  if (nargin < 2)
5866  print_usage ();
5867 
5868  octave_value retval;
5869 
5870  if (nargin == 2)
5871  {
5872  Array<double> vec = args(1).vector_value ();
5873  int ndim = vec.numel ();
5874  if (ndim == 1)
5875  {
5876  octave_idx_type m = static_cast<octave_idx_type> (vec(0));
5877  retval = args(0);
5878  retval = retval.resize (dim_vector (m, m), true);
5879  }
5880  else
5881  {
5882  dim_vector dv;
5883  dv.resize (ndim);
5884  for (int i = 0; i < ndim; i++)
5885  dv(i) = static_cast<octave_idx_type> (vec(i));
5886  retval = args(0);
5887  retval = retval.resize (dv, true);
5888  }
5889  }
5890  else
5891  {
5892  dim_vector dv;
5893  dv.resize (nargin - 1);
5894  for (octave_idx_type i = 1; i < nargin; i++)
5895  dv(i-1) = static_cast<octave_idx_type> (args(i).scalar_value ());
5896 
5897  retval = args(0);
5898  retval = retval.resize (dv, true);
5899  }
5900 
5901  return retval;
5902 }
5903 
5904 // FIXME: should use octave_idx_type for dimensions.
5905 
5906 DEFUN (reshape, args, ,
5907  doc: /* -*- texinfo -*-
5908 @deftypefn {} {@var{B} =} reshape (@var{A}, @var{m}, @var{n}, @dots{})
5909 @deftypefnx {} {@var{B} =} reshape (@var{A}, [@var{m} @var{n} @dots{}])
5910 @deftypefnx {} {@var{B} =} reshape (@var{A}, @dots{}, [], @dots{})
5911 @deftypefnx {} {@var{B} =} reshape (@var{A}, @var{size})
5912 Return a matrix with the specified dimensions (@var{m}, @var{n}, @dots{})
5913 whose elements are taken from the matrix @var{A}.
5914 
5915 The elements of the matrix are accessed in column-major order (like Fortran
5916 arrays are stored).
5917 
5918 The following code demonstrates reshaping a 1x4 row vector into a 2x2 square
5919 matrix.
5920 
5921 @example
5922 @group
5923 reshape ([1, 2, 3, 4], 2, 2)
5924  @result{} 1 3
5925  2 4
5926 @end group
5927 @end example
5928 
5929 @noindent
5930 Note that the total number of elements in the original matrix
5931 (@code{prod (size (@var{A}))}) must match the total number of elements
5932 in the new matrix (@code{prod ([@var{m} @var{n} @dots{}])}).
5933 
5934 A single dimension of the return matrix may be left unspecified and Octave
5935 will determine its size automatically. An empty matrix ([]) is used to flag
5936 the unspecified dimension.
5937 @seealso{resize, vec, postpad, cat, squeeze}
5938 @end deftypefn */)
5939 {
5940  int nargin = args.length ();
5941 
5942  if (nargin < 2)
5943  print_usage ();
5944 
5945  octave_value retval;
5946 
5947  dim_vector new_dims;
5948 
5949  if (nargin == 2)
5950  {
5951  Array<octave_idx_type> new_size = args(1).octave_idx_type_vector_value ();
5952 
5953  if (new_size.numel () < 2)
5954  error ("reshape: SIZE must have 2 or more dimensions");
5955 
5956  new_dims = dim_vector::alloc (new_size.numel ());
5957 
5958  for (octave_idx_type i = 0; i < new_size.numel (); i++)
5959  {
5960  if (new_size(i) < 0)
5961  error ("reshape: SIZE must be non-negative");
5962 
5963  new_dims(i) = new_size(i);
5964  }
5965  }
5966  else
5967  {
5968  new_dims = dim_vector::alloc (nargin-1);
5969  int empty_dim = -1;
5970 
5971  for (int i = 1; i < nargin; i++)
5972  {
5973  if (args(i).isempty ())
5974  {
5975  if (empty_dim > 0)
5976  error ("reshape: only a single dimension can be unknown");
5977 
5978  empty_dim = i;
5979  new_dims(i-1) = 1;
5980  }
5981  else
5982  {
5983  new_dims(i-1) = args(i).idx_type_value ();
5984 
5985  if (new_dims(i-1) < 0)
5986  error ("reshape: SIZE must be non-negative");
5987  }
5988  }
5989 
5990  if (empty_dim > 0)
5991  {
5992  octave_idx_type nel = new_dims.numel ();
5993 
5994  if (nel == 0)
5995  new_dims(empty_dim-1) = 0;
5996  else
5997  {
5998  octave_idx_type a_nel = args(0).numel ();
5999  octave_idx_type size_empty_dim = a_nel / nel;
6000 
6001  if (a_nel != size_empty_dim * nel)
6002  error ("reshape: SIZE is not divisible by the product of "
6003  "known dimensions (= %" OCTAVE_IDX_TYPE_FORMAT ")",
6004  nel);
6005 
6006  new_dims(empty_dim-1) = size_empty_dim;
6007  }
6008  }
6009  }
6010 
6011  retval = args(0).reshape (new_dims);
6012 
6013  return retval;
6014 }
6015 
6016 /*
6017 %!assert (size (reshape (ones (4, 4), 2, 8)), [2, 8])
6018 %!assert (size (reshape (ones (4, 4), 8, 2)), [8, 2])
6019 %!assert (size (reshape (ones (15, 4), 1, 60)), [1, 60])
6020 %!assert (size (reshape (ones (15, 4), 60, 1)), [60, 1])
6021 
6022 %!assert (size (reshape (ones (4, 4, "single"), 2, 8)), [2, 8])
6023 %!assert (size (reshape (ones (4, 4, "single"), 8, 2)), [8, 2])
6024 %!assert (size (reshape (ones (15, 4, "single"), 1, 60)), [1, 60])
6025 %!assert (size (reshape (ones (15, 4, "single"), 60, 1)), [60, 1])
6026 
6027 %!assert <*64080> (size (reshape (sparse (0, 1), 0, 0)), [0, 0])
6028 
6029 %!test
6030 %! s.a = 1;
6031 %! fail ("reshape (s, 2, 3)", "can't reshape 1x1 array to 2x3 array");
6032 
6033 %!error reshape ()
6034 %!error reshape (1, 2, 3, 4)
6035 %!error <SIZE must have 2 or more dimensions> reshape (1:3, 3)
6036 %!error <SIZE must be non-negative> reshape (1:3, [3 -1])
6037 %!error <only a single dimension can be unknown> reshape (1:3, 1,[],[],3)
6038 %!error <SIZE must be non-negative> reshape (1:3, 3, -1)
6039 %!error <SIZE is not divisible> reshape (1:3, 3, [], 2)
6040 */
6041 
6042 DEFUN (vec, args, ,
6043  doc: /* -*- texinfo -*-
6044 @deftypefn {} {@var{v} =} vec (@var{x})
6045 @deftypefnx {} {@var{v} =} vec (@var{x}, @var{dim})
6046 Return the vector obtained by stacking the columns of the matrix @var{x}
6047 one above the other.
6048 
6049 Without @var{dim} this is equivalent to @code{@var{x}(:)}.
6050 
6051 If @var{dim} is supplied, the dimensions of @var{v} are set to @var{dim}
6052 with all elements along the last dimension. This is equivalent to
6053 @code{shiftdim (@var{x}(:), 1-@var{dim})}.
6054 @seealso{vech, resize, cat}
6055 @end deftypefn */)
6056 {
6057  int nargin = args.length ();
6058 
6059  if (nargin < 1 || nargin > 2)
6060  print_usage ();
6061 
6062  int dim = 1;
6063  if (nargin == 2)
6064  {
6065  dim = args(1).idx_type_value ();
6066 
6067  if (dim < 1)
6068  error ("vec: DIM must be greater than zero");
6069  }
6070 
6072  octave_value arg = args(0);
6073 
6074  octave_value retval = arg.single_subsref ("(", colon);
6075 
6076  if (dim > 1)
6077  {
6078  dim_vector new_dims = dim_vector::alloc (dim);
6079 
6080  for (int i = 0; i < dim-1; i++)
6081  new_dims(i) = 1;
6082 
6083  new_dims(dim-1) = retval.numel ();
6084 
6085  retval = retval.reshape (new_dims);
6086  }
6087 
6088  return retval;
6089 }
6090 
6091 /*
6092 %!assert (vec ([1, 2; 3, 4]), [1; 3; 2; 4])
6093 %!assert (vec ([1, 3, 2, 4]), [1; 3; 2; 4])
6094 %!assert (vec ([1, 2, 3, 4], 2), [1, 2, 3, 4])
6095 %!assert (vec ([1, 2; 3, 4]), vec ([1, 2; 3, 4], 1))
6096 %!assert (vec ([1, 2; 3, 4], 1), [1; 3; 2; 4])
6097 %!assert (vec ([1, 2; 3, 4], 2), [1, 3, 2, 4])
6098 %!assert (vec ([1, 3; 2, 4], 3), reshape ([1, 2, 3, 4], 1, 1, 4))
6099 %!assert (vec ([1, 3; 2, 4], 3), shiftdim (vec ([1, 3; 2, 4]), -2))
6100 
6101 %!error vec ()
6102 %!error vec (1, 2, 3)
6103 %!error vec ([1, 2; 3, 4], 0)
6104 */
6105 
6106 DEFUN (squeeze, args, ,
6107  doc: /* -*- texinfo -*-
6108 @deftypefn {} {@var{B} =} squeeze (@var{A})
6109 Remove singleton dimensions from @var{A} and return the result.
6110 
6111 Note that for compatibility with @sc{matlab}, all objects have
6112 a minimum of two dimensions and row vectors are left unchanged.
6113 @seealso{reshape}
6114 @end deftypefn */)
6115 {
6116  if (args.length () != 1)
6117  print_usage ();
6118 
6119  return ovl (args(0).squeeze ());
6120 }
6121 
6122 DEFUN (full, args, ,
6123  doc: /* -*- texinfo -*-
6124 @deftypefn {} {@var{FM} =} full (@var{SM})
6125 Return a full storage matrix from a sparse, diagonal, or permutation matrix,
6126 or from a range.
6127 @seealso{sparse, issparse}
6128 @end deftypefn */)
6129 {
6130  if (args.length () != 1)
6131  print_usage ();
6132 
6133  return ovl (args(0).full_value ());
6134 }
6135 
6136 // Compute various norms of the vector X.
6137 
6138 DEFUN (norm, args, ,
6139  doc: /* -*- texinfo -*-
6140 @deftypefn {} {@var{n} =} norm (@var{A})
6141 @deftypefnx {} {@var{n} =} norm (@var{A}, @var{p})
6142 @deftypefnx {} {@var{n} =} norm (@var{A}, @var{p}, @var{opt})
6143 Compute the p-norm of the matrix @var{A}.
6144 
6145 If the second argument is not given, @w{@code{p = 2}} is used.
6146 
6147 If @var{A} is a matrix (or sparse matrix):
6148 
6149 @table @asis
6150 @item @var{p} = @code{1}
6151 1-norm, the largest column sum of the absolute values of @var{A}.
6152 
6153 @item @var{p} = @code{2}
6154 Largest singular value of @var{A}.
6155 
6156 @item @var{p} = @code{Inf} or @qcode{"inf"}
6157 @cindex infinity norm
6158 Infinity norm, the largest row sum of the absolute values of @var{A}.
6159 
6160 @item @var{p} = @qcode{"fro"}
6161 @cindex @nospell{Frobenius} norm
6162 @nospell{Frobenius} norm of @var{A},
6163 @code{sqrt (sum (diag (@var{A}' * @var{A})))}.
6164 
6165 @item other @var{p}, @code{@var{p} > 1}
6166 @cindex general p-norm
6167 maximum @code{norm (A*x, p)} such that @code{norm (x, p) == 1}
6168 @end table
6169 
6170 If @var{A} is a vector or a scalar:
6171 
6172 @table @asis
6173 @item @var{p} = @code{Inf} or @qcode{"inf"}
6174 @code{max (abs (@var{A}))}.
6175 
6176 @item @var{p} = @code{-Inf}
6177 @code{min (abs (@var{A}))}.
6178 
6179 @item @var{p} = @qcode{"fro"}
6180 @nospell{Frobenius} norm of @var{A}, @code{sqrt (sumsq (abs (A)))}.
6181 
6182 @item @var{p} = 0
6183 Hamming norm---the number of nonzero elements.
6184 
6185 @item other @var{p}, @code{@var{p} > 1}
6186 p-norm of @var{A}, @code{(sum (abs (@var{A}) .^ @var{p})) ^ (1/@var{p})}.
6187 
6188 @item other @var{p} @code{@var{p} < 1}
6189 the p-pseudonorm defined as above.
6190 @end table
6191 
6192 If @var{opt} is the value @qcode{"rows"}, treat each row as a vector and
6193 compute its norm. The result is returned as a column vector.
6194 Similarly, if @var{opt} is @qcode{"columns"} or @qcode{"cols"} then
6195 compute the norms of each column and return a row vector.
6196 @seealso{normest, normest1, vecnorm, cond, svd}
6197 @end deftypefn */)
6198 {
6199  int nargin = args.length ();
6200 
6201  if (nargin < 1 || nargin > 3)
6202  print_usage ();
6203 
6204  octave_value x_arg = args(0);
6205 
6206  if (x_arg.ndims () != 2)
6207  error ("norm: only valid for 2-D objects");
6208 
6209  enum {sfmatrix, sfcols, sfrows, sffrob, sfinf, sfneginf} strflag = sfmatrix;
6210  if (nargin > 1 && args(nargin-1).is_string ())
6211  {
6212  std::string str = args(nargin-1).string_value ();
6213  std::transform (str.begin (), str.end (), str.begin (), tolower);
6214  if (str == "cols" || str == "columns")
6215  strflag = sfcols;
6216  else if (str == "rows")
6217  strflag = sfrows;
6218  else if (str == "fro")
6219  strflag = sffrob;
6220  else if (str == "inf")
6221  strflag = sfinf;
6222  else if (str == "-inf")
6223  strflag = sfneginf;
6224  else
6225  error ("norm: unrecognized option: %s", str.c_str ());
6226 
6227  // we've handled the last parameter, so act as if it was removed
6228  nargin--;
6229  }
6230 
6231  octave_value p_arg = (nargin > 1) ? args(1) : octave_value (2);
6232 
6233  if (p_arg.isempty ())
6234  p_arg = octave_value (2);
6235  else if (p_arg.is_string ())
6236  {
6237  std::string str = p_arg.string_value ();
6238  std::transform (str.begin (), str.end (), str.begin (), tolower);
6239  if (strflag != sfcols && strflag != sfrows)
6240  error ("norm: invalid combination of options");
6241 
6242  if (str == "cols" || str == "columns" || str == "rows")
6243  error ("norm: invalid combination of options");
6244 
6245  if (str == "fro")
6246  p_arg = octave_value (2);
6247  else if (str == "inf")
6248  p_arg = numeric_limits<double>::Inf ();
6249  else if (str == "-inf")
6250  p_arg = -numeric_limits<double>::Inf ();
6251  else
6252  error ("norm: unrecognized option: %s", str.c_str ());
6253  }
6254  else if (! p_arg.is_scalar_type ())
6255  err_wrong_type_arg ("norm", p_arg);
6256 
6257  octave_value retval;
6258 
6259  switch (strflag)
6260  {
6261  case sfmatrix:
6262  retval = xnorm (x_arg, p_arg);
6263  break;
6264 
6265  case sfcols:
6266  retval = xcolnorms (x_arg, p_arg);
6267  break;
6268 
6269  case sfrows:
6270  retval = xrownorms (x_arg, p_arg);
6271  break;
6272 
6273  case sffrob:
6274  retval = xfrobnorm (x_arg);
6275  break;
6276 
6277  case sfinf:
6278  retval = xnorm (x_arg, numeric_limits<double>::Inf ());
6279  break;
6280 
6281  case sfneginf:
6282  retval = xnorm (x_arg, -numeric_limits<double>::Inf ());
6283  break;
6284  }
6285 
6286  return retval;
6287 }
6288 
6289 /*
6290 %!shared x
6291 %! x = [1, -3, 4, 5, -7];
6292 %!assert (norm (x,0), 5)
6293 %!assert (norm (x,1), 20)
6294 %!assert (norm (x,2), 10)
6295 %!assert (norm (x,3), 8.24257059961711, -4*eps)
6296 %!assert (norm (x,Inf), 7)
6297 %!assert (norm (x,-Inf), 1)
6298 %!assert (norm (x,"inf"), 7)
6299 %!assert (norm (x,"-Inf"), 1)
6300 %!assert (norm (x,"fro"), 10, -eps)
6301 %!assert (norm (x), 10)
6302 %!assert (norm ([1e200, 1]), 1e200)
6303 %!assert (norm ([3+4i, 3-4i, sqrt(31)]), 9, -4*eps)
6304 %!shared m
6305 %! m = magic (4);
6306 %!assert (norm (m,1), 34)
6307 %!assert (norm (m,2), 34, -eps)
6308 %!assert (norm (m,3), 34, -sqrt (eps))
6309 %!assert (norm (m,Inf), 34)
6310 %!assert (norm (m,"inf"), 34)
6311 %!shared m2, flo, fhi
6312 %! m2 = [1,2;3,4];
6313 %! flo = 1e-300;
6314 %! fhi = 1e+300;
6315 %!assert (norm (flo*m2,"fro"), sqrt (30)*flo, -eps)
6316 %!assert (norm (fhi*m2,"fro"), sqrt (30)*fhi, -eps)
6317 
6318 %!shared x
6319 %! x = single ([1, -3, 4, 5, -7]);
6320 %!assert (norm (x,0), single (5))
6321 %!assert (norm (x,1), single (20))
6322 %!assert (norm (x,2), single (10))
6323 %!assert (norm (x,3), single (8.24257059961711), -4* eps ("single"))
6324 %!assert (norm (x,Inf), single (7))
6325 %!assert (norm (x,-Inf), single (1))
6326 %!assert (norm (x,"inf"), single (7))
6327 %!assert (norm (x,"-Inf"), single (1))
6328 %!assert (norm (x,"fro"), single (10), -eps ("single"))
6329 %!assert (norm (x), single (10))
6330 %!assert (norm (single ([1e38, 1])), single (1e38))
6331 %!assert (norm (single ([3+4i, 3-4i, sqrt(31)])), single (9), -4* eps ("single"))
6332 %!shared m
6333 %! m = single (magic (4));
6334 %!assert (norm (m,1), single (34))
6335 %!assert (norm (m,2), single (34), -eps ("single"))
6336 %!assert (norm (m,3), single (34), -sqrt (eps ("single")))
6337 %!assert (norm (m,Inf), single (34))
6338 %!assert (norm (m,"inf"), single (34))
6339 %!shared m2, flo, fhi
6340 %! m2 = single ([1,2;3,4]);
6341 %! flo = single (1e-300);
6342 %! fhi = single (1e+300);
6343 %!assert (norm (flo*m2,"fro"), single (sqrt (30)*flo), -eps ("single"))
6344 %!assert (norm (fhi*m2,"fro"), single (sqrt (30)*fhi), -eps ("single"))
6345 
6346 ## Hamming norm (p == 0)
6347 %!assert (norm ([1, 0, 0, 0, 1], 0), 2)
6348 
6349 %!shared q
6350 %! q = rand (1e3, 3);
6351 %!assert (norm (q, 3, "rows"), sum (q.^3, 2).^(1/3), sqrt (eps))
6352 %!assert (norm (q, "fro", "rows"), sum (q.^2, 2).^(1/2), sqrt (eps))
6353 %!assert (norm (q, "fro", "rows"), sqrt (sumsq (q, 2)), sqrt (eps))
6354 %!assert (norm (q, "fro", "cols"), sqrt (sumsq (q, 1)), sqrt (eps))
6355 %!assert (norm (q, 3, "cols"), sum (q.^3, 1).^(1/3), sqrt (eps))
6356 %!assert (norm (q, "inf", "rows"), norm (q, Inf, "rows"))
6357 %!assert (norm (q, "inf", "cols"), norm (q, Inf, "cols"))
6358 %!assert (norm (q, [], "rows"), norm (q, 2, "rows"))
6359 %!assert (norm (q, [], "cols"), norm (q, 2, "cols"))
6360 
6361 %!test <30631>
6362 %! ## Test for norm returning NaN on sparse matrix
6363 %! A = sparse (2,2);
6364 %! A(2,1) = 1;
6365 %! assert (norm (A), 1);
6366 
6367 ## Test input validation
6368 %!error norm ()
6369 %!error norm (1,2,3,4)
6370 %!error <unrecognized option> norm (1, "invalid")
6371 %!error <unrecognized option> norm (1, "rows", "invalid")
6372 %!error <unrecognized option> norm (1, "invalid", "rows")
6373 %!error <invalid combination of options> norm (1, "cols", "rows")
6374 %!error <invalid combination of options> norm (1, "rows", "rows")
6375 %!error <p must be .= 1> norm (ones (2,2), -Inf)
6376 */
6377 
6378 static octave_value
6379 unary_op_defun_body (octave_value::unary_op op,
6380  const octave_value_list& args)
6381 {
6382  if (args.length () != 1)
6383  print_usage ();
6384 
6385  return unary_op (op, args(0));
6386 }
6387 
6388 DEFUN (not, args, ,
6389  doc: /* -*- texinfo -*-
6390 @deftypefn {} {@var{z} =} not (@var{x})
6391 Return the logical NOT of @var{x}.
6392 
6393 This function is equivalent to the operator syntax @w{@code{! @var{x}}}.
6394 @seealso{and, or, xor}
6395 @end deftypefn */)
6396 {
6397  return unary_op_defun_body (octave_value::op_not, args);
6398 }
6399 
6400 DEFUN (uplus, args, ,
6401  doc: /* -*- texinfo -*-
6402 @deftypefn {} {@var{B} =} uplus (@var{A})
6403 This function and @w{@tcode{+ @var{A}}} are equivalent.
6404 @seealso{uminus, plus}
6405 @end deftypefn */)
6406 {
6407  return unary_op_defun_body (octave_value::op_uplus, args);
6408 }
6409 
6410 DEFUN (uminus, args, ,
6411  doc: /* -*- texinfo -*-
6412 @deftypefn {} {@var{B} =} uminus (@var{A})
6413 This function and @w{@tcode{- @var{A}}} are equivalent.
6414 @seealso{uplus, minus}
6415 @end deftypefn */)
6416 {
6417  return unary_op_defun_body (octave_value::op_uminus, args);
6418 }
6419 
6420 DEFUN (transpose, args, ,
6421  doc: /* -*- texinfo -*-
6422 @deftypefn {} {@var{B} =} transpose (@var{A})
6423 Return the transpose of @var{A}.
6424 
6425 This function and @tcode{@var{A}.'@:} are equivalent.
6426 @seealso{ctranspose}
6427 @end deftypefn */)
6428 {
6429  return unary_op_defun_body (octave_value::op_transpose, args);
6430 }
6431 
6432 /*
6433 %!assert (2.', 2)
6434 %!assert (2i.', 2i)
6435 %!assert ([1:4].', [1;2;3;4])
6436 %!assert ([1;2;3;4].', [1:4])
6437 %!assert ([1,2;3,4].', [1,3;2,4])
6438 %!assert ([1,2i;3,4].', [1,3;2i,4])
6439 
6440 %!assert (transpose ([1,2;3,4]), [1,3;2,4])
6441 
6442 %!assert (single (2).', single (2))
6443 %!assert (single (2i).', single (2i))
6444 %!assert (single ([1:4]).', single ([1;2;3;4]))
6445 %!assert (single ([1;2;3;4]).', single ([1:4]))
6446 %!assert (single ([1,2;3,4]).', single ([1,3;2,4]))
6447 %!assert (single ([1,2i;3,4]).', single ([1,3;2i,4]))
6448 
6449 %!assert (transpose (single ([1,2;3,4])), single ([1,3;2,4]))
6450 */
6451 
6452 DEFUN (ctranspose, args, ,
6453  doc: /* -*- texinfo -*-
6454 @deftypefn {} {@var{B} =} ctranspose (@var{A})
6455 Return the complex conjugate transpose of @var{A}.
6456 
6457 This function and @tcode{@var{A}'} are equivalent.
6458 @seealso{transpose}
6459 @end deftypefn */)
6460 {
6461  return unary_op_defun_body (octave_value::op_hermitian, args);
6462 }
6463 
6464 /*
6465 %!assert (2', 2)
6466 %!assert (2i', -2i)
6467 %!assert ([1:4]', [1;2;3;4])
6468 %!assert ([1;2;3;4]', [1:4])
6469 %!assert ([1,2;3,4]', [1,3;2,4])
6470 %!assert ([1,2i;3,4]', [1,3;-2i,4])
6471 
6472 %!assert (ctranspose ([1,2i;3,4]), [1,3;-2i,4])
6473 
6474 %!assert (single (2)', single (2))
6475 %!assert (single (2i)', single (-2i))
6476 %!assert (single ([1:4])', single ([1;2;3;4]))
6477 %!assert (single ([1;2;3;4])', single ([1:4]))
6478 %!assert (single ([1,2;3,4])', single ([1,3;2,4]))
6479 %!assert (single ([1,2i;3,4])', single ([1,3;-2i,4]))
6480 
6481 %!assert (ctranspose (single ([1,2i;3,4])), single ([1,3;-2i,4]))
6482 */
6483 
6484 static octave_value
6485 binary_op_defun_body (octave_value::binary_op op,
6486  const octave_value_list& args)
6487 {
6488  if (args.length () != 2)
6489  print_usage ();
6490 
6491  return binary_op (op, args(0), args(1));
6492 }
6493 
6494 static octave_value
6495 binary_assoc_op_defun_body (octave_value::binary_op op,
6497  const octave_value_list& args)
6498 {
6499  int nargin = args.length ();
6500 
6501  if (nargin < 2)
6502  print_usage ();
6503 
6504  octave_value retval;
6505 
6506  if (nargin == 2)
6507  retval = binary_op (op, args(0), args(1));
6508  else
6509  {
6510  retval = binary_op (op, args(0), args(1));
6511 
6512  for (int i = 2; i < nargin; i++)
6513  retval.assign (aop, args(i));
6514  }
6515 
6516  return retval;
6517 }
6518 
6519 DEFUN (plus, args, ,
6520  doc: /* -*- texinfo -*-
6521 @deftypefn {} {@var{C} =} plus (@var{A}, @var{B})
6522 @deftypefnx {} {@var{C} =} plus (@var{A1}, @var{A2}, @dots{})
6523 This function and @w{@tcode{@var{A} + @var{B}}} are equivalent.
6524 
6525 If more arguments are given, the summation is applied
6526 cumulatively from left to right:
6527 
6528 @example
6529 (@dots{}((@var{A1} + @var{A2}) + @var{A3}) + @dots{})
6530 @end example
6531 
6532 @seealso{minus, uplus}
6533 @end deftypefn */)
6534 {
6535  return binary_assoc_op_defun_body (octave_value::op_add,
6536  octave_value::op_add_eq, args);
6537 }
6538 
6539 /*
6540 %!assert (plus (1,1), 2)
6541 %!assert (plus (1:3, 1), 2:4)
6542 %!assert (plus (1:3, 1, 3), 5:7)
6543 %!assert (plus (1,2,3,4,5,6,7,8,9), sum (1:9))
6544 
6545 ## Test input validation for all functions which use binary_assoc_op_defun_body
6546 %!error plus ()
6547 %!error plus (1)
6548 */
6549 
6550 DEFUN (minus, args, ,
6551  doc: /* -*- texinfo -*-
6552 @deftypefn {} {@var{C} =} minus (@var{A}, @var{B})
6553 This function and @w{@tcode{@var{A} - @var{B}}} are equivalent.
6554 @seealso{plus, uminus}
6555 @end deftypefn */)
6556 {
6557  return binary_op_defun_body (octave_value::op_sub, args);
6558 }
6559 
6560 DEFUN (mtimes, args, ,
6561  doc: /* -*- texinfo -*-
6562 @deftypefn {} {@var{C} =} mtimes (@var{A}, @var{B})
6563 @deftypefnx {} {@var{C} =} mtimes (@var{A1}, @var{A2}, @dots{})
6564 Return the matrix multiplication product of inputs.
6565 
6566 This function and @w{@tcode{@var{A} * @var{B}}} are equivalent.
6567 If more arguments are given, the multiplication is applied
6568 cumulatively from left to right:
6569 
6570 @example
6571 (@dots{}((@var{A1} * @var{A2}) * @var{A3}) * @dots{})
6572 @end example
6573 
6574 @seealso{times, plus, minus, rdivide, mrdivide, mldivide, mpower, tensorprod}
6575 @end deftypefn */)
6576 {
6577  return binary_assoc_op_defun_body (octave_value::op_mul,
6578  octave_value::op_mul_eq, args);
6579 }
6580 
6581 DEFUN (mrdivide, args, ,
6582  doc: /* -*- texinfo -*-
6583 @deftypefn {} {@var{C} =} mrdivide (@var{A}, @var{B})
6584 Return the matrix right division of @var{A} and @var{B}.
6585 
6586 This function and @w{@tcode{@var{A} / @var{B}}} are equivalent.
6587 
6588 If the system is not square, or if the coefficient matrix is singular, a
6589 minimum norm solution is computed.
6590 @seealso{mldivide, rdivide, plus, minus}
6591 @end deftypefn */)
6592 {
6593  return binary_op_defun_body (octave_value::op_div, args);
6594 }
6595 
6596 DEFUN (mpower, args, ,
6597  doc: /* -*- texinfo -*-
6598 @deftypefn {} {@var{C} =} mpower (@var{A}, @var{B})
6599 Return the matrix power operation of @var{A} raised to the @var{B} power.
6600 
6601 This function and @w{@tcode{@var{A} ^ @var{B}}} are equivalent.
6602 @seealso{power, mtimes, plus, minus}
6603 @end deftypefn */)
6604 {
6605  return binary_op_defun_body (octave_value::op_pow, args);
6606 }
6607 
6608 DEFUN (mldivide, args, ,
6609  doc: /* -*- texinfo -*-
6610 @deftypefn {} {@var{C} =} mldivide (@var{A}, @var{B})
6611 Return the matrix left division of @var{A} and @var{B}.
6612 
6613 This function and @w{@tcode{@var{A} @backslashchar{} @var{B}}} are equivalent.
6614 
6615 If the system is not square, or if the coefficient matrix is singular, a
6616 minimum norm solution is computed.
6617 @seealso{mrdivide, ldivide, rdivide, linsolve}
6618 @end deftypefn */)
6619 {
6620  return binary_op_defun_body (octave_value::op_ldiv, args);
6621 }
6622 
6623 DEFUN (lt, args, ,
6624  doc: /* -*- texinfo -*-
6625 @deftypefn {} {@var{TF} =} lt (@var{A}, @var{B})
6626 This function is equivalent to @w{@code{@var{A} < @var{B}}}.
6627 @seealso{le, eq, ge, gt, ne}
6628 @end deftypefn */)
6629 {
6630  return binary_op_defun_body (octave_value::op_lt, args);
6631 }
6632 
6633 DEFUN (le, args, ,
6634  doc: /* -*- texinfo -*-
6635 @deftypefn {} {@var{TF} =} le (@var{A}, @var{B})
6636 This function is equivalent to @w{@code{@var{A} <= @var{B}}}.
6637 @seealso{eq, ge, gt, ne, lt}
6638 @end deftypefn */)
6639 {
6640  return binary_op_defun_body (octave_value::op_le, args);
6641 }
6642 
6643 DEFUN (eq, args, ,
6644  doc: /* -*- texinfo -*-
6645 @deftypefn {} {@var{TF} =} eq (@var{A}, @var{B})
6646 Return true if the two inputs are equal.
6647 
6648 This function is equivalent to @w{@code{@var{A} == @var{B}}}.
6649 @seealso{ne, isequal, le, ge, gt, ne, lt}
6650 @end deftypefn */)
6651 {
6652  return binary_op_defun_body (octave_value::op_eq, args);
6653 }
6654 
6655 DEFUN (ge, args, ,
6656  doc: /* -*- texinfo -*-
6657 @deftypefn {} {@var{TF} =} ge (@var{A}, @var{B})
6658 This function is equivalent to @w{@code{@var{A} >= @var{B}}}.
6659 @seealso{le, eq, gt, ne, lt}
6660 @end deftypefn */)
6661 {
6662  return binary_op_defun_body (octave_value::op_ge, args);
6663 }
6664 
6665 DEFUN (gt, args, ,
6666  doc: /* -*- texinfo -*-
6667 @deftypefn {} {@var{TF} =} gt (@var{A}, @var{B})
6668 This function is equivalent to @w{@code{@var{A} > @var{B}}}.
6669 @seealso{le, eq, ge, ne, lt}
6670 @end deftypefn */)
6671 {
6672  return binary_op_defun_body (octave_value::op_gt, args);
6673 }
6674 
6675 DEFUN (ne, args, ,
6676  doc: /* -*- texinfo -*-
6677 @deftypefn {} {@var{TF} =} ne (@var{A}, @var{B})
6678 Return true if the two inputs are not equal.
6679 
6680 This function is equivalent to @w{@code{@var{A} != @var{B}}}.
6681 @seealso{eq, isequal, le, ge, lt}
6682 @end deftypefn */)
6683 {
6684  return binary_op_defun_body (octave_value::op_ne, args);
6685 }
6686 
6687 DEFUN (times, args, ,
6688  doc: /* -*- texinfo -*-
6689 @deftypefn {} {@var{C} =} times (@var{A}, @var{B})
6690 @deftypefnx {} {@var{C} =} times (@var{A1}, @var{A2}, @dots{})
6691 Return the element-by-element multiplication product of inputs.
6692 
6693 This function and @w{@tcode{@var{A} .* @var{B}}} are equivalent.
6694 If more arguments are given, the multiplication is applied
6695 cumulatively from left to right:
6696 
6697 @example
6698 (@dots{}((@var{A1} .* @var{A2}) .* @var{A3}) .* @dots{})
6699 @end example
6700 
6701 @seealso{mtimes, rdivide}
6702 @end deftypefn */)
6703 {
6704  return binary_assoc_op_defun_body (octave_value::op_el_mul,
6706 }
6707 
6708 DEFUN (rdivide, args, ,
6709  doc: /* -*- texinfo -*-
6710 @deftypefn {} {@var{C} =} rdivide (@var{A}, @var{B})
6711 Return the element-by-element right division of @var{A} and @var{B}.
6712 
6713 This function and @w{@tcode{@var{A} ./ @var{B}}} are equivalent.
6714 @seealso{ldivide, mrdivide, times, plus}
6715 @end deftypefn */)
6716 {
6717  return binary_op_defun_body (octave_value::op_el_div, args);
6718 }
6719 
6720 DEFUN (power, args, ,
6721  doc: /* -*- texinfo -*-
6722 @deftypefn {} {@var{C} =} power (@var{A}, @var{B})
6723 Return the element-by-element operation of @var{A} raised to the
6724 @var{B} power.
6725 
6726 This function and @w{@tcode{@var{A} .^ @var{B}}} are equivalent.
6727 
6728 If several complex results are possible, returns the one with smallest
6729 non-negative argument (angle). Use @code{realpow}, @code{realsqrt},
6730 @code{cbrt}, or @code{nthroot} if a real result is preferred.
6731 
6732 @seealso{mpower, realpow, realsqrt, cbrt, nthroot}
6733 @end deftypefn */)
6734 {
6735  return binary_op_defun_body (octave_value::op_el_pow, args);
6736 }
6737 
6738 DEFUN (ldivide, args, ,
6739  doc: /* -*- texinfo -*-
6740 @deftypefn {} {@var{C} =} ldivide (@var{A}, @var{B})
6741 Return the element-by-element left division of @var{A} and @var{B}.
6742 
6743 This function and @w{@tcode{@var{A} .@backslashchar{} @var{B}}} are
6744 equivalent.
6745 @seealso{rdivide, mldivide, times, plus}
6746 @end deftypefn */)
6747 {
6748  return binary_op_defun_body (octave_value::op_el_ldiv, args);
6749 }
6750 
6751 DEFUN (and, args, ,
6752  doc: /* -*- texinfo -*-
6753 @deftypefn {} {@var{TF} =} and (@var{x}, @var{y})
6754 @deftypefnx {} {@var{TF} =} and (@var{x1}, @var{x2}, @dots{})
6755 Return the logical AND of @var{x} and @var{y}.
6756 
6757 This function is equivalent to the operator syntax
6758 @w{@code{@var{x} & @var{y}}}. If more than two arguments are given, the
6759 logical AND is applied cumulatively from left to right:
6760 
6761 @example
6762 (@dots{}((@var{x1} & @var{x2}) & @var{x3}) & @dots{})
6763 @end example
6764 
6765 @seealso{or, not, xor}
6766 @end deftypefn */)
6767 {
6768  return binary_assoc_op_defun_body (octave_value::op_el_and,
6770 }
6771 
6772 DEFUN (or, args, ,
6773  doc: /* -*- texinfo -*-
6774 @deftypefn {} {@var{TF} =} or (@var{x}, @var{y})
6775 @deftypefnx {} {@var{TF} =} or (@var{x1}, @var{x2}, @dots{})
6776 Return the logical OR of @var{x} and @var{y}.
6777 
6778 This function is equivalent to the operator syntax
6779 @w{@code{@var{x} | @var{y}}}. If more than two arguments are given, the
6780 logical OR is applied cumulatively from left to right:
6781 
6782 @example
6783 (@dots{}((@var{x1} | @var{x2}) | @var{x3}) | @dots{})
6784 @end example
6785 
6786 @seealso{and, not, xor}
6787 @end deftypefn */)
6788 {
6789  return binary_assoc_op_defun_body (octave_value::op_el_or,
6791 }
6792 
6793 DEFUN (colon, args, ,
6794  doc: /* -*- texinfo -*-
6795 @deftypefn {} {@var{r} =} colon (@var{base}, @var{limit})
6796 @deftypefnx {} {@var{r} =} colon (@var{base}, @var{increment}, @var{limit})
6797 Return the result of the colon expression corresponding to @var{base},
6798 @var{limit}, and optionally, @var{increment}.
6799 
6800 This function is equivalent to the operator syntax
6801 @w{@code{@var{base} : @var{limit}}} or
6802 @w{@code{@var{base} : @var{increment} : @var{limit}}}.
6803 @seealso{linspace}
6804 @end deftypefn */)
6805 {
6806  int nargin = args.length ();
6807 
6808  if (nargin < 2 || nargin > 3)
6809  print_usage ();
6810 
6811  return (nargin == 2
6812  ? colon_op (args(0), args(1))
6813  : colon_op (args(0), args(1), args(2)));
6814 }
6815 
6816 static double tic_toc_timestamp = -1.0;
6817 
6818 DEFUN (tic, args, nargout,
6819  doc: /* -*- texinfo -*-
6820 @deftypefn {} {} tic ()
6821 @deftypefnx {} {@var{id} =} tic ()
6822 Initialize a wall-clock timer.
6823 
6824 Calling @code{tic} without an output argument resets the internal timer.
6825 Subsequent calls to @code{toc} return the number of seconds since the timer was
6826 set.
6827 
6828 If called with one output argument, @code{tic} creates a new timer instance and
6829 returns a timer identifier @var{id}. The @var{id} is a scalar of type
6830 @code{uint64} that may be passed to @code{toc} to check elapsed time on this
6831 timer, rather than the default internal timer.
6832 
6833 Example 1 : benchmarking code with internal timer
6834 
6835 @example
6836 @group
6837 tic;
6838 # many computations later@dots{}
6839 elapsed_time = toc;
6840 @end group
6841 @end example
6842 
6843 Example 2 : mixed timer id and internal timer
6844 
6845 @example
6846 @group
6847 tic;
6848 pause (1);
6849 toc
6850 @result{} Elapsed time is 1.0089 seconds.
6851 id = tic;
6852 pause (2);
6853 toc (id)
6854 @result{} Elapsed time is 2.01142 seconds.
6855 toc
6856 Elapsed time is 3.02308 seconds.
6857 @end group
6858 @end example
6859 
6860 @noindent
6861 Calling @code{tic} and @code{toc} in this way allows nested timing calls.
6862 
6863 If you are more interested in the CPU time that your process used, you should
6864 use the @code{cputime} function instead. The @code{tic} and @code{toc}
6865 functions report the actual wall clock time that elapsed between the calls.
6866 This may include time spent processing other jobs or doing nothing at all.
6867 @seealso{toc, cputime}
6868 @end deftypefn */)
6869 {
6870  if (args.length () != 0)
6871  warning ("tic: ignoring extra arguments");
6872 
6873  octave_value retval;
6874  sys::time now;
6875  double tmp = now.double_value ();
6876 
6877  if (nargout > 0)
6878  {
6879  double ip = 0.0;
6880  double frac = std::modf (tmp, &ip);
6881  uint64_t microsecs = static_cast<uint64_t> (CLOCKS_PER_SEC * frac);
6882  microsecs += CLOCKS_PER_SEC * static_cast<uint64_t> (ip);
6883  retval = octave_uint64 (microsecs);
6884  }
6885  else
6886  tic_toc_timestamp = tmp;
6887 
6888  return retval;
6889 }
6890 
6891 DEFUN (toc, args, nargout,
6892  doc: /* -*- texinfo -*-
6893 @deftypefn {} {} toc ()
6894 @deftypefnx {} {} toc (@var{id})
6895 @deftypefnx {} {@var{elapsed_time} =} toc (@dots{})
6896 Measure elapsed time on a wall-clock timer.
6897 
6898 With no arguments, return the number of seconds elapsed on the internal timer
6899 since the last call to @code{tic}.
6900 
6901 When given the identifier @var{id} of a specific timer, return the number of
6902 seconds elapsed since the timer @var{id} was initialized.
6903 
6904 @xref{XREFtic,,@code{tic}}, for examples of the use of @code{tic}/@code{toc}.
6905 
6906 @seealso{tic, cputime}
6907 @end deftypefn */)
6908 {
6909  int nargin = args.length ();
6910 
6911  if (nargin > 1)
6912  print_usage ();
6913 
6914  double start_time = tic_toc_timestamp;
6915 
6916  if (nargin == 1)
6917  {
6918  octave_uint64 id = args(0).xuint64_scalar_value ("toc: invalid ID");
6919 
6920  uint64_t val = id.value ();
6921 
6922  start_time
6923  = (static_cast<double> (val / CLOCKS_PER_SEC)
6924  + static_cast<double> (val % CLOCKS_PER_SEC)
6925  / CLOCKS_PER_SEC);
6926 
6927  // FIXME: should we also check to see whether the start
6928  // time is after the beginning of this Octave session?
6929  }
6930 
6931  if (start_time < 0)
6932  error ("toc: function called before timer initialization with tic()");
6933 
6934  sys::time now;
6935 
6936  double etime = now.double_value () - start_time;
6937 
6938  octave_value retval;
6939  if (nargout > 0)
6940  retval = etime;
6941  else
6942  octave_stdout << "Elapsed time is " << etime << " seconds.\n";
6943 
6944  return retval;
6945 }
6946 
6947 /*
6948 %!shared id
6949 %! id = tic ();
6950 %!assert (isa (id, "uint64"))
6951 %!assert (isa (toc (id), "double"))
6952 */
6953 
6954 DEFUN (cputime, args, ,
6955  doc: /* -*- texinfo -*-
6956 @deftypefn {} {[@var{total}, @var{user}, @var{system}] =} cputime ();
6957 Return the CPU time used by your Octave session.
6958 
6959 The first output is the total time spent executing your process and is equal
6960 to the sum of second and third outputs, which are the number of CPU seconds
6961 spent executing in user mode and the number of CPU seconds spent executing
6962 in system mode, respectively.
6963 
6964 If your system does not have a way to report CPU time usage, @code{cputime}
6965 returns 0 for each of its output values.
6966 
6967 Note that because Octave used some CPU time to start, it is reasonable
6968 to check to see if @code{cputime} works by checking to see if the total
6969 CPU time used is nonzero.
6970 @seealso{tic, toc}
6971 @end deftypefn */)
6972 {
6973  if (args.length () != 0)
6974  print_usage ();
6975 
6976  sys::cpu_time cpu_tm;
6977 
6978  double usr = cpu_tm.user ();
6979  double sys = cpu_tm.system ();
6980 
6981  return ovl (usr + sys, usr, sys);
6982 }
6983 
6984 DEFUN (sort, args, nargout,
6985  doc: /* -*- texinfo -*-
6986 @deftypefn {} {[@var{s}, @var{i}] =} sort (@var{x})
6987 @deftypefnx {} {[@var{s}, @var{i}] =} sort (@var{x}, @var{dim})
6988 @deftypefnx {} {[@var{s}, @var{i}] =} sort (@var{x}, @var{mode})
6989 @deftypefnx {} {[@var{s}, @var{i}] =} sort (@var{x}, @var{dim}, @var{mode})
6990 Return a copy of @var{x} with the elements arranged in increasing order.
6991 
6992 For matrices, @code{sort} orders the elements within columns
6993 
6994 For example:
6995 
6996 @example
6997 @group
6998 sort ([1, 2; 2, 3; 3, 1])
6999  @result{} 1 1
7000  2 2
7001  3 3
7002 @end group
7003 @end example
7004 
7005 If the optional argument @var{dim} is given, then the matrix is sorted
7006 along the dimension defined by @var{dim}. The optional argument @var{mode}
7007 defines the order in which the values will be sorted. Valid values of
7008 @var{mode} are @qcode{"ascend"} or @qcode{"descend"}.
7009 
7010 The @code{sort} function may also be used to produce a matrix
7011 containing the original row indices of the elements in the sorted
7012 matrix. For example:
7013 
7014 @example
7015 @group
7016 [s, i] = sort ([1, 2; 2, 3; 3, 1])
7017  @result{} s = 1 1
7018  2 2
7019  3 3
7020  @result{} i = 1 3
7021  2 1
7022  3 2
7023 @end group
7024 @end example
7025 
7026 For equal elements, the indices are such that equal elements are listed
7027 in the order in which they appeared in the original list.
7028 
7029 Sorting of complex entries is done first by magnitude
7030 (@w{@code{abs (@var{z})}}) and for any ties by phase angle
7031 (@w{@code{angle (z)}}). For example:
7032 
7033 @example
7034 @group
7035 sort ([1+i; 1; 1-i])
7036  @result{} 1 + 0i
7037  1 - 1i
7038  1 + 1i
7039 @end group
7040 @end example
7041 
7042 NaN values are treated as being greater than any other value and are sorted
7043 to the end of the list.
7044 
7045 The @code{sort} function may also be used to sort strings and cell arrays
7046 of strings, in which case ASCII dictionary order (uppercase 'A' precedes
7047 lowercase 'a') of the strings is used.
7048 
7049 The algorithm used in @code{sort} is optimized for the sorting of partially
7050 ordered lists.
7051 @seealso{sortrows, issorted}
7052 @end deftypefn */)
7053 {
7054  int nargin = args.length ();
7055 
7056  if (nargin < 1 || nargin > 3)
7057  print_usage ();
7058 
7059  sortmode smode = ASCENDING;
7060  bool return_idx = (nargout > 1);
7061  bool have_sortmode = (nargin > 1 && args(1).is_string ());
7062  octave_value arg = args(0);
7063 
7064  int dim = 0;
7065  if (nargin > 1)
7066  {
7067  if (have_sortmode)
7068  {
7069  std::string mode = args(1).string_value ();
7070  if (mode == "ascend")
7071  smode = ASCENDING;
7072  else if (mode == "descend")
7073  smode = DESCENDING;
7074  else
7075  error (R"(sort: MODE must be either "ascend" or "descend")");
7076  }
7077  else
7078  dim = args(1).nint_value () - 1;
7079  }
7080 
7081  if (nargin > 2)
7082  {
7083  if (have_sortmode)
7084  error ("sort: DIM must be a valid dimension");
7085 
7086  std::string mode = args(2).xstring_value ("sort: MODE must be a string");
7087 
7088  if (mode == "ascend")
7089  smode = ASCENDING;
7090  else if (mode == "descend")
7091  smode = DESCENDING;
7092  else
7093  error (R"(sort: MODE must be either "ascend" or "descend")");
7094  }
7095 
7096  const dim_vector dv = arg.dims ();
7097  if (nargin == 1 || have_sortmode)
7098  {
7099  dim = dv.first_non_singleton ();
7100  }
7101  else
7102  {
7103  if (dim < 0)
7104  error ("sort: DIM must be a valid dimension");
7105  }
7106 
7107  octave_value_list retval (return_idx ? 2 : 1);
7108 
7109  if (return_idx)
7110  {
7112 
7113  // NOTE: Can not change this to ovl() call because arg.sort changes sidx
7114  // and objects are declared const in ovl prototype.
7115  retval(0) = arg.sort (sidx, dim, smode);
7116  retval(1) = idx_vector (sidx, dv(dim)); // No checking, extent is known.
7117  }
7118  else
7119  retval = ovl (arg.sort (dim, smode));
7120 
7121  return retval;
7122 }
7123 
7124 /*
7125 ## Double
7126 %!assert (sort ([NaN, 1, -1, 2, Inf]), [-1, 1, 2, Inf, NaN])
7127 %!assert (sort ([NaN, 1, -1, 2, Inf], 1), [NaN, 1, -1, 2, Inf])
7128 %!assert (sort ([NaN, 1, -1, 2, Inf], 2), [-1, 1, 2, Inf, NaN])
7129 %!assert (sort ([NaN, 1, -1, 2, Inf], 3), [NaN, 1, -1, 2, Inf])
7130 %!assert (sort ([NaN, 1, -1, 2, Inf], "ascend"), [-1, 1, 2, Inf, NaN])
7131 %!assert (sort ([NaN, 1, -1, 2, Inf], 2, "ascend"), [-1, 1, 2, Inf, NaN])
7132 %!assert (sort ([NaN, 1, -1, 2, Inf], "descend"), [NaN, Inf, 2, 1, -1])
7133 %!assert (sort ([NaN, 1, -1, 2, Inf], 2, "descend"), [NaN, Inf, 2, 1, -1])
7134 %!assert (sort ([3, 1, 7, 5; 8, 2, 6, 4]), [3, 1, 6, 4; 8, 2, 7, 5])
7135 %!assert (sort ([3, 1, 7, 5; 8, 2, 6, 4], 1), [3, 1, 6, 4; 8, 2, 7, 5])
7136 %!assert (sort ([3, 1, 7, 5; 8, 2, 6, 4], 2), [1, 3, 5, 7; 2, 4, 6, 8])
7137 %!assert (sort (1), 1)
7138 
7139 %!test
7140 %! [v, i] = sort ([NaN, 1, -1, Inf, 1]);
7141 %! assert (v, [-1, 1, 1, Inf, NaN]);
7142 %! assert (i, [3, 2, 5, 4, 1]);
7143 
7144 ## Complex
7145 %!assert (sort ([NaN, 1i, -1, 2, Inf]), [1i, -1, 2, Inf, NaN])
7146 %!assert (sort ([NaN, 1i, -1, 2, Inf], 1), [NaN, 1i, -1, 2, Inf])
7147 %!assert (sort ([NaN, 1i, -1, 2, Inf], 2), [1i, -1, 2, Inf, NaN])
7148 %!assert (sort ([NaN, 1i, -1, 2, Inf], 3), [NaN, 1i, -1, 2, Inf])
7149 %!assert (sort ([NaN, 1i, -1, 2, Inf], "ascend"), [1i, -1, 2, Inf, NaN])
7150 %!assert (sort ([NaN, 1i, -1, 2, Inf], 2, "ascend"), [1i, -1, 2, Inf, NaN])
7151 %!assert (sort ([NaN, 1i, -1, 2, Inf], "descend"), [NaN, Inf, 2, -1, 1i])
7152 %!assert (sort ([NaN, 1i, -1, 2, Inf], 2, "descend"), [NaN, Inf, 2, -1, 1i])
7153 %!assert (sort ([3, 1i, 7, 5; 8, 2, 6, 4]), [3, 1i, 6, 4; 8, 2, 7, 5])
7154 %!assert (sort ([3, 1i, 7, 5; 8, 2, 6, 4], 1), [3, 1i, 6, 4; 8, 2, 7, 5])
7155 %!assert (sort ([3, 1i, 7, 5; 8, 2, 6, 4], 2), [1i, 3, 5, 7; 2, 4, 6, 8])
7156 %!assert (sort (1i), 1i)
7157 
7158 %!test
7159 %! [v, i] = sort ([NaN, 1i, -1, Inf, 1, 1i]);
7160 %! assert (v, [1, 1i, 1i, -1, Inf, NaN]);
7161 %! assert (i, [5, 2, 6, 3, 4, 1]);
7162 
7163 ## Single
7164 %!assert (sort (single ([NaN, 1, -1, 2, Inf])), single ([-1, 1, 2, Inf, NaN]))
7165 %!assert (sort (single ([NaN, 1, -1, 2, Inf]), 1),
7166 %! single ([NaN, 1, -1, 2, Inf]))
7167 %!assert (sort (single ([NaN, 1, -1, 2, Inf]), 2),
7168 %! single ([-1, 1, 2, Inf, NaN]))
7169 %!assert (sort (single ([NaN, 1, -1, 2, Inf]), 3),
7170 %! single ([NaN, 1, -1, 2, Inf]))
7171 %!assert (sort (single ([NaN, 1, -1, 2, Inf]), "ascend"),
7172 %! single ([-1, 1, 2, Inf, NaN]))
7173 %!assert (sort (single ([NaN, 1, -1, 2, Inf]), 2, "ascend"),
7174 %! single ([-1, 1, 2, Inf, NaN]))
7175 %!assert (sort (single ([NaN, 1, -1, 2, Inf]), "descend"),
7176 %! single ([NaN, Inf, 2, 1, -1]))
7177 %!assert (sort (single ([NaN, 1, -1, 2, Inf]), 2, "descend"),
7178 %! single ([NaN, Inf, 2, 1, -1]))
7179 %!assert (sort (single ([3, 1, 7, 5; 8, 2, 6, 4])),
7180 %! single ([3, 1, 6, 4; 8, 2, 7, 5]))
7181 %!assert (sort (single ([3, 1, 7, 5; 8, 2, 6, 4]), 1),
7182 %! single ([3, 1, 6, 4; 8, 2, 7, 5]))
7183 %!assert (sort (single ([3, 1, 7, 5; 8, 2, 6, 4]), 2),
7184 %! single ([1, 3, 5, 7; 2, 4, 6, 8]))
7185 %!assert (sort (single (1)), single (1))
7186 
7187 %!test
7188 %! [v, i] = sort (single ([NaN, 1, -1, Inf, 1]));
7189 %! assert (v, single ([-1, 1, 1, Inf, NaN]));
7190 %! assert (i, [3, 2, 5, 4, 1]);
7191 
7192 ## Single Complex
7193 %!assert (sort (single ([NaN, 1i, -1, 2, Inf])), single ([1i, -1, 2, Inf, NaN]))
7194 %!assert (sort (single ([NaN, 1i, -1, 2, Inf]), 1),
7195 %! single ([NaN, 1i, -1, 2, Inf]))
7196 %!assert (sort (single ([NaN, 1i, -1, 2, Inf]), 2),
7197 %! single ([1i, -1, 2, Inf, NaN]))
7198 %!assert (sort (single ([NaN, 1i, -1, 2, Inf]), 3),
7199 %! single ([NaN, 1i, -1, 2, Inf]))
7200 %!assert (sort (single ([NaN, 1i, -1, 2, Inf]), "ascend"),
7201 %! single ([1i, -1, 2, Inf, NaN]))
7202 %!assert (sort (single ([NaN, 1i, -1, 2, Inf]), 2, "ascend"),
7203 %! single ([1i, -1, 2, Inf, NaN]))
7204 %!assert (sort (single ([NaN, 1i, -1, 2, Inf]), "descend"),
7205 %! single ([NaN, Inf, 2, -1, 1i]))
7206 %!assert (sort (single ([NaN, 1i, -1, 2, Inf]), 2, "descend"),
7207 %! single ([NaN, Inf, 2, -1, 1i]))
7208 %!assert (sort (single ([3, 1i, 7, 5; 8, 2, 6, 4])),
7209 %! single ([3, 1i, 6, 4; 8, 2, 7, 5]))
7210 %!assert (sort (single ([3, 1i, 7, 5; 8, 2, 6, 4]), 1),
7211 %! single ([3, 1i, 6, 4; 8, 2, 7, 5]))
7212 %!assert (sort (single ([3, 1i, 7, 5; 8, 2, 6, 4]), 2),
7213 %! single ([1i, 3, 5, 7; 2, 4, 6, 8]))
7214 %!assert (sort (single (1i)), single (1i))
7215 
7216 %!test
7217 %! [v, i] = sort (single ([NaN, 1i, -1, Inf, 1, 1i]));
7218 %! assert (v, single ([1, 1i, 1i, -1, Inf, NaN]));
7219 %! assert (i, [5, 2, 6, 3, 4, 1]);
7220 
7221 ## Bool
7222 %!assert (sort ([true, false, true, false]), [false, false, true, true])
7223 %!assert (sort ([true, false, true, false], 1), [true, false, true, false])
7224 %!assert (sort ([true, false, true, false], 2), [false, false, true, true])
7225 %!assert (sort ([true, false, true, false], 3), [true, false, true, false])
7226 %!assert (sort ([true, false, true, false], "ascend"),
7227 %! [false, false, true, true])
7228 %!assert (sort ([true, false, true, false], 2, "ascend"),
7229 %! [false, false, true, true])
7230 %!assert (sort ([true, false, true, false], "descend"),
7231 %! [true, true, false, false])
7232 %!assert (sort ([true, false, true, false], 2, "descend"),
7233 %! [true, true, false, false])
7234 %!assert (sort (true), true)
7235 
7236 %!test
7237 %! [v, i] = sort ([true, false, true, false]);
7238 %! assert (v, [false, false, true, true]);
7239 %! assert (i, [2, 4, 1, 3]);
7240 
7241 ## Sparse Double
7242 %!assert (sort (sparse ([0, NaN, 1, 0, -1, 2, Inf])),
7243 %! sparse ([-1, 0, 0, 1, 2, Inf, NaN]))
7244 %!assert (sort (sparse ([0, NaN, 1, 0, -1, 2, Inf]), 1),
7245 %! sparse ([0, NaN, 1, 0, -1, 2, Inf]))
7246 %!assert (sort (sparse ([0, NaN, 1, 0, -1, 2, Inf]), 2),
7247 %! sparse ([-1, 0, 0, 1, 2, Inf, NaN]))
7248 %!assert (sort (sparse ([0, NaN, 1, 0, -1, 2, Inf]), 3),
7249 %! sparse ([0, NaN, 1, 0, -1, 2, Inf]))
7250 %!assert (sort (sparse ([0, NaN, 1, 0, -1, 2, Inf]), "ascend"),
7251 %! sparse ([-1, 0, 0, 1, 2, Inf, NaN]))
7252 %!assert (sort (sparse ([0, NaN, 1, 0, -1, 2, Inf]), 2, "ascend"),
7253 %! sparse ([-1, 0, 0, 1, 2, Inf, NaN]))
7254 %!assert (sort (sparse ([0, NaN, 1, 0, -1, 2, Inf]), "descend"),
7255 %! sparse ([NaN, Inf, 2, 1, 0, 0, -1]))
7256 %!assert (sort (sparse ([0, NaN, 1, 0, -1, 2, Inf]), 2, "descend"),
7257 %! sparse ([NaN, Inf, 2, 1, 0, 0, -1]))
7258 
7259 %!shared a
7260 %! a = randn (10, 10);
7261 %! a(a < 0) = 0;
7262 %!assert (sort (sparse (a)), sparse (sort (a)))
7263 %!assert (sort (sparse (a), 1), sparse (sort (a, 1)))
7264 %!assert (sort (sparse (a), 2), sparse (sort (a, 2)))
7265 %!test
7266 %! [v, i] = sort (a);
7267 %! [vs, is] = sort (sparse (a));
7268 %! assert (vs, sparse (v));
7269 %! assert (is, i);
7270 
7271 ## Sparse Complex
7272 %!assert (sort (sparse ([0, NaN, 1i, 0, -1, 2, Inf])),
7273 %! sparse ([0, 0, 1i, -1, 2, Inf, NaN]))
7274 %!assert (sort (sparse ([0, NaN, 1i, 0, -1, 2, Inf]), 1),
7275 %! sparse ([0, NaN, 1i, 0, -1, 2, Inf]))
7276 %!assert (sort (sparse ([0, NaN, 1i, 0, -1, 2, Inf]), 2),
7277 %! sparse ([0, 0, 1i, -1, 2, Inf, NaN]))
7278 %!assert (sort (sparse ([0, NaN, 1i, 0, -1, 2, Inf]), 3),
7279 %! sparse ([0, NaN, 1i, 0, -1, 2, Inf]))
7280 %!assert (sort (sparse ([0, NaN, 1i, 0, -1, 2, Inf]), "ascend"),
7281 %! sparse ([0, 0, 1i, -1, 2, Inf, NaN]))
7282 %!assert (sort (sparse ([0, NaN, 1i, 0, -1, 2, Inf]), 2, "ascend"),
7283 %! sparse ([0, 0, 1i, -1, 2, Inf, NaN]))
7284 %!assert (sort (sparse ([0, NaN, 1i, 0, -1, 2, Inf]), "descend"),
7285 %! sparse ([NaN, Inf, 2, -1, 1i, 0, 0]))
7286 %!assert (sort (sparse ([0, NaN, 1i, 0, -1, 2, Inf]), 2, "descend"),
7287 %! sparse ([NaN, Inf, 2, -1, 1i, 0, 0]))
7288 
7289 %!shared a
7290 %! a = randn (10, 10);
7291 %! a(a < 0) = 0;
7292 %! a = 1i * a;
7293 %!assert (sort (sparse (a)), sparse (sort (a)))
7294 %!assert (sort (sparse (a), 1), sparse (sort (a, 1)))
7295 %!assert (sort (sparse (a), 2), sparse (sort (a, 2)))
7296 %!test
7297 %! [v, i] = sort (a);
7298 %! [vs, is] = sort (sparse (a));
7299 %! assert (vs, sparse (v));
7300 %! assert (is, i);
7301 
7302 ## Sparse Bool
7303 %!assert (sort (sparse ([true, false, true, false])),
7304 %! sparse ([false, false, true, true]))
7305 %!assert (sort (sparse ([true, false, true, false]), 1),
7306 %! sparse ([true, false, true, false]))
7307 %!assert (sort (sparse ([true, false, true, false]), 2),
7308 %! sparse ([false, false, true, true]))
7309 %!assert (sort (sparse ([true, false, true, false]), 3),
7310 %! sparse ([true, false, true, false]))
7311 %!assert (sort (sparse ([true, false, true, false]), "ascend"),
7312 %! sparse ([false, false, true, true]))
7313 %!assert (sort (sparse ([true, false, true, false]), 2, "ascend"),
7314 %! sparse ([false, false, true, true]))
7315 %!assert (sort (sparse ([true, false, true, false]), "descend"),
7316 %! sparse ([true, true, false, false]))
7317 %!assert (sort (sparse ([true, false, true, false]), 2, "descend"),
7318 %! sparse ([true, true, false, false]))
7319 
7320 %!test
7321 %! [v, i] = sort (sparse ([true, false, true, false]));
7322 %! assert (v, sparse ([false, false, true, true]));
7323 %! assert (i, [2, 4, 1, 3]);
7324 
7325 ## Cell string array
7326 %!shared a, b, c
7327 %! a = {"Alice", "Cecile", "Eric", "Barry", "David"};
7328 %! b = {"Alice", "Barry", "Cecile", "David", "Eric"};
7329 %! c = {"Eric", "David", "Cecile", "Barry", "Alice"};
7330 %!assert (sort (a), b)
7331 %!assert (sort (a, 1), a)
7332 %!assert (sort (a, 2), b)
7333 %!assert (sort (a, 3), a)
7334 %!assert (sort (a, "ascend"), b)
7335 %!assert (sort (a, 2, "ascend"), b)
7336 %!assert (sort (a, "descend"), c)
7337 %!assert (sort (a, 2, "descend"), c)
7338 
7339 %!test
7340 %! [v, i] = sort (a);
7341 %! assert (i, [1, 4, 2, 5, 3]);
7342 
7343 %!error sort ()
7344 %!error sort (1, 2, 3, 4)
7345 */
7346 
7347 // Sort the rows of the matrix @var{a} according to the order
7348 // specified by @var{mode}, which can either be 'ascend' or 'descend'
7349 // and return the index vector corresponding to the sort order.
7350 //
7351 // FIXME: This function does not yet support sparse matrices.
7352 
7353 DEFUN (__sort_rows_idx__, args, ,
7354  doc: /* -*- texinfo -*-
7355 @deftypefn {} {@var{idx} =} __sort_rows_idx__ (@var{A}, @var{mode})
7356 Called internally from @file{sortrows.m}.
7357 @end deftypefn */)
7358 {
7359  int nargin = args.length ();
7360 
7361  if (nargin < 1 || nargin > 2)
7362  print_usage ();
7363 
7364  if (nargin == 2 && ! args(1).is_string ())
7365  error ("__sort_rows_idx__: second argument must be a string");
7366 
7367  sortmode smode = ASCENDING;
7368  if (nargin > 1)
7369  {
7370  std::string mode = args(1).string_value ();
7371  if (mode == "ascend")
7372  smode = ASCENDING;
7373  else if (mode == "descend")
7374  smode = DESCENDING;
7375  else
7376  error (R"(__sort_rows_idx__: MODE must be either "ascend" or "descend")");
7377  }
7378 
7379  octave_value arg = args(0);
7380 
7381  if (arg.issparse ())
7382  error ("__sort_rows_idx__: sparse matrices not yet supported");
7383 
7384  if (arg.ndims () != 2)
7385  error ("__sort_rows_idx__: needs a 2-D object");
7386 
7387  Array<octave_idx_type> idx = arg.sort_rows_idx (smode);
7388 
7389  // This cannot be ovl(), relies on special overloaded octave_value call.
7390  return octave_value (idx, true, true);
7391 }
7392 
7393 static sortmode
7394 get_sort_mode_option (const octave_value& arg)
7395 {
7396  // FIXME: we initialize to UNSORTED here to avoid a GCC warning
7397  // about possibly using sortmode uninitialized.
7398  // FIXME: shouldn't these modes be scoped inside a class?
7399  sortmode smode = UNSORTED;
7400 
7401  std::string mode = arg.xstring_value ("issorted: MODE must be a string");
7402 
7403  if (mode == "ascend")
7404  smode = ASCENDING;
7405  else if (mode == "descend")
7406  smode = DESCENDING;
7407  else if (mode == "either")
7408  smode = UNSORTED;
7409  else
7410  error (R"(issorted: MODE must be "ascend", "descend", or "either")");
7411 
7412  return smode;
7413 }
7414 
7415 DEFUN (issorted, args, ,
7416  doc: /* -*- texinfo -*-
7417 @deftypefn {} {@var{tf} =} issorted (@var{A})
7418 @deftypefnx {} {@var{tf} =} issorted (@var{A}, @var{mode})
7419 @deftypefnx {} {@var{tf} =} issorted (@var{A}, "rows", @var{mode})
7420 Return true if the vector @var{A} is sorted according to @var{mode}, which
7421 may be either @qcode{"ascend"}, @qcode{"descend"}, or @qcode{"either"}.
7422 
7423 By default, @var{mode} is @qcode{"ascend"}. NaNs are treated in the same
7424 manner as @code{sort}.
7425 
7426 If the optional argument @qcode{"rows"} is supplied, check whether the matrix
7427 is sorted by rows as output by the function @code{sortrows} (with no options).
7428 
7429 This function does not support sparse matrices.
7430 @seealso{sort, sortrows}
7431 @end deftypefn */)
7432 {
7433  int nargin = args.length ();
7434 
7435  if (nargin < 1 || nargin > 3)
7436  print_usage ();
7437 
7438  bool by_rows = false;
7439 
7440  sortmode smode = ASCENDING;
7441 
7442  if (nargin > 1)
7443  {
7444  if (nargin == 3)
7445  smode = get_sort_mode_option (args(2));
7446 
7447  std::string tmp = args(1).xstring_value ("issorted: second argument must be a string");
7448  if (tmp == "rows")
7449  by_rows = true;
7450  else
7451  smode = get_sort_mode_option (args(1));
7452  }
7453 
7454  octave_value retval;
7455 
7456  octave_value arg = args(0);
7457 
7458  if (arg.isempty ())
7459  retval = true;
7460  else if (by_rows)
7461  {
7462  if (arg.issparse ())
7463  error ("issorted: sparse matrices not yet supported");
7464 
7465  if (arg.ndims () != 2)
7466  error ("issorted: A must be a 2-D object");
7467 
7468  retval = arg.is_sorted_rows (smode) != UNSORTED;
7469  }
7470  else
7471  {
7472  if (! arg.dims ().isvector ())
7473  error ("issorted: needs a vector");
7474 
7475  retval = args(0).issorted (smode) != UNSORTED;
7476  }
7477 
7478  return retval;
7479 }
7480 
7481 /*
7482 %!shared sm, um, sv, uv
7483 %! sm = [1, 2; 3, 4];
7484 %! um = [3, 1; 2, 4];
7485 %! sv = [1, 2, 3, 4];
7486 %! uv = [2, 1, 4, 3];
7487 
7488 %!assert (issorted (sm, "rows"))
7489 %!assert (! issorted (um, "rows"))
7490 %!assert (issorted (sv))
7491 %!assert (! issorted (uv))
7492 %!assert (issorted (sv'))
7493 %!assert (! issorted (uv'))
7494 %!assert (issorted (sm, "rows", "ascend"))
7495 %!assert (! issorted (um, "rows", "ascend"))
7496 %!assert (issorted (sv, "ascend"))
7497 %!assert (! issorted (uv, "ascend"))
7498 %!assert (issorted (sv', "ascend"))
7499 %!assert (! issorted (uv', "ascend"))
7500 %!assert (! issorted (sm, "rows", "descend"))
7501 %!assert (issorted (flipud (sm), "rows", "descend"))
7502 %!assert (! issorted (sv, "descend"))
7503 %!assert (issorted (fliplr (sv), "descend"))
7504 %!assert (! issorted (sv', "descend"))
7505 %!assert (issorted (fliplr (sv)', "descend"))
7506 %!assert (! issorted (um, "rows", "either"))
7507 %!assert (! issorted (uv, "either"))
7508 %!assert (issorted (sm, "rows", "either"))
7509 %!assert (issorted (flipud (sm), "rows", "either"))
7510 %!assert (issorted (sv, "either"))
7511 %!assert (issorted (fliplr (sv), "either"))
7512 %!assert (issorted (sv', "either"))
7513 %!assert (issorted (fliplr (sv)', "either"))
7514 
7515 %!assert (issorted ([]))
7516 %!assert (issorted ([], "rows"))
7517 %!assert (issorted ([], "ascend"))
7518 %!assert (issorted ([], "rows", "ascend"))
7519 %!assert (issorted ([], "descend"))
7520 %!assert (issorted ([], "rows", "descend"))
7521 %!assert (issorted ({}))
7522 %!assert (issorted ({}, "rows"))
7523 %!assert (issorted ({}, "ascend"))
7524 %!assert (issorted ({}, "rows", "ascend"))
7525 %!assert (issorted ({}, "descend"))
7526 %!assert (issorted ({}, "rows", "descend"))
7527 %!assert (issorted (""))
7528 %!assert (issorted ("", "rows"))
7529 %!assert (issorted ("", "ascend"))
7530 %!assert (issorted ("", "rows", "ascend"))
7531 %!assert (issorted ("", "descend"))
7532 %!assert (issorted ("", "rows", "descend"))
7533 
7534 ## Test input validation
7535 %!error issorted ()
7536 %!error issorted (1,2,3,4)
7537 %!error <second argument must be a string> issorted (1, 2)
7538 %!error <second argument must be a string> issorted (1, {"rows"})
7539 %!error <sparse matrices not yet supported> issorted (sparse ([1 2 3]), "rows")
7540 %!error <A must be a 2-D object> issorted (rand (2,2,2), "rows")
7541 %!error <needs a vector> issorted (ones (2,2))
7542 */
7543 
7544 DEFUN (nth_element, args, ,
7545  doc: /* -*- texinfo -*-
7546 @deftypefn {} {@var{nel} =} nth_element (@var{x}, @var{n})
7547 @deftypefnx {} {@var{nel} =} nth_element (@var{x}, @var{n}, @var{dim})
7548 Select the n-th smallest element of a vector, using the ordering defined by
7549 @code{sort}.
7550 
7551 The result is equivalent to @code{sort(@var{x})(@var{n})}.
7552 
7553 @var{n} can also be a contiguous range, either ascending @code{l:u}
7554 or descending @code{u:-1:l}, in which case a range of elements is returned.
7555 
7556 If @var{x} is an array, @code{nth_element} operates along the dimension
7557 defined by @var{dim}, or the first non-singleton dimension if @var{dim} is
7558 not given.
7559 
7560 Programming Note: nth_element encapsulates the C++ standard library
7561 algorithms nth_element and partial_sort. On average, the complexity of the
7562 operation is O(M*log(K)), where @w{@code{M = size (@var{x}, @var{dim})}} and
7563 @w{@code{K = length (@var{n})}}. This function is intended for cases where
7564 the ratio K/M is small; otherwise, it may be better to use @code{sort}.
7565 @seealso{sort, min, max}
7566 @end deftypefn */)
7567 {
7568  int nargin = args.length ();
7569 
7570  if (nargin < 2 || nargin > 3)
7571  print_usage ();
7572 
7573  int dim = -1;
7574  if (nargin == 3)
7575  {
7576  dim = args(2).int_value (true) - 1;
7577  if (dim < 0)
7578  error ("nth_element: DIM must be a valid dimension");
7579  }
7580 
7581  octave_value argx = args(0);
7582  if (dim < 0)
7583  dim = argx.dims ().first_non_singleton ();
7584 
7585  octave_value retval;
7586 
7587  try
7588  {
7589  idx_vector n = args(1).index_vector ();
7590 
7591  switch (argx.builtin_type ())
7592  {
7593  case btyp_double:
7594  retval = argx.array_value ().nth_element (n, dim);
7595  break;
7596  case btyp_float:
7597  retval = argx.float_array_value ().nth_element (n, dim);
7598  break;
7599  case btyp_complex:
7600  retval = argx.complex_array_value ().nth_element (n, dim);
7601  break;
7602  case btyp_float_complex:
7603  retval = argx.float_complex_array_value ().nth_element (n, dim);
7604  break;
7605 
7606 #define MAKE_INT_BRANCH(X) \
7607  case btyp_ ## X: \
7608  retval = argx.X ## _array_value ().nth_element (n, dim); \
7609  break;
7610 
7611  MAKE_INT_BRANCH (int8);
7612  MAKE_INT_BRANCH (int16);
7613  MAKE_INT_BRANCH (int32);
7614  MAKE_INT_BRANCH (int64);
7615  MAKE_INT_BRANCH (uint8);
7616  MAKE_INT_BRANCH (uint16);
7617  MAKE_INT_BRANCH (uint32);
7618  MAKE_INT_BRANCH (uint64);
7619  MAKE_INT_BRANCH (bool);
7620 
7621 #undef MAKE_INT_BRANCH
7622 
7623  default:
7624  if (argx.iscellstr ())
7625  retval = argx.cellstr_value ().nth_element (n, dim);
7626  else
7627  err_wrong_type_arg ("nth_element", argx);
7628  }
7629  }
7630  catch (const index_exception& ie)
7631  {
7632  error ("nth_element: invalid index %s", ie.what ());
7633  }
7634 
7635  return retval;
7636 }
7637 
7638 /*
7639 %!assert (nth_element ([1:10], 1), 1)
7640 %!assert (nth_element ([1:10], 10), 10)
7641 %!assert (nth_element ([1:10], 1:3), [1 2 3])
7642 %!assert (nth_element ([1:10], 1:10), [1:10])
7643 
7644 %!assert <*51329> (nth_element ([1:10], [1:10]), [1:10])
7645 
7646 %!error nth_element ()
7647 %!error nth_element (1)
7648 %!error nth_element (1, 1.5)
7649 %!error nth_element (1, 2, 3, 4)
7650 %!error nth_element ("abcd", 3)
7651 */
7652 
7653 template <typename NDT>
7654 static NDT
7655 do_accumarray_sum (const idx_vector& idx, const NDT& vals,
7656  octave_idx_type n = -1)
7657 {
7658  typedef typename NDT::element_type T;
7659  if (n < 0)
7660  n = idx.extent (0);
7661  else if (idx.extent (n) > n)
7662  error ("accumarray: index out of range");
7663 
7664  NDT retval (dim_vector (n, 1), T ());
7665 
7666  if (vals.numel () == 1)
7667  retval.idx_add (idx, vals (0));
7668  else if (vals.numel () == idx.length (n))
7669  retval.idx_add (idx, vals);
7670  else
7671  error ("accumarray: dimensions mismatch");
7672 
7673  return retval;
7674 }
7675 
7676 DEFUN (__accumarray_sum__, args, ,
7677  doc: /* -*- texinfo -*-
7678 @deftypefn {} {} __accumarray_sum__ (@var{idx}, @var{vals}, @var{n})
7679 Undocumented internal function.
7680 @end deftypefn */)
7681 {
7682  int nargin = args.length ();
7683 
7684  if (nargin < 2 || nargin > 3)
7685  print_usage ();
7686 
7687  if (! args(0).isnumeric ())
7688  error ("__accumarray_sum__: first argument must be numeric");
7689 
7690  octave_value retval;
7691 
7692  try
7693  {
7694  idx_vector idx = args(0).index_vector ();
7695  octave_idx_type n = -1;
7696  if (nargin == 3)
7697  n = args(2).idx_type_value (true);
7698 
7699  octave_value vals = args(1);
7700 
7701  if (vals.is_range ())
7702  {
7703  range<double> r = vals.range_value ();
7704  if (r.increment () == 0)
7705  vals = r.base ();
7706  }
7707 
7708  if (vals.is_single_type ())
7709  {
7710  if (vals.iscomplex ())
7711  retval = do_accumarray_sum (idx,
7712  vals.float_complex_array_value (),
7713  n);
7714  else
7715  retval = do_accumarray_sum (idx, vals.float_array_value (), n);
7716  }
7717  else if (vals.isnumeric () || vals.islogical ())
7718  {
7719  if (vals.iscomplex ())
7720  retval = do_accumarray_sum (idx,
7721  vals.complex_array_value (),
7722  n);
7723  else
7724  retval = do_accumarray_sum (idx, vals.array_value (), n);
7725  }
7726  else
7727  err_wrong_type_arg ("accumarray", vals);
7728  }
7729  catch (const index_exception& ie)
7730  {
7731  error ("__accumarray_sum__: invalid index %s", ie.what ());
7732  }
7733 
7734  return retval;
7735 }
7736 
7737 template <typename NDT>
7738 static NDT
7739 do_accumarray_minmax (const idx_vector& idx, const NDT& vals,
7740  octave_idx_type n, bool ismin,
7741  const typename NDT::element_type& zero_val)
7742 {
7743  typedef typename NDT::element_type T;
7744  if (n < 0)
7745  n = idx.extent (0);
7746  else if (idx.extent (n) > n)
7747  error ("accumarray: index out of range");
7748 
7749  NDT retval (dim_vector (n, 1), zero_val);
7750 
7751  // Pick minimizer or maximizer.
7752  void (MArray<T>::*op) (const idx_vector&, const MArray<T>&)
7753  = ismin ? (&MArray<T>::idx_min) : (&MArray<T>::idx_max);
7754 
7755  octave_idx_type l = idx.length (n);
7756  if (vals.numel () == 1)
7757  (retval.*op) (idx, NDT (dim_vector (l, 1), vals(0)));
7758  else if (vals.numel () == l)
7759  (retval.*op) (idx, vals);
7760  else
7761  error ("accumarray: dimensions mismatch");
7762 
7763  return retval;
7764 }
7765 
7766 static octave_value_list
7767 do_accumarray_minmax_fcn (const octave_value_list& args,
7768  bool ismin)
7769 {
7770  int nargin = args.length ();
7771 
7772  if (nargin < 3 || nargin > 4)
7773  print_usage ();
7774 
7775  if (! args(0).isnumeric ())
7776  error ("accumarray: first argument must be numeric");
7777 
7778  octave_value retval;
7779 
7780  try
7781  {
7782  idx_vector idx = args(0).index_vector ();
7783  octave_idx_type n = -1;
7784  if (nargin == 4)
7785  n = args(3).idx_type_value (true);
7786 
7787  octave_value vals = args(1);
7788  octave_value zero = args(2);
7789 
7790  switch (vals.builtin_type ())
7791  {
7792  case btyp_double:
7793  retval = do_accumarray_minmax (idx, vals.array_value (), n, ismin,
7794  zero.double_value ());
7795  break;
7796 
7797  case btyp_float:
7798  retval = do_accumarray_minmax (idx, vals.float_array_value (), n,
7799  ismin, zero.float_value ());
7800  break;
7801 
7802  case btyp_complex:
7803  retval = do_accumarray_minmax (idx, vals.complex_array_value (),
7804  n, ismin, zero.complex_value ());
7805  break;
7806 
7807  case btyp_float_complex:
7808  retval = do_accumarray_minmax (idx,
7809  vals.float_complex_array_value (),
7810  n, ismin,
7811  zero.float_complex_value ());
7812  break;
7813 
7814 #define MAKE_INT_BRANCH(X) \
7815  case btyp_ ## X: \
7816  retval = do_accumarray_minmax (idx, vals.X ## _array_value (), \
7817  n, ismin, zero.X ## _scalar_value ()); \
7818  break;
7819 
7820  MAKE_INT_BRANCH (int8);
7821  MAKE_INT_BRANCH (int16);
7822  MAKE_INT_BRANCH (int32);
7823  MAKE_INT_BRANCH (int64);
7824  MAKE_INT_BRANCH (uint8);
7825  MAKE_INT_BRANCH (uint16);
7826  MAKE_INT_BRANCH (uint32);
7827  MAKE_INT_BRANCH (uint64);
7828 
7829 #undef MAKE_INT_BRANCH
7830 
7831  case btyp_bool:
7832  retval = do_accumarray_minmax (idx, vals.array_value (), n, ismin,
7833  zero.bool_value ());
7834  break;
7835 
7836  default:
7837  err_wrong_type_arg ("accumarray", vals);
7838  }
7839  }
7840  catch (const index_exception& ie)
7841  {
7842  error ("do_accumarray_minmax_fcn: invalid index %s", ie.what ());
7843  }
7844 
7845  return retval;
7846 }
7847 
7848 DEFUN (__accumarray_min__, args, ,
7849  doc: /* -*- texinfo -*-
7850 @deftypefn {} {} __accumarray_min__ (@var{idx}, @var{vals}, @var{zero}, @var{n})
7851 Undocumented internal function.
7852 @end deftypefn */)
7853 {
7854  return do_accumarray_minmax_fcn (args, true);
7855 }
7856 
7857 DEFUN (__accumarray_max__, args, ,
7858  doc: /* -*- texinfo -*-
7859 @deftypefn {} {} __accumarray_max__ (@var{idx}, @var{vals}, @var{zero}, @var{n})
7860 Undocumented internal function.
7861 @end deftypefn */)
7862 {
7863  return do_accumarray_minmax_fcn (args, false);
7864 }
7865 
7866 template <typename NDT>
7867 static NDT
7868 do_accumdim_sum (const idx_vector& idx, const NDT& vals,
7869  int dim = -1, octave_idx_type n = -1)
7870 {
7871  typedef typename NDT::element_type T;
7872  if (n < 0)
7873  n = idx.extent (0);
7874  else if (idx.extent (n) > n)
7875  error ("accumdim: index out of range");
7876 
7877  dim_vector vals_dim = vals.dims ();
7878  dim_vector rdv = vals_dim;
7879 
7880  if (dim < 0)
7881  dim = vals.dims ().first_non_singleton ();
7882  else if (dim >= rdv.ndims ())
7883  rdv.resize (dim+1, 1);
7884 
7885  rdv(dim) = n;
7886 
7887  NDT retval (rdv, T ());
7888 
7889  if (idx.length () != vals_dim(dim))
7890  error ("accumdim: dimension mismatch");
7891 
7892  retval.idx_add_nd (idx, vals, dim);
7893 
7894  return retval;
7895 }
7896 
7897 DEFUN (__accumdim_sum__, args, ,
7898  doc: /* -*- texinfo -*-
7899 @deftypefn {} {} __accumdim_sum__ (@var{idx}, @var{vals}, @var{dim}, @var{n})
7900 Undocumented internal function.
7901 @end deftypefn */)
7902 {
7903  int nargin = args.length ();
7904 
7905  if (nargin < 2 || nargin > 4)
7906  print_usage ();
7907 
7908  if (! args(0).isnumeric ())
7909  error ("__accumdim_sum__: first argument must be numeric");
7910 
7911  octave_value retval;
7912 
7913  try
7914  {
7915  idx_vector idx = args(0).index_vector ();
7916  int dim = -1;
7917  if (nargin >= 3)
7918  dim = args(2).int_value () - 1;
7919 
7920  octave_idx_type n = -1;
7921  if (nargin == 4)
7922  n = args(3).idx_type_value (true);
7923 
7924  octave_value vals = args(1);
7925 
7926  if (vals.is_single_type ())
7927  {
7928  if (vals.iscomplex ())
7929  retval = do_accumdim_sum (idx,
7930  vals.float_complex_array_value (),
7931  dim, n);
7932  else
7933  retval = do_accumdim_sum (idx, vals.float_array_value (),
7934  dim, n);
7935  }
7936  else if (vals.isnumeric () || vals.islogical ())
7937  {
7938  if (vals.iscomplex ())
7939  retval = do_accumdim_sum (idx, vals.complex_array_value (),
7940  dim, n);
7941  else
7942  retval = do_accumdim_sum (idx, vals.array_value (), dim, n);
7943  }
7944  else
7945  err_wrong_type_arg ("accumdim", vals);
7946  }
7947  catch (const index_exception& ie)
7948  {
7949  error ("__accumdim_sum__: invalid index %s", ie.what ());
7950  }
7951 
7952  return retval;
7953 }
7954 
7955 template <typename NDT>
7956 static NDT
7957 do_merge (const Array<bool>& mask,
7958  const NDT& tval, const NDT& fval)
7959 {
7960  typedef typename NDT::element_type T;
7961  dim_vector dv = mask.dims ();
7962  NDT retval (dv);
7963 
7964  bool tscl = tval.numel () == 1;
7965  bool fscl = fval.numel () == 1;
7966 
7967  if ((! tscl && tval.dims () != dv) || (! fscl && fval.dims () != dv))
7968  error ("merge: MASK, TVAL, and FVAL dimensions must match");
7969 
7970  T *rv = retval.fortran_vec ();
7971  octave_idx_type n = retval.numel ();
7972 
7973  const T *tv = tval.data ();
7974  const T *fv = fval.data ();
7975  const bool *mv = mask.data ();
7976 
7977  if (tscl)
7978  {
7979  if (fscl)
7980  {
7981  T ts = tv[0];
7982  T fs = fv[0];
7983  for (octave_idx_type i = 0; i < n; i++)
7984  rv[i] = (mv[i] ? ts : fs);
7985  }
7986  else
7987  {
7988  T ts = tv[0];
7989  for (octave_idx_type i = 0; i < n; i++)
7990  rv[i] = (mv[i] ? ts : fv[i]);
7991  }
7992  }
7993  else
7994  {
7995  if (fscl)
7996  {
7997  T fs = fv[0];
7998  for (octave_idx_type i = 0; i < n; i++)
7999  rv[i] = (mv[i] ? tv[i] : fs);
8000  }
8001  else
8002  {
8003  for (octave_idx_type i = 0; i < n; i++)
8004  rv[i] = (mv[i] ? tv[i] : fv[i]);
8005  }
8006  }
8007 
8008  return retval;
8009 }
8010 
8011 #define MAKE_INT_BRANCH(INTX) \
8012  else if (tval.is_ ## INTX ## _type () && fval.is_ ## INTX ## _type ()) \
8013  { \
8014  retval = do_merge (mask, \
8015  tval.INTX ## _array_value (), \
8016  fval.INTX ## _array_value ()); \
8017  }
8018 
8019 DEFUN (merge, args, ,
8020  doc: /* -*- texinfo -*-
8021 @deftypefn {} {@var{M} =} merge (@var{mask}, @var{tval}, @var{fval})
8022 @deftypefnx {} {@var{M} =} ifelse (@var{mask}, @var{tval}, @var{fval})
8023 Merge elements of @var{true_val} and @var{false_val}, depending on the
8024 value of @var{mask}.
8025 
8026 If @var{mask} is a logical scalar, the other two arguments can be arbitrary
8027 values. Otherwise, @var{mask} must be a logical array, and @var{tval},
8028 @var{fval} should be arrays of matching class, or cell arrays. In the
8029 scalar mask case, @var{tval} is returned if @var{mask} is true, otherwise
8030 @var{fval} is returned.
8031 
8032 In the array mask case, both @var{tval} and @var{fval} must be either
8033 scalars or arrays with dimensions equal to @var{mask}. The result is
8034 constructed as follows:
8035 
8036 @example
8037 @group
8038 result(mask) = tval(mask);
8039 result(! mask) = fval(! mask);
8040 @end group
8041 @end example
8042 
8043 @var{mask} can also be arbitrary numeric type, in which case it is first
8044 converted to logical.
8045 
8046 Programming Note: @code{ifelse} is an alias for @code{merge} and can be used
8047 interchangeably.
8048 @seealso{logical, diff}
8049 @end deftypefn */)
8050 {
8051  if (args.length () != 3)
8052  print_usage ();
8053 
8054  if (! (args(0).islogical () || args(0).isnumeric ()))
8055  error ("merge: first argument must be logical or numeric");
8056 
8057  octave_value retval;
8058 
8059  octave_value mask_val = args(0);
8060 
8061  if (mask_val.is_scalar_type ())
8062  retval = (mask_val.is_true () ? args(1) : args(2));
8063  else
8064  {
8065  boolNDArray mask = mask_val.bool_array_value ();
8066 
8067  octave_value tval = args(1);
8068  octave_value fval = args(2);
8069 
8070  if (tval.is_double_type () && fval.is_double_type ())
8071  {
8072  if (tval.iscomplex () || fval.iscomplex ())
8073  retval = do_merge (mask,
8074  tval.complex_array_value (),
8075  fval.complex_array_value ());
8076  else
8077  retval = do_merge (mask,
8078  tval.array_value (),
8079  fval.array_value ());
8080  }
8081  else if (tval.is_single_type () && fval.is_single_type ())
8082  {
8083  if (tval.iscomplex () || fval.iscomplex ())
8084  retval = do_merge (mask,
8085  tval.float_complex_array_value (),
8086  fval.float_complex_array_value ());
8087  else
8088  retval = do_merge (mask,
8089  tval.float_array_value (),
8090  fval.float_array_value ());
8091  }
8092  else if (tval.is_string () && fval.is_string ())
8093  {
8094  bool sq_string = tval.is_sq_string () || fval.is_sq_string ();
8095  retval = octave_value (do_merge (mask,
8096  tval.char_array_value (),
8097  fval.char_array_value ()),
8098  sq_string ? '\'' : '"');
8099  }
8100  else if (tval.iscell () && fval.iscell ())
8101  {
8102  retval = do_merge (mask,
8103  tval.cell_value (),
8104  fval.cell_value ());
8105  }
8106 
8107  MAKE_INT_BRANCH (int8)
8108  MAKE_INT_BRANCH (int16)
8109  MAKE_INT_BRANCH (int32)
8110  MAKE_INT_BRANCH (int64)
8111  MAKE_INT_BRANCH (uint8)
8112  MAKE_INT_BRANCH (uint16)
8113  MAKE_INT_BRANCH (uint32)
8114  MAKE_INT_BRANCH (uint64)
8115 
8116  else
8117  error ("merge: cannot merge %s with %s with array mask",
8118  tval.class_name ().c_str (),
8119  fval.class_name ().c_str ());
8120  }
8121 
8122  return retval;
8123 }
8124 
8125 DEFALIAS (ifelse, merge);
8126 
8127 #undef MAKE_INT_BRANCH
8128 
8129 template <typename SparseT>
8130 static SparseT
8131 do_sparse_diff (const SparseT& array, octave_idx_type order,
8132  int dim)
8133 {
8134  SparseT retval = array;
8135  if (dim == 1)
8136  {
8137  octave_idx_type k = retval.columns ();
8138  while (order > 0 && k > 0)
8139  {
8140  idx_vector col1 (':'), col2 (':'), sl1 (1, k), sl2 (0, k-1);
8141  retval = SparseT (retval.index (col1, sl1))
8142  - SparseT (retval.index (col2, sl2));
8143  error_unless (retval.columns () == k-1);
8144  order--;
8145  k--;
8146  }
8147  }
8148  else
8149  {
8150  octave_idx_type k = retval.rows ();
8151  while (order > 0 && k > 0)
8152  {
8153  idx_vector col1 (':'), col2 (':'), sl1 (1, k), sl2 (0, k-1);
8154  retval = SparseT (retval.index (sl1, col1))
8155  - SparseT (retval.index (sl2, col2));
8156  error_unless (retval.rows () == k-1);
8157  order--;
8158  k--;
8159  }
8160  }
8161 
8162  return retval;
8163 }
8164 
8165 static octave_value
8166 do_diff (const octave_value& array, octave_idx_type order,
8167  int dim = -1)
8168 {
8169  octave_value retval;
8170 
8171  const dim_vector& dv = array.dims ();
8172  if (dim == -1)
8173  {
8174  dim = array.dims ().first_non_singleton ();
8175 
8176  // Bother Matlab. This behavior is really wicked.
8177  if (dv(dim) <= order)
8178  {
8179  if (dv(dim) == 1)
8180  retval = array.resize (dim_vector (0, 0));
8181  else
8182  {
8183  retval = array;
8184  while (order > 0)
8185  {
8186  if (dim == dv.ndims ())
8187  {
8188  retval = do_diff (array, order, dim - 1);
8189  order = 0;
8190  }
8191  else if (dv(dim) == 1)
8192  dim++;
8193  else
8194  {
8195  retval = do_diff (array, dv(dim) - 1, dim);
8196  order -= dv(dim) - 1;
8197  dim++;
8198  }
8199  }
8200  }
8201 
8202  return retval;
8203  }
8204  }
8205 
8206  if (array.isinteger ())
8207  {
8208  if (array.is_int8_type ())
8209  retval = array.int8_array_value ().diff (order, dim);
8210  else if (array.is_int16_type ())
8211  retval = array.int16_array_value ().diff (order, dim);
8212  else if (array.is_int32_type ())
8213  retval = array.int32_array_value ().diff (order, dim);
8214  else if (array.is_int64_type ())
8215  retval = array.int64_array_value ().diff (order, dim);
8216  else if (array.is_uint8_type ())
8217  retval = array.uint8_array_value ().diff (order, dim);
8218  else if (array.is_uint16_type ())
8219  retval = array.uint16_array_value ().diff (order, dim);
8220  else if (array.is_uint32_type ())
8221  retval = array.uint32_array_value ().diff (order, dim);
8222  else if (array.is_uint64_type ())
8223  retval = array.uint64_array_value ().diff (order, dim);
8224  else
8225  panic_impossible ();
8226  }
8227  else if (array.issparse ())
8228  {
8229  if (array.iscomplex ())
8230  retval = do_sparse_diff (array.sparse_complex_matrix_value (),
8231  order, dim);
8232  else
8233  retval = do_sparse_diff (array.sparse_matrix_value (), order, dim);
8234  }
8235  else if (array.is_single_type ())
8236  {
8237  if (array.iscomplex ())
8238  retval = array.float_complex_array_value ().diff (order, dim);
8239  else
8240  retval = array.float_array_value ().diff (order, dim);
8241  }
8242  else
8243  {
8244  if (array.iscomplex ())
8245  retval = array.complex_array_value ().diff (order, dim);
8246  else
8247  retval = array.array_value ().diff (order, dim);
8248  }
8249 
8250  return retval;
8251 }
8252 
8253 DEFUN (diff, args, ,
8254  doc: /* -*- texinfo -*-
8255 @deftypefn {} {@var{y} =} diff (@var{x})
8256 @deftypefnx {} {@var{y} =} diff (@var{x}, @var{k})
8257 @deftypefnx {} {@var{y} =} diff (@var{x}, @var{k}, @var{dim})
8258 If @var{x} is a vector of length @math{n}, @w{@code{diff (@var{x})}} is the
8259 vector of first differences
8260 @tex
8261  $x_2 - x_1, \ldots{}, x_n - x_{n-1}$.
8262 @end tex
8263 @ifnottex
8264  @var{x}(2) - @var{x}(1), @dots{}, @var{x}(n) - @var{x}(n-1).
8265 @end ifnottex
8266 
8267 If @var{x} is a matrix, @w{@code{diff (@var{x})}} is the matrix of column
8268 differences along the first non-singleton dimension.
8269 
8270 The second argument is optional. If supplied,
8271 @w{@code{diff (@var{x}, @var{k})}}, where @var{k} is a non-negative integer,
8272 returns the @var{k}-th differences. It is possible that @var{k} is larger
8273 than the first non-singleton dimension of the matrix. In this case,
8274 @code{diff} continues to take the differences along the next
8275 non-singleton dimension.
8276 
8277 The dimension along which to take the difference can be explicitly
8278 stated with the optional variable @var{dim}. In this case the
8279 @var{k}-th order differences are calculated along this dimension.
8280 In the case where @var{k} exceeds @w{@code{size (@var{x}, @var{dim})}}
8281 an empty matrix is returned.
8282 @seealso{sort, merge}
8283 @end deftypefn */)
8284 {
8285  int nargin = args.length ();
8286 
8287  if (nargin < 1 || nargin > 3)
8288  print_usage ();
8289 
8290  if (! (args(0).isnumeric () || args(0).islogical ()))
8291  error ("diff: X must be numeric or logical");
8292 
8293  int dim = -1;
8294  octave_idx_type order = 1;
8295  if (nargin > 1)
8296  {
8297  if (args(1).is_scalar_type ())
8298  order = args(1).idx_type_value (true, false);
8299  else if (! args(1).is_zero_by_zero ())
8300  error ("diff: order K must be a scalar or []");
8301  if (order < 0)
8302  error ("diff: order K must be non-negative");
8303  }
8304 
8305  if (nargin > 2)
8306  {
8307  dim = args(2).int_value (true, false);
8308  if (dim < 1 || dim > args(0).ndims ())
8309  error ("diff: DIM must be a valid dimension");
8310 
8311  dim -= 1;
8312  }
8313 
8314  return do_diff (args(0), order, dim);
8315 }
8316 
8317 /*
8318 %!assert (diff ([1, 2, 3, 4]), [1, 1, 1])
8319 %!assert (diff ([1, 3, 7, 19], 2), [2, 8])
8320 %!assert (diff ([1, 2; 5, 4; 8, 7; 9, 6; 3, 1]), [4, 2; 3, 3; 1, -1; -6, -5])
8321 %!assert (diff ([1, 2; 5, 4; 8, 7; 9, 6; 3, 1], 3), [-1, -5; -5, 0])
8322 %!assert (isempty (diff (1)))
8323 
8324 %!error diff ()
8325 %!error diff (1, 2, 3, 4)
8326 %!error diff ("foo")
8327 %!error diff ([1, 2; 3, 4], -1)
8328 */
8329 
8330 template <typename T>
8331 static Array<T>
8332 do_repelems (const Array<T>& src, const Array<octave_idx_type>& rep)
8333 {
8334  Array<T> retval;
8335 
8336  if (rep.ndims () != 2 || rep.rows () != 2)
8337  error ("repelems: R must be a 2-row, N-column matrix of integers");
8338 
8339  octave_idx_type n = rep.columns ();
8340  octave_idx_type l = 0;
8341  for (octave_idx_type i = 0; i < n; i++)
8342  {
8343  octave_idx_type k = rep(1, i);
8344  if (k < 0)
8345  error ("repelems: second row must contain non-negative numbers");
8346 
8347  l += k;
8348  }
8349 
8350  retval.clear (1, l);
8351  T *dest = retval.fortran_vec ();
8352  l = 0;
8353  for (octave_idx_type i = 0; i < n; i++)
8354  {
8355  octave_idx_type k = rep(1, i);
8356  std::fill_n (dest, k, src.checkelem (rep(0, i) - 1));
8357  dest += k;
8358  }
8359 
8360  return retval;
8361 }
8362 
8363 DEFUN (repelems, args, ,
8364  doc: /* -*- texinfo -*-
8365 @deftypefn {} {@var{y} =} repelems (@var{x}, @var{r})
8366 Construct a vector of repeated elements from @var{x}.
8367 
8368 @var{r} is a 2x@var{N} integer matrix specifying which elements to repeat
8369 and how often to repeat each element. Entries in the first row,
8370 @var{r}(1,j), select an element to repeat. The corresponding entry in the
8371 second row, @var{r}(2,j), specifies the repeat count. If @var{x} is a
8372 matrix then the columns of @var{x} are imagined to be stacked on top of
8373 each other for purposes of the selection index. A row vector is always
8374 returned.
8375 
8376 Conceptually the result is calculated as follows:
8377 
8378 @example
8379 @group
8380 y = [];
8381 for i = 1:columns (@var{r})
8382  y = [y, @var{x}(@var{r}(1,i)*ones(1, @var{r}(2,i)))];
8383 endfor
8384 @end group
8385 @end example
8386 @seealso{repmat, cat}
8387 @end deftypefn */)
8388 {
8389  if (args.length () != 2)
8390  print_usage ();
8391 
8392  octave_value retval;
8393 
8394  const Matrix rm = args(1).matrix_value ();
8395 
8396  if (rm.rows () != 2 || rm.ndims () != 2)
8397  error ("repelems: R must be a matrix with two rows");
8398 
8399  octave_value x = args(0);
8400 
8401  Array<octave_idx_type> r (rm.dims ());
8402 
8403  for (octave_idx_type i = 0; i < rm.numel (); i++)
8404  {
8405  octave_idx_type rx = rm(i);
8406  if (static_cast<double> (rx) != rm(i))
8407  error ("repelems: R must be a matrix of integers");
8408 
8409  r.xelem (i) = rx;
8410  }
8411 
8412  switch (x.builtin_type ())
8413  {
8414 #define BTYP_BRANCH(X, EX) \
8415  case btyp_ ## X: \
8416  retval = do_repelems (x.EX ## _value (), r); \
8417  break;
8418 
8419  BTYP_BRANCH (double, array);
8420  BTYP_BRANCH (float, float_array);
8421  BTYP_BRANCH (complex, complex_array);
8422  BTYP_BRANCH (float_complex, float_complex_array);
8423  BTYP_BRANCH (bool, bool_array);
8424  BTYP_BRANCH (char, char_array);
8425 
8426  BTYP_BRANCH (int8, int8_array);
8427  BTYP_BRANCH (int16, int16_array);
8428  BTYP_BRANCH (int32, int32_array);
8429  BTYP_BRANCH (int64, int64_array);
8430  BTYP_BRANCH (uint8, uint8_array);
8431  BTYP_BRANCH (uint16, uint16_array);
8432  BTYP_BRANCH (uint32, uint32_array);
8433  BTYP_BRANCH (uint64, uint64_array);
8434 
8435  BTYP_BRANCH (cell, cell);
8436  //BTYP_BRANCH (struct, map);//FIXME
8437 
8438 #undef BTYP_BRANCH
8439 
8440  default:
8441  err_wrong_type_arg ("repelems", x);
8442  }
8443 
8444  return retval;
8445 }
8446 
8447 DEFUN (base64_encode, args, ,
8448  doc: /* -*- texinfo -*-
8449 @deftypefn {} {@var{s} =} base64_encode (@var{x})
8450 Encode a double matrix or array @var{x} into the base64 format string
8451 @var{s}.
8452 
8453 @seealso{base64_decode, matlab.net.base64decode, matlab.net.base64encode}
8454 @end deftypefn */)
8455 {
8456  if (args.length () != 1)
8457  print_usage ();
8458 
8459  if (! args(0).isnumeric ())
8460  error ("base64_encode: encoding is supported only for numeric arrays");
8461 
8462  if (args(0).iscomplex () || args(0).issparse ())
8463  error ("base64_encode: encoding complex or sparse data is not supported");
8464 
8465  octave_value_list retval;
8466 
8467  if (args(0).isinteger ())
8468  {
8469 #define MAKE_INT_BRANCH(X) \
8470  if (args(0).is_ ## X ## _type ()) \
8471  { \
8472  const X##NDArray in = args(0). X## _array_value (); \
8473  std::size_t inlen = in.numel () * sizeof (X## _t) / sizeof (char); \
8474  const char *inc = reinterpret_cast<const char *> (in.data ()); \
8475  char *out; \
8476  if (base64_encode (inc, inlen, &out)) \
8477  { \
8478  retval(0) = octave_value (out); \
8479  ::free (out); \
8480  } \
8481  }
8482 
8483  MAKE_INT_BRANCH(int8)
8484  else MAKE_INT_BRANCH(int16)
8485  else MAKE_INT_BRANCH(int32)
8486  else MAKE_INT_BRANCH(int64)
8487  else MAKE_INT_BRANCH(uint8)
8488  else MAKE_INT_BRANCH(uint16)
8489  else MAKE_INT_BRANCH(uint32)
8490  else MAKE_INT_BRANCH(uint64)
8491 
8492 #undef MAKE_INT_BRANCH
8493 
8494  else
8495  panic_impossible ();
8496  }
8497  else if (args(0).is_single_type ())
8498  {
8499  const Array<float> in = args(0).float_array_value ();
8500  std::size_t inlen;
8501  inlen = in.numel () * sizeof (float) / sizeof (char);
8502  const char *inc;
8503  inc = reinterpret_cast<const char *> (in.data ());
8504  char *out;
8505  if (base64_encode (inc, inlen, &out))
8506  {
8507  retval(0) = octave_value (out);
8508  ::free (out);
8509  }
8510  }
8511  else // double_type
8512  {
8513  const Array<double> in = args(0).array_value ();
8514  std::size_t inlen;
8515  inlen = in.numel () * sizeof (double) / sizeof (char);
8516  const char *inc;
8517  inc = reinterpret_cast<const char *> (in.data ());
8518  char *out;
8519  if (base64_encode (inc, inlen, &out))
8520  {
8521  retval(0) = octave_value (out);
8522  ::free (out);
8523  }
8524  }
8525 
8526  return retval;
8527 }
8528 
8529 /*
8530 %!test
8531 %! ## FIXME: better test for endianness?
8532 %! if (bitunpack (uint16 (1))(1) == 1)
8533 %! expected = "2w9JQA==";
8534 %! else
8535 %! expected = "QEkP2w==";
8536 %! endif
8537 %! assert (base64_encode (single (pi)), expected);
8538 
8539 %!assert (base64_encode (uint8 ([0 0 0])), "AAAA")
8540 %!assert (base64_encode (uint16 ([0 0 0])), "AAAAAAAA")
8541 %!assert (base64_encode (uint32 ([0 0 0])), "AAAAAAAAAAAAAAAA")
8542 %!assert (base64_encode (uint64 ([0 0 0])), "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA")
8543 %!assert (base64_encode (uint8 ([255 255 255])), "////")
8544 
8545 %!error base64_encode ()
8546 %!error base64_encode (1,2)
8547 %!error base64_encode ("A string")
8548 %!error base64_encode ({"A cell array"})
8549 %!error base64_encode (struct ())
8550 */
8551 
8552 DEFUN (base64_decode, args, ,
8553  doc: /* -*- texinfo -*-
8554 @deftypefn {} {@var{x} =} base64_decode (@var{s})
8555 @deftypefnx {} {@var{x} =} base64_decode (@var{s}, @var{dims})
8556 Decode the double matrix or array @var{x} from the base64 encoded string
8557 @var{s}.
8558 
8559 The optional input parameter @var{dims} should be a vector containing the
8560 dimensions of the decoded array.
8561 @seealso{base64_encode, matlab.net.base64decode, matlab.net.base64encode}
8562 @end deftypefn */)
8563 {
8564  int nargin = args.length ();
8565 
8566  if (nargin < 1 || nargin > 2)
8567  print_usage ();
8568 
8569  std::string str = args(0).string_value ();
8570 
8571  Array<double> retval = base64_decode (str);
8572 
8573  if (nargin == 2)
8574  {
8575  dim_vector dims;
8576 
8577  const Array<octave_idx_type> size
8578  = args(1).octave_idx_type_vector_value ();
8579 
8580  dims = dim_vector::alloc (size.numel ());
8581  for (octave_idx_type i = 0; i < size.numel (); i++)
8582  dims(i) = size(i);
8583 
8584  retval = retval.reshape (dims);
8585  }
8586 
8587  return ovl (retval);
8588 }
8589 
8590 /*
8591 %!assert (base64_decode (base64_encode (pi)), pi)
8592 %!
8593 %!test
8594 %! in = randn (10);
8595 %! outv = base64_decode (base64_encode (in));
8596 %! outm = base64_decode (base64_encode (in), size (in));
8597 %! assert (outv, in(:).');
8598 %! assert (outm, in);
8599 
8600 %!error base64_decode ()
8601 %!error base64_decode (1,2,3)
8602 %!error base64_decode (1, "this is not a valid set of dimensions")
8603 %!error <input was not valid base64> base64_decode (1)
8604 %!error <input was not valid base64> base64_decode ("AQ=")
8605 %!error <incorrect input size> base64_decode ("AQ==")
8606 */
8607 
8608 DEFUN (__base64_decode_bytes__, args, ,
8609  doc: /* -*- texinfo -*-
8610 @deftypefn {} {@var{x} =} base64_decode_bytes (@var{s})
8611 @deftypefnx {} {@var{x} =} base64_decode_bytes (@var{s}, @var{dims})
8612 Decode the uint8 matrix or array @var{x} from the base64 encoded string
8613 @var{s}.
8614 
8615 The optional input parameter @var{dims} should be a vector containing the
8616 dimensions of the decoded array.
8617 @seealso{base64_decode}
8618 @end deftypefn */)
8619 {
8620  int nargin = args.length ();
8621 
8622  if (nargin < 1 || nargin > 2)
8623  print_usage ();
8624 
8625  std::string str = args(0).string_value ();
8626 
8628 
8629  if (nargin == 2)
8630  {
8631  dim_vector dims;
8632 
8633  const Array<octave_idx_type> size
8634  = args(1).octave_idx_type_vector_value ();
8635 
8636  dims = dim_vector::alloc (size.numel ());
8637  for (octave_idx_type i = 0; i < size.numel (); i++)
8638  dims(i) = size(i);
8639 
8640  retval = retval.reshape (dims);
8641  }
8642 
8643  return ovl (retval);
8644 }
8645 
8646 /*
8647 %!assert (__base64_decode_bytes__ (base64_encode (uint8 (1))), uint8 (1))
8648 
8649 %!test
8650 %! in = uint8 (rand (10)*255);
8651 %! outv = __base64_decode_bytes__ (base64_encode (in));
8652 %! outm = __base64_decode_bytes__ (base64_encode (in), size (in));
8653 %! assert (outv, in(:).');
8654 %! assert (outm, in);
8655 
8656 %!error __base64_decode_bytes__ ()
8657 %!error __base64_decode_bytes__ (1,2,3)
8658 %!error __base64_decode_bytes__ (1, "this is not a valid set of dimensions")
8659 %!error <input was not valid base64> __base64_decode_bytes__ (1)
8660 */
8661 
8662 OCTAVE_END_NAMESPACE(octave)
bool isvector(const dim_vector &dim)
Definition: Array-util.cc:140
ComplexMatrix linspace(const ComplexColumnVector &x1, const ComplexColumnVector &x2, octave_idx_type n)
Definition: CMatrix.cc:3629
#define Inf
Definition: Faddeeva.cc:260
#define NaN
Definition: Faddeeva.cc:261
charNDArray max(char d, const charNDArray &m)
Definition: chNDArray.cc:230
charNDArray min(char d, const charNDArray &m)
Definition: chNDArray.cc:207
T * fortran_vec()
Size of the specified dimension.
Definition: Array-base.cc:1764
Array< T, Alloc > nth_element(const octave::idx_vector &n, int dim=0) const
Returns the n-th element in increasing order, using the same ordering as used for sort.
Definition: Array-base.cc:2319
void clear()
Definition: Array-base.cc:109
int ndims() const
Size of the specified dimension.
Definition: Array.h:671
octave_idx_type rows() const
Definition: Array.h:459
void resize(const dim_vector &dv, const T &rfv)
Size of the specified dimension.
Definition: Array-base.cc:1023
const T * data() const
Size of the specified dimension.
Definition: Array.h:663
octave_idx_type columns() const
Definition: Array.h:471
const dim_vector & dims() const
Return a const-reference so that dims ()(i) works efficiently.
Definition: Array.h:503
T & xelem(octave_idx_type n)
Size of the specified dimension.
Definition: Array.h:524
Array< T, Alloc > reshape(octave_idx_type nr, octave_idx_type nc) const
Size of the specified dimension.
Definition: Array.h:635
T & checkelem(octave_idx_type n)
Size of the specified dimension.
Definition: Array-base.cc:214
static Array< T, Alloc > cat(int dim, octave_idx_type n, const Array< T, Alloc > *array_list)
Concatenation along a specified (0-based) dimension, equivalent to cat().
Definition: Array-base.cc:2643
octave_idx_type numel() const
Number of elements in the array.
Definition: Array.h:414
Definition: Cell.h:43
ComplexNDArray prod(int dim=-1) const
Definition: CNDArray.cc:370
ComplexNDArray cumsum(int dim=-1) const
Definition: CNDArray.cc:364
ComplexNDArray diff(octave_idx_type order=1, int dim=-1) const
Definition: CNDArray.cc:394
ComplexNDArray xsum(int dim=-1) const
Definition: CNDArray.cc:382
ComplexNDArray sum(int dim=-1) const
Definition: CNDArray.cc:376
FloatComplexNDArray sum(int dim=-1) const
Definition: fCNDArray.cc:384
ComplexNDArray dsum(int dim=-1) const
Definition: fCNDArray.cc:390
FloatComplexNDArray diff(octave_idx_type order=1, int dim=-1) const
Definition: fCNDArray.cc:402
FloatComplexNDArray prod(int dim=-1) const
Definition: fCNDArray.cc:372
FloatComplexNDArray cumsum(int dim=-1) const
Definition: fCNDArray.cc:365
ComplexNDArray dprod(int dim=-1) const
Definition: fCNDArray.cc:378
FloatNDArray sum(int dim=-1) const
Definition: fNDArray.cc:388
FloatNDArray prod(int dim=-1) const
Definition: fNDArray.cc:376
NDArray dprod(int dim=-1) const
Definition: fNDArray.cc:382
FloatNDArray cumsum(int dim=-1) const
Definition: fNDArray.cc:370
NDArray dsum(int dim=-1) const
Definition: fNDArray.cc:394
FloatNDArray diff(octave_idx_type order=1, int dim=-1) const
Definition: fNDArray.cc:454
Template for N-dimensional array classes with like-type math operators.
Definition: MArray.h:63
MArray< T > reshape(const dim_vector &new_dims) const
Definition: MArray.h:87
Definition: dMatrix.h:42
NDArray diff(octave_idx_type order=1, int dim=-1) const
Definition: dNDArray.cc:491
NDArray cumsum(int dim=-1) const
Definition: dNDArray.cc:413
NDArray prod(int dim=-1) const
Definition: dNDArray.cc:419
NDArray xsum(int dim=-1) const
Definition: dNDArray.cc:431
NDArray sum(int dim=-1) const
Definition: dNDArray.cc:425
SparseBoolMatrix all(int dim=-1) const
Definition: boolSparse.cc:140
SparseMatrix sum(int dim=-1) const
Definition: boolSparse.cc:192
SparseBoolMatrix any(int dim=-1) const
Definition: boolSparse.cc:146
SparseComplexMatrix prod(int dim=-1) const
Definition: CSparse.cc:7389
SparseComplexMatrix sum(int dim=-1) const
Definition: CSparse.cc:7401
SparseComplexMatrix cumsum(int dim=-1) const
Definition: CSparse.cc:7383
SparseMatrix sum(int dim=-1) const
Definition: dSparse.cc:7407
SparseMatrix prod(int dim=-1) const
Definition: dSparse.cc:7395
SparseMatrix cumsum(int dim=-1) const
Definition: dSparse.cc:7389
octave_idx_type cols() const
Definition: Sparse.h:352
octave_idx_type * cidx()
Definition: Sparse.h:596
T * data()
Definition: Sparse.h:574
octave_idx_type * ridx()
Definition: Sparse.h:583
static Sparse< T, Alloc > cat(int dim, octave_idx_type n, const Sparse< T, Alloc > *sparse_list)
Definition: Sparse.cc:2667
octave_idx_type nnz() const
Actual number of nonzero terms.
Definition: Sparse.h:339
octave_idx_type rows() const
Definition: Sparse.h:351
dim_vector dims() const
Definition: Sparse.h:371
boolNDArray any(int dim=-1) const
Definition: boolNDArray.cc:67
boolNDArray all(int dim=-1) const
Definition: boolNDArray.cc:61
Vector representing the dimensions (size) of an Array.
Definition: dim-vector.h:94
bool concat(const dim_vector &dvb, int dim)
This corresponds to cat().
Definition: dim-vector.cc:140
octave_idx_type numel(int n=0) const
Number of elements that a matrix with this dimensions would have.
Definition: dim-vector.h:335
void resize(int n, int fill_value=0)
Definition: dim-vector.h:272
static dim_vector alloc(int n)
Definition: dim-vector.h:202
octave_idx_type ndims() const
Number of dimensions.
Definition: dim-vector.h:257
bool isvector() const
Definition: dim-vector.h:395
bool hvcat(const dim_vector &dvb, int dim)
This corresponds to [,] (horzcat, dim = 0) and [;] (vertcat, dim = 1).
Definition: dim-vector.cc:201
int first_non_singleton(int def=0) const
Definition: dim-vector.h:444
dim_vector redim(int n) const
Force certain dimensionality, preserving numel ().
Definition: dim-vector.cc:226
octave_idx_type length(octave_idx_type n=0) const
Definition: idx-vector.h:520
octave_idx_type extent(octave_idx_type n) const
Definition: idx-vector.h:523
intNDArray diff(octave_idx_type order=1, int dim=-1) const
Definition: intNDArray.cc:299
symbol_table & get_symbol_table()
Definition: interpreter.h:298
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.
static data_type string_to_data_type(const std::string &s)
Definition: data-conv.cc:293
static octave_map cat(int dim, octave_idx_type n, const octave_scalar_map *map_list)
Definition: oct-map.cc:690
void resize(octave_idx_type n, const octave_value &rfv=octave_value())
Definition: ovl.h:117
Array< octave_value > array_value() const
Definition: ovl.h:90
bool empty() const
Definition: ovl.h:115
octave_value_list slice(octave_idx_type offset, octave_idx_type len, bool tags=false) const
Definition: ovl.h:131
octave_idx_type length() const
Definition: ovl.h:113
bool is_uint32_type() const
Definition: ov.h:724
bool isinteger() const
Definition: ov.h:730
boolNDArray bool_array_value(bool warn=false) const
Definition: ov.h:891
SparseMatrix sparse_matrix_value(bool frc_str_conv=false) const
Definition: ov.h:900
std::string class_name() const
Definition: ov.h:1347
bool bool_value(bool warn=false) const
Definition: ov.h:885
FloatComplexNDArray xfloat_complex_array_value(const char *fmt,...) const
int32NDArray int32_array_value() const
Definition: ov.h:956
uint16NDArray uint16_array_value() const
Definition: ov.h:965
bool is_true() const
Definition: ov.h:758
int16NDArray int16_array_value() const
Definition: ov.h:953
Cell cell_value() const
unary_op
Definition: ov.h:79
@ op_hermitian
Definition: ov.h:84
@ op_uminus
Definition: ov.h:82
@ op_not
Definition: ov.h:80
@ op_transpose
Definition: ov.h:83
@ op_uplus
Definition: ov.h:81
int8NDArray int8_array_value() const
Definition: ov.h:950
int ndims() const
Definition: ov.h:551
octave_idx_type rows() const
Definition: ov.h:545
bool is_scalar_type() const
Definition: ov.h:744
bool is_sq_string() const
Definition: ov.h:640
octave::range< double > range_value() const
Definition: ov.h:985
bool is_string() const
Definition: ov.h:637
bool isnumeric() const
Definition: ov.h:750
bool is_int8_type() const
Definition: ov.h:706
Complex complex_value(bool frc_str_conv=false) const
Definition: ov.h:865
octave_idx_type idx_type_value(bool req_int=false, bool frc_str_conv=false) const
Complex xcomplex_value(const char *fmt,...) const
octave_value sort(octave_idx_type dim=0, sortmode mode=ASCENDING) const
Definition: ov.h:1416
bool is_range() const
Definition: ov.h:646
ComplexNDArray complex_array_value(bool frc_str_conv=false) const
Definition: ov.h:878
bool is_single_type() const
Definition: ov.h:698
bool is_defined() const
Definition: ov.h:592
charNDArray char_array_value(bool frc_str_conv=false) const
Definition: ov.h:897
bool isempty() const
Definition: ov.h:601
FloatComplex float_complex_value(bool frc_str_conv=false) const
Definition: ov.h:868
assign_op
Definition: ov.h:134
@ op_add_eq
Definition: ov.h:136
@ op_mul_eq
Definition: ov.h:138
@ op_el_and_eq
Definition: ov.h:146
@ op_el_mul_eq
Definition: ov.h:142
@ op_el_or_eq
Definition: ov.h:147
bool is_uint8_type() const
Definition: ov.h:718
bool is_uint64_type() const
Definition: ov.h:727
bool is_uint16_type() const
Definition: ov.h:721
uint64NDArray uint64_array_value() const
Definition: ov.h:971
float float_value(bool frc_str_conv=false) const
Definition: ov.h:844
SparseComplexMatrix xsparse_complex_matrix_value(const char *fmt,...) const
bool is_int16_type() const
Definition: ov.h:709
bool issparse() const
Definition: ov.h:753
octave_value reshape(const dim_vector &dv) const
Definition: ov.h:571
octave_value & assign(assign_op op, const std::string &type, const std::list< octave_value_list > &idx, const octave_value &rhs)
double scalar_value(bool frc_str_conv=false) const
Definition: ov.h:847
bool iscell() const
Definition: ov.h:604
octave_idx_type numel() const
Definition: ov.h:559
@ magic_colon_t
Definition: ov.h:170
std::string string_value(bool force=false) const
Definition: ov.h:974
bool is_int64_type() const
Definition: ov.h:715
bool iscomplex() const
Definition: ov.h:741
ComplexNDArray xcomplex_array_value(const char *fmt,...) const
binary_op
Definition: ov.h:92
@ op_ldiv
Definition: ov.h:98
@ op_ne
Definition: ov.h:104
@ op_el_or
Definition: ov.h:110
@ op_el_ldiv
Definition: ov.h:108
@ op_pow
Definition: ov.h:97
@ op_ge
Definition: ov.h:102
@ op_div
Definition: ov.h:96
@ op_el_pow
Definition: ov.h:107
@ op_mul
Definition: ov.h:95
@ op_add
Definition: ov.h:93
@ op_sub
Definition: ov.h:94
@ op_el_mul
Definition: ov.h:105
@ op_le
Definition: ov.h:100
@ op_lt
Definition: ov.h:99
@ op_gt
Definition: ov.h:103
@ op_eq
Definition: ov.h:101
@ op_el_and
Definition: ov.h:109
@ op_el_div
Definition: ov.h:106
sortmode is_sorted_rows(sortmode mode=UNSORTED) const
Definition: ov.h:1428
octave_value single_subsref(const std::string &type, const octave_value_list &idx)
int64NDArray int64_array_value() const
Definition: ov.h:959
SparseBoolMatrix sparse_bool_matrix_value(bool warn=false) const
Definition: ov.h:907
NDArray array_value(bool frc_str_conv=false) const
Definition: ov.h:859
FloatComplex xfloat_complex_value(const char *fmt,...) const
bool is_double_type() const
Definition: ov.h:695
bool is_int32_type() const
Definition: ov.h:712
uint8NDArray uint8_array_value() const
Definition: ov.h:962
std::string xstring_value(const char *fmt,...) const
FloatComplexNDArray float_complex_array_value(bool frc_str_conv=false) const
Definition: ov.h:882
octave_value resize(const dim_vector &dv, bool fill=false) const
Definition: ov.h:580
bool iscellstr() const
Definition: ov.h:607
FloatNDArray float_array_value(bool frc_str_conv=false) const
Definition: ov.h:862
uint32NDArray uint32_array_value() const
Definition: ov.h:968
octave_idx_type columns() const
Definition: ov.h:547
builtin_type_t builtin_type() const
Definition: ov.h:690
octave_value diag(octave_idx_type k=0) const
Definition: ov.h:1410
double double_value(bool frc_str_conv=false) const
Definition: ov.h:841
bool isobject() const
Definition: ov.h:664
SparseComplexMatrix sparse_complex_matrix_value(bool frc_str_conv=false) const
Definition: ov.h:904
bool islogical() const
Definition: ov.h:735
octave_value abs() const
Definition: ov.h:1447
Array< std::string > cellstr_value() const
Definition: ov.h:982
dim_vector dims() const
Definition: ov.h:541
Array< octave_idx_type > sort_rows_idx(sortmode mode=ASCENDING) const
Definition: ov.h:1425
octave_value find_method(const std::string &name, const std::string &dispatch_type)
Definition: symtab.cc:128
OCTAVE_BEGIN_NAMESPACE(octave) static octave_value daspk_fcn
#define INSTANTIATE_EYE(T)
Definition: data.cc:5391
template octave_value identity_matrix< int8NDArray >(int, int)
octave_value do_class_concat(const octave_value_list &ovl, const std::string &cattype, int dim)
Definition: data.cc:1742
template octave_value identity_matrix< uint64NDArray >(int, int)
template octave_value identity_matrix< int16NDArray >(int, int)
#define BTYP_BRANCH(X, EX)
void map_2_xlog2(const Array< T > &x, Array< T > &f, Array< ET > &e)
Definition: data.cc:448
template octave_value identity_matrix< int64NDArray >(int, int)
template octave_value identity_matrix< int32NDArray >(int, int)
template octave_value identity_matrix< uint8NDArray >(int, int)
octave_value identity_matrix(int nr, int nc)
Definition: data.cc:5361
T eps(const T &x)
Definition: data.cc:4964
#define MAKE_INT_BRANCH(X)
Definition: data.cc:8011
template octave_value identity_matrix< uint16NDArray >(int, int)
#define DATA_REDUCTION(FCN)
Definition: data.cc:933
template octave_value identity_matrix< boolNDArray >(int, int)
template octave_value identity_matrix< uint32NDArray >(int, int)
void print_usage(void)
Definition: defun-int.h:72
#define DEFUN(name, args_name, nargout_name, doc)
Macro to define a builtin function.
Definition: defun.h:56
#define DEFALIAS(alias, name)
Macro to define an alias for another existing function name.
Definition: defun.h:160
void warning(const char *fmt,...)
Definition: error.cc:1063
void() error(const char *fmt,...)
Definition: error.cc:988
#define error_unless(cond)
Definition: error.h:530
#define panic_impossible()
Definition: error.h:503
void err_wrong_type_arg(const char *name, const char *s)
Definition: errwarn.cc:166
void warn_implicit_conversion(const char *id, const char *from, const char *to)
Definition: errwarn.cc:344
double norm(const ColumnVector &v)
Definition: graphics.cc:5547
ColumnVector transform(const Matrix &m, double x, double y, double z)
Definition: graphics.cc:5468
octave::idx_vector idx_vector
Definition: idx-vector.h:1022
intNDArray< octave_int16 > int16NDArray
Definition: int16NDArray.h:36
intNDArray< octave_int32 > int32NDArray
Definition: int32NDArray.h:36
intNDArray< octave_int64 > int64NDArray
Definition: int64NDArray.h:36
intNDArray< octave_int8 > int8NDArray
Definition: int8NDArray.h:36
interpreter & __get_interpreter__()
double lo_ieee_na_value()
Definition: lo-ieee.cc:76
float lo_ieee_float_nan_value()
Definition: lo-ieee.cc:116
float lo_ieee_float_na_value()
Definition: lo-ieee.cc:108
double lo_ieee_nan_value()
Definition: lo-ieee.cc:84
float lo_ieee_float_inf_value()
Definition: lo-ieee.cc:100
double lo_ieee_inf_value()
Definition: lo-ieee.cc:68
Complex log2(const Complex &x)
Definition: lo-mappers.cc:141
double frexp(double x, int *expptr)
Definition: lo-mappers.cc:129
Complex atan(const Complex &x)
Definition: lo-mappers.h:71
bool isinteger(double x)
Definition: lo-mappers.h:225
bool isinf(double x)
Definition: lo-mappers.h:203
T mod(T x, T y)
Definition: lo-mappers.h:294
T rem(T x, T y)
Definition: lo-mappers.h:327
bool isnan(bool)
Definition: lo-mappers.h:178
F77_RET_T const F77_DBLE * x
F77_RET_T const F77_DBLE const F77_DBLE * f
T octave_idx_type m
Definition: mx-inlines.cc:781
octave_idx_type n
Definition: mx-inlines.cc:761
T * r
Definition: mx-inlines.cc:781
std::string get_dispatch_type(const octave_value_list &args, builtin_type_t &builtin_type)
Definition: fcn-info.cc:271
void get_dimensions(const octave_value &a, const char *warn_for, dim_vector &dim)
Definition: utils.cc:1348
Array< double > base64_decode(const std::string &str)
Definition: oct-base64.cc:61
bool base64_encode(const char *inc, const std::size_t inlen, char **out)
Definition: oct-base64.cc:39
intNDArray< octave_uint8 > base64_decode_bytes(const std::string &str)
Definition: oct-base64.cc:99
std::complex< double > Complex
Definition: oct-cmplx.h:33
std::complex< float > FloatComplex
Definition: oct-cmplx.h:34
octave_int< uint64_t > octave_uint64
octave_int< T > pow(const octave_int< T > &a, const octave_int< T > &b)
#define OCTAVE_LOCAL_BUFFER(T, buf, size)
Definition: oct-locbuf.h:44
double xfrobnorm(const Matrix &x)
Definition: oct-norm.cc:610
double xnorm(const ColumnVector &x, double p)
Definition: oct-norm.cc:610
RowVector xcolnorms(const Matrix &m, double p)
Definition: oct-norm.cc:653
ColumnVector xrownorms(const Matrix &m, double p)
Definition: oct-norm.cc:653
sortmode
Definition: oct-sort.h:97
@ UNSORTED
Definition: oct-sort.h:97
@ ASCENDING
Definition: oct-sort.h:97
@ DESCENDING
Definition: oct-sort.h:97
T::size_type numel(const T &str)
Definition: oct-string.cc:74
void free(void *)
const octave_base_value const Array< octave_idx_type > & ra_idx
return octave_value(v1.char_array_value() . concat(v2.char_array_value(), ra_idx),((a1.is_sq_string()||a2.is_sq_string()) ? '\'' :'"'))
builtin_type_t
Definition: ov-base.h:83
@ btyp_float_complex
Definition: ov-base.h:87
@ btyp_double
Definition: ov-base.h:84
@ btyp_float
Definition: ov-base.h:85
@ btyp_bool
Definition: ov-base.h:96
@ btyp_char
Definition: ov-base.h:97
@ btyp_complex
Definition: ov-base.h:86
octave_value colon_op(const octave_value &base, const octave_value &increment, const octave_value &limit, bool is_for_cmd_expr=false)
octave_value cat_op(type_info &ti, const octave_value &a, const octave_value &b, const Array< octave_idx_type > &ra_idx)
octave_value binary_op(type_info &ti, octave_value::binary_op op, const octave_value &a, const octave_value &b)
octave_value unary_op(type_info &ti, octave_value::unary_op op, const octave_value &a)
octave_value_list ovl(const OV_Args &... args)
Construct an octave_value_list with less typing.
Definition: ovl.h:219
#define octave_stdout
Definition: pager.h:309
void maybe_warn_string_concat(bool all_dq_strings_p, bool all_sq_strings_p)
Definition: pt-mat.cc:134
std::string get_concat_class(const std::string &c1, const std::string &c2)
Definition: pt-mat.cc:63
intNDArray< octave_uint16 > uint16NDArray
Definition: uint16NDArray.h:36
intNDArray< octave_uint32 > uint32NDArray
Definition: uint32NDArray.h:36
intNDArray< octave_uint64 > uint64NDArray
Definition: uint64NDArray.h:36
intNDArray< octave_uint8 > uint8NDArray
Definition: uint8NDArray.h:36
octave_idx_type dims_to_numel(const dim_vector &dims, const octave_value_list &idx)
void check_dimensions(dim_vector &dim, const char *warnfor)
F77_RET_T len
Definition: xerbla.cc:61