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