1## Copyright 2014-2016 Oliver Heimlich
2##
3## This program is free software; you can redistribute it and/or modify
4## it under the terms of the GNU General Public License as published by
5## the Free Software Foundation; either version 3 of the License, or
6## (at your option) any later version.
7##
8## This program is distributed in the hope that it will be useful,
9## but WITHOUT ANY WARRANTY; without even the implied warranty of
10## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11## GNU General Public License for more details.
12##
13## You should have received a copy of the GNU General Public License
14## along with this program; if not, see <http://www.gnu.org/licenses/>.
15
16## -*- texinfo -*-
17## @documentencoding UTF-8
18## @defmethod {@@infsup} min (@var{X})
19## @defmethodx {@@infsup} min (@var{X}, @var{Y})
20## @defmethodx {@@infsup} min (@var{X}, [], @var{DIM})
21##
22## Compute the minimum value chosen from intervals.
23##
24## This function does not return the least element of the interval (see
25## @code{inf}), but returns an interval enclosure of the function:
26## @display
27## min (@var{x}, @var{y}) = ( (x + y) - abs (x - y) ) / 2
28## @end display
29##
30## With two arguments the function is applied element-wise.  Otherwise the
31## minimum is computed for all interval members along dimension @var{DIM},
32## which defaults to the first non-singleton dimension.
33##
34## Accuracy: The result is a tight enclosure.
35##
36## @example
37## @group
38## x = infsup (2, 3);
39## y = infsup (1, 2);
40## min (x, y)
41##   @result{} ans = [1, 2]
42## @end group
43## @end example
44## @seealso{@@infsup/max}
45## @end defmethod
46
47## Author: Oliver Heimlich
48## Keywords: interval
49## Created: 2014-10-04
50
51function x = min (x, y, dim)
52
53  if (not (isa (x, "infsup")))
54    x = infsup (x);
55  endif
56
57  switch (nargin)
58    case 1
59      l = min (x.inf);
60      u = min (x.sup);
61      l(any (isempty (x))) = inf;
62    case 2
63      if (not (isa (y, "infsup")))
64        y = infsup (y);
65      endif
66      l = min (x.inf, y.inf);
67      u = min (x.sup, y.sup);
68      l(isempty (x) | isempty (y)) = inf;
69    case 3
70      if (not (builtin ("isempty", y)))
71        warning ("min: second argument is ignored");
72      endif
73      l = min (x.inf, [], dim);
74      u = min (x.sup, [], dim);
75      l(any (isempty (x), dim)) = inf;
76    otherwise
77      print_usage ();
78      return
79  endswitch
80
81  x.inf = l;
82  x.sup = u;
83
84endfunction
85
86%!# from the documentation string
87%!assert (min (infsup (2, 3), infsup (1, 2)) == infsup (1, 2));
88
89%!shared testdata
90%! # Load compiled test data (from src/test/*.itl)
91%! testdata = load (file_in_loadpath ("test/itl.mat"));
92
93%!test
94%! # Scalar evaluation
95%! testcases = testdata.NoSignal.infsup.min;
96%! for testcase = [testcases]'
97%!   assert (isequaln (...
98%!     min (testcase.in{1}, testcase.in{2}), ...
99%!     testcase.out));
100%! endfor
101
102%!test
103%! # Vector evaluation
104%! testcases = testdata.NoSignal.infsup.min;
105%! in1 = vertcat (vertcat (testcases.in){:, 1});
106%! in2 = vertcat (vertcat (testcases.in){:, 2});
107%! out = vertcat (testcases.out);
108%! assert (isequaln (min (in1, in2), out));
109
110%!test
111%! # N-dimensional array evaluation
112%! testcases = testdata.NoSignal.infsup.min;
113%! in1 = vertcat (vertcat (testcases.in){:, 1});
114%! in2 = vertcat (vertcat (testcases.in){:, 2});
115%! out = vertcat (testcases.out);
116%! # Reshape data
117%! i = -1;
118%! do
119%!   i = i + 1;
120%!   testsize = factor (numel (in1) + i);
121%! until (numel (testsize) > 2)
122%! in1 = reshape ([in1; in1(1:i)], testsize);
123%! in2 = reshape ([in2; in2(1:i)], testsize);
124%! out = reshape ([out; out(1:i)], testsize);
125%! assert (isequaln (min (in1, in2), out));
126