Mercurial > hg > octave-lyh
changeset 9800:ef4c4186cb47
improve some mx_inline loops
author | Jaroslav Hajek <highegg@gmail.com> |
---|---|
date | Wed, 11 Nov 2009 10:59:27 +0100 |
parents | cfd0aa788ae1 |
children | 13868ea67c71 |
files | liboctave/Array.h liboctave/CNDArray.cc liboctave/ChangeLog liboctave/dNDArray.cc liboctave/fCNDArray.cc liboctave/fNDArray.cc liboctave/mx-inlines.cc |
diffstat | 7 files changed, 101 insertions(+), 86 deletions(-) [+] |
line wrap: on
line diff
--- a/liboctave/Array.h +++ b/liboctave/Array.h @@ -676,25 +676,6 @@ return result; } - // This is non-breakable map, suitable for fast functions. Efficiency - // relies on compiler's ability to inline a function pointer. This seems - // to be OK with recent GCC. - template <class U> - Array<U> - fastmap (U (*fcn) (typename ref_param<T>::type)) const - { - octave_idx_type len = length (); - - const T *m = data (); - - Array<U> result (dims ()); - U *p = result.fortran_vec (); - - std::transform (m, m + len, p, fcn); - - return result; - } - template <class U> friend class Array; private:
--- a/liboctave/CNDArray.cc +++ b/liboctave/CNDArray.cc @@ -760,33 +760,31 @@ NDArray ComplexNDArray::abs (void) const { - return NDArray (mx_inline_cabs_dup (data (), length ()), - dims ()); + return do_mx_unary_map<NDArray, ComplexNDArray, std::abs> (*this); } boolNDArray ComplexNDArray::isnan (void) const { - return Array<bool> (fastmap<bool> (xisnan)); + return do_mx_unary_map<boolNDArray, ComplexNDArray, xisnan> (*this); } boolNDArray ComplexNDArray::isinf (void) const { - return Array<bool> (fastmap<bool> (xisinf)); + return do_mx_unary_map<boolNDArray, ComplexNDArray, xisinf> (*this); } boolNDArray ComplexNDArray::isfinite (void) const { - return Array<bool> (fastmap<bool> (xfinite)); + return do_mx_unary_map<boolNDArray, ComplexNDArray, xfinite> (*this); } ComplexNDArray conj (const ComplexNDArray& a) { - return ComplexNDArray (mx_inline_conj_dup (a.data (), a.length ()), - a.dims ()); + return do_mx_unary_map<ComplexNDArray, ComplexNDArray, std::conj> (a); } ComplexNDArray&
--- a/liboctave/ChangeLog +++ b/liboctave/ChangeLog @@ -1,3 +1,21 @@ +2009-11-11 Jaroslav Hajek <highegg@gmail.com> + + * mx-inlines.cc (mx_inline_map): New template loop. + (DEFMXMAPPER): New macro. + (DEFMXMAPPER2): Rename from DEFMXMAPPER. + (do_mx_unary_map): New applier. + (mx_inline_real, mx_inline_complex): New loops. + * dNDArray.cc (NDArray::abs, NDArray::isnan, NDArray::isinf, + NDArray::isfinite, real, imag): Use new constructs. + * fNDArray.cc (FloatNDArray::abs, FloatNDArray::isnan, + FloatNDArray::isinf, FloatNDArray::isfinite, real, imag): Ditto. + * CNDArray.cc (ComplexNDArray::abs, ComplexNDArray::isnan, + ComplexNDArray::isinf, ComplexNDArray::isfinite, conj): Use new + constructs. + * fCNDArray.cc (FloatComplexNDArray::abs, FloatComplexNDArray::isnan, + FloatComplexNDArray::isinf, FloatComplexNDArray::isfinite, conj): Use + new constructs. + 2009-11-10 John W. Eaton <jwe@octave.org> * mx-ops, sparse-mx-ops, vx-ops b/liboctave/vx-ops:
--- a/liboctave/dNDArray.cc +++ b/liboctave/dNDArray.cc @@ -849,15 +849,13 @@ NDArray real (const ComplexNDArray& a) { - return NDArray (mx_inline_real_dup (a.data (), a.length ()), - a.dims ()); + return do_mx_unary_op<NDArray, ComplexNDArray> (a, mx_inline_real); } NDArray imag (const ComplexNDArray& a) { - return NDArray (mx_inline_imag_dup (a.data (), a.length ()), - a.dims ()); + return do_mx_unary_op<NDArray, ComplexNDArray> (a, mx_inline_imag); } NDArray& @@ -877,26 +875,25 @@ NDArray NDArray::abs (void) const { - return NDArray (mx_inline_fabs_dup (data (), length ()), - dims ()); + return do_mx_unary_map<NDArray, NDArray, std::abs> (*this); } boolNDArray NDArray::isnan (void) const { - return Array<bool> (fastmap<bool> (xisnan)); + return do_mx_unary_map<boolNDArray, NDArray, xisnan> (*this); } boolNDArray NDArray::isinf (void) const { - return Array<bool> (fastmap<bool> (xisinf)); + return do_mx_unary_map<boolNDArray, NDArray, xisinf> (*this); } boolNDArray NDArray::isfinite (void) const { - return Array<bool> (fastmap<bool> (xfinite)); + return do_mx_unary_map<boolNDArray, NDArray, xfinite> (*this); } Matrix
--- a/liboctave/fCNDArray.cc +++ b/liboctave/fCNDArray.cc @@ -755,33 +755,31 @@ FloatNDArray FloatComplexNDArray::abs (void) const { - return FloatNDArray (mx_inline_cabs_dup (data (), length ()), - dims ()); + return do_mx_unary_map<FloatNDArray, FloatComplexNDArray, std::abs> (*this); } boolNDArray FloatComplexNDArray::isnan (void) const { - return Array<bool> (fastmap<bool> (xisnan)); + return do_mx_unary_map<boolNDArray, FloatComplexNDArray, xisnan> (*this); } boolNDArray FloatComplexNDArray::isinf (void) const { - return Array<bool> (fastmap<bool> (xisinf)); + return do_mx_unary_map<boolNDArray, FloatComplexNDArray, xisinf> (*this); } boolNDArray FloatComplexNDArray::isfinite (void) const { - return Array<bool> (fastmap<bool> (xfinite)); + return do_mx_unary_map<boolNDArray, FloatComplexNDArray, xfinite> (*this); } FloatComplexNDArray conj (const FloatComplexNDArray& a) { - return FloatComplexNDArray (mx_inline_conj_dup (a.data (), a.length ()), - a.dims ()); + return do_mx_unary_map<FloatComplexNDArray, FloatComplexNDArray, std::conj> (a); } FloatComplexNDArray&
--- a/liboctave/fNDArray.cc +++ b/liboctave/fNDArray.cc @@ -807,15 +807,13 @@ FloatNDArray real (const FloatComplexNDArray& a) { - return FloatNDArray (mx_inline_real_dup (a.data (), a.length ()), - a.dims ()); + return do_mx_unary_op<FloatNDArray, FloatComplexNDArray> (a, mx_inline_real); } FloatNDArray imag (const FloatComplexNDArray& a) { - return FloatNDArray (mx_inline_imag_dup (a.data (), a.length ()), - a.dims ()); + return do_mx_unary_op<FloatNDArray, FloatComplexNDArray> (a, mx_inline_imag); } FloatNDArray& @@ -835,26 +833,25 @@ FloatNDArray FloatNDArray::abs (void) const { - return FloatNDArray (mx_inline_fabs_dup (data (), length ()), - dims ()); + return do_mx_unary_map<FloatNDArray, FloatNDArray, std::abs> (*this); } boolNDArray FloatNDArray::isnan (void) const { - return Array<bool> (fastmap<bool> (xisnan)); + return do_mx_unary_map<boolNDArray, FloatNDArray, xisnan> (*this); } boolNDArray FloatNDArray::isinf (void) const { - return Array<bool> (fastmap<bool> (xisinf)); + return do_mx_unary_map<boolNDArray, FloatNDArray, xisinf> (*this); } boolNDArray FloatNDArray::isfinite (void) const { - return Array<bool> (fastmap<bool> (xfinite)); + return do_mx_unary_map<boolNDArray, FloatNDArray, xfinite> (*this); } FloatMatrix
--- a/liboctave/mx-inlines.cc +++ b/liboctave/mx-inlines.cc @@ -197,8 +197,20 @@ DEFMXANYNAN(Complex) DEFMXANYNAN(FloatComplex) +#define DEFMXMAPPER(F, FUN) \ +template <class T> \ +inline void F (size_t n, T *r, const T *x) \ +{ for (size_t i = 0; i < n; i++) r[i] = FUN (x[i]); } + +template<class T> +inline void mx_inline_real (size_t n, T *r, const std::complex<T>* x) +{ for (size_t i = 0; i < n; i++) r[i] = x[i].real (); } +template<class T> +inline void mx_inline_imag (size_t n, T *r, const std::complex<T>* x) +{ for (size_t i = 0; i < n; i++) r[i] = x[i].imag (); } + // Pairwise minimums/maximums -#define DEFMXMAPPER(F, FUN) \ +#define DEFMXMAPPER2(F, FUN) \ template <class T> \ inline void F (size_t n, T *r, const T *x, const T *y) \ { for (size_t i = 0; i < n; i++) r[i] = FUN (x[i], y[i]); } \ @@ -209,35 +221,54 @@ inline void F (size_t n, T *r, T x, const T *y) \ { for (size_t i = 0; i < n; i++) r[i] = FUN (x, y[i]); } -DEFMXMAPPER (mx_inline_xmin, xmin) -DEFMXMAPPER (mx_inline_xmax, xmax) +DEFMXMAPPER2 (mx_inline_xmin, xmin) +DEFMXMAPPER2 (mx_inline_xmax, xmax) -#define DEFMXLOCALMAPPER(F, FUN, T) \ -static void F (size_t n, T *r, const T *x, const T *y) \ -{ for (size_t i = 0; i < n; i++) r[i] = FUN (x[i], y[i]); } \ -static void F (size_t n, T *r, const T *x, T y) \ -{ for (size_t i = 0; i < n; i++) r[i] = FUN (x[i], y); } \ -static void F (size_t n, T *r, T x, const T *y) \ -{ for (size_t i = 0; i < n; i++) r[i] = FUN (x, y[i]); } +// Arbitrary function appliers. The function is a template parameter to enable +// inlining. +template <class R, class X, R fun (X x)> +inline void mx_inline_map (size_t n, R *r, const X *x) +{ for (size_t i = 0; i < n; i++) r[i] = fun (x[i]); } + +template <class R, class X, R fun (const X& x)> +inline void mx_inline_map (size_t n, R *r, const X *x) +{ for (size_t i = 0; i < n; i++) r[i] = fun (x[i]); } // Appliers. Since these call the operation just once, we pass it as // a pointer, to allow the compiler reduce number of instances. +#define AELEMT(ARRAY) typename ARRAY::element_type template <class RNDA, class XNDA> inline RNDA do_mx_unary_op (const XNDA& x, - void (*op) (size_t, typename RNDA::element_type *, - const typename XNDA::element_type *)) + void (*op) (size_t, AELEMT(RNDA) *, + const AELEMT(XNDA) *)) { RNDA r (x.dims ()); op (r.length (), r.fortran_vec (), x.data ()); return r; } +// Shortcuts for applying mx_inline_map. + +template <class RNDA, class XNDA, AELEMT(RNDA) fun (AELEMT(XNDA))> +inline RNDA +do_mx_unary_map (const XNDA& x) +{ + return do_mx_unary_op<RNDA, XNDA> (x, mx_inline_map<AELEMT(RNDA), AELEMT(XNDA), fun>); +} + +template <class RNDA, class XNDA, AELEMT(RNDA) fun (const AELEMT(XNDA)&)> +inline RNDA +do_mx_unary_map (const XNDA& x) +{ + return do_mx_unary_op<RNDA, XNDA> (x, mx_inline_map<AELEMT(RNDA), AELEMT(XNDA), fun>); +} + template <class RNDA> inline RNDA& do_mx_inplace_op (RNDA& r, - void (*op) (size_t, typename RNDA::element_type *)) + void (*op) (size_t, AELEMT(RNDA) *)) { op (r.numel (), r.fortran_vec ()); return r; @@ -247,9 +278,9 @@ template <class RNDA, class XNDA, class YNDA> inline RNDA do_mm_binary_op (const XNDA& x, const YNDA& y, - void (*op) (size_t, typename RNDA::element_type *, - const typename XNDA::element_type *, - const typename YNDA::element_type *), + void (*op) (size_t, AELEMT(RNDA) *, + const AELEMT(XNDA) *, + const AELEMT(YNDA) *), const char *opname) { dim_vector dx = x.dims (), dy = y.dims (); @@ -269,8 +300,8 @@ template <class RNDA, class XNDA, class YS> inline RNDA do_ms_binary_op (const XNDA& x, const YS& y, - void (*op) (size_t, typename RNDA::element_type *, - const typename XNDA::element_type *, YS)) + void (*op) (size_t, AELEMT(RNDA) *, + const AELEMT(XNDA) *, YS)) { RNDA r (x.dims ()); op (r.length (), r.fortran_vec (), x.data (), y); @@ -280,8 +311,8 @@ template <class RNDA, class XS, class YNDA> inline RNDA do_sm_binary_op (const XS& x, const YNDA& y, - void (*op) (size_t, typename RNDA::element_type *, XS, - const typename YNDA::element_type *)) + void (*op) (size_t, AELEMT(RNDA) *, XS, + const AELEMT(YNDA) *)) { RNDA r (y.dims ()); op (r.length (), r.fortran_vec (), x, y.data ()); @@ -291,8 +322,8 @@ template <class RNDA, class XNDA> inline RNDA& do_mm_inplace_op (RNDA& r, const XNDA& x, - void (*op) (size_t, typename RNDA::element_type *, - const typename XNDA::element_type *), + void (*op) (size_t, AELEMT(RNDA) *, + const AELEMT(XNDA) *), const char *opname) { dim_vector dr = r.dims (), dx = x.dims (); @@ -306,7 +337,7 @@ template <class RNDA, class XS> inline RNDA& do_ms_inplace_op (RNDA& r, const XS& x, - void (*op) (size_t, typename RNDA::element_type *, XS)) + void (*op) (size_t, AELEMT(RNDA) *, XS)) { op (r.length (), r.fortran_vec (), x); return r; @@ -1084,7 +1115,7 @@ template <class ArrayType, class T> inline ArrayType do_mx_red_op (const Array<T>& src, int dim, - void (*mx_red_op) (const T *, typename ArrayType::element_type *, + void (*mx_red_op) (const T *, AELEMT(ArrayType) *, octave_idx_type, octave_idx_type, octave_idx_type)) { octave_idx_type l, n, u; @@ -1108,7 +1139,7 @@ template <class ArrayType, class T> inline ArrayType do_mx_cum_op (const Array<T>& src, int dim, - void (*mx_cum_op) (const T *, typename ArrayType::element_type *, + void (*mx_cum_op) (const T *, AELEMT(ArrayType) *, octave_idx_type, octave_idx_type, octave_idx_type)) { octave_idx_type l, n, u; @@ -1125,8 +1156,7 @@ template <class ArrayType> inline ArrayType do_mx_minmax_op (const ArrayType& src, int dim, - void (*mx_minmax_op) (const typename ArrayType::element_type *, - typename ArrayType::element_type *, + void (*mx_minmax_op) (const AELEMT(ArrayType) *, AELEMT(ArrayType) *, octave_idx_type, octave_idx_type, octave_idx_type)) { octave_idx_type l, n, u; @@ -1146,8 +1176,7 @@ template <class ArrayType> inline ArrayType do_mx_minmax_op (const ArrayType& src, Array<octave_idx_type>& idx, int dim, - void (*mx_minmax_op) (const typename ArrayType::element_type *, - typename ArrayType::element_type *, + void (*mx_minmax_op) (const AELEMT(ArrayType) *, AELEMT(ArrayType) *, octave_idx_type *, octave_idx_type, octave_idx_type, octave_idx_type)) { @@ -1171,8 +1200,7 @@ template <class ArrayType> inline ArrayType do_mx_cumminmax_op (const ArrayType& src, int dim, - void (*mx_cumminmax_op) (const typename ArrayType::element_type *, - typename ArrayType::element_type *, + void (*mx_cumminmax_op) (const AELEMT(ArrayType) *, AELEMT(ArrayType) *, octave_idx_type, octave_idx_type, octave_idx_type)) { octave_idx_type l, n, u; @@ -1188,8 +1216,7 @@ template <class ArrayType> inline ArrayType do_mx_cumminmax_op (const ArrayType& src, Array<octave_idx_type>& idx, int dim, - void (*mx_cumminmax_op) (const typename ArrayType::element_type *, - typename ArrayType::element_type *, + void (*mx_cumminmax_op) (const AELEMT(ArrayType) *, AELEMT(ArrayType) *, octave_idx_type *, octave_idx_type, octave_idx_type, octave_idx_type)) { @@ -1209,8 +1236,7 @@ template <class ArrayType> inline ArrayType do_mx_diff_op (const ArrayType& src, int dim, octave_idx_type order, - void (*mx_diff_op) (const typename ArrayType::element_type *, - typename ArrayType::element_type *, + void (*mx_diff_op) (const AELEMT(ArrayType) *, AELEMT(ArrayType) *, octave_idx_type, octave_idx_type, octave_idx_type, octave_idx_type)) {