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