changeset 8780:ea76466605ba

support native cumsum, gripe on overflow in sum/cumsum
author Jaroslav Hajek <highegg@gmail.com>
date Tue, 17 Feb 2009 14:23:35 +0100
parents 949708f930d0
children f57c9fdb6836
files liboctave/ChangeLog liboctave/boolNDArray.cc liboctave/boolNDArray.h liboctave/intNDArray.cc liboctave/intNDArray.h liboctave/mx-inlines.cc src/ChangeLog src/DLD-FUNCTIONS/max.cc src/data.cc src/gripes.cc src/gripes.h
diffstat 11 files changed, 93 insertions(+), 33 deletions(-) [+]
line wrap: on
line diff
--- a/liboctave/ChangeLog	Tue Feb 17 12:52:13 2009 +0100
+++ b/liboctave/ChangeLog	Tue Feb 17 14:23:35 2009 +0100
@@ -1,3 +1,13 @@
+2009-02-17  Jaroslav Hajek  <highegg@gmail.com>
+
+	* 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  <highegg@gmail.com>
 
 	* mx-inlines.cc (OP_CUMMINMAX_FCN, OP_CUMMINMAX_FCN2,
--- a/liboctave/boolNDArray.cc	Tue Feb 17 12:52:13 2009 +0100
+++ b/liboctave/boolNDArray.cc	Tue Feb 17 14:23:35 2009 +0100
@@ -65,6 +65,13 @@
   return do_mx_red_op<Array<octave_idx_type> > (*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<Array<octave_idx_type> > (*this, dim, mx_inline_cumcount);
+}
+
 boolNDArray
 boolNDArray::concat (const boolNDArray& rb, const Array<octave_idx_type>& ra_idx)
 {
--- a/liboctave/boolNDArray.h	Tue Feb 17 12:52:13 2009 +0100
+++ b/liboctave/boolNDArray.h	Tue Feb 17 14:23:35 2009 +0100
@@ -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<octave_idx_type>& ra_idx);
 
--- a/liboctave/intNDArray.cc	Tue Feb 17 12:52:13 2009 +0100
+++ b/liboctave/intNDArray.cc	Tue Feb 17 14:23:35 2009 +0100
@@ -211,6 +211,13 @@
 
 template <class T>
 intNDArray<T>
+intNDArray<T>::cumsum (int dim) const
+{
+  return do_mx_cum_op<intNDArray<T> > (*this, dim, mx_inline_cumsum);
+}
+
+template <class T>
+intNDArray<T>
 intNDArray<T>::max (int dim) const
 {
   return do_mx_minmax_op<intNDArray<T> > (*this, dim, mx_inline_max);
--- a/liboctave/intNDArray.h	Tue Feb 17 12:52:13 2009 +0100
+++ b/liboctave/intNDArray.h	Tue Feb 17 14:23:35 2009 +0100
@@ -84,6 +84,7 @@
   intNDArray cummin (ArrayN<octave_idx_type>& index, int dim = 0) const;
   
   intNDArray sum (int dim) const;
+  intNDArray cumsum (int dim) const;
 
   intNDArray abs (void) const;
   intNDArray signum (void) const;
--- a/liboctave/mx-inlines.cc	Tue Feb 17 12:52:13 2009 +0100
+++ b/liboctave/mx-inlines.cc	Tue Feb 17 14:23:35 2009 +0100
@@ -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 <class T> \
 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 <class T> \
 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 <class T> \
 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 <class T> \
--- a/src/ChangeLog	Tue Feb 17 12:52:13 2009 +0100
+++ b/src/ChangeLog	Tue Feb 17 14:23:35 2009 +0100
@@ -1,3 +1,11 @@
+2009-02-17  Jaroslav Hajek  <highegg@gmail.com>
+
+	* 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  <highegg@gmail.com>
 
 	* DLD-FUNCTIONS/max.cc (Fcummin, Fcummax): Improve inline docs.
--- a/src/DLD-FUNCTIONS/max.cc	Tue Feb 17 12:52:13 2009 +0100
+++ b/src/DLD-FUNCTIONS/max.cc	Tue Feb 17 14:23:35 2009 +0100
@@ -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\
--- a/src/data.cc	Tue Feb 17 12:52:13 2009 +0100
+++ b/src/data.cc	Tue Feb 17 14:23:35 2009 +0100
@@ -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);
 }
 
 /*
--- a/src/gripes.cc	Tue Feb 17 12:52:13 2009 +0100
+++ b/src/gripes.cc	Tue Feb 17 14:23:35 2009 +0100
@@ -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",
--- a/src/gripes.h	Tue Feb 17 12:52:13 2009 +0100
+++ b/src/gripes.h	Tue Feb 17 14:23:35 2009 +0100
@@ -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