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