Mercurial > hg > octave-avbm
changeset 8777:724c0f46d9d4
implement cummin/cummax functions
author | Jaroslav Hajek <highegg@gmail.com> |
---|---|
date | Tue, 17 Feb 2009 11:26:29 +0100 |
parents | d23c33ec6bd3 |
children | 09ab0cc57ba6 |
files | liboctave/CNDArray.cc liboctave/CNDArray.h liboctave/ChangeLog liboctave/dNDArray.cc liboctave/dNDArray.h liboctave/fCNDArray.cc liboctave/fCNDArray.h liboctave/fNDArray.cc liboctave/fNDArray.h liboctave/intNDArray.cc liboctave/intNDArray.h liboctave/mx-inlines.cc src/ChangeLog src/DLD-FUNCTIONS/max.cc |
diffstat | 14 files changed, 561 insertions(+), 17 deletions(-) [+] |
line wrap: on
line diff
--- a/liboctave/CNDArray.cc +++ b/liboctave/CNDArray.cc @@ -714,6 +714,30 @@ return do_mx_minmax_op<ComplexNDArray> (*this, idx_arg, dim, mx_inline_min); } +ComplexNDArray +ComplexNDArray::cummax (int dim) const +{ + return do_mx_cumminmax_op<ComplexNDArray> (*this, dim, mx_inline_cummax); +} + +ComplexNDArray +ComplexNDArray::cummax (ArrayN<octave_idx_type>& idx_arg, int dim) const +{ + return do_mx_cumminmax_op<ComplexNDArray> (*this, idx_arg, dim, mx_inline_cummax); +} + +ComplexNDArray +ComplexNDArray::cummin (int dim) const +{ + return do_mx_cumminmax_op<ComplexNDArray> (*this, dim, mx_inline_cummin); +} + +ComplexNDArray +ComplexNDArray::cummin (ArrayN<octave_idx_type>& idx_arg, int dim) const +{ + return do_mx_cumminmax_op<ComplexNDArray> (*this, idx_arg, dim, mx_inline_cummin); +} + NDArray ComplexNDArray::abs (void) const {
--- a/liboctave/CNDArray.h +++ b/liboctave/CNDArray.h @@ -85,6 +85,12 @@ ComplexNDArray max (ArrayN<octave_idx_type>& index, int dim = 0) const; ComplexNDArray min (int dim = 0) const; ComplexNDArray min (ArrayN<octave_idx_type>& index, int dim = 0) const; + + ComplexNDArray cummax (int dim = 0) const; + ComplexNDArray cummax (ArrayN<octave_idx_type>& index, int dim = 0) const; + ComplexNDArray cummin (int dim = 0) const; + ComplexNDArray cummin (ArrayN<octave_idx_type>& index, int dim = 0) const; + ComplexNDArray& insert (const NDArray& a, octave_idx_type r, octave_idx_type c); ComplexNDArray& insert (const ComplexNDArray& a, octave_idx_type r, octave_idx_type c); ComplexNDArray& insert (const ComplexNDArray& a, const Array<octave_idx_type>& ra_idx);
--- a/liboctave/ChangeLog +++ b/liboctave/ChangeLog @@ -1,3 +1,28 @@ +2009-02-17 Jaroslav Hajek <highegg@gmail.com> + + * mx-inlines.cc (OP_CUMMINMAX_FCN, OP_CUMMINMAX_FCN2, + OP_CUMMINMAX_FCNN): New macros. + (mx_inline_cummax, mx_inline_cummin, do_mx_cumminmax_op): + New overloaded template functions. + + * dNDArray.cc (NDArray::cummin, NDArray::cummax): New methods. + * dNDArray.h: Declare them. + + * fNDArray.cc (FloatNDArray::cummin, FloatNDArray::cummax): New + methods. + * fNDArray.h: Declare them. + + * CNDArray.cc (ComplexNDArray::cummin, ComplexNDArray::cummax): New + methods. + * CNDArray.h: Declare them. + + * fCNDArray.cc (FloatComplexNDArray::cummin, + FloatComplexNDArray::cummax): New methods. + * fCNDArray.h: Declare them. + + * intNDArray.cc (intNDArray::cummin, intNDArray::cummax): New methods. + * intNDArray.h: Declare them. + 2009-02-17 Jaroslav Hajek <highegg@gmail.com> * mx-inlines.cc (OP_MINMAX_FCN): Correct behaviour with NaNs.
--- a/liboctave/dNDArray.cc +++ b/liboctave/dNDArray.cc @@ -754,6 +754,30 @@ } NDArray +NDArray::cummax (int dim) const +{ + return do_mx_cumminmax_op<NDArray> (*this, dim, mx_inline_cummax); +} + +NDArray +NDArray::cummax (ArrayN<octave_idx_type>& idx_arg, int dim) const +{ + return do_mx_cumminmax_op<NDArray> (*this, idx_arg, dim, mx_inline_cummax); +} + +NDArray +NDArray::cummin (int dim) const +{ + return do_mx_cumminmax_op<NDArray> (*this, dim, mx_inline_cummin); +} + +NDArray +NDArray::cummin (ArrayN<octave_idx_type>& idx_arg, int dim) const +{ + return do_mx_cumminmax_op<NDArray> (*this, idx_arg, dim, mx_inline_cummin); +} + +NDArray NDArray::concat (const NDArray& rb, const Array<octave_idx_type>& ra_idx) { if (rb.numel () > 0)
--- a/liboctave/dNDArray.h +++ b/liboctave/dNDArray.h @@ -97,6 +97,11 @@ NDArray min (int dim = 0) const; NDArray min (ArrayN<octave_idx_type>& index, int dim = 0) const; + NDArray cummax (int dim = 0) const; + NDArray cummax (ArrayN<octave_idx_type>& index, int dim = 0) const; + NDArray cummin (int dim = 0) const; + NDArray cummin (ArrayN<octave_idx_type>& index, int dim = 0) const; + NDArray& insert (const NDArray& a, octave_idx_type r, octave_idx_type c); NDArray& insert (const NDArray& a, const Array<octave_idx_type>& ra_idx);
--- a/liboctave/fCNDArray.cc +++ b/liboctave/fCNDArray.cc @@ -709,6 +709,30 @@ return do_mx_minmax_op<FloatComplexNDArray> (*this, idx_arg, dim, mx_inline_min); } +FloatComplexNDArray +FloatComplexNDArray::cummax (int dim) const +{ + return do_mx_cumminmax_op<FloatComplexNDArray> (*this, dim, mx_inline_cummax); +} + +FloatComplexNDArray +FloatComplexNDArray::cummax (ArrayN<octave_idx_type>& idx_arg, int dim) const +{ + return do_mx_cumminmax_op<FloatComplexNDArray> (*this, idx_arg, dim, mx_inline_cummax); +} + +FloatComplexNDArray +FloatComplexNDArray::cummin (int dim) const +{ + return do_mx_cumminmax_op<FloatComplexNDArray> (*this, dim, mx_inline_cummin); +} + +FloatComplexNDArray +FloatComplexNDArray::cummin (ArrayN<octave_idx_type>& idx_arg, int dim) const +{ + return do_mx_cumminmax_op<FloatComplexNDArray> (*this, idx_arg, dim, mx_inline_cummin); +} + FloatNDArray FloatComplexNDArray::abs (void) const {
--- a/liboctave/fCNDArray.h +++ b/liboctave/fCNDArray.h @@ -85,6 +85,12 @@ FloatComplexNDArray max (ArrayN<octave_idx_type>& index, int dim = 0) const; FloatComplexNDArray min (int dim = 0) const; FloatComplexNDArray min (ArrayN<octave_idx_type>& index, int dim = 0) const; + + FloatComplexNDArray cummax (int dim = 0) const; + FloatComplexNDArray cummax (ArrayN<octave_idx_type>& index, int dim = 0) const; + FloatComplexNDArray cummin (int dim = 0) const; + FloatComplexNDArray cummin (ArrayN<octave_idx_type>& index, int dim = 0) const; + FloatComplexNDArray& insert (const NDArray& a, octave_idx_type r, octave_idx_type c); FloatComplexNDArray& insert (const FloatComplexNDArray& a, octave_idx_type r, octave_idx_type c); FloatComplexNDArray& insert (const FloatComplexNDArray& a, const Array<octave_idx_type>& ra_idx);
--- a/liboctave/fNDArray.cc +++ b/liboctave/fNDArray.cc @@ -709,6 +709,30 @@ } FloatNDArray +FloatNDArray::cummax (int dim) const +{ + return do_mx_cumminmax_op<FloatNDArray> (*this, dim, mx_inline_cummax); +} + +FloatNDArray +FloatNDArray::cummax (ArrayN<octave_idx_type>& idx_arg, int dim) const +{ + return do_mx_cumminmax_op<FloatNDArray> (*this, idx_arg, dim, mx_inline_cummax); +} + +FloatNDArray +FloatNDArray::cummin (int dim) const +{ + return do_mx_cumminmax_op<FloatNDArray> (*this, dim, mx_inline_cummin); +} + +FloatNDArray +FloatNDArray::cummin (ArrayN<octave_idx_type>& idx_arg, int dim) const +{ + return do_mx_cumminmax_op<FloatNDArray> (*this, idx_arg, dim, mx_inline_cummin); +} + +FloatNDArray FloatNDArray::concat (const FloatNDArray& rb, const Array<octave_idx_type>& ra_idx) { if (rb.numel () > 0)
--- a/liboctave/fNDArray.h +++ b/liboctave/fNDArray.h @@ -94,6 +94,11 @@ FloatNDArray min (int dim = 0) const; FloatNDArray min (ArrayN<octave_idx_type>& index, int dim = 0) const; + FloatNDArray cummax (int dim = 0) const; + FloatNDArray cummax (ArrayN<octave_idx_type>& index, int dim = 0) const; + FloatNDArray cummin (int dim = 0) const; + FloatNDArray cummin (ArrayN<octave_idx_type>& index, int dim = 0) const; + FloatNDArray& insert (const FloatNDArray& a, octave_idx_type r, octave_idx_type c); FloatNDArray& insert (const FloatNDArray& a, const Array<octave_idx_type>& ra_idx);
--- a/liboctave/intNDArray.cc +++ b/liboctave/intNDArray.cc @@ -237,6 +237,34 @@ return do_mx_minmax_op<intNDArray<T> > (*this, idx_arg, dim, mx_inline_min); } +template <class T> +intNDArray<T> +intNDArray<T>::cummax (int dim) const +{ + return do_mx_cumminmax_op<intNDArray<T> > (*this, dim, mx_inline_cummax); +} + +template <class T> +intNDArray<T> +intNDArray<T>::cummax (ArrayN<octave_idx_type>& idx_arg, int dim) const +{ + return do_mx_cumminmax_op<intNDArray<T> > (*this, idx_arg, dim, mx_inline_cummax); +} + +template <class T> +intNDArray<T> +intNDArray<T>::cummin (int dim) const +{ + return do_mx_cumminmax_op<intNDArray<T> > (*this, dim, mx_inline_cummin); +} + +template <class T> +intNDArray<T> +intNDArray<T>::cummin (ArrayN<octave_idx_type>& idx_arg, int dim) const +{ + return do_mx_cumminmax_op<intNDArray<T> > (*this, idx_arg, dim, mx_inline_cummin); +} + /* ;;; Local Variables: *** ;;; mode: C++ ***
--- a/liboctave/intNDArray.h +++ b/liboctave/intNDArray.h @@ -78,6 +78,11 @@ intNDArray min (int dim = 0) const; intNDArray min (ArrayN<octave_idx_type>& index, int dim = 0) const; + intNDArray cummax (int dim = 0) const; + intNDArray cummax (ArrayN<octave_idx_type>& index, int dim = 0) const; + intNDArray cummin (int dim = 0) const; + intNDArray cummin (ArrayN<octave_idx_type>& index, int dim = 0) const; + intNDArray sum (int dim) const; intNDArray abs (void) const;
--- a/liboctave/mx-inlines.cc +++ b/liboctave/mx-inlines.cc @@ -2,6 +2,8 @@ Copyright (C) 1993, 1994, 1995, 1996, 1997, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 John W. Eaton +Copyright (C) 2009 Jaroslav Hajek +Copyright (C) 2009 VZLU Prague This file is part of Octave. @@ -656,6 +658,186 @@ OP_MINMAX_FCNN (mx_inline_min) OP_MINMAX_FCNN (mx_inline_max) +#define OP_CUMMINMAX_FCN(F, OP) \ +template <class T> \ +void F (const T *v, T *r, octave_idx_type n) \ +{ \ + if (! n) return; \ + T tmp = v[0]; \ + octave_idx_type i = 1, j = 0; \ + if (xisnan (tmp)) \ + { \ + for (; i < n && xisnan (v[i]); i++) ; \ + for (; j < i; j++) r[j] = tmp; \ + if (i < n) tmp = v[i]; \ + } \ + for (; i < n; i++) \ + if (v[i] OP tmp) \ + { \ + for (; j < i; j++) r[j] = tmp; \ + tmp = v[i]; \ + } \ + for (; j < i; j++) r[j] = tmp; \ +} \ +template <class T> \ +void F (const T *v, T *r, octave_idx_type *ri, octave_idx_type n) \ +{ \ + if (! n) return; \ + T tmp = v[0]; octave_idx_type tmpi = 0; \ + octave_idx_type i = 1, j = 0; \ + if (xisnan (tmp)) \ + { \ + for (; i < n && xisnan (v[i]); i++) ; \ + for (; j < i; j++) { r[j] = tmp; ri[j] = tmpi; } \ + if (i < n) { tmp = v[i]; tmpi = i; } \ + } \ + for (; i < n; i++) \ + if (v[i] OP tmp) \ + { \ + for (; j < i; j++) { r[j] = tmp; ri[j] = tmpi; } \ + tmp = v[i]; tmpi = i; \ + } \ + for (; j < i; j++) { r[j] = tmp; ri[j] = tmpi; } \ +} + +OP_CUMMINMAX_FCN (mx_inline_cummin, <) +OP_CUMMINMAX_FCN (mx_inline_cummax, >) + +// Row reductions will be slightly complicated. We will proceed with checks +// for NaNs until we detect that no row will yield a NaN, in which case we +// proceed to a faster code. + +#define OP_CUMMINMAX_FCN2(F, OP) \ +template <class T> \ +inline void \ +F (const T *v, T *r, octave_idx_type m, octave_idx_type n) \ +{ \ + if (! n) return; \ + bool nan = false; \ + const T *r0; \ + octave_idx_type j = 0; \ + for (octave_idx_type i = 0; i < m; i++) \ + { \ + r[i] = v[i]; \ + if (xisnan (v[i])) nan = true; \ + } \ + j++; v += m; r0 = r; r += m; \ + while (nan && j < n) \ + { \ + nan = false; \ + for (octave_idx_type i = 0; i < m; i++) \ + { \ + if (xisnan (v[i])) \ + { r[i] = r0[i]; nan = true; } \ + else if (xisnan (r[i]) || v[i] OP r[i]) \ + r[i] = v[i]; \ + } \ + j++; v += m; r0 = r; r += m; \ + } \ + while (j < n) \ + { \ + for (octave_idx_type i = 0; i < m; i++) \ + if (v[i] OP r[i]) \ + r[i] = v[i]; \ + else \ + r[i] = r0[i]; \ + j++; v += m; r0 = r; r += m; \ + } \ +} \ +template <class T> \ +inline void \ +F (const T *v, T *r, octave_idx_type *ri, \ + octave_idx_type m, octave_idx_type n) \ +{ \ + if (! n) return; \ + bool nan = false; \ + const T *r0; const octave_idx_type *r0i; \ + octave_idx_type j = 0; \ + for (octave_idx_type i = 0; i < m; i++) \ + { \ + r[i] = v[i]; ri[i] = 0; \ + if (xisnan (v[i])) nan = true; \ + } \ + j++; v += m; r0 = r; r += m; r0i = ri; ri += m; \ + while (nan && j < n) \ + { \ + nan = false; \ + for (octave_idx_type i = 0; i < m; i++) \ + { \ + if (xisnan (v[i])) \ + { r[i] = r0[i]; ri[i] = r0i[i]; nan = true; } \ + else if (xisnan (r[i]) || v[i] OP r[i]) \ + { r[i] = v[i]; ri[i] = j; }\ + } \ + j++; v += m; r0 = r; r += m; r0i = ri; ri += m; \ + } \ + while (j < n) \ + { \ + for (octave_idx_type i = 0; i < m; i++) \ + if (v[i] OP r[i]) \ + { r[i] = v[i]; ri[i] = j; } \ + else \ + { r[i] = r0[i]; ri[i] = r0i[i]; } \ + j++; v += m; r0 = r; r += m; r0i = ri; ri += m; \ + } \ +} + +OP_CUMMINMAX_FCN2 (mx_inline_cummin, <) +OP_CUMMINMAX_FCN2 (mx_inline_cummax, >) + +#define OP_CUMMINMAX_FCNN(F) \ +template <class T> \ +inline void \ +F (const T *v, T *r, octave_idx_type l, \ + octave_idx_type n, octave_idx_type u) \ +{ \ + if (! n) return; \ + if (l == 1) \ + { \ + for (octave_idx_type i = 0; i < u; i++) \ + { \ + F (v, r, n); \ + v += n; r += n; \ + } \ + } \ + else \ + { \ + for (octave_idx_type i = 0; i < u; i++) \ + { \ + F (v, r, l, n); \ + v += l*n; \ + r += l*n; \ + } \ + } \ +} \ +template <class T> \ +inline void \ +F (const T *v, T *r, octave_idx_type *ri, \ + octave_idx_type l, octave_idx_type n, octave_idx_type u) \ +{ \ + if (! n) return; \ + if (l == 1) \ + { \ + for (octave_idx_type i = 0; i < u; i++) \ + { \ + F (v, r, ri, n); \ + v += n; r += n; ri += n; \ + } \ + } \ + else \ + { \ + for (octave_idx_type i = 0; i < u; i++) \ + { \ + F (v, r, ri, l, n); \ + v += l*n; \ + r += l*n; ri += l*n; \ + } \ + } \ +} + +OP_CUMMINMAX_FCNN (mx_inline_cummin) +OP_CUMMINMAX_FCNN (mx_inline_cummax) + // Assistant function inline void @@ -777,6 +959,44 @@ return ret; } +template <class ArrayType> +inline ArrayType +do_mx_cumminmax_op (const ArrayType& src, int dim, + void (*mx_cumminmax_op) (const typename ArrayType::element_type *, + typename ArrayType::element_type *, + octave_idx_type, octave_idx_type, octave_idx_type)) +{ + octave_idx_type l, n, u; + dim_vector dims = src.dims (); + get_extent_triplet (dims, dim, l, n, u); + + ArrayType ret (dims); + mx_cumminmax_op (src.data (), ret.fortran_vec (), l, n, u); + + return ret; +} + +template <class ArrayType> +inline ArrayType +do_mx_cumminmax_op (const ArrayType& src, Array<octave_idx_type>& idx, int dim, + void (*mx_cumminmax_op) (const typename ArrayType::element_type *, + typename ArrayType::element_type *, + octave_idx_type *, + octave_idx_type, octave_idx_type, octave_idx_type)) +{ + octave_idx_type l, n, u; + dim_vector dims = src.dims (); + get_extent_triplet (dims, dim, l, n, u); + + ArrayType ret (dims); + if (idx.dims () != dims) idx = Array<octave_idx_type> (dims); + + mx_cumminmax_op (src.data (), ret.fortran_vec (), idx.fortran_vec (), + l, n, u); + + return ret; +} + #endif /*
--- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,14 @@ +2009-02-17 Jaroslav Hajek <highegg@gmail.com> + + * DLD-FUNCTIONS/max.cc (MINMAX_DOUBLE_SBODY): New macro. + (MINMAX_DOUBLE_BODY): Move part of code to MINMAX_DOUBLE_SBODY. + (MINMAX_SINGLE_SBODY): New macro. + (MINMAX_SINGLE_BODY): Move part of code to MINMAX_DOUBLE_SBODY. + (MINMAX_INT_SBODY): New macro. + (MINMAX_INT_BODY): Move part of code to MINMAX_DOUBLE_SBODY. + (CUMMINMAX_BODY): New macro. + (Fcummin, Fcummax): New DLD functions. + 2009-02-17 John W. Eaton <jwe@octave.org> * octave.gperf: Eliminate whitespace to allow gperf 2.7.2 to work.
--- a/src/DLD-FUNCTIONS/max.cc +++ b/src/DLD-FUNCTIONS/max.cc @@ -2,6 +2,7 @@ Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 John W. Eaton +Copyright (C) 2009 VZLU Prague This file is part of Octave. @@ -41,11 +42,9 @@ #include "ov-re-sparse.h" #include "ov-cx-sparse.h" -#define MINMAX_DOUBLE_BODY(FCN) \ +#define MINMAX_DOUBLE_SBODY(FCN) \ { \ - bool single_arg = (nargin == 1) || (arg2.is_empty() && nargin == 3); \ - \ - if (single_arg && (nargout == 1 || nargout == 0)) \ + if (nargout == 1 || nargout == 0) \ { \ if (arg1.is_real_type ()) \ { \ @@ -70,7 +69,7 @@ else \ gripe_wrong_type_arg (#FCN, arg1); \ } \ - else if (single_arg && nargout == 2) \ + else if (nargout == 2) \ { \ ArrayN<octave_idx_type> index; \ \ @@ -104,6 +103,13 @@ else \ retval(1) = NDArray (); \ } \ +} + +#define MINMAX_DOUBLE_BODY(FCN) \ +{ \ + bool single_arg = (nargin == 1) || (arg2.is_empty() && nargin == 3); \ + if (single_arg) \ + MINMAX_DOUBLE_SBODY (FCN) \ else \ { \ int arg1_is_scalar = arg1.is_scalar_type (); \ @@ -203,11 +209,9 @@ } \ } -#define MINMAX_SINGLE_BODY(FCN) \ +#define MINMAX_SINGLE_SBODY(FCN) \ { \ - bool single_arg = (nargin == 1) || (arg2.is_empty() && nargin == 3); \ - \ - if (single_arg && (nargout == 1 || nargout == 0)) \ + if (nargout == 1 || nargout == 0) \ { \ if (arg1.is_real_type ()) \ { \ @@ -232,7 +236,7 @@ else \ gripe_wrong_type_arg (#FCN, arg1); \ } \ - else if (single_arg && nargout == 2) \ + else if (nargout == 2) \ { \ ArrayN<octave_idx_type> index; \ \ @@ -266,6 +270,13 @@ else \ retval(1) = NDArray (); \ } \ +} + +#define MINMAX_SINGLE_BODY(FCN) \ +{ \ + bool single_arg = (nargin == 1) || (arg2.is_empty() && nargin == 3); \ + if (single_arg) \ + MINMAX_SINGLE_SBODY(FCN) \ else \ { \ int arg1_is_scalar = arg1.is_scalar_type (); \ @@ -365,12 +376,9 @@ } \ } - -#define MINMAX_INT_BODY(FCN, TYP) \ - { \ - bool single_arg = (nargin == 1) || (arg2.is_empty() && nargin == 3); \ - \ - if (single_arg && (nargout == 1 || nargout == 0)) \ +#define MINMAX_INT_SBODY(FCN, TYP) \ +{ \ + if (nargout == 1 || nargout == 0) \ { \ TYP ## NDArray m = arg1. TYP ## _array_value (); \ \ @@ -380,7 +388,7 @@ retval(0) = n; \ } \ } \ - else if (single_arg && nargout == 2) \ + else if (nargout == 2) \ { \ ArrayN<octave_idx_type> index; \ \ @@ -399,6 +407,13 @@ else \ retval(1) = NDArray (); \ } \ +} + +#define MINMAX_INT_BODY(FCN, TYP) \ + { \ + bool single_arg = (nargin == 1) || (arg2.is_empty() && nargin == 3); \ + if (single_arg) \ + MINMAX_INT_SBODY (FCN, TYP) \ else \ { \ int arg1_is_scalar = arg1.is_scalar_type (); \ @@ -818,6 +833,128 @@ */ +#define CUMMINMAX_BODY(FCN) \ + \ + octave_value_list retval; \ + \ + int nargin = args.length (); \ + \ + if (nargin < 1 || nargin > 2 || nargout > 2) \ + { \ + print_usage (); \ + return retval; \ + } \ + \ + octave_value arg1; \ + octave_value arg2; \ + \ + switch (nargin) \ + { \ + case 2: \ + arg2 = args(1); \ + \ + case 1: \ + arg1 = args(0); \ + break; \ + \ + default: \ + panic_impossible (); \ + break; \ + } \ + \ + dim_vector dv = arg1.dims (); \ + if (error_state) \ + { \ + gripe_wrong_type_arg (#FCN, arg1); \ + return retval; \ + } \ + \ + int dim = 0; \ + while ((dim < dv.length ()) && (dv (dim) <= 1)) \ + dim++; \ + if (dim == dv.length ()) \ + dim = 0; \ + \ + if (arg1.is_integer_type ()) \ + { \ + if (arg1.is_uint8_type ()) \ + MINMAX_INT_SBODY (FCN, uint8) \ + else if (arg1.is_uint16_type ()) \ + MINMAX_INT_SBODY (FCN, uint16) \ + else if (arg1.is_uint32_type ()) \ + MINMAX_INT_SBODY (FCN, uint32) \ + else if (arg1.is_uint64_type ()) \ + MINMAX_INT_SBODY (FCN, uint64) \ + else if (arg1.is_int8_type ()) \ + MINMAX_INT_SBODY (FCN, int8) \ + else if (arg1.is_int16_type ()) \ + MINMAX_INT_SBODY (FCN, int16) \ + else if (arg1.is_int32_type ()) \ + MINMAX_INT_SBODY (FCN, int32) \ + else if (arg1.is_int64_type ()) \ + MINMAX_INT_SBODY (FCN, int64) \ + } \ + else if (arg1.is_single_type ()) \ + MINMAX_SINGLE_SBODY (FCN) \ + else \ + MINMAX_DOUBLE_SBODY (FCN) \ + \ + return retval; + +DEFUN_DLD (cummin, args, nargout, + "-*- texinfo -*-\n\ +@deftypefn {Mapping Function} {} cummin (@var{x}, @var{dim})\n\ +@deftypefnx {Mapping Function} {[@var{w}, @var{iw}] =} cummin (@var{x})\n\ +@cindex Utility Functions\n\ +Return the cumulative minimum values. That means, the call\n\ +@example\n\ + [@var{w}, @var{iw}] = cummin (@var{x}, @var{dim})}\n\ +@end example\n\ +\n\ +@noindent\n\ +is equivalent to the following code:\n\ +@example\n\ + for i = 1:size (x, dim)\n\ + [w(i), iw(i)] = min(x(:,@dots{},i,:,@dots{}), dim);\n\ + endfor\n\ +@end example\n\ +\n\ +@noindent\n\ +but computed in a much faster manner.\n\ +The behaviour if @var{dim} or @var{iw} is unspecified is analogous\n\ +to @code{min}.\n\ +@end deftypefn") +{ + CUMMINMAX_BODY (cummin); +} + +DEFUN_DLD (cummax, args, nargout, + "-*- texinfo -*-\n\ +@deftypefn {Mapping Function} {} cummax (@var{x}, @var{dim})\n\ +@deftypefnx {Mapping Function} {[@var{w}, @var{iw}] =} cummax (@var{x})\n\ +@cindex Utility Functions\n\ +Return the cumulative maximum values. That means, the call\n\ +@example\n\ + [@var{w}, @var{iw}] = cummax (@var{x}, @var{dim})}\n\ +@end example\n\ +\n\ +@noindent\n\ +is equivalent to the following code:\n\ +@example\n\ + for i = 1:size (x, dim)\n\ + [w(i), iw(i)] = max(x(:,@dots{},i,:,@dots{}), dim);\n\ + endfor\n\ +@end example\n\ +\n\ +@noindent\n\ +but computed in a much faster manner.\n\ +The behaviour if @var{dim} or @var{iw} is unspecified is analogous\n\ +to @code{max}.\n\ +@end deftypefn") +{ + CUMMINMAX_BODY (cummax); +} + /* ;;; Local Variables: *** ;;; mode: C++ ***