GNU Octave  4.2.1
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
max.cc
Go to the documentation of this file.
1 /*
2 
3 Copyright (C) 1996-2017 John W. Eaton
4 Copyright (C) 2009 VZLU Prague
5 
6 This file is part of Octave.
7 
8 Octave is free software; you can redistribute it and/or modify it
9 under the terms of the GNU General Public License as published by the
10 Free Software Foundation; either version 3 of the License, or (at your
11 option) any later version.
12 
13 Octave is distributed in the hope that it will be useful, but WITHOUT
14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 for more details.
17 
18 You should have received a copy of the GNU General Public License
19 along with Octave; see the file COPYING. If not, see
20 <http://www.gnu.org/licenses/>.
21 
22 */
23 
24 #if defined (HAVE_CONFIG_H)
25 # include "config.h"
26 #endif
27 
28 #include "lo-ieee.h"
29 #include "lo-mappers.h"
30 #include "lo-math.h"
31 #include "dNDArray.h"
32 #include "CNDArray.h"
33 #include "quit.h"
34 
35 #include "defun.h"
36 #include "error.h"
37 #include "errwarn.h"
38 #include "ovl.h"
39 
40 #include "ov-cx-mat.h"
41 #include "ov-re-sparse.h"
42 #include "ov-cx-sparse.h"
43 
44 template <typename ArrayType>
45 static octave_value_list
47  int nargout, int dim, bool ismin)
48 {
49  octave_value_list retval (nargout > 1 ? 2 : 1);
50  ArrayType array = octave_value_extract<ArrayType> (arg);
51 
52  if (nargout <= 1)
53  {
54  if (ismin)
55  retval(0) = array.min (dim);
56  else
57  retval(0) = array.max (dim);
58  }
59  else
60  {
62  if (ismin)
63  retval(0) = array.min (idx, dim);
64  else
65  retval(0) = array.max (idx, dim);
66 
67  retval(1) = octave_value (idx, true, true);
68  }
69 
70  return retval;
71 }
72 
73 // Matlab returns double arrays for min/max operations on character
74 // arrays, so we specialize here to get that behavior. Other possible
75 // solutions are to convert the argument to double here and call the
76 // code for double, but that could waste memory, or to have the
77 // underlying charNDArray::min/max functions return NDArray instead of
78 // charNDArray, but that is inconsistent with the way other min/max
79 // functions work.
80 
81 template <>
84  int nargout, int dim, bool ismin)
85 {
86  octave_value_list retval (nargout > 1 ? 2 : 1);
88 
89  if (nargout <= 1)
90  {
91  if (ismin)
92  retval(0) = NDArray (array.min (dim));
93  else
94  retval(0) = NDArray (array.max (dim));
95  }
96  else
97  {
99  if (ismin)
100  retval(0) = NDArray (array.min (idx, dim));
101  else
102  retval(0) = NDArray (array.max (idx, dim));
103 
104  retval(1) = octave_value (idx, true, true);
105  }
106 
107  return retval;
108 }
109 
110 // Specialization for bool arrays (dense or sparse).
111 template <>
114  int nargout, int dim, bool ismin)
115 {
117 
118  if (! arg.is_sparse_type ())
119  {
120  if (nargout <= 1)
121  {
122  // This case can be handled using any/all.
124 
125  if (array.is_empty ())
126  retval(0) = array;
127  else if (ismin)
128  retval(0) = array.all (dim);
129  else
130  retval(0) = array.any (dim);
131  }
132  else
133  {
134  // any/all don't have indexed versions, so do it via a conversion.
135  retval = do_minmax_red_op<int8NDArray> (arg, nargout, dim, ismin);
136 
137  retval(0) = retval(0).bool_array_value ();
138  }
139  }
140  else
141  {
142  // Sparse: Don't use any/all trick, as full matrix could exceed memory.
143  // Instead, convert to double.
144  retval = do_minmax_red_op<SparseMatrix> (arg, nargout, dim, ismin);
145 
147  }
148 
149  return retval;
150 }
151 
152 template <typename ArrayType>
153 static octave_value
154 do_minmax_bin_op (const octave_value& argx, const octave_value& argy,
155  bool ismin)
156 {
157  typedef typename ArrayType::element_type ScalarType;
158 
160 
161  if (argx.is_scalar_type ())
162  {
163  ScalarType x = octave_value_extract<ScalarType> (argx);
164  ArrayType y = octave_value_extract<ArrayType> (argy);
165 
166  if (ismin)
167  retval = min (x, y);
168  else
169  retval = max (x, y);
170  }
171  else if (argy.is_scalar_type ())
172  {
173  ArrayType x = octave_value_extract<ArrayType> (argx);
174  ScalarType y = octave_value_extract<ScalarType> (argy);
175 
176  if (ismin)
177  retval = min (x, y);
178  else
179  retval = max (x, y);
180  }
181  else
182  {
183  ArrayType x = octave_value_extract<ArrayType> (argx);
184  ArrayType y = octave_value_extract<ArrayType> (argy);
185 
186  if (ismin)
187  retval = min (x, y);
188  else
189  retval = max (x, y);
190  }
191 
192  return retval;
193 }
194 
195 // Matlab returns double arrays for min/max operations on character
196 // arrays, so we specialize here to get that behavior. Other possible
197 // solutions are to convert the arguments to double here and call the
198 // code for double, but that could waste a lot of memory, or to have the
199 // underlying charNDArray::min/max functions return NDArray instead of
200 // charNDArray, but that is inconsistent with the way other min/max
201 // functions work.
202 
203 template <>
206  const octave_value& argy, bool ismin)
207 {
209 
212 
213  if (ismin)
214  {
215  if (x.numel () == 1)
216  retval = NDArray (min (x(0), y));
217  else if (y.numel () == 1)
218  retval = NDArray (min (x, y(0)));
219  else
220  retval = NDArray (min (x, y));
221  }
222  else
223  {
224  if (x.numel () == 1)
225  retval = NDArray (max (x(0), y));
226  else if (y.numel () == 1)
227  retval = NDArray (max (x, y(0)));
228  else
229  retval = NDArray (max (x, y));
230  }
231 
232  return retval;
233 }
234 
235 static octave_value_list
237  int nargout, bool ismin)
238 {
239  int nargin = args.length ();
240 
241  if (nargin < 1 || nargin > 3)
242  print_usage ();
243 
244  octave_value_list retval (nargout > 1 ? 2 : 1);
245 
246  const char *func = ismin ? "min" : "max";
247 
248  if (nargin == 3 || nargin == 1)
249  {
250  octave_value arg = args(0);
251  int dim = -1;
252  if (nargin == 3)
253  {
254  dim = args(2).int_value (true) - 1;
255 
256  if (dim < 0)
257  error ("%s: DIM must be a valid dimension", func);
258 
259  if (! args(1).is_empty ())
260  warning ("%s: second argument is ignored", func);
261  }
262 
263  switch (arg.builtin_type ())
264  {
265  case btyp_double:
266  {
267  if (arg.is_range () && (dim == -1 || dim == 1))
268  {
269  Range range = arg.range_value ();
270  if (range.numel () < 1)
271  {
272  retval(0) = arg;
273  if (nargout > 1)
274  retval(1) = arg;
275  }
276  else if (ismin)
277  {
278  retval(0) = range.min ();
279  if (nargout > 1)
280  retval(1) = static_cast<double>
281  (range.inc () < 0 ? range.numel () : 1);
282  }
283  else
284  {
285  retval(0) = range.max ();
286  if (nargout > 1)
287  retval(1) = static_cast<double>
288  (range.inc () >= 0 ? range.numel () : 1);
289  }
290  }
291  else if (arg.is_sparse_type ())
292  retval = do_minmax_red_op<SparseMatrix> (arg, nargout, dim,
293  ismin);
294  else
295  retval = do_minmax_red_op<NDArray> (arg, nargout, dim, ismin);
296 
297  }
298  break;
299 
300  case btyp_complex:
301  {
302  if (arg.is_sparse_type ())
303  retval = do_minmax_red_op<SparseComplexMatrix> (arg, nargout, dim,
304  ismin);
305  else
306  retval = do_minmax_red_op<ComplexNDArray> (arg, nargout, dim,
307  ismin);
308  }
309  break;
310 
311  case btyp_float:
312  retval = do_minmax_red_op<FloatNDArray> (arg, nargout, dim, ismin);
313  break;
314 
315  case btyp_float_complex:
316  retval = do_minmax_red_op<FloatComplexNDArray> (arg, nargout, dim,
317  ismin);
318  break;
319 
320  case btyp_char:
321  retval = do_minmax_red_op<charNDArray> (arg, nargout, dim, ismin);
322  break;
323 
324 #define MAKE_INT_BRANCH(X) \
325  case btyp_ ## X: \
326  retval = do_minmax_red_op<X ## NDArray> (arg, nargout, dim, ismin); \
327  break;
328 
329  MAKE_INT_BRANCH (int8);
333  MAKE_INT_BRANCH (uint8);
336  MAKE_INT_BRANCH (uint64);
337 
338 #undef MAKE_INT_BRANCH
339 
340  case btyp_bool:
341  retval = do_minmax_red_op<boolNDArray> (arg, nargout, dim, ismin);
342  break;
343 
344  default:
345  err_wrong_type_arg (func, arg);
346  }
347  }
348  else
349  {
350  octave_value argx = args(0);
351  octave_value argy = args(1);
352  builtin_type_t xtyp = argx.builtin_type ();
353  builtin_type_t ytyp = argy.builtin_type ();
354  builtin_type_t rtyp;
355  if (xtyp == btyp_char && ytyp == btyp_char)
356  rtyp = btyp_char;
357  // FIXME: This is what should happen when boolNDArray has max()
358  // else if (xtyp == btyp_bool && ytyp == btyp_bool)
359  // rtyp = btyp_bool;
360  else
361  rtyp = btyp_mixed_numeric (xtyp, ytyp);
362 
363  switch (rtyp)
364  {
365  case btyp_double:
366  {
367  if ((argx.is_sparse_type ()
368  && (argy.is_sparse_type () || argy.is_scalar_type ()))
369  || (argy.is_sparse_type () && argx.is_scalar_type ()))
370  retval = do_minmax_bin_op<SparseMatrix> (argx, argy, ismin);
371  else
372  retval = do_minmax_bin_op<NDArray> (argx, argy, ismin);
373  }
374  break;
375 
376  case btyp_complex:
377  {
378  if ((argx.is_sparse_type ()
379  && (argy.is_sparse_type () || argy.is_scalar_type ()))
380  || (argy.is_sparse_type () && argx.is_scalar_type ()))
381  retval = do_minmax_bin_op<SparseComplexMatrix> (argx, argy,
382  ismin);
383  else
384  retval = do_minmax_bin_op<ComplexNDArray> (argx, argy, ismin);
385  }
386  break;
387 
388  case btyp_float:
389  retval = do_minmax_bin_op<FloatNDArray> (argx, argy, ismin);
390  break;
391 
392  case btyp_float_complex:
393  retval = do_minmax_bin_op<FloatComplexNDArray> (argx, argy, ismin);
394  break;
395 
396  case btyp_char:
397  retval = do_minmax_bin_op<charNDArray> (argx, argy, ismin);
398  break;
399 
400 #define MAKE_INT_BRANCH(X) \
401  case btyp_ ## X: \
402  retval = do_minmax_bin_op<X ## NDArray> (argx, argy, ismin); \
403  break;
404 
405  MAKE_INT_BRANCH (int8);
409  MAKE_INT_BRANCH (uint8);
412  MAKE_INT_BRANCH (uint64);
413 
414 #undef MAKE_INT_BRANCH
415 
416  // FIXME: This is what should happen when boolNDArray has max()
417  // case btyp_bool:
418  // retval = do_minmax_bin_op<boolNDArray> (argx, argy, ismin);
419  // break;
420 
421  default:
422  error ("%s: cannot compute %s (%s, %s)", func, func,
423  argx.type_name ().c_str (), argy.type_name ().c_str ());
424  }
425 
426  // FIXME: Delete when boolNDArray has max()
427  if (xtyp == btyp_bool && ytyp == btyp_bool)
428  retval(0) = retval(0).bool_array_value ();
429 
430  }
431 
432  return retval;
433 }
434 
435 DEFUN (min, args, nargout,
436  doc: /* -*- texinfo -*-
437 @deftypefn {} {} min (@var{x})
438 @deftypefnx {} {} min (@var{x}, [], @var{dim})
439 @deftypefnx {} {[@var{w}, @var{iw}] =} min (@var{x})
440 @deftypefnx {} {} min (@var{x}, @var{y})
441 Find minimum values in the array @var{x}.
442 
443 For a vector argument, return the minimum value. For a matrix argument,
444 return a row vector with the minimum value of each column. For a
445 multi-dimensional array, @code{min} operates along the first non-singleton
446 dimension.
447 
448 If the optional third argument @var{dim} is present then operate along
449 this dimension. In this case the second argument is ignored and should be
450 set to the empty matrix.
451 
452 For two matrices (or a matrix and a scalar), return the pairwise minimum.
453 
454 Thus,
455 
456 @example
457 min (min (@var{x}))
458 @end example
459 
460 @noindent
461 returns the smallest element of the 2-D matrix @var{x}, and
462 
463 @example
464 @group
465 min (2:5, pi)
466  @result{} 2.0000 3.0000 3.1416 3.1416
467 @end group
468 @end example
469 
470 @noindent
471 compares each element of the range @code{2:5} with @code{pi}, and returns a
472 row vector of the minimum values.
473 
474 For complex arguments, the magnitude of the elements are used for
475 comparison. If the magnitudes are identical, then the results are ordered
476 by phase angle in the range (-pi, pi]. Hence,
477 
478 @example
479 @group
480 min ([-1 i 1 -i])
481  @result{} -i
482 @end group
483 @end example
484 
485 @noindent
486 because all entries have magnitude 1, but -i has the smallest phase angle
487 with value -pi/2.
488 
489 If called with one input and two output arguments, @code{min} also returns
490 the first index of the minimum value(s). Thus,
491 
492 @example
493 @group
494 [x, ix] = min ([1, 3, 0, 2, 0])
495  @result{} x = 0
496  ix = 3
497 @end group
498 @end example
499 @seealso{max, cummin, cummax}
500 @end deftypefn */)
501 {
502  return do_minmax_body (args, nargout, true);
503 }
504 
505 /*
506 ## Test generic double class
507 %!assert (min ([1, 4, 2, 3]), 1)
508 %!assert (min ([1; -10; 5; -2]), -10)
509 %!assert (min ([4, 2i 4.999; -2, 2, 3+4i]), [-2, 2, 4.999])
510 ## Special routines for char arrays
511 %!assert (min (["abc", "ABC"]), 65)
512 %!assert (min (["abc"; "CBA"]), [67 66 65])
513 ## Special routines for logical arrays
514 %!assert (min (logical ([])), logical ([]))
515 %!assert (min (logical ([0 0 1 0])), false)
516 %!assert (min (logical ([0 0 1 0; 0 1 1 0])), logical ([0 0 1 0]))
517 ## Single values
518 %!assert (min (single ([1, 4, 2, 3])), single (1))
519 %!assert (min (single ([1; -10; 5; -2])), single (-10))
520 %!assert (min (single ([4, 2i 4.999; -2, 2, 3+4i])), single ([-2, 2, 4.999]))
521 ## Integer values
522 %!assert (min (uint8 ([1, 4, 2, 3])), uint8 (1))
523 %!assert (min (uint8 ([1; -10; 5; -2])), uint8 (-10))
524 %!assert (min (int8 ([1, 4, 2, 3])), int8 (1))
525 %!assert (min (int8 ([1; -10; 5; -2])), int8 (-10))
526 %!assert (min (uint16 ([1, 4, 2, 3])), uint16 (1))
527 %!assert (min (uint16 ([1; -10; 5; -2])), uint16 (-10))
528 %!assert (min (int16 ([1, 4, 2, 3])), int16 (1))
529 %!assert (min (int16 ([1; -10; 5; -2])), int16 (-10))
530 %!assert (min (uint32 ([1, 4, 2, 3])), uint32 (1))
531 %!assert (min (uint32 ([1; -10; 5; -2])), uint32 (-10))
532 %!assert (min (int32 ([1, 4, 2, 3])), int32 (1))
533 %!assert (min (int32 ([1; -10; 5; -2])), int32 (-10))
534 %!assert (min (uint64 ([1, 4, 2, 3])), uint64 (1))
535 %!assert (min (uint64 ([1; -10; 5; -2])), uint64 (-10))
536 %!assert (min (int64 ([1, 4, 2, 3])), int64 (1))
537 %!assert (min (int64 ([1; -10; 5; -2])), int64 (-10))
538 ## Sparse double values
539 %!assert (min (sparse ([1, 4, 2, 3])), sparse (1))
540 %!assert (min (sparse ([1; -10; 5; -2])), sparse(-10))
541 ## FIXME: sparse doesn't order complex values by phase angle
542 %!xtest
543 %! assert (min (sparse ([4, 2i 4.999; -2, 2, 3+4i])), sparse ([-2, 2, 4.999]));
544 
545 ## Test dimension argument
546 %!test
547 %! x = reshape (1:8, [2,2,2]);
548 %! assert (min (x, [], 1), reshape ([1, 3, 5, 7], [1,2,2]));
549 %! assert (min (x, [], 2), reshape ([1, 2, 5, 6], [2,1,2]));
550 %! [y, i] = min (x, [], 3);
551 %! assert (ndims (y), 2);
552 %! assert (y, [1, 3; 2, 4]);
553 %! assert (ndims (i), 2);
554 %! assert (i, [1, 1; 1, 1]);
555 
556 ## Test 2-output forms for various arg types
557 ## Special routines for char arrays
558 %!test
559 %! [y, i] = min (["abc", "ABC"]);
560 %! assert (y, 65);
561 %! assert (i, 4);
562 ## Special routines for logical arrays
563 %!test
564 %! x = logical ([0 0 1 0]);
565 %! [y, i] = min (x);
566 %! assert (y, false);
567 %! assert (i, 1);
568 ## Special handling of ranges
569 %!test
570 %! rng = 1:2:10;
571 %! [y, i] = min (rng);
572 %! assert (y, 1);
573 %! assert (i, 1);
574 %! rng = 10:-2:1;
575 %! [y, i] = min (rng);
576 %! assert (y, 2);
577 %! assert (i, 5);
578 
579 ## Test 2-input calling form for various arg types
580 ## Test generic double class
581 %!test
582 %! x = [1, 2, 3, 4]; y = fliplr (x);
583 %! assert (min (x, y), [1 2 2 1]);
584 %! assert (min (x, 3), [1 2 3 3]);
585 %! assert (min (2, x), [1 2 2 2]);
586 %! assert (min (x, 2.1i), [1 2 2.1i 2.1i]);
587 ## FIXME: Ordering of complex results with equal magnitude is not by phase
588 ## angle in the 2-input form. Instead, it is in the order in which it
589 ## appears in the argument list.
590 %!xtest
591 %! x = [1, 2, 3, 4]; y = fliplr (x);
592 %! assert (min (x, 2i), [2i 2i 3 4]);
593 ## Special routines for char arrays
594 %!assert (min ("abc", "b"), [97 98 98])
595 %!assert (min ("b", "cba"), [98 98 97])
596 ## Special handling for logical arrays
597 %!assert (min ([true false], false), [false false])
598 %!assert (min (true, [true false]), [true false])
599 ## Single values
600 %!test
601 %! x = single ([1, 2, 3, 4]); y = fliplr (x);
602 %! assert (min (x, y), single ([1 2 2 1]));
603 %! assert (min (x, 3), single ([1 2 3 3]));
604 %! assert (min (2, x), single ([1 2 2 2]));
605 %! assert (min (x, 2.1i), single ([1 2 2.1i 2.1i]));
606 ## Integer values
607 %!test
608 %! x = uint8 ([1, 2, 3, 4]); y = fliplr (x);
609 %! assert (min (x, y), uint8 ([1 2 2 1]));
610 %! assert (min (x, 3), uint8 ([1 2 3 3]));
611 %! assert (min (2, x), uint8 ([1 2 2 2]));
612 %! x = int8 ([1, 2, 3, 4]); y = fliplr (x);
613 %! assert (min (x, y), int8 ([1 2 2 1]));
614 %! assert (min (x, 3), int8 ([1 2 3 3]));
615 %! assert (min (2, x), int8 ([1 2 2 2]));
616 %! x = uint16 ([1, 2, 3, 4]); y = fliplr (x);
617 %! assert (min (x, y), uint16 ([1 2 2 1]));
618 %! assert (min (x, 3), uint16 ([1 2 3 3]));
619 %! assert (min (2, x), uint16 ([1 2 2 2]));
620 %! x = int16 ([1, 2, 3, 4]); y = fliplr (x);
621 %! assert (min (x, y), int16 ([1 2 2 1]));
622 %! assert (min (x, 3), int16 ([1 2 3 3]));
623 %! assert (min (2, x), int16 ([1 2 2 2]));
624 %! x = uint32 ([1, 2, 3, 4]); y = fliplr (x);
625 %! assert (min (x, y), uint32 ([1 2 2 1]));
626 %! assert (min (x, 3), uint32 ([1 2 3 3]));
627 %! assert (min (2, x), uint32 ([1 2 2 2]));
628 %! x = int32 ([1, 2, 3, 4]); y = fliplr (x);
629 %! assert (min (x, y), int32 ([1 2 2 1]));
630 %! assert (min (x, 3), int32 ([1 2 3 3]));
631 %! assert (min (2, x), int32 ([1 2 2 2]));
632 %! x = uint64 ([1, 2, 3, 4]); y = fliplr (x);
633 %! assert (min (x, y), uint64 ([1 2 2 1]));
634 %! assert (min (x, 3), uint64 ([1 2 3 3]));
635 %! assert (min (2, x), uint64 ([1 2 2 2]));
636 %! x = int64 ([1, 2, 3, 4]); y = fliplr (x);
637 %! assert (min (x, y), int64 ([1 2 2 1]));
638 %! assert (min (x, 3), int64 ([1 2 3 3]));
639 %! assert (min (2, x), int64 ([1 2 2 2]));
640 ## Sparse double values
641 %!test
642 %! x = sparse ([1, 2, 3, 4]); y = fliplr (x);
643 %! assert (min (x, y), sparse ([1 2 2 1]));
644 %! assert (min (x, 3), sparse ([1 2 3 3]));
645 %! assert (min (2, x), sparse ([1 2 2 2]));
646 %! assert (min (x, 2.1i), sparse ([1 2 2.1i 2.1i]));
647 
648 %!error min ()
649 %!error min (1, 2, 3, 4)
650 %!error <DIM must be a valid dimension> min ([1 2; 3 4], [], -3)
651 %!warning <second argument is ignored> min ([1 2 3 4], 2, 2);
652 %!error <wrong type argument 'cell'> min ({1 2 3 4})
653 %!error <cannot compute min \(cell, scalar\)> min ({1, 2, 3}, 2)
654 */
655 
656 DEFUN (max, args, nargout,
657  doc: /* -*- texinfo -*-
658 @deftypefn {} {} max (@var{x})
659 @deftypefnx {} {} max (@var{x}, [], @var{dim})
660 @deftypefnx {} {[@var{w}, @var{iw}] =} max (@var{x})
661 @deftypefnx {} {} max (@var{x}, @var{y})
662 Find maximum values in the array @var{x}.
663 
664 For a vector argument, return the maximum value. For a matrix argument,
665 return a row vector with the maximum value of each column. For a
666 multi-dimensional array, @code{max} operates along the first non-singleton
667 dimension.
668 
669 If the optional third argument @var{dim} is present then operate along
670 this dimension. In this case the second argument is ignored and should be
671 set to the empty matrix.
672 
673 For two matrices (or a matrix and a scalar), return the pairwise maximum.
674 
675 Thus,
676 
677 @example
678 max (max (@var{x}))
679 @end example
680 
681 @noindent
682 returns the largest element of the 2-D matrix @var{x}, and
683 
684 @example
685 @group
686 max (2:5, pi)
687  @result{} 3.1416 3.1416 4.0000 5.0000
688 @end group
689 @end example
690 
691 @noindent
692 compares each element of the range @code{2:5} with @code{pi}, and returns a
693 row vector of the maximum values.
694 
695 For complex arguments, the magnitude of the elements are used for
696 comparison. If the magnitudes are identical, then the results are ordered
697 by phase angle in the range (-pi, pi]. Hence,
698 
699 @example
700 @group
701 max ([-1 i 1 -i])
702  @result{} -1
703 @end group
704 @end example
705 
706 @noindent
707 because all entries have magnitude 1, but -1 has the largest phase angle
708 with value pi.
709 
710 If called with one input and two output arguments, @code{max} also returns
711 the first index of the maximum value(s). Thus,
712 
713 @example
714 @group
715 [x, ix] = max ([1, 3, 5, 2, 5])
716  @result{} x = 5
717  ix = 3
718 @end group
719 @end example
720 @seealso{min, cummax, cummin}
721 @end deftypefn */)
722 {
723  return do_minmax_body (args, nargout, false);
724 }
725 
726 /*
727 ## Test generic double class
728 %!assert (max ([1, 4, 2, 3]), 4)
729 %!assert (max ([1; -10; 5; -2]), 5)
730 %!assert (max ([4, 2i 4.999; -2, 2, 3+4i]), [4, 2i, 3+4i])
731 ## Special routines for char arrays
732 %!assert (max (["abc", "ABC"]), 99)
733 %!assert (max (["abc"; "CBA"]), [97 98 99])
734 ## Special routines for logical arrays
735 %!assert (max (logical ([])), logical ([]))
736 %!assert (max (logical ([0 0 1 0])), true)
737 %!assert (max (logical ([0 0 1 0; 0 1 0 0])), logical ([0 1 1 0]))
738 ## Single values
739 %!assert (max (single ([1, 4, 2, 3])), single (4))
740 %!assert (max (single ([1; -10; 5; -2])), single (5))
741 %!assert (max (single ([4, 2i 4.999; -2, 2, 3+4i])), single ([4, 2i, 3+4i]))
742 ## Integer values
743 %!assert (max (uint8 ([1, 4, 2, 3])), uint8 (4))
744 %!assert (max (uint8 ([1; -10; 5; -2])), uint8 (5))
745 %!assert (max (int8 ([1, 4, 2, 3])), int8 (4))
746 %!assert (max (int8 ([1; -10; 5; -2])), int8 (5))
747 %!assert (max (uint16 ([1, 4, 2, 3])), uint16 (4))
748 %!assert (max (uint16 ([1; -10; 5; -2])), uint16 (5))
749 %!assert (max (int16 ([1, 4, 2, 3])), int16 (4))
750 %!assert (max (int16 ([1; -10; 5; -2])), int16 (5))
751 %!assert (max (uint32 ([1, 4, 2, 3])), uint32 (4))
752 %!assert (max (uint32 ([1; -10; 5; -2])), uint32 (5))
753 %!assert (max (int32 ([1, 4, 2, 3])), int32 (4))
754 %!assert (max (int32 ([1; -10; 5; -2])), int32 (5))
755 %!assert (max (uint64 ([1, 4, 2, 3])), uint64 (4))
756 %!assert (max (uint64 ([1; -10; 5; -2])), uint64 (5))
757 %!assert (max (int64 ([1, 4, 2, 3])), int64 (4))
758 %!assert (max (int64 ([1; -10; 5; -2])), int64 (5))
759 ## Sparse double values
760 %!assert (max (sparse ([1, 4, 2, 3])), sparse (4))
761 %!assert (max (sparse ([1; -10; 5; -2])), sparse(5))
762 %!assert (max (sparse ([4, 2i 4.999; -2, 2, 3+4i])), sparse ([4, 2i, 3+4i]))
763 
764 ## Test dimension argument
765 %!test
766 %! x = reshape (1:8, [2,2,2]);
767 %! assert (min (x, [], 1), reshape ([1, 3, 5, 7], [1,2,2]));
768 %! assert (min (x, [], 2), reshape ([1, 2, 5, 6], [2,1,2]));
769 %! [y, i] = min (x, [], 3);
770 %! assert (ndims (y), 2);
771 %! assert (y, [1, 3; 2, 4]);
772 %! assert (ndims (i), 2);
773 %! assert (i, [1, 1; 1, 1]);
774 
775 ## Test 2-output forms for various arg types
776 ## Special routines for char arrays
777 %!test
778 %! [y, i] = max (["abc", "ABC"]);
779 %! assert (y, 99);
780 %! assert (i, 3);
781 ## Special routines for logical arrays
782 %!test
783 %! x = logical ([0 0 1 0]);
784 %! [y, i] = max (x);
785 %! assert (y, true);
786 %! assert (i, 3);
787 ## Special handling of ranges
788 %!test
789 %! rng = 1:2:10;
790 %! [y, i] = max (rng);
791 %! assert (y, 9);
792 %! assert (i, 5);
793 %! rng = 10:-2:1;
794 %! [y, i] = max (rng);
795 %! assert (y, 10);
796 %! assert (i, 1);
797 
798 ## Test 2-input calling form for various arg types
799 ## Test generic double class
800 %!test
801 %! x = [1, 2, 3, 4]; y = fliplr (x);
802 %! assert (max (x, y), [4 3 3 4]);
803 %! assert (max (x, 3), [3 3 3 4]);
804 %! assert (max (2, x), [2 2 3 4]);
805 %! assert (max (x, 2.1i), [2.1i 2.1i 3 4]);
806 ## FIXME: Ordering of complex results with equal magnitude is not by phase
807 ## angle in the 2-input form. Instead, it is in the order in which it
808 ## appears in the argument list.
809 %!xtest
810 %! x = [1, 2, 3, 4]; y = fliplr (x);
811 %! assert (max (x, 2i), [2i 2i 3 4]);
812 ## Special routines for char arrays
813 %!assert (max ("abc", "b"), [98 98 99])
814 %!assert (max ("b", "cba"), [99 98 98])
815 ## Special handling for logical arrays
816 %!assert (max ([true false], false), [true false])
817 %!assert (max (true, [false false]), [true true])
818 ## Single values
819 %!test
820 %! x = single ([1, 2, 3, 4]); y = fliplr (x);
821 %! assert (max (x, y), single ([4 3 3 4]));
822 %! assert (max (x, 3), single ([3 3 3 4]));
823 %! assert (max (2, x), single ([2 2 3 4]));
824 %! assert (max (x, 2.1i), single ([2.1i 2.1i 3 4]));
825 ## Integer values
826 %!test
827 %! x = uint8 ([1, 2, 3, 4]); y = fliplr (x);
828 %! assert (max (x, y), uint8 ([4 3 3 4]));
829 %! assert (max (x, 3), uint8 ([3 3 3 4]));
830 %! assert (max (2, x), uint8 ([2 2 3 4]));
831 %! x = int8 ([1, 2, 3, 4]); y = fliplr (x);
832 %! assert (max (x, y), int8 ([4 3 3 4]));
833 %! assert (max (x, 3), int8 ([3 3 3 4]));
834 %! assert (max (2, x), int8 ([2 2 3 4]));
835 %! x = uint16 ([1, 2, 3, 4]); y = fliplr (x);
836 %! assert (max (x, y), uint16 ([4 3 3 4]));
837 %! assert (max (x, 3), uint16 ([3 3 3 4]));
838 %! assert (max (2, x), uint16 ([2 2 3 4]));
839 %! x = int16 ([1, 2, 3, 4]); y = fliplr (x);
840 %! assert (max (x, y), int16 ([4 3 3 4]));
841 %! assert (max (x, 3), int16 ([3 3 3 4]));
842 %! assert (max (2, x), int16 ([2 2 3 4]));
843 %! x = uint32 ([1, 2, 3, 4]); y = fliplr (x);
844 %! assert (max (x, y), uint32 ([4 3 3 4]));
845 %! assert (max (x, 3), uint32 ([3 3 3 4]));
846 %! assert (max (2, x), uint32 ([2 2 3 4]));
847 %! x = int32 ([1, 2, 3, 4]); y = fliplr (x);
848 %! assert (max (x, y), int32 ([4 3 3 4]));
849 %! assert (max (x, 3), int32 ([3 3 3 4]));
850 %! assert (max (2, x), int32 ([2 2 3 4]));
851 %! x = uint64 ([1, 2, 3, 4]); y = fliplr (x);
852 %! assert (max (x, y), uint64 ([4 3 3 4]));
853 %! assert (max (x, 3), uint64 ([3 3 3 4]));
854 %! assert (max (2, x), uint64 ([2 2 3 4]));
855 %! x = int64 ([1, 2, 3, 4]); y = fliplr (x);
856 %! assert (max (x, y), int64 ([4 3 3 4]));
857 %! assert (max (x, 3), int64 ([3 3 3 4]));
858 %! assert (max (2, x), int64 ([2 2 3 4]));
859 ## Sparse double values
860 %!test
861 %! x = sparse ([1, 2, 3, 4]); y = fliplr (x);
862 %! assert (max (x, y), sparse ([4 3 3 4]));
863 %! assert (max (x, 3), sparse ([3 3 3 4]));
864 %! assert (max (2, x), sparse ([2 2 3 4]));
865 %! assert (max (x, 2.1i), sparse ([2.1i 2.1i 3 4]));
866 
867 ## Test for bug #40743
868 %!assert <40743> (max (zeros (1,0), ones (1,1)), zeros (1,0))
869 %!assert <40743> (max (sparse (zeros (1,0)), sparse (ones (1,1))),
870  sparse (zeros (1,0)))
871 
872 %!error max ()
873 %!error max (1, 2, 3, 4)
874 %!error <DIM must be a valid dimension> max ([1 2; 3 4], [], -3)
875 %!warning <second argument is ignored> max ([1 2 3 4], 2, 2);
876 %!error <wrong type argument 'cell'> max ({1 2 3 4})
877 %!error <cannot compute max \(cell, scalar\)> max ({1, 2, 3}, 2)
878 
879 */
880 
881 template <typename ArrayType>
882 static octave_value_list
883 do_cumminmax_red_op (const octave_value& arg,
884  int nargout, int dim, bool ismin)
885 {
886  octave_value_list retval (nargout > 1 ? 2 : 1);
887  ArrayType array = octave_value_extract<ArrayType> (arg);
888 
889  if (nargout <= 1)
890  {
891  if (ismin)
892  retval(0) = array.cummin (dim);
893  else
894  retval(0) = array.cummax (dim);
895  }
896  else
897  {
898  retval.resize (2);
900  if (ismin)
901  retval(0) = array.cummin (idx, dim);
902  else
903  retval(0) = array.cummax (idx, dim);
904 
905  retval(1) = octave_value (idx, true, true);
906  }
907 
908  return retval;
909 }
910 
911 static octave_value_list
912 do_cumminmax_body (const octave_value_list& args,
913  int nargout, bool ismin)
914 {
915  int nargin = args.length ();
916 
917  if (nargin < 1 || nargin > 2)
918  print_usage ();
919 
920  const char *func = ismin ? "cummin" : "cummax";
921 
922  octave_value arg = args(0);
923  int dim = -1;
924  if (nargin == 2)
925  {
926  dim = args(1).int_value (true) - 1;
927 
928  if (dim < 0)
929  error ("%s: DIM must be a valid dimension", func);
930  }
931 
933 
934  switch (arg.builtin_type ())
935  {
936  case btyp_double:
937  retval = do_cumminmax_red_op<NDArray> (arg, nargout, dim, ismin);
938  break;
939 
940  case btyp_complex:
941  retval = do_cumminmax_red_op<ComplexNDArray> (arg, nargout, dim,
942  ismin);
943  break;
944 
945  case btyp_float:
946  retval = do_cumminmax_red_op<FloatNDArray> (arg, nargout, dim, ismin);
947  break;
948 
949  case btyp_float_complex:
950  retval = do_cumminmax_red_op<FloatComplexNDArray> (arg, nargout, dim,
951  ismin);
952  break;
953 
954 #define MAKE_INT_BRANCH(X) \
955  case btyp_ ## X: \
956  retval = do_cumminmax_red_op<X ## NDArray> (arg, nargout, dim, ismin); \
957  break;
958 
959  MAKE_INT_BRANCH (int8);
963  MAKE_INT_BRANCH (uint8);
966  MAKE_INT_BRANCH (uint64);
967 
968 #undef MAKE_INT_BRANCH
969 
970  case btyp_bool:
971  {
972  retval = do_cumminmax_red_op<int8NDArray> (arg, nargout, dim,
973  ismin);
974  if (retval.length () > 0)
975  retval(0) = retval(0).bool_array_value ();
976  }
977  break;
978 
979  default:
980  err_wrong_type_arg (func, arg);
981  }
982 
983  return retval;
984 }
985 
986 DEFUN (cummin, args, nargout,
987  doc: /* -*- texinfo -*-
988 @deftypefn {} {} cummin (@var{x})
989 @deftypefnx {} {} cummin (@var{x}, @var{dim})
990 @deftypefnx {} {[@var{w}, @var{iw}] =} cummin (@var{x})
991 Return the cumulative minimum values along dimension @var{dim}.
992 
993 If @var{dim} is unspecified it defaults to column-wise operation. For
994 example:
995 
996 @example
997 @group
998 cummin ([5 4 6 2 3 1])
999  @result{} 5 4 4 2 2 1
1000 @end group
1001 @end example
1002 
1003 If called with two output arguments the index of the minimum value is also
1004 returned.
1005 
1006 @example
1007 @group
1008 [w, iw] = cummin ([5 4 6 2 3 1])
1009 @result{}
1010 w = 5 4 4 2 2 1
1011 iw = 1 2 2 4 4 6
1012 @end group
1013 @end example
1014 
1015 @seealso{cummax, min, max}
1016 @end deftypefn */)
1017 {
1018  return do_cumminmax_body (args, nargout, true);
1019 }
1020 
1021 /*
1022 %!assert (cummin ([1, 4, 2, 3]), [1 1 1 1])
1023 %!assert (cummin ([1; -10; 5; -2]), [1; -10; -10; -10])
1024 %!assert (cummin ([4, i; -2, 2]), [4, i; -2, i])
1025 %!assert (cummin ([1 2; NaN 1], 2), [1 1; NaN 1])
1026 
1027 %!test
1028 %! x = reshape (1:8, [2,2,2]);
1029 %! assert (cummin (x, 1), reshape ([1 1 3 3 5 5 7 7], [2,2,2]));
1030 %! assert (cummin (x, 2), reshape ([1 2 1 2 5 6 5 6], [2,2,2]));
1031 %! [w, iw] = cummin (x, 3);
1032 %! assert (ndims (w), 3);
1033 %! assert (w, repmat ([1 3; 2 4], [1 1 2]));
1034 %! assert (ndims (iw), 3);
1035 %! assert (iw, ones (2,2,2));
1036 
1037 %!error cummin ()
1038 %!error cummin (1, 2, 3)
1039 */
1040 
1041 DEFUN (cummax, args, nargout,
1042  doc: /* -*- texinfo -*-
1043 @deftypefn {} {} cummax (@var{x})
1044 @deftypefnx {} {} cummax (@var{x}, @var{dim})
1045 @deftypefnx {} {[@var{w}, @var{iw}] =} cummax (@dots{})
1046 Return the cumulative maximum values along dimension @var{dim}.
1047 
1048 If @var{dim} is unspecified it defaults to column-wise operation. For
1049 example:
1050 
1051 @example
1052 @group
1053 cummax ([1 3 2 6 4 5])
1054  @result{} 1 3 3 6 6 6
1055 @end group
1056 @end example
1057 
1058 If called with two output arguments the index of the maximum value is also
1059 returned.
1060 
1061 @example
1062 @group
1063 [w, iw] = cummax ([1 3 2 6 4 5])
1064 @result{}
1065 w = 1 3 3 6 6 6
1066 iw = 1 2 2 4 4 4
1067 @end group
1068 @end example
1069 
1070 @seealso{cummin, max, min}
1071 @end deftypefn */)
1072 {
1073  return do_cumminmax_body (args, nargout, false);
1074 }
1075 
1076 /*
1077 %!assert (cummax ([1, 4, 2, 3]), [1 4 4 4])
1078 %!assert (cummax ([1; -10; 5; -2]), [1; 1; 5; 5])
1079 %!assert (cummax ([4, i 4.9, -2, 2, 3+4i]), [4, 4, 4.9, 4.9, 4.9, 3+4i])
1080 %!assert (cummax ([1 NaN 0; NaN NaN 1], 2), [1 1 1; NaN NaN 1])
1081 
1082 %!test
1083 %! x = reshape (8:-1:1, [2,2,2]);
1084 %! assert (cummax (x, 1), reshape ([8 8 6 6 4 4 2 2], [2,2,2]));
1085 %! assert (cummax (x, 2), reshape ([8 7 8 7 4 3 4 3], [2,2,2]));
1086 %! [w, iw] = cummax (x, 3);
1087 %! assert (ndims (w), 3);
1088 %! assert (w, repmat ([8 6; 7 5], [1 1 2]));
1089 %! assert (ndims (iw), 3);
1090 %! assert (iw, ones (2,2,2));
1091 
1092 %!error cummax ()
1093 %!error cummax (1, 2, 3)
1094 */
boolNDArray all(int dim=-1) const
Definition: boolNDArray.cc:60
charNDArray max(int dim=-1) const
Definition: chNDArray.cc:140
bool is_empty(void) const
Definition: Array.h:575
bool is_range(void) const
Definition: ov.h:587
OCTINTERP_API void print_usage(void)
Definition: defun.cc:52
octave_idx_type numel(void) const
Number of elements in the array.
Definition: Array.h:363
OCTAVE_EXPORT octave_value_list uint16
Definition: ov.cc:1258
octave_idx_type length(void) const
Definition: ovl.h:96
bool is_scalar_type(void) const
Definition: ov.h:673
Definition: Range.h:33
#define DEFUN(name, args_name, nargout_name, doc)
Definition: defun.h:46
void error(const char *fmt,...)
Definition: error.cc:570
boolNDArray any(int dim=-1) const
Definition: boolNDArray.cc:66
octave_value resize(const dim_vector &dv, bool fill=false) const
Definition: ov.h:524
double min(void) const
Definition: Range.cc:164
builtin_type_t
Definition: ov-base.h:61
boolNDArray bool_array_value(bool warn=false) const
Definition: ov.h:825
octave_value arg
Definition: pr-output.cc:3440
JNIEnv void * args
Definition: ov-java.cc:67
octave_value_list do_minmax_red_op< boolNDArray >(const octave_value &arg, int nargout, int dim, bool ismin)
Definition: max.cc:113
builtin_type_t btyp_mixed_numeric(builtin_type_t x, builtin_type_t y)
Definition: ov-base.cc:60
double max(void) const
Definition: Range.cc:185
OCTAVE_EXPORT octave_value_list return the number of command line arguments passed to Octave If called with the optional argument the function xample nargout(@histc)
Definition: ov-usr-fcn.cc:935
bool is_sparse_type(void) const
Definition: ov.h:682
OCTAVE_EXPORT octave_value_list uint32
Definition: ov.cc:1258
then the function must return scalars which will be concatenated into the return array(s).If code
Definition: cellfun.cc:398
Range range_value(void) const
Definition: ov.h:923
int nargin
Definition: graphics.cc:10115
static octave_value_list do_minmax_body(const octave_value_list &args, int nargout, bool ismin)
Definition: max.cc:236
double inc(void) const
Definition: Range.h:80
OCTAVE_EXPORT octave_value_list int16
Definition: ov.cc:1302
octave_idx_type numel(void) const
Definition: Range.h:85
static octave_value do_minmax_bin_op(const octave_value &argx, const octave_value &argy, bool ismin)
Definition: max.cc:154
SparseBoolMatrix sparse_bool_matrix_value(bool warn=false) const
Definition: ov.h:841
octave_value retval
Definition: data.cc:6294
OCTAVE_EXPORT octave_value_list int32
Definition: ov.cc:1258
charNDArray octave_value_extract< charNDArray >(const octave_value &v)
Definition: ov.h:1585
static octave_value_list do_minmax_red_op(const octave_value &arg, int nargout, int dim, bool ismin)
Definition: max.cc:46
void err_wrong_type_arg(const char *name, const char *s)
Definition: errwarn.cc:156
#define MAKE_INT_BRANCH(X)
OCTAVE_EXPORT octave_value_list int64
Definition: ov.cc:1258
void warning(const char *fmt,...)
Definition: error.cc:788
charNDArray max(char d, const charNDArray &m)
Definition: chNDArray.cc:228
charNDArray min(int dim=-1) const
Definition: chNDArray.cc:152
the element is set to zero In other the statement xample y
Definition: data.cc:5342
octave_value do_minmax_bin_op< charNDArray >(const octave_value &argx, const octave_value &argy, bool ismin)
Definition: max.cc:205
builtin_type_t builtin_type(void) const
Definition: ov.h:619
octave_value_list do_minmax_red_op< charNDArray >(const octave_value &arg, int nargout, int dim, bool ismin)
Definition: max.cc:83
OCTAVE_EXPORT octave_value_list or cell arrays Arguments are concatenated vertically The returned values are padded with blanks as needed to make each row of the string array have the same length Empty input strings are significant and will concatenated in the output For numerical each element is converted to the corresponding ASCII character A range error results if an input is outside the ASCII range(0-255).For cell arrays
F77_RET_T F77_REAL &F77_RET_T F77_DBLE &F77_RET_T F77_REAL &F77_RET_T F77_DBLE &F77_RET_T F77_REAL &F77_RET_T F77_DBLE &F77_RET_T const F77_REAL const F77_REAL F77_REAL &F77_RET_T const F77_DBLE const F77_DBLE F77_DBLE &F77_RET_T F77_REAL &F77_RET_T F77_DBLE &F77_RET_T F77_DBLE &F77_RET_T F77_REAL &F77_RET_T F77_REAL &F77_RET_T F77_DBLE &F77_RET_T const F77_DBLE F77_DBLE &F77_RET_T const F77_REAL F77_REAL &F77_RET_T F77_REAL F77_REAL &F77_RET_T F77_DBLE F77_DBLE &F77_RET_T const F77_DBLE * x
return octave_value(v1.char_array_value().concat(v2.char_array_value(), ra_idx),((a1.is_sq_string()||a2.is_sq_string())? '\'': '"'))
charNDArray min(char d, const charNDArray &m)
Definition: chNDArray.cc:205