tor, 30 10 2008 kl. 19:08 -0400, skrev Dave Goel:
> > Yeah, I can't come up with anything of the top of my head. But I'll make
> > you a deal. If you write an m-file version using for-loops, that handle
> > the N-dimensional case, then I'll re-implement it in C++.
> 
> I am including here an m-version, tested, and also attaching it.  But,
> really, I stand by my last post.  Why re-implement the wheel?  We
> should simply use the exact same logic and facilities used by
> tmpcumsum.

Yeah, it seems better to extend the current code. It is, however, not
trivial. The attached patch (against development sources, but it might
work with 3.0.x as well -- I don't know) adds support for 'cummin' and
'cummax' by extending the current code. It should be noted that

  * It doesn't work with sparse matrices. The code just adds some
    placeholder code, that's just too ugly to be pushed upstream.

  * For complex matrices, absolute values are compared.

Søren
diff --git a/liboctave/CMatrix.cc b/liboctave/CMatrix.cc
--- a/liboctave/CMatrix.cc
+++ b/liboctave/CMatrix.cc
@@ -3439,13 +3439,25 @@
 ComplexMatrix
 ComplexMatrix::cumprod (int dim) const
 {
-  MX_CUMULATIVE_OP (ComplexMatrix, Complex, *=);
+  MX_CUMULATIVE_FUN (ComplexMatrix, Complex, PROD);
 }
 
 ComplexMatrix
 ComplexMatrix::cumsum (int dim) const
 {
-  MX_CUMULATIVE_OP (ComplexMatrix, Complex, +=);
+  MX_CUMULATIVE_FUN (ComplexMatrix, Complex, PLUS);
+}
+
+ComplexMatrix
+ComplexMatrix::cummin (int dim) const
+{
+  MX_CUMULATIVE_FUN (ComplexMatrix, Complex, complex_min);
+}
+
+ComplexMatrix
+ComplexMatrix::cummax (int dim) const
+{
+  MX_CUMULATIVE_FUN (ComplexMatrix, Complex, complex_max);
 }
 
 ComplexMatrix
diff --git a/liboctave/CMatrix.h b/liboctave/CMatrix.h
--- a/liboctave/CMatrix.h
+++ b/liboctave/CMatrix.h
@@ -338,6 +338,8 @@
 
   ComplexMatrix cumprod (int dim = -1) const;
   ComplexMatrix cumsum (int dim = -1) const;
+  ComplexMatrix cummin (int dim = -1) const;
+  ComplexMatrix cummax (int dim = -1) const;
   ComplexMatrix prod (int dim = -1) const;
   ComplexMatrix sum (int dim = -1) const;
   ComplexMatrix sumsq (int dim = -1) const;
diff --git a/liboctave/CNDArray.cc b/liboctave/CNDArray.cc
--- a/liboctave/CNDArray.cc
+++ b/liboctave/CNDArray.cc
@@ -638,13 +638,25 @@
 ComplexNDArray
 ComplexNDArray::cumprod (int dim) const
 {
-  MX_ND_CUMULATIVE_OP (ComplexNDArray, Complex, Complex (1, 0), *);
+  MX_ND_CUMULATIVE_FUN (ComplexNDArray, Complex, Complex (1, 0), PROD);
 }
 
 ComplexNDArray
 ComplexNDArray::cumsum (int dim) const
 {
-  MX_ND_CUMULATIVE_OP (ComplexNDArray, Complex, Complex (0, 0), +);
+  MX_ND_CUMULATIVE_FUN (ComplexNDArray, Complex, Complex (0, 0), PLUS);
+}
+
+ComplexNDArray
+ComplexNDArray::cummin (int dim) const
+{
+  MX_ND_CUMULATIVE_FUN (ComplexNDArray, Complex, Complex (0, 0), complex_min);
+}
+
+ComplexNDArray
+ComplexNDArray::cummax (int dim) const
+{
+  MX_ND_CUMULATIVE_FUN (ComplexNDArray, Complex, Complex (0, 0), complex_max);
 }
 
 ComplexNDArray
diff --git a/liboctave/CNDArray.h b/liboctave/CNDArray.h
--- a/liboctave/CNDArray.h
+++ b/liboctave/CNDArray.h
@@ -75,6 +75,8 @@
 
   ComplexNDArray cumprod (int dim = -1) const;
   ComplexNDArray cumsum (int dim = -1) const;
+  ComplexNDArray cummin (int dim = -1) const;
+  ComplexNDArray cummax (int dim = -1) const;
   ComplexNDArray prod (int dim = -1) const;
   ComplexNDArray sum (int dim = -1) const;
   ComplexNDArray sumsq (int dim = -1) const;
diff --git a/liboctave/CSparse.cc b/liboctave/CSparse.cc
--- a/liboctave/CSparse.cc
+++ b/liboctave/CSparse.cc
@@ -7317,6 +7317,22 @@
 }
 
 SparseComplexMatrix
+SparseComplexMatrix::cummin (int dim) const
+{
+  // FIXME: this is just a placeholder
+  SparseComplexMatrix placeholder;
+  return placeholder;
+}
+
+SparseComplexMatrix
+SparseComplexMatrix::cummax (int dim) const
+{
+  // FIXME: this is just a placeholder
+  SparseComplexMatrix placeholder;
+  return placeholder;
+}
+
+SparseComplexMatrix
 SparseComplexMatrix::prod (int dim) const
 {
   if ((rows() == 1 && dim == -1) || dim == 1)
diff --git a/liboctave/CSparse.h b/liboctave/CSparse.h
--- a/liboctave/CSparse.h
+++ b/liboctave/CSparse.h
@@ -415,6 +415,8 @@
 
   SparseComplexMatrix cumprod (int dim = -1) const;
   SparseComplexMatrix cumsum (int dim = -1) const;
+  SparseComplexMatrix cummin (int dim = -1) const;
+  SparseComplexMatrix cummax (int dim = -1) const;
   SparseComplexMatrix prod (int dim = -1) const;
   SparseComplexMatrix sum (int dim = -1) const;
   SparseComplexMatrix sumsq (int dim = -1) const;
diff --git a/liboctave/dMatrix.cc b/liboctave/dMatrix.cc
--- a/liboctave/dMatrix.cc
+++ b/liboctave/dMatrix.cc
@@ -2962,13 +2962,13 @@
 Matrix
 Matrix::cumprod (int dim) const
 {
-  MX_CUMULATIVE_OP (Matrix, double, *=);
+  MX_CUMULATIVE_FUN (Matrix, double, PROD);
 }
 
 Matrix
 Matrix::cumsum (int dim) const
 {
-  MX_CUMULATIVE_OP (Matrix, double, +=);
+  MX_CUMULATIVE_FUN (Matrix, double, PLUS);
 }
 
 Matrix
diff --git a/liboctave/dNDArray.cc b/liboctave/dNDArray.cc
--- a/liboctave/dNDArray.cc
+++ b/liboctave/dNDArray.cc
@@ -702,13 +702,25 @@
 NDArray
 NDArray::cumprod (int dim) const
 {
-  MX_ND_CUMULATIVE_OP (NDArray, double, 1, *);
+  MX_ND_CUMULATIVE_FUN (NDArray, double, 1, PROD);
 }
 
 NDArray
 NDArray::cumsum (int dim) const
 {
-  MX_ND_CUMULATIVE_OP (NDArray, double, 0, +);
+  MX_ND_CUMULATIVE_FUN (NDArray, double, 0, PLUS);
+}
+
+NDArray
+NDArray::cummin (int dim) const
+{
+  MX_ND_CUMULATIVE_FUN (NDArray, double, 0, std::min);
+}
+
+NDArray
+NDArray::cummax (int dim) const
+{
+  MX_ND_CUMULATIVE_FUN (NDArray, double, 0, std::max);
 }
 
 NDArray
diff --git a/liboctave/dNDArray.h b/liboctave/dNDArray.h
--- a/liboctave/dNDArray.h
+++ b/liboctave/dNDArray.h
@@ -85,6 +85,8 @@
 
   NDArray cumprod (int dim = -1) const;
   NDArray cumsum (int dim = -1) const;
+  NDArray cummin (int dim = -1) const;
+  NDArray cummax (int dim = -1) const;
   NDArray prod (int dim = -1) const;
   NDArray sum (int dim = -1) const;  
   NDArray sumsq (int dim = -1) const;
diff --git a/liboctave/dSparse.cc b/liboctave/dSparse.cc
--- a/liboctave/dSparse.cc
+++ b/liboctave/dSparse.cc
@@ -7401,6 +7401,22 @@
 }
 
 SparseMatrix
+SparseMatrix::cummin (int dim) const
+{
+  // FIXME: this is just a placeholder
+  SparseMatrix placeholder;
+  return placeholder;
+}
+
+SparseMatrix
+SparseMatrix::cummax (int dim) const
+{
+  // FIXME: this is just a placeholder
+  SparseMatrix placeholder;
+  return placeholder;
+}
+
+SparseMatrix
 SparseMatrix::prod (int dim) const
 {
   if ((rows() == 1 && dim == -1) || dim == 1)
diff --git a/liboctave/dSparse.h b/liboctave/dSparse.h
--- a/liboctave/dSparse.h
+++ b/liboctave/dSparse.h
@@ -386,6 +386,8 @@
 
   SparseMatrix cumprod (int dim = -1) const;
   SparseMatrix cumsum (int dim = -1) const;
+  SparseMatrix cummin (int dim = -1) const;
+  SparseMatrix cummax (int dim = -1) const;
   SparseMatrix prod (int dim = -1) const;
   SparseMatrix sum (int dim = -1) const;
   SparseMatrix sumsq (int dim = -1) const;
diff --git a/liboctave/fCMatrix.cc b/liboctave/fCMatrix.cc
--- a/liboctave/fCMatrix.cc
+++ b/liboctave/fCMatrix.cc
@@ -3472,13 +3472,25 @@
 FloatComplexMatrix
 FloatComplexMatrix::cumprod (int dim) const
 {
-  MX_CUMULATIVE_OP (FloatComplexMatrix, FloatComplex, *=);
+  MX_CUMULATIVE_FUN (FloatComplexMatrix, FloatComplex, PROD);
 }
 
 FloatComplexMatrix
 FloatComplexMatrix::cumsum (int dim) const
 {
-  MX_CUMULATIVE_OP (FloatComplexMatrix, FloatComplex, +=);
+  MX_CUMULATIVE_FUN (FloatComplexMatrix, FloatComplex, PLUS);
+}
+
+FloatComplexMatrix
+FloatComplexMatrix::cummin (int dim) const
+{
+  MX_CUMULATIVE_FUN (FloatComplexMatrix, FloatComplex, complex_min);
+}
+
+FloatComplexMatrix
+FloatComplexMatrix::cummax (int dim) const
+{
+  MX_CUMULATIVE_FUN (FloatComplexMatrix, FloatComplex, complex_max);
 }
 
 FloatComplexMatrix
diff --git a/liboctave/fCMatrix.h b/liboctave/fCMatrix.h
--- a/liboctave/fCMatrix.h
+++ b/liboctave/fCMatrix.h
@@ -338,6 +338,8 @@
 
   FloatComplexMatrix cumprod (int dim = -1) const;
   FloatComplexMatrix cumsum (int dim = -1) const;
+  FloatComplexMatrix cummin (int dim = -1) const;
+  FloatComplexMatrix cummax (int dim = -1) const;
   FloatComplexMatrix prod (int dim = -1) const;
   FloatComplexMatrix sum (int dim = -1) const;
   FloatComplexMatrix sumsq (int dim = -1) const;
diff --git a/liboctave/fCNDArray.cc b/liboctave/fCNDArray.cc
--- a/liboctave/fCNDArray.cc
+++ b/liboctave/fCNDArray.cc
@@ -633,13 +633,25 @@
 FloatComplexNDArray
 FloatComplexNDArray::cumprod (int dim) const
 {
-  MX_ND_CUMULATIVE_OP (FloatComplexNDArray, FloatComplex, FloatComplex (1, 0), *);
+  MX_ND_CUMULATIVE_FUN (FloatComplexNDArray, FloatComplex, FloatComplex (1, 0), PROD);
 }
 
 FloatComplexNDArray
 FloatComplexNDArray::cumsum (int dim) const
 {
-  MX_ND_CUMULATIVE_OP (FloatComplexNDArray, FloatComplex, FloatComplex (0, 0), +);
+  MX_ND_CUMULATIVE_FUN (FloatComplexNDArray, FloatComplex, FloatComplex (0, 0), PLUS);
+}
+
+FloatComplexNDArray
+FloatComplexNDArray::cummin (int dim) const
+{
+  MX_ND_CUMULATIVE_FUN (FloatComplexNDArray, FloatComplex, FloatComplex (0, 0), complex_min);
+}
+
+FloatComplexNDArray
+FloatComplexNDArray::cummax (int dim) const
+{
+  MX_ND_CUMULATIVE_FUN (FloatComplexNDArray, FloatComplex, FloatComplex (0, 0), complex_max);
 }
 
 FloatComplexNDArray
diff --git a/liboctave/fCNDArray.h b/liboctave/fCNDArray.h
--- a/liboctave/fCNDArray.h
+++ b/liboctave/fCNDArray.h
@@ -75,6 +75,8 @@
 
   FloatComplexNDArray cumprod (int dim = -1) const;
   FloatComplexNDArray cumsum (int dim = -1) const;
+  FloatComplexNDArray cummin (int dim = -1) const;
+  FloatComplexNDArray cummax (int dim = -1) const;
   FloatComplexNDArray prod (int dim = -1) const;
   FloatComplexNDArray sum (int dim = -1) const;
   FloatComplexNDArray sumsq (int dim = -1) const;
diff --git a/liboctave/fMatrix.cc b/liboctave/fMatrix.cc
--- a/liboctave/fMatrix.cc
+++ b/liboctave/fMatrix.cc
@@ -2962,13 +2962,13 @@
 FloatMatrix
 FloatMatrix::cumprod (int dim) const
 {
-  MX_CUMULATIVE_OP (FloatMatrix, float, *=);
+  MX_CUMULATIVE_FUN (FloatMatrix, float, PROD);
 }
 
 FloatMatrix
 FloatMatrix::cumsum (int dim) const
 {
-  MX_CUMULATIVE_OP (FloatMatrix, float, +=);
+  MX_CUMULATIVE_FUN (FloatMatrix, float, PLUS);
 }
 
 FloatMatrix
diff --git a/liboctave/fNDArray.cc b/liboctave/fNDArray.cc
--- a/liboctave/fNDArray.cc
+++ b/liboctave/fNDArray.cc
@@ -657,13 +657,25 @@
 FloatNDArray
 FloatNDArray::cumprod (int dim) const
 {
-  MX_ND_CUMULATIVE_OP (FloatNDArray, float, 1, *);
+  MX_ND_CUMULATIVE_FUN (FloatNDArray, float, 1, PROD);
 }
 
 FloatNDArray
 FloatNDArray::cumsum (int dim) const
 {
-  MX_ND_CUMULATIVE_OP (FloatNDArray, float, 0, +);
+  MX_ND_CUMULATIVE_FUN (FloatNDArray, float, 0, PLUS);
+}
+
+FloatNDArray
+FloatNDArray::cummin (int dim) const
+{
+  MX_ND_CUMULATIVE_FUN (FloatNDArray, float, 0, std::min);
+}
+
+FloatNDArray
+FloatNDArray::cummax (int dim) const
+{
+  MX_ND_CUMULATIVE_FUN (FloatNDArray, float, 0, std::max);
 }
 
 FloatNDArray
diff --git a/liboctave/fNDArray.h b/liboctave/fNDArray.h
--- a/liboctave/fNDArray.h
+++ b/liboctave/fNDArray.h
@@ -82,6 +82,8 @@
 
   FloatNDArray cumprod (int dim = -1) const;
   FloatNDArray cumsum (int dim = -1) const;
+  FloatNDArray cummin (int dim = -1) const;
+  FloatNDArray cummax (int dim = -1) const;
   FloatNDArray prod (int dim = -1) const;
   FloatNDArray sum (int dim = -1) const;  
   FloatNDArray sumsq (int dim = -1) const;
diff --git a/liboctave/mx-inlines.cc b/liboctave/mx-inlines.cc
--- a/liboctave/mx-inlines.cc
+++ b/liboctave/mx-inlines.cc
@@ -271,7 +271,7 @@
 
 // Avoid some code duplication.  Maybe we should use templates.
 
-#define MX_CUMULATIVE_OP(RET_TYPE, ELT_TYPE, OP) \
+#define MX_CUMULATIVE_FUN(RET_TYPE, ELT_TYPE, FUN) \
  \
   octave_idx_type nr = rows (); \
   octave_idx_type nc = cols (); \
@@ -289,7 +289,7 @@
 		{ \
 		  retval.elem (i, j) = t; \
 		  if (j < nc - 1) \
-		    t OP elem (i, j+1); \
+		    t = FUN(t, elem (i, j+1)); \
 		} \
 	    } \
 	} \
@@ -302,7 +302,7 @@
 		{ \
 		  retval.elem (i, j) = t; \
 		  if (i < nr - 1) \
-		    t OP elem (i+1, j); \
+		    t = FUN(t, elem (i+1, j)); \
 		} \
 	    } \
 	} \
@@ -521,7 +521,23 @@
 #define MX_ND_ANY_ALL_REDUCTION(EVAL_EXPR, VAL) \
   MX_ND_REDUCTION (EVAL_EXPR, VAL, boolNDArray)
 
-#define MX_ND_CUMULATIVE_OP(RET_TYPE, ACC_TYPE, INIT_VAL, OP) \
+#define PLUS(A, B) A + B
+
+#define PROD(A, B) A * B
+
+template <class complex_type>
+inline complex_type complex_min (const complex_type &a, const complex_type &b)
+{
+  return (std::abs (a) < std::abs (b)) ? a : b;
+}
+
+template <class complex_type>
+inline complex_type complex_max (const complex_type &a, const complex_type &b)
+{
+  return (std::abs (a) < std::abs (b)) ? b : a;
+}
+
+#define MX_ND_CUMULATIVE_FUN(RET_TYPE, ACC_TYPE, INIT_VAL, FUN) \
  \
   RET_TYPE retval; \
  \
@@ -605,7 +621,7 @@
 		} \
 	      else \
 		{ \
-		  prev_val = prev_val OP elem (iter_idx); \
+		  prev_val = FUN(prev_val, elem (iter_idx)); \
 		  retval(iter_idx) = prev_val; \
 		} \
  \
diff --git a/src/data.cc b/src/data.cc
--- a/src/data.cc
+++ b/src/data.cc
@@ -1576,6 +1576,42 @@
 %!assert (cumsum (single([1, 2; 3, 4]), 2), single([1, 3; 3, 7]));
 
  */
+
+DEFUN (cummin, args, ,
+  "-*- texinfo -*-\n\
[EMAIL PROTECTED] {Built-in Function} {} cummin (@var{x}, @var{dim})\n\
+Cumulative minimum 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\
+For complex matrices, the minimum value is computed as the number with\n\
+smallest absolute value.\n\
[EMAIL PROTECTED]
[EMAIL PROTECTED] deftypefn")
+{
+  DATA_REDUCTION (cummin);
+}
+
+DEFUN (cummax, args, ,
+  "-*- texinfo -*-\n\
[EMAIL PROTECTED] {Built-in Function} {} cummax (@var{x}, @var{dim})\n\
+Cumulative maximum 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\
+For complex matrices, the maximum value is computed as the number with\n\
+largest absolute value.\n\
[EMAIL PROTECTED]
[EMAIL PROTECTED] deftypefn")
+{
+  DATA_REDUCTION (cummax);
+}
 
 DEFUN (diag, args, ,
   "-*- texinfo -*-\n\
-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
_______________________________________________
Octave-dev mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/octave-dev

Reply via email to