26#if defined (HAVE_CONFIG_H)
52 bool& allflag,
const char *fcn)
58 error (
"%s: invalid dimension DIM = %d", fcn, dim + 1);
63 std::vector<int> vecdim;
65 int ndims = arg.
ndims ();
67 for (
int i = 0; i < vec.
numel (); i++)
71 error (
"%s: invalid dimension in VECDIM = %d", fcn, vec(i)+1);
73 vecdim.push_back (vec(i));
75 int n = vecdim.size ();
85 std::sort (vecdim.begin (), vecdim.end ());
87 auto dup = std::adjacent_find (vecdim.begin (), vecdim.end ());
88 if (dup != vecdim.end ())
89 error (
"%s: duplicate dimension in VECDIM = %d", fcn, *dup + 1);
92 int out_pos = ndims - n;
96 perm_vec(out_pos++) =
d;
109 new_sz.
resize (ndims - n + 1);
112 for (
int i = 0; i < ndims; i++)
114 if (std::find (vecdim.begin (), vecdim.end (), i)
122 new_sz(idx) = szvecdim;
123 arg = arg.
permute (perm_vec,
false);
136 for (
int i = 0; i < ndims; i++)
139 for (
int i = 1; i < ndims; i++)
144 for (
int i = 0; i < ndims; i++)
161 idx -= (tmp - 1) * dsz;
176 for (
int i = 0; i < ndims; i++)
189 ind += szce(i) * (dims(i) - 1);
204 int nd_arg = arg.
ndims ();
208 std::vector<int> dim_page;
210 if (vecdim(i) <= nd_arg)
211 dim_page.push_back (vecdim(i));
212 int nd_page = dim_page.size ();
221 std::sort (dim_page.begin (), dim_page.end ());
226 for (
int i = 0; i < nd_page; i++)
227 sz_page(i) = sz_arg(dim_page[i]-1);
230 std::vector<int> dim_index;
233 for (
int i = 0; i < nd_arg; i++)
236 bool addindex =
true;
237 for (
int j = 0; j < nd_page; j++)
238 if (i+1 == dim_page[j])
241 if (addindex && sz_arg(i) > 1)
242 dim_index.push_back (i + 1);
245 int nd_index = dim_index.size ();
247 sz_index.
resize (nd_index);
248 for (
int i = 0; i < nd_index; i++)
249 sz_index(i) = sz_arg(dim_index[i]-1);
262 prod_vecdim *= sz_page(i);
263 if (dim_page[0] > dim_index[0])
264 for (
int i = 0; i < nd_index; i++)
265 if (dim_page[0] > dim_index[i])
266 group_index *= sz_index(i);
276 if (group_index == 1)
277 ii = i / prod_vecdim;
282 ii = igm + ((igf / prod_vecdim) * group_index);
288 tmp = custom_ind2sub (sz_index, ii+1, nd_index);
290 dim_vec(dim_index[j]-1) = tmp(j);
293 tmp = custom_ind2sub (sz_page, idx(i), nd_page);
295 dim_vec(dim_page[j]-1) = tmp(j);
298 idx(i) = custom_sub2ind (sz_arg, dim_vec, nd_arg);
304template <
typename ArrayType>
307 int nargout,
int dim,
bool ismin)
310 ArrayType array = octave_value_extract<ArrayType> (arg);
315 retval(0) = array.min (dim);
317 retval(0) = array.max (dim);
323 retval(0) = array.min (idx, dim);
325 retval(0) = array.max (idx, dim);
333template <
typename ArrayType>
336 int dim,
bool nanflag,
bool ismin)
339 ArrayType array = octave_value_extract<ArrayType> (arg);
344 retval(0) = array.min (dim, nanflag);
346 retval(0) = array.max (dim, nanflag);
352 retval(0) = array.min (idx, dim, nanflag);
354 retval(0) = array.max (idx, dim, nanflag);
362template <
typename ArrayType>
365 int dim,
bool nanflag,
bool realabs,
bool ismin)
368 ArrayType array = octave_value_extract<ArrayType> (arg);
373 retval(0) = array.min (dim, nanflag, realabs);
375 retval(0) = array.max (dim, nanflag, realabs);
381 retval(0) = array.min (idx, dim, nanflag, realabs);
383 retval(0) = array.max (idx, dim, nanflag, realabs);
402 int nargout,
int dim,
bool ismin)
410 retval(0) =
NDArray (array.min (dim));
412 retval(0) =
NDArray (array.max (dim));
418 retval(0) =
NDArray (array.min (idx, dim));
420 retval(0) =
NDArray (array.max (idx, dim));
432 int nargout,
int dim,
bool ismin)
446 retval(0) = array.
all (dim);
448 retval(0) = array.
any (dim);
453 retval = do_minmax_red_op<int8NDArray> (arg, nargout, dim, ismin);
455 retval(0) = retval(0).bool_array_value ();
462 retval = do_minmax_red_op<SparseMatrix> (arg, nargout, dim, ismin);
464 retval(0) = retval(0).sparse_bool_matrix_value ();
470template <
typename ArrayType>
475 typedef typename ArrayType::element_type ScalarType;
481 ScalarType
x = octave_value_extract<ScalarType> (argx);
482 ArrayType y = octave_value_extract<ArrayType> (argy);
491 ArrayType
x = octave_value_extract<ArrayType> (argx);
492 ScalarType y = octave_value_extract<ScalarType> (argy);
501 ArrayType
x = octave_value_extract<ArrayType> (argx);
502 ArrayType y = octave_value_extract<ArrayType> (argy);
513template <
typename ArrayType>
516 bool nanflag,
bool ismin)
518 typedef typename ArrayType::element_type ScalarType;
524 ScalarType
x = octave_value_extract<ScalarType> (argx);
525 ArrayType y = octave_value_extract<ArrayType> (argy);
528 retval =
min (
x, y, nanflag);
530 retval =
max (
x, y, nanflag);
534 ArrayType
x = octave_value_extract<ArrayType> (argx);
535 ScalarType y = octave_value_extract<ScalarType> (argy);
538 retval =
min (
x, y, nanflag);
540 retval =
max (
x, y, nanflag);
544 ArrayType
x = octave_value_extract<ArrayType> (argx);
545 ArrayType y = octave_value_extract<ArrayType> (argy);
548 retval =
min (
x, y, nanflag);
550 retval =
max (
x, y, nanflag);
556template <
typename ArrayType>
559 bool nanflag,
bool realabs,
bool ismin)
561 typedef typename ArrayType::element_type ScalarType;
567 ScalarType
x = octave_value_extract<ScalarType> (argx);
568 ArrayType y = octave_value_extract<ArrayType> (argy);
571 retval =
min (
x, y, nanflag, realabs);
573 retval =
max (
x, y, nanflag, realabs);
577 ArrayType
x = octave_value_extract<ArrayType> (argx);
578 ScalarType y = octave_value_extract<ScalarType> (argy);
581 retval =
min (
x, y, nanflag, realabs);
583 retval =
max (
x, y, nanflag, realabs);
587 ArrayType
x = octave_value_extract<ArrayType> (argx);
588 ArrayType y = octave_value_extract<ArrayType> (argy);
591 retval =
min (
x, y, nanflag, realabs);
593 retval =
max (
x, y, nanflag, realabs);
621 else if (y.
numel () == 1)
630 else if (y.
numel () == 1)
642 int nargin = args.
length ();
643 int orig_nargin = nargin;
645 const char *fcn = (ismin ?
"min" :
"max");
647 bool do_perm =
false;
648 bool allflag =
false;
657 && args(nargin - 1).is_string () && args(nargin - 2).is_string ())
659 std::string name = args(nargin - 2).string_value ();
660 std::string sval = args(nargin - 1).string_value ();
661 if (name ==
"ComparisonMethod" || name ==
"comparisonmethod")
665 else if (sval ==
"real")
667 else if (sval ==
"abs")
673 error (
"%s: invalid comparison method '%s'", fcn, sval.c_str ());
679 while (nargin > 2 && args(nargin - 1).is_string ())
681 std::string str = args(nargin - 1).string_value ();
688 else if (str ==
"omitnan" || str ==
"omitmissing")
690 if (args(0).is_double_type () || args(0).is_single_type ())
693 else if (str ==
"includenan" || str ==
"includemissing")
695 else if (str ==
"linear")
698 error (
"%s: unrecognized optional argument '%s'", fcn, str.c_str ());
703 if (nargin < 1 || nargin > 3)
705 if (allflag && nargin > 2)
706 error (
"%s: cannot set DIM or VECDIM with 'all' flag", fcn);
710 if (orig_nargin > 2 && args(1).rows () == 0 && args(1). columns () == 0)
716 if (nargin == 1 || red_op)
725 get_dim_vecdim_all (dimarg, arg, dim, perm_vec, do_perm, allflag, fcn);
728 if (! args(1).isempty ())
729 warning (
"%s: second argument is ignored", fcn);
745 if (arg.
is_range () && (dim == -1 || dim == 1))
748 if (
range.numel () < 1)
756 retval(0) =
range.min ();
758 retval(1) =
static_cast<double>
759 (
range.increment () < 0 ?
range.numel () : 1);
763 retval(0) =
range.max ();
765 retval(1) =
static_cast<double>
773 retval = do_minmax_red_op<SparseMatrix>
774 (arg, nargout, dim, nanflag, ismin);
776 retval = do_minmax_red_op<SparseMatrix>
777 (arg, nargout, dim, nanflag, realabs, ismin);
782 retval = do_minmax_red_op<NDArray>
783 (arg, nargout, dim, nanflag, ismin);
785 retval = do_minmax_red_op<NDArray>
786 (arg, nargout, dim, nanflag, realabs, ismin);
796 retval = do_minmax_red_op<SparseComplexMatrix>
797 (arg, nargout, dim, nanflag, ismin);
799 retval = do_minmax_red_op<SparseComplexMatrix>
800 (arg, nargout, dim, nanflag, realabs, ismin);
805 retval = do_minmax_red_op<ComplexNDArray>
806 (arg, nargout, dim, nanflag, ismin);
808 retval = do_minmax_red_op<ComplexNDArray>
809 (arg, nargout, dim, nanflag, realabs, ismin);
817 retval = do_minmax_red_op<FloatNDArray>
818 (arg, nargout, dim, nanflag, ismin);
820 retval = do_minmax_red_op<FloatNDArray>
821 (arg, nargout, dim, nanflag, realabs, ismin);
828 retval = do_minmax_red_op<FloatComplexNDArray>
829 (arg, nargout, dim, nanflag, ismin);
831 retval = do_minmax_red_op<FloatComplexNDArray>
832 (arg, nargout, dim, nanflag, realabs, ismin);
840#define MAKE_INT_BRANCH(X) \
844 retval = do_minmax_red_op<X ## NDArray> (arg, \
845 nargout, dim, ismin); \
847 retval = do_minmax_red_op<X ## NDArray> (arg, \
848 nargout, dim, nanflag, realabs, ismin); \
861#undef MAKE_INT_BRANCH
873 retval(0) = retval(0).permute (perm_vec,
true);
875 retval(1) = retval(1).permute (perm_vec,
true);
881 error (
"%s: two output arguments are not supported for two input arrays", fcn);
883 error (
"%s: 'linear' is not supported for two input arrays", fcn);
906 retval = do_minmax_bin_op<SparseMatrix>
907 (argx, argy, nanflag, ismin);
909 retval = do_minmax_bin_op<SparseMatrix>
910 (argx, argy, nanflag, realabs, ismin);
915 retval = do_minmax_bin_op<NDArray>
916 (argx, argy, nanflag, ismin);
918 retval = do_minmax_bin_op<NDArray>
919 (argx, argy, nanflag, realabs, ismin);
931 retval = do_minmax_bin_op<SparseComplexMatrix>
932 (argx, argy, nanflag, ismin);
934 retval = do_minmax_bin_op<SparseComplexMatrix>
935 (argx, argy, nanflag, realabs, ismin);
940 retval = do_minmax_bin_op<ComplexNDArray>
941 (argx, argy, nanflag, ismin);
943 retval = do_minmax_bin_op<ComplexNDArray>
944 (argx, argy, nanflag, realabs, ismin);
952 retval = do_minmax_bin_op<FloatNDArray>
953 (argx, argy, nanflag, ismin);
955 retval = do_minmax_bin_op<FloatNDArray>
956 (argx, argy, nanflag, realabs, ismin);
963 retval = do_minmax_bin_op<FloatComplexNDArray>
964 (argx, argy, nanflag, ismin);
966 retval = do_minmax_bin_op<FloatComplexNDArray>
967 (argx, argy, nanflag, realabs, ismin);
975#define MAKE_INT_BRANCH(X) \
979 retval = do_minmax_bin_op<X ## NDArray> \
980 (argx, argy, ismin); \
982 retval = do_minmax_bin_op<X ## NDArray> \
983 (argx, argy, nanflag, realabs, ismin); \
996#undef MAKE_INT_BRANCH
1004 error (
"%s: cannot compute %s (%s, %s)", fcn, fcn,
1010 retval(0) = retval(0).bool_array_value ();
1015 if (linear && nargout > 1 && ! allflag && ! args(0).isempty ())
1016 retval(1) = get_linear_index (retval(1), args(0), vecdim,
false);
1096 return do_minmax_body (args, nargout,
true);
1503 return do_minmax_body (args, nargout,
false);
1847 idx(i) = dim_size - idx(i) - 1;
1851template <
typename ArrayType>
1853do_cumminmax_red_op (
const octave_value& arg,
int nargout,
int dim,
1854 bool nanflag,
bool ismin,
bool direction)
1857 ArrayType array = octave_value_extract<ArrayType> (arg);
1864 retval(0) = array.flip (dim).cummin (dim, nanflag).flip (dim);
1866 retval(0) = array.cummin (dim, nanflag);
1871 retval(0) = array.flip (dim).cummax (dim, nanflag).flip (dim);
1873 retval(0) = array.cummax (dim, nanflag);
1884 retval(0) = array.flip (dim).cummin (idx, dim, nanflag).flip (dim);
1885 idx = reverse_index (idx, array.dims (), dim);
1888 retval(0) = array.cummin (idx, dim, nanflag);
1894 retval(0) = array.flip (dim).cummax (idx, dim, nanflag).flip (dim);
1895 idx = reverse_index (idx, array.dims (), dim);
1898 retval(0) = array.cummax (idx, dim, nanflag);
1909template <
typename ArrayType>
1911do_cumminmax_red_op (
const octave_value& arg,
int nargout,
int dim,
1912 bool nanflag,
bool realabs,
bool ismin,
bool direction)
1915 ArrayType array = octave_value_extract<ArrayType> (arg);
1922 retval(0) = array.flip (dim).cummin (dim, nanflag, realabs).flip (dim);
1924 retval(0) = array.cummin (dim, nanflag, realabs);
1929 retval(0) = array.flip (dim).cummax (dim, nanflag, realabs).flip (dim);
1931 retval(0) = array.cummax (dim, nanflag, realabs);
1942 retval(0) = array.flip (dim).cummin (idx, dim, nanflag, realabs).flip (dim);
1943 idx = reverse_index (idx, array.dims (), dim);
1946 retval(0) = array.cummin (idx, dim, nanflag, realabs);
1952 retval(0) = array.flip (dim).cummax (idx, dim, nanflag, realabs).flip (dim);
1953 idx = reverse_index (idx, array.dims (), dim);
1956 retval(0) = array.cummax (idx, dim, nanflag, realabs);
1969 int nargout,
bool ismin)
1971 int nargin = args.
length ();
1973 const char *fcn = (ismin ?
"cummin" :
"cummax");
1975 bool direction =
false;
1976 bool do_perm =
false;
1977 bool allflag =
false;
1978 bool nanflag =
true;
1979 bool cmethod =
true;
1980 bool realabs =
true;
1981 bool linear =
false;
1985 && args(nargin - 1).is_string () && args(nargin - 2).is_string ())
1987 std::string name = args(nargin - 2).string_value ();
1988 std::string sval = args(nargin - 1).string_value ();
1989 if (name ==
"ComparisonMethod" || name ==
"comparisonmethod")
1993 else if (sval ==
"real")
1995 else if (sval ==
"abs")
2001 error (
"%s: invalid comparison method '%s'", fcn, sval.c_str ());
2007 while (nargin > 1 && args(nargin - 1).is_string ())
2009 std::string str = args(nargin - 1).string_value ();
2011 if (str ==
"forward")
2013 else if (str ==
"reverse")
2015 else if (str ==
"all")
2017 else if (str ==
"omitnan" || str ==
"omitmissing")
2019 if (args(0).is_double_type () || args(0).is_single_type ())
2022 else if (str ==
"includenan" || str ==
"includemissing")
2024 else if (str ==
"linear")
2027 error (
"%s: unrecognized optional argument '%s'", fcn, str.c_str ());
2032 if (nargin < 1 || nargin > 2)
2034 if (allflag && nargin > 1)
2035 error (
"%s: cannot set DIM or VECDIM with 'all' flag", fcn);
2046 get_dim_vecdim_all (dimarg, arg, dim, perm_vec, do_perm, allflag, fcn);
2067 retval = do_cumminmax_red_op<NDArray>
2068 (arg, nargout, dim, nanflag, ismin, direction);
2070 retval = do_cumminmax_red_op<NDArray>
2071 (arg, nargout, dim, nanflag, realabs, ismin, direction);
2078 retval = do_cumminmax_red_op<ComplexNDArray>
2079 (arg, nargout, dim, nanflag, ismin, direction);
2081 retval = do_cumminmax_red_op<ComplexNDArray>
2082 (arg, nargout, dim, nanflag, realabs, ismin, direction);
2089 retval = do_cumminmax_red_op<FloatNDArray>
2090 (arg, nargout, dim, nanflag, ismin, direction);
2092 retval = do_cumminmax_red_op<FloatNDArray>
2093 (arg, nargout, dim, nanflag, realabs, ismin, direction);
2100 retval = do_cumminmax_red_op<FloatComplexNDArray>
2101 (arg, nargout, dim, nanflag, ismin, direction);
2103 retval = do_cumminmax_red_op<FloatComplexNDArray>
2104 (arg, nargout, dim, nanflag, realabs, ismin, direction);
2108#define MAKE_INT_BRANCH(X) \
2112 retval = do_cumminmax_red_op<X ## NDArray> (arg, nargout, \
2113 dim, nanflag, ismin, direction); \
2115 retval = do_cumminmax_red_op<X ## NDArray> (arg, nargout, \
2116 dim, nanflag, realabs, ismin, direction); \
2129#undef MAKE_INT_BRANCH
2134 retval = do_cumminmax_red_op<int8NDArray>
2135 (arg, nargout, dim, nanflag, ismin, direction);
2137 retval = do_cumminmax_red_op<int8NDArray>
2138 (arg, nargout, dim, nanflag, realabs, ismin, direction);
2139 if (retval.
length () > 0)
2140 retval(0) = retval(0).bool_array_value ();
2150 retval(0) = retval(0).permute (perm_vec,
true);
2152 retval(1) = retval(1).permute (perm_vec,
true);
2156 if (linear && nargout > 1 && ! allflag && ! args(0).isempty ())
2157 retval(1) = get_linear_index (retval(1), args(0), vecdim,
true);
2162DEFUN (cummin, args, nargout,
2250 return do_cumminmax_body (args, nargout,
true);
2483DEFUN (cummax, args, nargout,
2571 return do_cumminmax_body (args, nargout,
false);
2804OCTAVE_END_NAMESPACE(octave)
charNDArray max(char d, const charNDArray &m)
charNDArray min(char d, const charNDArray &m)
N Dimensional Array with copy-on-write semantics.
void resize(const dim_vector &dv, const T &rfv)
Size of the specified dimension.
bool isempty() const
Size of the specified dimension.
octave_idx_type numel() const
Number of elements in the array.
boolNDArray any(int dim=-1) const
boolNDArray all(int dim=-1) const
Vector representing the dimensions (size) of an Array.
void resize(int n, int fill_value=0)
int first_non_singleton(int def=0) const
void resize(octave_idx_type n, const octave_value &rfv=octave_value())
Array< octave_value > array_value() const
octave_idx_type length() const
boolNDArray bool_array_value(bool warn=false) const
int int_value(bool req_int=false, bool frc_str_conv=false) const
bool is_scalar_type() const
octave_value permute(const Array< int > &vec, bool inv=false) const
octave_value reshape(const dim_vector &dv) const
octave_idx_type numel() const
Array< int > int_vector_value(bool req_int=false, bool frc_str_conv=false, bool frc_vec_conv=false) const
std::string type_name() const
builtin_type_t builtin_type() const
octave::range< double > range_value() const
OCTAVE_BEGIN_NAMESPACE(octave) static octave_value daspk_fcn
#define DEFUN(name, args_name, nargout_name, doc)
Macro to define a builtin function.
void warning(const char *fmt,...)
void error(const char *fmt,...)
void err_wrong_type_arg(const char *name, const char *s)
octave_value do_minmax_bin_op< charNDArray >(const octave_value &argx, const octave_value &argy, bool ismin)
#define MAKE_INT_BRANCH(X)
octave_value_list do_minmax_red_op< boolNDArray >(const octave_value &arg, int nargout, int dim, bool ismin)
octave_value_list do_minmax_red_op< charNDArray >(const octave_value &arg, int nargout, int dim, bool ismin)
builtin_type_t btyp_mixed_numeric(builtin_type_t x, builtin_type_t y)
Determine the resulting type for a possible mixed-type operation.
charNDArray octave_value_extract< charNDArray >(const octave_value &v)
F77_RET_T const F77_DBLE const F77_DBLE F77_DBLE * d
F77_RET_T const F77_DBLE * x