Reputation: 587
This is the code I have in Octave:
sum(bsxfun(@times, X*Y, X), 2)
The bsxfun part of the code produces element-wise multiplication so I thought that numpy.multiply(X*Y, X)
would do the trick but I got an exception. When I did a bit of research I found that element-wise multiplication won't work on Python arrays (specifically if X and Y are of type "numpy.ndarray"). So I was wondering if anyone can explain this a bit more -- i.e. would type casting to a different type of object work? The Octave code works so I know I don't have a linear algebra mistake. I'm assuming that bsxfun and numpy.multiply are not actually equivalent but I'm not sure why so any explanations would be great.
I was able to find a website! that gives Octave to Matlab function conversions but it didn't seem to be help in my case.
Upvotes: 12
Views: 8795
Reputation: 238139
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
2
n =
2
M = repmat(x,1,n+1)
M =
-2 -2 -2
-1 -1 -1
0 0 0
1 1 1
2 2 2
M = 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]: x
Out[8]:
array([[-2],
[-1],
[ 0],
[ 1],
[ 2]])
In [9]: n=2
In [11]: M = np.tile(x, (1, n + 1))
In [12]: M
Out[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]: M
Out[14]:
array([[ 1, -2, 4],
[ 1, -1, 1],
[ 1, 0, 0],
[ 1, 1, 1],
[ 1, 2, 4]])
Upvotes: 0
Reputation: 45752
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.
Upvotes: 14
Reputation: 2236
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.
Upvotes: 3