File Exchange

Binary array expansion function

version 1.0 (3.32 KB) by

element-by-element binary operations (e.g. plus, times, eq, gt) with array expansion (AX) enabled.

Updated

This function is a generalization of BSXFUN, provided as a builtin function in MATLAB R2007a and later releases. It is part of the ARRAYLAB toolbox, together with MULTIPROD (MATLAB Central, file #8773) and the Vector algebra toolbox (MATLAB Central file #8782).

BAXFUN is called by some of the functions in the vector algebra toolbox.

C = BAXFUN(FUNC, A, B) applies an element-by-element binary operation to arrays A and B, with singleton expansion (SX) enabled. It is equivalent to C = BSXFUN(FUNC, A, B). FUNC is a function handle.

C = BAXFUN(FUNC, A, B, SHIFTA, SHIFTB) applies an element-by-element binary operation to arrays A and B, with array expansion (AX) enabled. FUNC is a function handle. SHIFTA and SHIFTB specify the number of dimensions by which arrays A and B are optionally shifted to the right (positive values) or left (negative values). Thus,
C = BAXFUN(FUNC, A, B, SHIFTA, SHIFTB) is equivalent to
C = BAXFUN(FUNC, SHIFTDIM(A,-SHIFTA), SHIFTDIM(B,-SHIFTB)).
C = BAXFUN(FUNC, A, B, SHIFTA) can be used if B is not to be shifted.

FUNC can either be an handle for an M-function, or one of the following built-in-function handles:

@plus Plus
@minus Minus
@times Array multiply
@rdivide Right array divide
@ldivide Left array divide
@power Array power
@max Binary maximum
@min Binary minimum
@rem Division remainder
@mod Division modulus
@hypot SQRT of sum of squares
@eq Equal
@ne Not equal
@lt Less than
@le Less than or equal
@gt Greater than
@ge Greater than or equal
@and Logical AND
@or Logical OR
@xor Logical EXCLUSIVE OR

If an M-function handle is specified, the M-function must be able to accept as input either two column vectors of the same size, or one column vector and one scalar, and return as output a column vector of the same size as the input(s).

Array expansion (AX) is a powerful generalization of the concept of scalar expansion. Scalar expansion is the virtual replication or annihilation of a scalar which allows you to combine it, element by element, with an array X of any size (e.g. X+10, X*10, or []-10). Similarly, in BAXFUN, the purpose of AX is to virtually match the sizes of A and B, before FUNC is applied. Indeed, A and B can be scalars, vectors, matrices, or multi-dimensional arrays, and may have different sizes. Dimension matching is achieved by means of a dimension shift followed by a singleton expansion:

1) DIMENSION SHIFT
A dimension shift (see SHIFTIM) is applied to A or B if a non-zero value is specified for SHIFTA or SHIFTB. Notice that, in BAXFUN, a shift to the left is hardly ever needed. Hence, positive values of SHIFTA/B indicate a shift to the rigth, and negative values a shift to the left, whereas SHIFTDIM uses the opposite convention.

2) SINGLETON EXPANSION (SX)
Whenever a dimension of either A or B is singleton and the corresponding dimension of the other array is not, the mismatch is fixed by virtually replicating (or diminishing to length 0) the array along that dimension.

BAXFUN applies elementwise operations. Matrix multiplications with AX enabled can be performed using MULTIPROD (MATLAB Central, file #8773). BAXFUN calls the builtin function BBXFUN, available in MATLAB R2007a. For earlier MATLAB releases, use Schwarz's replacement of BSXFUN (MATLAB Central, file #23005)

Examples:
Subtracting the column means from a matrix A
a = magic(5); % ................. 5×5
a = baxfun(@minus, a, mean(a)); % 5×5

Subtracting the matrix means from 10 matrices contained in A
a = rand(3, 3, 10); % ............... 3×3×10
means = mean(reshape(a, 9, 10)); % .... 1×10
a = baxfun(@minus, a, means, 0, 1); % 3×3×10

Multiplying matrix A by each element of B, i.e. multiplying each
element of A by each element of B (all possible combinations)
a = [1 2 3 4; 5 6 7 8]; % ....... 2×4
b = [1 10 100]; % ................. 1×3
c = baxfun(@times, a, b, 0, 1); % 2×4×3

c(:,:,1) =
1 2 3 4
5 6 7 8

c(:,:,2) =
10 20 30 40
50 60 70 80

c(:,:,3) =
100 200 300 400
500 600 700 800

Paolo de Leva

Paolo de Leva (view profile)

BAXFUN is just a trifling enhancement to the built-in function BSXFUN. The enhanced syntax just allows you to operate a dimension shift before applying the specified binary function. However, I believe it is useful to publish it for two reasons:
1) it teaches to whoever is willing to read the help text how much additional power you can obtain from BSXFUN if you combine it with a dimension shift (see examples), and it provides a compact syntax to do it with a single instruction.
2) AX was first enabled for matrix multiplication, with version 2.0 of MULTIPROD (MATLAB Central, file #8773), and for vectorial operations, with the latest version of the Vector algebra toolbox, (MATLAB Central file #8782). In these applications, it provides a terrific service. For the sake of consistency, however, I felt that it was also necessary to enable AX for element-wise operations.

MATLAB 7 (R14)