# HG changeset patch # Parent b80b18f537ca059ce00df82376448638a52b474f Make bsxfun automatic for most binary operators. * MArray.cc: Give do_mm_binary_op two extra loop arguments so it can pass them to bsxfun. * MDiagArray2.cc: Ditto. * mx-op-defs.h: Ditto. * bsxfun.h: New file. * Makefile.am: Add bsxfun.h to includes. * mx-inlines.cc: Call do_bsxfun_op when appropriate. diff -r b80b18f537ca liboctave/MArray.cc --- a/liboctave/MArray.cc Tue Aug 16 10:03:33 2011 -0700 +++ b/liboctave/MArray.cc Wed Aug 17 02:02:04 2011 -0500 @@ -339,7 +339,7 @@ MArray \ FCN (const MArray& a, const MArray& b) \ { \ - return do_mm_binary_op (a, b, FN, #FCN); \ + return do_mm_binary_op (a, b, FN, FN, FN, #FCN); \ } MARRAY_NDND_OP (operator +, +, mx_inline_add) diff -r b80b18f537ca liboctave/MDiagArray2.cc --- a/liboctave/MDiagArray2.cc Tue Aug 16 10:03:33 2011 -0700 +++ b/liboctave/MDiagArray2.cc Wed Aug 17 02:02:04 2011 -0500 @@ -82,7 +82,7 @@ { \ if (a.d1 != b.d1 || a.d2 != b.d2) \ gripe_nonconformant (#FCN, a.d1, a.d2, b.d1, b.d2); \ - return MDiagArray2 (do_mm_binary_op (a, b, FN, #FCN), a.d1, a.d2); \ + return MDiagArray2 (do_mm_binary_op (a, b, FN, FN, FN, #FCN), a.d1, a.d2); \ } MARRAY_DADA_OP (operator +, +, mx_inline_add) diff -r b80b18f537ca liboctave/Makefile.am --- a/liboctave/Makefile.am Tue Aug 16 10:03:33 2011 -0700 +++ b/liboctave/Makefile.am Wed Aug 17 02:02:04 2011 -0500 @@ -188,6 +188,7 @@ base-dae.h \ base-de.h \ base-min.h \ + bsxfun.h \ byte-swap.h \ caseless-str.h \ cmd-edit.h \ diff -r b80b18f537ca liboctave/bsxfun.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/liboctave/bsxfun.h Wed Aug 17 02:02:04 2011 -0500 @@ -0,0 +1,40 @@ +/* + +Copyright (C) 2011 Jordi GutiƩrrez Hermoso + +This file is part of Octave. + +Octave is free software; you can redistribute it and/or modify it +under the terms of the GNU General Public License as published by the +Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +Octave is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with Octave; see the file COPYING. If not, see +. + +*/ + +#include + +#include "Array.h" +#include "dim-vector.h" + +#include "bsxfun-defs.cc" + +inline +bool +is_valid_bsxfun (const dim_vector& dx, const dim_vector& dy) +{ + for (int i = 0; i < std::min (dx.length (), dy.length ()); i++) + { + if ( dx(i) > 1 && dy(i) > 1 && dx(i) != dy(i)) + return false; + } + return true; +} diff -r b80b18f537ca liboctave/mx-inlines.cc --- a/liboctave/mx-inlines.cc Tue Aug 16 10:03:33 2011 -0700 +++ b/liboctave/mx-inlines.cc Wed Aug 17 02:02:04 2011 -0500 @@ -37,6 +37,8 @@ #include "Array.h" #include "Array-util.h" +#include "bsxfun.h" + // Provides some commonly repeated, basic loop templates. template @@ -336,11 +338,12 @@ return r; } - template inline Array do_mm_binary_op (const Array& x, const Array& y, void (*op) (size_t, R *, const X *, const Y *) throw (), + void (*op1) (size_t, R *, X, const Y *) throw (), + void (*op2) (size_t, R *, const X *, Y) throw (), const char *opname) { dim_vector dx = x.dims (), dy = y.dims (); @@ -350,6 +353,10 @@ op (r.length (), r.fortran_vec (), x.data (), y.data ()); return r; } + else if (is_valid_bsxfun (dx, dy)) + { + return do_bsxfun_op (x, y, op, op1, op2); + } else { gripe_nonconformant (opname, dx, dy); diff -r b80b18f537ca liboctave/mx-op-defs.h --- a/liboctave/mx-op-defs.h Tue Aug 16 10:03:33 2011 -0700 +++ b/liboctave/mx-op-defs.h Wed Aug 17 02:02:04 2011 -0500 @@ -72,7 +72,7 @@ R \ F (const V1& v1, const V2& v2) \ { \ - return do_mm_binary_op (v1, v2, OP, #F); \ + return do_mm_binary_op (v1, v2, OP, OP, OP, #F); \ } #define VV_BIN_OPS(R, V1, V2) \ @@ -173,7 +173,7 @@ R \ OP (const M1& m1, const M2& m2) \ { \ - return do_mm_binary_op (m1, m2, F, #OP); \ + return do_mm_binary_op (m1, m2, F, F, F, #OP); \ } #define MM_BIN_OPS(R, M1, M2) \ @@ -186,7 +186,7 @@ boolMatrix \ F (const M1& m1, const M2& m2) \ { \ - return do_mm_binary_op (m1, m2, OP, #F); \ + return do_mm_binary_op (m1, m2, OP, OP, OP, #F); \ } #define MM_CMP_OPS(M1, M2) \ @@ -203,7 +203,7 @@ { \ MNANCHK (m1, M1::element_type); \ MNANCHK (m2, M2::element_type); \ - return do_mm_binary_op (m1, m2, OP, #F); \ + return do_mm_binary_op (m1, m2, OP, OP, OP, #F); \ } #define MM_BOOL_OPS(M1, M2) \ @@ -310,7 +310,7 @@ R \ OP (const ND1& m1, const ND2& m2) \ { \ - return do_mm_binary_op (m1, m2, F, #OP); \ + return do_mm_binary_op (m1, m2, F, F, F, #OP); \ } #define NDND_BIN_OPS(R, ND1, ND2) \ @@ -323,7 +323,7 @@ boolNDArray \ F (const ND1& m1, const ND2& m2) \ { \ - return do_mm_binary_op (m1, m2, OP, #F); \ + return do_mm_binary_op (m1, m2, OP, OP, OP, #F); \ } #define NDND_CMP_OPS(ND1, ND2) \ @@ -340,7 +340,7 @@ { \ MNANCHK (m1, ND1::element_type); \ MNANCHK (m2, ND2::element_type); \ - return do_mm_binary_op (m1, m2, OP, #F); \ + return do_mm_binary_op (m1, m2, OP, OP, OP, #F); \ } #define NDND_BOOL_OPS(ND1, ND2) \ @@ -583,7 +583,7 @@ T \ FCN (const T& a, const T& b) \ { \ - return do_mm_binary_op (a, b, mx_inline_x##FCN, #FCN); \ + return do_mm_binary_op (a, b, mx_inline_x##FCN, mx_inline_x##FCN, mx_inline_x##FCN, #FCN); \ } #define MINMAX_FCNS(T, S) \