Mercurial > hg > octave-lyh
changeset 8743:1bd918cfb6e2
reimplement any & all using the new reduction code
author | Jaroslav Hajek <highegg@gmail.com> |
---|---|
date | Sat, 14 Feb 2009 19:50:43 +0100 |
parents | d2b06871afac |
children | 4142982c66c6 |
files | liboctave/CMatrix.cc liboctave/CNDArray.cc liboctave/ChangeLog liboctave/boolMatrix.cc liboctave/boolNDArray.cc liboctave/dMatrix.cc liboctave/dNDArray.cc liboctave/fCMatrix.cc liboctave/fCNDArray.cc liboctave/fMatrix.cc liboctave/fNDArray.cc liboctave/intNDArray.cc liboctave/mx-inlines.cc |
diffstat | 13 files changed, 123 insertions(+), 96 deletions(-) [+] |
line wrap: on
line diff
--- a/liboctave/CMatrix.cc +++ b/liboctave/CMatrix.cc @@ -3252,13 +3252,13 @@ boolMatrix ComplexMatrix::all (int dim) const { - MX_ALL_OP (dim); + return do_mx_red_op<boolMatrix> (*this, dim, mx_inline_all); } boolMatrix ComplexMatrix::any (int dim) const { - MX_ANY_OP (dim); + return do_mx_red_op<boolMatrix> (*this, dim, mx_inline_any); } ComplexMatrix
--- a/liboctave/CNDArray.cc +++ b/liboctave/CNDArray.cc @@ -622,18 +622,13 @@ boolNDArray ComplexNDArray::all (int dim) const { - MX_ND_ANY_ALL_REDUCTION - (MX_ND_ALL_EVAL (elem (iter_idx) == Complex (0, 0)), true); + return do_mx_red_op<boolNDArray> (*this, dim, mx_inline_all); } boolNDArray ComplexNDArray::any (int dim) const { - MX_ND_ANY_ALL_REDUCTION - (MX_ND_ANY_EVAL (elem (iter_idx) != Complex (0, 0) - && ! (lo_ieee_isnan (std::real (elem (iter_idx))) - || lo_ieee_isnan (std::imag (elem (iter_idx))))), - false); + return do_mx_red_op<boolNDArray> (*this, dim, mx_inline_any); } ComplexNDArray
--- a/liboctave/ChangeLog +++ b/liboctave/ChangeLog @@ -1,3 +1,38 @@ +2009-02-14 Jaroslav Hajek <highegg@gmail.com> + + * mx-inlines.cc (OP_RED_FCN, OP_RED_FCN2, OP_RED_FCNN, OP_CUM_FCN, + OP_CUM_FCN2, OP_CUM_FCNN): Include TRET parameter. + (OP_RED_ANYC, OP_RED_ANYR, OP_RED_ALLC, OP_RED_ALLR): New macros. + (is_true, is_false): New template functions. + (mx_inline_any, mx_inline_all): New template functions. + + * dMatrix.cc (Matrix::any, Matrix::all): Use do_mx_red_op and + do_mx_cum_op. + * fMatrix.cc (FloatMatrix::any, FloatMatrix::all): Use do_mx_red_op + and do_mx_cum_op. + * CMatrix.cc (ComplexMatrix::any, ComplexMatrix::all): Use + do_mx_red_op and do_mx_cum_op. + * fCMatrix.cc (FloatComplexMatrix::any, FloatComplexMatrix::all): Use + do_mx_red_op and do_mx_cum_op. + + * dNDArray.cc (NDArray::any, NDArray::all): Use do_mx_red_op and + do_mx_cum_op. + * fNDArray.cc (FloatNDArray::any, FloatNDArray::all): Use do_mx_red_op + and do_mx_cum_op. + * CNDArray.cc (ComplexNDArray::any, ComplexNDArray::all): Use + do_mx_red_op and do_mx_cum_op. + * fCNDArray.cc (FloatComplexNDArray::any, FloatComplexNDArray::all): + Use do_mx_red_op and do_mx_cum_op. + + * intNDArray.cc (intNDArray::any, intNDArray::all): Use do_mx_red_op and + do_mx_cum_op. + + * boolNDArray.cc (boolNDArray::any, boolNDArray::all): Use do_mx_red_op and + do_mx_cum_op. + + * boolMatrix.cc (boolMatrix::any, boolMatrix::all): Use do_mx_red_op and + do_mx_cum_op. + 2009-02-14 Jaroslav Hajek <highegg@gmail.com> * intNDArray.cc: include mx-inlines.cc.
--- a/liboctave/boolMatrix.cc +++ b/liboctave/boolMatrix.cc @@ -89,13 +89,13 @@ boolMatrix boolMatrix::all (int dim) const { - MX_ALL_OP (dim); + return do_mx_red_op<boolMatrix> (*this, dim, mx_inline_all); } boolMatrix boolMatrix::any (int dim) const { - MX_ANY_OP (dim); + return do_mx_red_op<boolMatrix> (*this, dim, mx_inline_any); } MM_CMP_OPS (boolMatrix, , boolMatrix, )
--- a/liboctave/boolNDArray.cc +++ b/liboctave/boolNDArray.cc @@ -48,13 +48,13 @@ boolNDArray boolNDArray::all (int dim) const { - MX_ND_ANY_ALL_REDUCTION (MX_ND_ALL_EVAL (MX_ND_ALL_EXPR), true); + return do_mx_red_op<boolNDArray> (*this, dim, mx_inline_all); } boolNDArray boolNDArray::any (int dim) const { - MX_ND_ANY_ALL_REDUCTION (MX_ND_ANY_EVAL (MX_ND_ANY_EXPR), false); + return do_mx_red_op<boolNDArray> (*this, dim, mx_inline_any); } boolNDArray
--- a/liboctave/dMatrix.cc +++ b/liboctave/dMatrix.cc @@ -2786,13 +2786,13 @@ boolMatrix Matrix::all (int dim) const { - MX_ALL_OP (dim); + return do_mx_red_op<boolMatrix> (*this, dim, mx_inline_all); } boolMatrix Matrix::any (int dim) const { - MX_ANY_OP (dim); + return do_mx_red_op<boolMatrix> (*this, dim, mx_inline_any); } Matrix
--- a/liboctave/dNDArray.cc +++ b/liboctave/dNDArray.cc @@ -689,15 +689,13 @@ boolNDArray NDArray::all (int dim) const { - MX_ND_ANY_ALL_REDUCTION (MX_ND_ALL_EVAL (MX_ND_ALL_EXPR), true); + return do_mx_red_op<boolNDArray> (*this, dim, mx_inline_all); } boolNDArray NDArray::any (int dim) const { - MX_ND_ANY_ALL_REDUCTION - (MX_ND_ANY_EVAL (elem (iter_idx) != 0 - && ! lo_ieee_isnan (elem (iter_idx))), false); + return do_mx_red_op<boolNDArray> (*this, dim, mx_inline_any); } NDArray
--- a/liboctave/fCMatrix.cc +++ b/liboctave/fCMatrix.cc @@ -3246,53 +3246,13 @@ boolMatrix FloatComplexMatrix::all (int dim) const { - // FIXME Can't use MX_ALL_OP as need to static cast to float to the ROW - // and COL expressions - -#define ROW_EXPR \ - if (elem (i, j) == static_cast<float> (0.0)) \ - { \ - retval.elem (i, 0) = false; \ - break; \ - } - -#define COL_EXPR \ - if (elem (i, j) == static_cast<float> (0.0)) \ - { \ - retval.elem (0, j) = false; \ - break; \ - } - - MX_BASE_REDUCTION_OP (boolMatrix, ROW_EXPR, COL_EXPR, true, true); - -#undef ROW_EXPR -#undef COL_EXPR + return do_mx_red_op<boolMatrix> (*this, dim, mx_inline_all); } boolMatrix FloatComplexMatrix::any (int dim) const { - // FIXME Can't use MX_ANY_OP as need to static cast to float to the ROW - // and COL expressions - -#define ROW_EXPR \ - if (elem (i, j) != static_cast<float> (0.0)) \ - { \ - retval.elem (i, 0) = true; \ - break; \ - } - -#define COL_EXPR \ - if (elem (i, j) != static_cast<float> (0.0)) \ - { \ - retval.elem (0, j) = true; \ - break; \ - } - - MX_BASE_REDUCTION_OP (boolMatrix, ROW_EXPR, COL_EXPR, false, false); - -#undef ROW_EXPR -#undef COL_EXPR + return do_mx_red_op<boolMatrix> (*this, dim, mx_inline_any); } FloatComplexMatrix
--- a/liboctave/fCNDArray.cc +++ b/liboctave/fCNDArray.cc @@ -617,18 +617,13 @@ boolNDArray FloatComplexNDArray::all (int dim) const { - MX_ND_ANY_ALL_REDUCTION - (MX_ND_ALL_EVAL (elem (iter_idx) == FloatComplex (0, 0)), true); + return do_mx_red_op<boolNDArray> (*this, dim, mx_inline_all); } boolNDArray FloatComplexNDArray::any (int dim) const { - MX_ND_ANY_ALL_REDUCTION - (MX_ND_ANY_EVAL (elem (iter_idx) != FloatComplex (0, 0) - && ! (lo_ieee_isnan (std::real (elem (iter_idx))) - || lo_ieee_isnan (std::imag (elem (iter_idx))))), - false); + return do_mx_red_op<boolNDArray> (*this, dim, mx_inline_any); } FloatComplexNDArray
--- a/liboctave/fMatrix.cc +++ b/liboctave/fMatrix.cc @@ -2785,13 +2785,13 @@ boolMatrix FloatMatrix::all (int dim) const { - MX_ALL_OP (dim); + return do_mx_red_op<boolMatrix> (*this, dim, mx_inline_all); } boolMatrix FloatMatrix::any (int dim) const { - MX_ANY_OP (dim); + return do_mx_red_op<boolMatrix> (*this, dim, mx_inline_any); } FloatMatrix
--- a/liboctave/fNDArray.cc +++ b/liboctave/fNDArray.cc @@ -644,15 +644,13 @@ boolNDArray FloatNDArray::all (int dim) const { - MX_ND_ANY_ALL_REDUCTION (MX_ND_ALL_EVAL (MX_ND_ALL_EXPR), true); + return do_mx_red_op<boolNDArray> (*this, dim, mx_inline_all); } boolNDArray FloatNDArray::any (int dim) const { - MX_ND_ANY_ALL_REDUCTION - (MX_ND_ANY_EVAL (elem (iter_idx) != 0 - && ! lo_ieee_isnan (elem (iter_idx))), false); + return do_mx_red_op<boolNDArray> (*this, dim, mx_inline_any); } FloatNDArray
--- a/liboctave/intNDArray.cc +++ b/liboctave/intNDArray.cc @@ -74,14 +74,14 @@ boolNDArray intNDArray<T>::all (int dim) const { - MX_ND_ANY_ALL_REDUCTION (MX_ND_ALL_EVAL (this->elem (iter_idx) == T (0)), true); + return do_mx_red_op<boolNDArray> (*this, dim, mx_inline_all); } template <class T> boolNDArray intNDArray<T>::any (int dim) const { - MX_ND_ANY_ALL_REDUCTION (MX_ND_ANY_EVAL (this->elem (iter_idx) != T (0)), false); + return do_mx_red_op<boolNDArray> (*this, dim, mx_inline_any); } template <class T>
--- a/liboctave/mx-inlines.cc +++ b/liboctave/mx-inlines.cc @@ -284,7 +284,7 @@ // NOTE: std::norm is NOT equivalent template <class T> -T cabsq (const std::complex<T>& c) +inline T cabsq (const std::complex<T>& c) { return c.real () * c.real () + c.imag () * c.imag (); } #define OP_RED_SUM(ac, el) ac += el @@ -292,26 +292,64 @@ #define OP_RED_SUMSQ(ac, el) ac += el*el #define OP_RED_SUMSQC(ac, el) ac += cabsq (el) -#define OP_RED_FCN(F, TSRC, OP, ZERO) \ +// default. works for integers and bool. +template <class T> +inline bool xis_true (T x) { return x; } +template <class T> +inline bool xis_false (T x) { return ! x; } +// for octave_ints +template <class T> +inline bool xis_true (const octave_int<T>& x) { return x.value (); } +template <class T> +inline bool xis_false (const octave_int<T>& x) { return ! x.value (); } +// for reals, we want to ignore NaNs. +inline bool xis_true (double x) { return ! xisnan (x) && x != 0.0; } +inline bool xis_false (double x) { return x == 0.0; } +inline bool xis_true (float x) { return ! xisnan (x) && x != 0.0f; } +inline bool xis_false (float x) { return x == 0.0f; } +// Ditto for complex. +inline bool xis_true (const Complex& x) { return ! xisnan (x) && x != 0.0; } +inline bool xis_false (const Complex& x) { return x == 0.0; } +inline bool xis_true (const FloatComplex& x) { return ! xisnan (x) && x != 0.0f; } +inline bool xis_false (const FloatComplex& x) { return x == 0.0f; } + +// The following two implement a simple short-circuiting. +#define OP_RED_ANYC(ac, el) if (xis_true (el)) { ac = true; break; } else continue +#define OP_RED_ALLC(ac, el) if (xis_false (el)) { ac = false; break; } else continue + +// Row any/all reductions are a tradeoff - we traverse the array by +// columns to gain cache coherence, but sacrifice short-circuiting for that. +// For certain logical arrays, this could mean a significant loss. +// A more sophisticated implementation could introduce a buffer of active +// row indices to achieve both. Right now, I don't see the operation as +// important enough. + +#define OP_RED_ANYR(ac, el) if (xis_true (el)) ac = true +#define OP_RED_ALLR(ac, el) if (xis_false (el)) ac = false + +#define OP_RED_FCN(F, TSRC, TRES, OP, ZERO) \ template <class T> \ -inline T \ +inline TRES \ F (const TSRC* v, octave_idx_type n) \ { \ - T ac = ZERO; \ + TRES ac = ZERO; \ for (octave_idx_type i = 0; i < n; i++) \ OP(ac, v[i]); \ return ac; \ } -OP_RED_FCN (mx_inline_sum, T, OP_RED_SUM, 0) -OP_RED_FCN (mx_inline_prod, T, OP_RED_PROD, 1) -OP_RED_FCN (mx_inline_sumsq, T, OP_RED_SUMSQ, 0) -OP_RED_FCN (mx_inline_sumsq, std::complex<T>, OP_RED_SUMSQC, 0) +OP_RED_FCN (mx_inline_sum, T, T, OP_RED_SUM, 0) +OP_RED_FCN (mx_inline_prod, T, T, OP_RED_PROD, 1) +OP_RED_FCN (mx_inline_sumsq, T, T, OP_RED_SUMSQ, 0) +OP_RED_FCN (mx_inline_sumsq, std::complex<T>, T, OP_RED_SUMSQC, 0) +OP_RED_FCN (mx_inline_any, T, bool, OP_RED_ANYC, false) +OP_RED_FCN (mx_inline_all, T, bool, OP_RED_ALLC, true) -#define OP_RED_FCN2(F, TSRC, OP, ZERO) \ + +#define OP_RED_FCN2(F, TSRC, TRES, OP, ZERO) \ template <class T> \ inline void \ -F (const TSRC* 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) \ { \ for (octave_idx_type i = 0; i < m; i++) \ r[i] = ZERO; \ @@ -323,15 +361,17 @@ } \ } -OP_RED_FCN2 (mx_inline_sum, T, OP_RED_SUM, 0) -OP_RED_FCN2 (mx_inline_prod, T, OP_RED_PROD, 1) -OP_RED_FCN2 (mx_inline_sumsq, T, OP_RED_SUMSQ, 0) -OP_RED_FCN2 (mx_inline_sumsq, std::complex<T>, OP_RED_SUMSQC, 0) +OP_RED_FCN2 (mx_inline_sum, T, T, OP_RED_SUM, 0) +OP_RED_FCN2 (mx_inline_prod, T, T, OP_RED_PROD, 1) +OP_RED_FCN2 (mx_inline_sumsq, T, T, OP_RED_SUMSQ, 0) +OP_RED_FCN2 (mx_inline_sumsq, std::complex<T>, T, OP_RED_SUMSQC, 0) +OP_RED_FCN2 (mx_inline_any, T, bool, OP_RED_ANYR, false) +OP_RED_FCN2 (mx_inline_all, T, bool, OP_RED_ALLR, true) -#define OP_RED_FCNN(F, TSRC) \ +#define OP_RED_FCNN(F, TSRC, TRES) \ template <class T> \ inline void \ -F (const TSRC *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) \ @@ -353,10 +393,12 @@ } \ } -OP_RED_FCNN (mx_inline_sum, T) -OP_RED_FCNN (mx_inline_prod, T) -OP_RED_FCNN (mx_inline_sumsq, T) -OP_RED_FCNN (mx_inline_sumsq, std::complex<T>) +OP_RED_FCNN (mx_inline_sum, T, T) +OP_RED_FCNN (mx_inline_prod, T, T) +OP_RED_FCNN (mx_inline_sumsq, T, T) +OP_RED_FCNN (mx_inline_sumsq, std::complex<T>, T) +OP_RED_FCNN (mx_inline_any, T, bool) +OP_RED_FCNN (mx_inline_all, T, bool) #define OP_CUM_FCN(F, OP) \ template <class T> \ @@ -467,6 +509,10 @@ { octave_idx_type l, n, u; dim_vector dims = src.dims (); + // M*b inconsistency: sum([]) = 0 etc. + if (dims.length () == 2 && dims(0) == 0 && dims(1) == 0) + dims (1) = 1; + get_extent_triplet (dims, dim, l, n, u); // Reduction operation reduces the array size.