# HG changeset patch # User Jaroslav Hajek # Date 1234637443 -3600 # Node ID 1bd918cfb6e2dd04525506bbd108bce37a2afc11 # Parent d2b06871aface3efbe565bc02c5ae33d2473fd96 reimplement any & all using the new reduction code diff -r d2b06871afac -r 1bd918cfb6e2 liboctave/CMatrix.cc --- a/liboctave/CMatrix.cc Sat Feb 14 07:27:34 2009 +0100 +++ b/liboctave/CMatrix.cc Sat Feb 14 19:50:43 2009 +0100 @@ -3252,13 +3252,13 @@ boolMatrix ComplexMatrix::all (int dim) const { - MX_ALL_OP (dim); + return do_mx_red_op (*this, dim, mx_inline_all); } boolMatrix ComplexMatrix::any (int dim) const { - MX_ANY_OP (dim); + return do_mx_red_op (*this, dim, mx_inline_any); } ComplexMatrix diff -r d2b06871afac -r 1bd918cfb6e2 liboctave/CNDArray.cc --- a/liboctave/CNDArray.cc Sat Feb 14 07:27:34 2009 +0100 +++ b/liboctave/CNDArray.cc Sat Feb 14 19:50:43 2009 +0100 @@ -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 (*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 (*this, dim, mx_inline_any); } ComplexNDArray diff -r d2b06871afac -r 1bd918cfb6e2 liboctave/ChangeLog --- a/liboctave/ChangeLog Sat Feb 14 07:27:34 2009 +0100 +++ b/liboctave/ChangeLog Sat Feb 14 19:50:43 2009 +0100 @@ -1,3 +1,38 @@ +2009-02-14 Jaroslav Hajek + + * 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 * intNDArray.cc: include mx-inlines.cc. diff -r d2b06871afac -r 1bd918cfb6e2 liboctave/boolMatrix.cc --- a/liboctave/boolMatrix.cc Sat Feb 14 07:27:34 2009 +0100 +++ b/liboctave/boolMatrix.cc Sat Feb 14 19:50:43 2009 +0100 @@ -89,13 +89,13 @@ boolMatrix boolMatrix::all (int dim) const { - MX_ALL_OP (dim); + return do_mx_red_op (*this, dim, mx_inline_all); } boolMatrix boolMatrix::any (int dim) const { - MX_ANY_OP (dim); + return do_mx_red_op (*this, dim, mx_inline_any); } MM_CMP_OPS (boolMatrix, , boolMatrix, ) diff -r d2b06871afac -r 1bd918cfb6e2 liboctave/boolNDArray.cc --- a/liboctave/boolNDArray.cc Sat Feb 14 07:27:34 2009 +0100 +++ b/liboctave/boolNDArray.cc Sat Feb 14 19:50:43 2009 +0100 @@ -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 (*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 (*this, dim, mx_inline_any); } boolNDArray diff -r d2b06871afac -r 1bd918cfb6e2 liboctave/dMatrix.cc --- a/liboctave/dMatrix.cc Sat Feb 14 07:27:34 2009 +0100 +++ b/liboctave/dMatrix.cc Sat Feb 14 19:50:43 2009 +0100 @@ -2786,13 +2786,13 @@ boolMatrix Matrix::all (int dim) const { - MX_ALL_OP (dim); + return do_mx_red_op (*this, dim, mx_inline_all); } boolMatrix Matrix::any (int dim) const { - MX_ANY_OP (dim); + return do_mx_red_op (*this, dim, mx_inline_any); } Matrix diff -r d2b06871afac -r 1bd918cfb6e2 liboctave/dNDArray.cc --- a/liboctave/dNDArray.cc Sat Feb 14 07:27:34 2009 +0100 +++ b/liboctave/dNDArray.cc Sat Feb 14 19:50:43 2009 +0100 @@ -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 (*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 (*this, dim, mx_inline_any); } NDArray diff -r d2b06871afac -r 1bd918cfb6e2 liboctave/fCMatrix.cc --- a/liboctave/fCMatrix.cc Sat Feb 14 07:27:34 2009 +0100 +++ b/liboctave/fCMatrix.cc Sat Feb 14 19:50:43 2009 +0100 @@ -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 (0.0)) \ - { \ - retval.elem (i, 0) = false; \ - break; \ - } - -#define COL_EXPR \ - if (elem (i, j) == static_cast (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 (*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 (0.0)) \ - { \ - retval.elem (i, 0) = true; \ - break; \ - } - -#define COL_EXPR \ - if (elem (i, j) != static_cast (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 (*this, dim, mx_inline_any); } FloatComplexMatrix diff -r d2b06871afac -r 1bd918cfb6e2 liboctave/fCNDArray.cc --- a/liboctave/fCNDArray.cc Sat Feb 14 07:27:34 2009 +0100 +++ b/liboctave/fCNDArray.cc Sat Feb 14 19:50:43 2009 +0100 @@ -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 (*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 (*this, dim, mx_inline_any); } FloatComplexNDArray diff -r d2b06871afac -r 1bd918cfb6e2 liboctave/fMatrix.cc --- a/liboctave/fMatrix.cc Sat Feb 14 07:27:34 2009 +0100 +++ b/liboctave/fMatrix.cc Sat Feb 14 19:50:43 2009 +0100 @@ -2785,13 +2785,13 @@ boolMatrix FloatMatrix::all (int dim) const { - MX_ALL_OP (dim); + return do_mx_red_op (*this, dim, mx_inline_all); } boolMatrix FloatMatrix::any (int dim) const { - MX_ANY_OP (dim); + return do_mx_red_op (*this, dim, mx_inline_any); } FloatMatrix diff -r d2b06871afac -r 1bd918cfb6e2 liboctave/fNDArray.cc --- a/liboctave/fNDArray.cc Sat Feb 14 07:27:34 2009 +0100 +++ b/liboctave/fNDArray.cc Sat Feb 14 19:50:43 2009 +0100 @@ -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 (*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 (*this, dim, mx_inline_any); } FloatNDArray diff -r d2b06871afac -r 1bd918cfb6e2 liboctave/intNDArray.cc --- a/liboctave/intNDArray.cc Sat Feb 14 07:27:34 2009 +0100 +++ b/liboctave/intNDArray.cc Sat Feb 14 19:50:43 2009 +0100 @@ -74,14 +74,14 @@ boolNDArray intNDArray::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 (*this, dim, mx_inline_all); } template boolNDArray intNDArray::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 (*this, dim, mx_inline_any); } template diff -r d2b06871afac -r 1bd918cfb6e2 liboctave/mx-inlines.cc --- a/liboctave/mx-inlines.cc Sat Feb 14 07:27:34 2009 +0100 +++ b/liboctave/mx-inlines.cc Sat Feb 14 19:50:43 2009 +0100 @@ -284,7 +284,7 @@ // NOTE: std::norm is NOT equivalent template -T cabsq (const std::complex& c) +inline T cabsq (const std::complex& 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 +inline bool xis_true (T x) { return x; } +template +inline bool xis_false (T x) { return ! x; } +// for octave_ints +template +inline bool xis_true (const octave_int& x) { return x.value (); } +template +inline bool xis_false (const octave_int& 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 \ -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, 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, 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 \ 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, 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, 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 \ 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) +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) +OP_RED_FCNN (mx_inline_any, T, bool) +OP_RED_FCNN (mx_inline_all, T, bool) #define OP_CUM_FCN(F, OP) \ template \ @@ -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.