Converting bsxfun with @times to numpy Converting bsxfun with @times to numpy numpy numpy

Converting bsxfun with @times to numpy


bsxfun in Matlab stand for binary singleton expansion, in numpy it's called broadcasting and should happen automatically. The solution will depend on the dimensions of your X, i.e. is it a row or column vector but this answer shows one way to do it:

How to multiply numpy 2D array with numpy 1D array?

I think that the issue here is that broadcasting requires one of the dimensions to be 1 and, unlike Matlab, numpy seems to differentiate between a 1 dimensional 2 element vector and a 2 dimensional 2 element, i.e. the difference between a matrix of shape (2,) and of shape (2,1), you need the latter for broadcasting to happen.


For those who don't know Numpy, I think it's worth pointing out that the equivalent of Octave's (and Matlab's) * operator (matrix multiplication) is numpy.dot (and, debatably, numpy.outer). Numpy's * operator is similar to bsxfun(@times,...) in Octave, which is itself a generalization of .*.

In Octave, when applying bsxfun, there are implicit singleton dimensions to the right of the "true" size of the operands; that is, an n1 x n2 x n3 array can be considered as n1 x n2 x n3 x 1 x 1 x 1 x.... In Numpy, the implicit singleton dimensions are to the left; so an m1 x m2 x m3 can be considered as ... x 1 x 1 x m1 x m2 x m3. This matters when considering operand sizes: in Octave, bsxfun(@times,a,b) will work if a is 2 x 3 x 4 and b is 2 x 3. In Numpy one could not multiply two such arrays, but one could multiply a 2 x 3 x 4 and a 3 x 4 array.

Finally, bsxfun(@times, X*Y, X) in Octave will probably look something like numpy.dot(X,Y) * X. There are still some gotchas: for instance, if you're expecting an outer product (that is, in Octave X is a column vector, Y a row vector), you could look at using numpy.outer instead, or be careful about the shape of X and Y.


Little late, but I would like to provide an example of having equivalent bsxfun and repmat in python. This is a little bit of code I was just converting from Matlab to Python numpy:

Matlab:

x =    -2    -1     0     1     2n = 2M = repmat(x,1,n+1)M =    -2    -2    -2    -1    -1    -1     0     0     0     1     1     1     2     2     2M = bsxfun(@power,M,0:n)M =     1    -2     4     1    -1     1     1     0     0     1     1     1     1     2     4

Equivalent in Python:

In [8]: xOut[8]: array([[-2],       [-1],       [ 0],       [ 1],       [ 2]])In [9]: n=2In [11]: M = np.tile(x, (1, n + 1))In [12]: MOut[12]: array([[-2, -2, -2],       [-1, -1, -1],       [ 0,  0,  0],       [ 1,  1,  1],       [ 2,  2,  2]])In [13]:  M = np.apply_along_axis(pow, 1, M, range(n + 1))In [14]: MOut[14]: array([[ 1, -2,  4],       [ 1, -1,  1],       [ 1,  0,  0],       [ 1,  1,  1],       [ 1,  2,  4]])