# HG changeset patch # User Jaroslav Hajek # Date 1234877015 -3600 # Node ID ea76466605ba11928f80745b0a58a60b5ea2dbf4 # Parent 949708f930d04c0fbc8236e0e9f937eab2058906 support native cumsum, gripe on overflow in sum/cumsum diff --git a/liboctave/ChangeLog b/liboctave/ChangeLog --- a/liboctave/ChangeLog +++ b/liboctave/ChangeLog @@ -1,3 +1,13 @@ +2009-02-17 Jaroslav Hajek + + * mx-inlines.cc (OP_CUM_FCN, OP_CUM_FCN2, OP_CUM_FCNN): + Add TSRC/TRES parameters. + (mx_inline_cumcount): New function. + * intNDArray.cc (intNDArray::cumsum): New method. + * intNDArray.h: Declare it. + * boolNDArray.cc (boolNDArray::cumsum): New method. + * boolNDArray.h: Declare it. + 2009-02-17 Jaroslav Hajek * mx-inlines.cc (OP_CUMMINMAX_FCN, OP_CUMMINMAX_FCN2, diff --git a/liboctave/boolNDArray.cc b/liboctave/boolNDArray.cc --- a/liboctave/boolNDArray.cc +++ b/liboctave/boolNDArray.cc @@ -65,6 +65,13 @@ return do_mx_red_op > (*this, dim, mx_inline_count); } +NDArray +boolNDArray::cumsum (int dim) const +{ + // NOTE: going via octave_idx_type is faster even though it requires a conversion. + return do_mx_cum_op > (*this, dim, mx_inline_cumcount); +} + boolNDArray boolNDArray::concat (const boolNDArray& rb, const Array& ra_idx) { diff --git a/liboctave/boolNDArray.h b/liboctave/boolNDArray.h --- a/liboctave/boolNDArray.h +++ b/liboctave/boolNDArray.h @@ -67,6 +67,7 @@ boolNDArray any (int dim = -1) const; NDArray sum (int dim = -1) const; + NDArray cumsum (int dim = -1) const; boolNDArray concat (const boolNDArray& rb, const Array& ra_idx); diff --git a/liboctave/intNDArray.cc b/liboctave/intNDArray.cc --- a/liboctave/intNDArray.cc +++ b/liboctave/intNDArray.cc @@ -211,6 +211,13 @@ template intNDArray +intNDArray::cumsum (int dim) const +{ + return do_mx_cum_op > (*this, dim, mx_inline_cumsum); +} + +template +intNDArray intNDArray::max (int dim) const { return do_mx_minmax_op > (*this, dim, mx_inline_max); diff --git a/liboctave/intNDArray.h b/liboctave/intNDArray.h --- a/liboctave/intNDArray.h +++ b/liboctave/intNDArray.h @@ -84,6 +84,7 @@ intNDArray cummin (ArrayN& index, int dim = 0) const; intNDArray sum (int dim) const; + intNDArray cumsum (int dim) const; intNDArray abs (void) const; intNDArray signum (void) const; diff --git a/liboctave/mx-inlines.cc b/liboctave/mx-inlines.cc --- a/liboctave/mx-inlines.cc +++ b/liboctave/mx-inlines.cc @@ -426,26 +426,27 @@ OP_RED_FCNN (mx_inline_any, T, bool) OP_RED_FCNN (mx_inline_all, T, bool) -#define OP_CUM_FCN(F, OP) \ +#define OP_CUM_FCN(F, TSRC, TRES, OP) \ template \ inline void \ -F (const T *v, T *r, octave_idx_type n) \ +F (const TSRC *v, TRES *r, octave_idx_type n) \ { \ if (n) \ { \ - T t = r[0] = v[0]; \ + TRES t = r[0] = v[0]; \ for (octave_idx_type i = 1; i < n; i++) \ r[i] = t = t OP v[i]; \ } \ } -OP_CUM_FCN (mx_inline_cumsum, +) -OP_CUM_FCN (mx_inline_cumprod, *) +OP_CUM_FCN (mx_inline_cumsum, T, T, +) +OP_CUM_FCN (mx_inline_cumprod, T, T, *) +OP_CUM_FCN (mx_inline_cumcount, bool, T, +) -#define OP_CUM_FCN2(F, OP) \ +#define OP_CUM_FCN2(F, TSRC, TRES, OP) \ template \ inline void \ -F (const T *v, T *r, octave_idx_type m, octave_idx_type n) \ +F (const TSRC *v, TRES *r, octave_idx_type m, octave_idx_type n) \ { \ if (n) \ { \ @@ -456,19 +457,20 @@ { \ r += m; v += m; \ for (octave_idx_type i = 0; i < m; i++) \ - r[i] = v[i] OP r0[i]; \ + r[i] = r0[i] OP v[i]; \ r0 += m; \ } \ } \ } -OP_CUM_FCN2 (mx_inline_cumsum, +) -OP_CUM_FCN2 (mx_inline_cumprod, *) +OP_CUM_FCN2 (mx_inline_cumsum, T, T, +) +OP_CUM_FCN2 (mx_inline_cumprod, T, T, *) +OP_CUM_FCN2 (mx_inline_cumcount, bool, T, *) -#define OP_CUM_FCNN(F) \ +#define OP_CUM_FCNN(F, TSRC, TRES) \ template \ inline void \ -F (const T *v, T *r, octave_idx_type l, \ +F (const TSRC *v, TRES *r, octave_idx_type l, \ octave_idx_type n, octave_idx_type u) \ { \ if (l == 1) \ @@ -490,8 +492,9 @@ } \ } -OP_CUM_FCNN (mx_inline_cumsum) -OP_CUM_FCNN (mx_inline_cumprod) +OP_CUM_FCNN (mx_inline_cumsum, T, T) +OP_CUM_FCNN (mx_inline_cumprod, T, T) +OP_CUM_FCNN (mx_inline_cumcount, bool, T) #define OP_MINMAX_FCN(F, OP) \ template \ diff --git a/src/ChangeLog b/src/ChangeLog --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,11 @@ +2009-02-17 Jaroslav Hajek + + * DLD-FUNCTIONS/data.cc (NATIVE_REDUCTION): Add BOOL_FCN argument. + (NATIVE_REDUCTION_1): Check integer overflow flags and possibly gripe. + (Fsum): Reflect change. + (Fcumsum): USE NATIVE_REDUCTION. + * gripes.cc (gripe_native_integer_math_truncated): New function. + 2009-02-17 Jaroslav Hajek * DLD-FUNCTIONS/max.cc (Fcummin, Fcummax): Improve inline docs. diff --git a/src/DLD-FUNCTIONS/max.cc b/src/DLD-FUNCTIONS/max.cc --- a/src/DLD-FUNCTIONS/max.cc +++ b/src/DLD-FUNCTIONS/max.cc @@ -686,8 +686,8 @@ DEFUN_DLD (min, args, nargout, "-*- texinfo -*-\n\ -@deftypefn {Mapping Function} {} min (@var{x}, @var{y}, @var{dim})\n\ -@deftypefnx {Mapping Function} {[@var{w}, @var{iw}] =} min (@var{x})\n\ +@deftypefn {Loadable Function} {} min (@var{x}, @var{y}, @var{dim})\n\ +@deftypefnx {Loadable Function} {[@var{w}, @var{iw}] =} min (@var{x})\n\ @cindex Utility Functions\n\ For a vector argument, return the minimum value. For a matrix\n\ argument, return the minimum value from each column, as a row\n\ @@ -760,8 +760,8 @@ DEFUN_DLD (max, args, nargout, "-*- texinfo -*-\n\ -@deftypefn {Mapping Function} {} max (@var{x}, @var{y}, @var{dim})\n\ -@deftypefnx {Mapping Function} {[@var{w}, @var{iw}] =} max (@var{x})\n\ +@deftypefn {Loadable Function} {} max (@var{x}, @var{y}, @var{dim})\n\ +@deftypefnx {Loadable Function} {[@var{w}, @var{iw}] =} max (@var{x})\n\ @cindex Utility Functions\n\ For a vector argument, return the maximum value. For a matrix\n\ argument, return the maximum value from each column, as a row\n\ @@ -903,8 +903,8 @@ 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\ +@deftypefn {Loadable Function} {} cummin (@var{x}, @var{dim})\n\ +@deftypefnx {Loadable 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\ @@ -915,8 +915,8 @@ is equivalent to the following code:\n\ @example\n\ for i = 1:size (x, dim)\n\ - [@var{w}(:,@dots{},i:,@dots{},), @var{iw}(:,@dots{},i:,@dots{},)] =\ - min(@var{x}(:,@dots{},i,:,@dots{}), @var{dim});\n\ + [@var{w}(:,@dots{},i,:,@dots{}), @var{iw}(:,@dots{},i,:,@dots{})] =\ + min(@var{x}(:,@dots{},1:i,:,@dots{}), @var{dim});\n\ endfor\n\ @end example\n\ \n\ @@ -931,8 +931,8 @@ 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\ +@deftypefn {Loadable Function} {} cummax (@var{x}, @var{dim})\n\ +@deftypefnx {Loadable 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\ @@ -943,8 +943,8 @@ is equivalent to the following code:\n\ @example\n\ for i = 1:size (x, dim)\n\ - [@var{w}(:,@dots{},i:,@dots{},), @var{iw}(:,@dots{},i:,@dots{},)] =\ - max(@var{x}(:,@dots{},i,:,@dots{}), @var{dim});\n\ + [@var{w}(:,@dots{},i,:,@dots{}), @var{iw}(:,@dots{},i,:,@dots{})] =\ + max(@var{x}(:,@dots{},1:i,:,@dots{}), @var{dim});\n\ endfor\n\ @end example\n\ \n\ diff --git a/src/data.cc b/src/data.cc --- a/src/data.cc +++ b/src/data.cc @@ -1268,10 +1268,19 @@ TYPE ## NDArray tmp = arg. TYPE ##_array_value (); \ \ if (! error_state) \ - retval = tmp.FCN (DIM); \ + { \ + octave_ ## TYPE::clear_conv_flags (); \ + retval = tmp.FCN (DIM); \ + if (octave_ ## TYPE::get_trunc_flag ()) \ + { \ + gripe_native_integer_math_truncated (#FCN, \ + octave_ ## TYPE::type_name ()); \ + octave_ ## TYPE::clear_conv_flags (); \ + } \ + } \ } -#define NATIVE_REDUCTION(FCN) \ +#define NATIVE_REDUCTION(FCN, BOOL_FCN) \ \ octave_value retval; \ \ @@ -1337,11 +1346,10 @@ else if NATIVE_REDUCTION_1 (FCN, int64, dim) \ else if (arg.is_bool_type ()) \ { \ - boolNDArray tmp = arg. bool_array_value (); \ + boolNDArray tmp = arg.bool_array_value (); \ if (! error_state) \ - retval = tmp.any (dim); \ + retval = boolNDArray (tmp.BOOL_FCN (dim)); \ } \ - \ else if (arg.is_char_matrix ()) \ { \ error (#FCN, ": invalid char type"); \ @@ -1558,15 +1566,19 @@ DEFUN (cumsum, args, , "-*- texinfo -*-\n\ @deftypefn {Built-in Function} {} cumsum (@var{x}, @var{dim})\n\ +@deftypefnx {Built-in Function} {} cumsum (@dots{}, 'native')\n\ Cumulative sum of elements along dimension @var{dim}. If @var{dim}\n\ is omitted, it defaults to 1 (column-wise cumulative sums).\n\ \n\ As a special case, if @var{x} is a vector and @var{dim} is omitted,\n\ return the cumulative sum of the elements as a vector with the\n\ same orientation as @var{x}.\n\ +\n\ +The \"native\" argument implies the summation is performed in native type,\n\ +analogously to @code{sum}.\n\ @end deftypefn") { - DATA_REDUCTION (cumsum); + NATIVE_REDUCTION (cumsum, cumsum); } /* @@ -2549,7 +2561,7 @@ @end example\n\ @end deftypefn") { - NATIVE_REDUCTION (sum); + NATIVE_REDUCTION (sum, any); } /* diff --git a/src/gripes.cc b/src/gripes.cc --- a/src/gripes.cc +++ b/src/gripes.cc @@ -221,6 +221,14 @@ } void +gripe_native_integer_math_truncated (const char *fcn, const char *type) +{ + warning_with_id ("Octave:int-math-overflow", + "data truncated for %s native %s operation", + type, fcn); +} + +void gripe_unop_integer_math_truncated (const char* op, const char *type) { warning_with_id ("Octave:int-math-overflow", diff --git a/src/gripes.h b/src/gripes.h --- a/src/gripes.h +++ b/src/gripes.h @@ -114,6 +114,9 @@ gripe_binop_integer_math_truncated (const char *op, const char *type1, const char *type2); extern OCTINTERP_API void +gripe_native_integer_math_truncated (const char *fcn, const char *type); + +extern OCTINTERP_API void gripe_unop_integer_math_truncated (const char *op, const char *type); extern OCTINTERP_API void