# HG changeset patch # User Jordi GutiƩrrez Hermoso # Date 1314263231 18000 # Node ID 61be447052c385d514d65e493ee15929c31f05b9 # Parent 4061106b1c4b26bac6473fbc265f6d9046e4ef83 Implement automatic bsxfun almost everywhere now except sparse matrices. * bsxfun.h: Move the .cc include since it uses the declaration of the function * oct-binmap.h: Call bsxfun on Array-Array binmap, and pass functions by pointer instead of by reference so they can be passed to do_bsxfun_op. * xor.m: Trivially call bsxfun by default. diff -r 4061106b1c4b -r 61be447052c3 liboctave/bsxfun.h --- a/liboctave/bsxfun.h Wed Aug 24 23:12:28 2011 -0500 +++ b/liboctave/bsxfun.h Thu Aug 25 04:07:11 2011 -0500 @@ -27,8 +27,6 @@ #include "Array.h" #include "dim-vector.h" -#include "bsxfun-defs.cc" - inline bool is_valid_bsxfun (const dim_vector& dx, const dim_vector& dy) @@ -41,4 +39,6 @@ return true; } +#include "bsxfun-defs.cc" + #endif diff -r 4061106b1c4b -r 61be447052c3 liboctave/oct-binmap.h --- a/liboctave/oct-binmap.h Wed Aug 24 23:12:28 2011 -0500 +++ b/liboctave/oct-binmap.h Thu Aug 25 04:07:11 2011 -0500 @@ -27,9 +27,13 @@ #include "Sparse.h" #include "Array-util.h" -// This source implements a general binary maping function for arrays. -// The syntax is binmap (a, b, f, [name]). type denotes the expected -// return type of the operation. a, b, should be one of the 6 combinations: +#include "bsxfun.h" + +// This source file implements a general binary maping function for +// arrays. The syntax is binmap (a, b, f, [name]). type denotes +// the expected return type of the operation. a, b, should be one of +// the 6 combinations: +// // Array-Array // Array-scalar // scalar-Array @@ -37,11 +41,12 @@ // Sparse-scalar // scalar-Sparse // -// If both operands are nonscalar, name must be supplied. It is used as the base for error message -// when operands are nonconforming. +// If both operands are nonscalar, name must be supplied. It is used +// as the base for error message when operands are nonconforming. // -// The operation needs not be homogeneous, i.e. a, b and the result may be of distinct types. -// f can have any of the four signatures: +// The operation needs not be homogeneous, i.e. a, b and the result +// may be of distinct types. f can have any of the four signatures: +// // U f (T, R) // U f (const T&, R) // U f (T, const R&) @@ -49,7 +54,51 @@ // // Additionally, f can be an arbitrary functor object. // -// octave_quit() is called at appropriate places, hence the operation is breakable. +// octave_quit() is called at appropriate places, hence the operation +// is breakable. + +// The following template wrappers are provided for automatic bsxfun +// calls (see the function signature for do_bsxfun_op). + +template +class bsxfun_wrapper +{ +private: + static F f; + +public: + static void + set_f (const F& f_in) + { + f = f_in; + } + + static void + op_mm (size_t n, R* r, const X* x , const Y* y) + { + for (size_t i = 0; i < n; i++) + r[i] = f (x[i], y[i]); + } + + static void + op_sm (size_t n, R* r, X x, const Y* y) + { + for (size_t i = 0; i < n; i++) + r[i] = f (x, y[i]); + } + + static void + op_ms (size_t n , R* r, const X* x, Y y) + { + for (size_t i = 0; i < n; i++) + r[i] = f (x[i], y); + } +}; + +// Static init +template +F bsxfun_wrapper::f; + // scalar-Array template @@ -118,12 +167,24 @@ Array binmap (const Array& xa, const Array& ya, F fcn, const char *name) { + dim_vector xad = xa.dims (), yad = ya.dims (); if (xa.numel () == 1) return binmap (xa(0), ya, fcn); else if (ya.numel () == 1) return binmap (xa, ya(0), fcn); - else if (xa.dims () != ya.dims ()) - gripe_nonconformant (name, xa.dims (), ya.dims ()); + else if (xad != yad) + { + if (is_valid_bsxfun (xad, yad)) + { + bsxfun_wrapper::set_f(fcn); + return do_bsxfun_op (xa, ya, + bsxfun_wrapper::op_mm, + bsxfun_wrapper::op_sm, + bsxfun_wrapper::op_ms); + } + else + gripe_nonconformant (name, xad, yad); + } octave_idx_type len = xa.numel (); @@ -273,134 +334,134 @@ fcn, name)); } -// Overloads for function references. +// Overloads for function pointers. // Signature (T, R) template inline Array -binmap (const Array& xa, const Array& ya, U (&fcn) (T, R), const char *name) -{ return binmap (xa, ya, fcn, name); } +binmap (const Array& xa, const Array& ya, U (*fcn) (T, R), const char *name) +{ return binmap (xa, ya, fcn, name); } template inline Array -binmap (const T& x, const Array& ya, U (&fcn) (T, R)) -{ return binmap (x, ya, fcn); } +binmap (const T& x, const Array& ya, U (*fcn) (T, R)) +{ return binmap (x, ya, fcn); } template inline Array -binmap (const Array& xa, const R& y, U (&fcn) (T, R)) -{ return binmap (xa, y, fcn); } +binmap (const Array& xa, const R& y, U (*fcn) (T, R)) +{ return binmap (xa, y, fcn); } template inline Sparse -binmap (const Sparse& xa, const Sparse& ya, U (&fcn) (T, R), const char *name) -{ return binmap (xa, ya, fcn, name); } +binmap (const Sparse& xa, const Sparse& ya, U (*fcn) (T, R), const char *name) +{ return binmap (xa, ya, fcn, name); } template inline Sparse -binmap (const T& x, const Sparse& ya, U (&fcn) (T, R)) -{ return binmap (x, ya, fcn); } +binmap (const T& x, const Sparse& ya, U (*fcn) (T, R)) +{ return binmap (x, ya, fcn); } template inline Sparse -binmap (const Sparse& xa, const R& y, U (&fcn) (T, R)) -{ return binmap (xa, y, fcn); } +binmap (const Sparse& xa, const R& y, U (*fcn) (T, R)) +{ return binmap (xa, y, fcn); } // Signature (const T&, const R&) template inline Array -binmap (const Array& xa, const Array& ya, U (&fcn) (const T&, const R&), const char *name) -{ return binmap (xa, ya, fcn, name); } +binmap (const Array& xa, const Array& ya, U (*fcn) (const T&, const R&), const char *name) +{ return binmap (xa, ya, fcn, name); } template inline Array -binmap (const T& x, const Array& ya, U (&fcn) (const T&, const R&)) -{ return binmap (x, ya, fcn); } +binmap (const T& x, const Array& ya, U (*fcn) (const T&, const R&)) +{ return binmap (x, ya, fcn); } template inline Array -binmap (const Array& xa, const R& y, U (&fcn) (const T&, const R&)) -{ return binmap (xa, y, fcn); } +binmap (const Array& xa, const R& y, U (*fcn) (const T&, const R&)) +{ return binmap (xa, y, fcn); } template inline Sparse -binmap (const Sparse& xa, const Sparse& ya, U (&fcn) (const T&, const R&), const char *name) -{ return binmap (xa, ya, fcn, name); } +binmap (const Sparse& xa, const Sparse& ya, U (*fcn) (const T&, const R&), const char *name) +{ return binmap (xa, ya, fcn, name); } template inline Sparse -binmap (const T& x, const Sparse& ya, U (&fcn) (const T&, const R&)) -{ return binmap (x, ya, fcn); } +binmap (const T& x, const Sparse& ya, U (*fcn) (const T&, const R&)) +{ return binmap (x, ya, fcn); } template inline Sparse -binmap (const Sparse& xa, const R& y, U (&fcn) (const T&, const R&)) -{ return binmap (xa, y, fcn); } +binmap (const Sparse& xa, const R& y, U (*fcn) (const T&, const R&)) +{ return binmap (xa, y, fcn); } // Signature (const T&, R) template inline Array -binmap (const Array& xa, const Array& ya, U (&fcn) (const T&, R), const char *name) -{ return binmap (xa, ya, fcn, name); } +binmap (const Array& xa, const Array& ya, U (*fcn) (const T&, R), const char *name) +{ return binmap (xa, ya, fcn, name); } template inline Array -binmap (const T& x, const Array& ya, U (&fcn) (const T&, R)) -{ return binmap (x, ya, fcn); } +binmap (const T& x, const Array& ya, U (*fcn) (const T&, R)) +{ return binmap (x, ya, fcn); } template inline Array -binmap (const Array& xa, const R& y, U (&fcn) (const T&, R)) -{ return binmap (xa, y, fcn); } +binmap (const Array& xa, const R& y, U (*fcn) (const T&, R)) +{ return binmap (xa, y, fcn); } template inline Sparse -binmap (const Sparse& xa, const Sparse& ya, U (&fcn) (const T&, R), const char *name) -{ return binmap (xa, ya, fcn, name); } +binmap (const Sparse& xa, const Sparse& ya, U (*fcn) (const T&, R), const char *name) +{ return binmap (xa, ya, fcn, name); } template inline Sparse -binmap (const T& x, const Sparse& ya, U (&fcn) (const T&, R)) -{ return binmap (x, ya, fcn); } +binmap (const T& x, const Sparse& ya, U (*fcn) (const T&, R)) +{ return binmap (x, ya, fcn); } template inline Sparse -binmap (const Sparse& xa, const R& y, U (&fcn) (const T&, R)) -{ return binmap (xa, y, fcn); } +binmap (const Sparse& xa, const R& y, U (*fcn) (const T&, R)) +{ return binmap (xa, y, fcn); } // Signature (T, const R&) template inline Array -binmap (const Array& xa, const Array& ya, U (&fcn) (T, const R&), const char *name) -{ return binmap (xa, ya, fcn, name); } +binmap (const Array& xa, const Array& ya, U (*fcn) (T, const R&), const char *name) +{ return binmap (xa, ya, fcn, name); } template inline Array -binmap (const T& x, const Array& ya, U (&fcn) (T, const R&)) -{ return binmap (x, ya, fcn); } +binmap (const T& x, const Array& ya, U (*fcn) (T, const R&)) +{ return binmap (x, ya, fcn); } template inline Array -binmap (const Array& xa, const R& y, U (&fcn) (T, const R&)) -{ return binmap (xa, y, fcn); } +binmap (const Array& xa, const R& y, U (*fcn) (T, const R&)) +{ return binmap (xa, y, fcn); } template inline Sparse -binmap (const Sparse& xa, const Sparse& ya, U (&fcn) (T, const R&), const char *name) -{ return binmap (xa, ya, fcn, name); } +binmap (const Sparse& xa, const Sparse& ya, U (*fcn) (T, const R&), const char *name) +{ return binmap (xa, ya, fcn, name); } template inline Sparse -binmap (const T& x, const Sparse& ya, U (&fcn) (T, const R&)) -{ return binmap (x, ya, fcn); } +binmap (const T& x, const Sparse& ya, U (*fcn) (T, const R&)) +{ return binmap (x, ya, fcn); } template inline Sparse -binmap (const Sparse& xa, const R& y, U (&fcn) (T, const R&)) -{ return binmap (xa, y, fcn); } +binmap (const Sparse& xa, const R& y, U (*fcn) (T, const R&)) +{ return binmap (xa, y, fcn); } #endif diff -r 4061106b1c4b -r 61be447052c3 scripts/miscellaneous/xor.m --- a/scripts/miscellaneous/xor.m Wed Aug 24 23:12:28 2011 -0500 +++ b/scripts/miscellaneous/xor.m Thu Aug 25 04:07:11 2011 -0500 @@ -48,7 +48,11 @@ ## Typecast to logicals is necessary for other numeric types. z = logical (x) != logical (y); else - error ("xor: X and Y must be of common size or scalars"); + try + z = bsxfun (@xor, x, y); + catch + error ("xor: X and Y must be of compatible size or scalars"); + end_try_catch endif else print_usage ();