Matlab equivalent of Numpy broadcasting?
Asked Answered
R

4

24

I'm trying to find some way to substract a size 3 vector from each column of a 3*(a big number) matrix in Matlab. Of course I could use a loop, but I'm trying to find some more efficient solution, a bit like numpy broadcasting. Oh, and I can't use repmat because I just don't have enough memory to use it (as it creates yet another 3*(a big number) matrix)...

Is this possible?

Redletter answered 9/7, 2010 at 13:49 Comment(1)
As one of the more recent answers points out, Matlab R2016b appears to have added broadcasting as a standard feature. (nickhigham.wordpress.com/2016/09/20/…)Benita
B
18

Loops aren't bad in MATLAB anymore thanks to compiler optimizations like just-in-time acceleration (JITA). etc. Most of the time, I've noticed that a solution with loops in current MATLAB versions is much faster than complicated (albeit, cool :D) one-liners.

bsxfun might do the trick but in my experience, it tends to have memory issues as well but less so than repmat.

So the syntax would be:

AA = bsxfun(@minus,A,b) where b is the vector and A is your big matrix

But I urge you to profile the loopy version and then decide! Most probably, due to memory constraints, you might not have a choice :)

Brumal answered 9/7, 2010 at 13:51 Comment(5)
You may be right about BSXFUN. It will still have memory issues, but I believe it usually does slightly better than using REPMAT.Kairouan
The thing I like about bsxfun is that in the 2010a and 2010b versions it will natively multithread your code for improved performance without too much intervention on your part.Plott
@JudoWill: That's great! I've been looking for a clear case against repmat --- do you have any documentation regarding it?Brumal
Perhaps this link: mathworks.com/support/solutions/en/data/1-4PG4AN/… , as you can see, multithreading only kicks in for large enough matrices.Lachrymal
As one of the more recent answers points out, Matlab R2016b appears to have added broadcasting as a standard feature. (nickhigham.wordpress.com/2016/09/20/…)Benita
I
19

The other answers are a bit out of date -- Matlab R2016b appears to have added broadcasting as a standard feature. An example from that blog post that matches the question:

>> A = ones(2) + [1 5]'
A =
     2     2
     6     6
Inclining answered 18/10, 2016 at 9:44 Comment(2)
There's some other amazing new features in 2016b too, like first-class strings (mathworks.com/help/matlab/matlab_prog/create-string-arrays.html) that you can concatenate with "+". Oh, I was just being sarcastic :-)Redletter
Note: Broadcasting is great but sometimes you don't get what you want. I just spent 4 hours tracking down this mistake in my code: x=(1-A+K*C)^-1; % A is an nxn matrix. MATLAB doesn't know I wanted the identity matrix! (sharing for the benefit of others).Diatom
B
18

Loops aren't bad in MATLAB anymore thanks to compiler optimizations like just-in-time acceleration (JITA). etc. Most of the time, I've noticed that a solution with loops in current MATLAB versions is much faster than complicated (albeit, cool :D) one-liners.

bsxfun might do the trick but in my experience, it tends to have memory issues as well but less so than repmat.

So the syntax would be:

AA = bsxfun(@minus,A,b) where b is the vector and A is your big matrix

But I urge you to profile the loopy version and then decide! Most probably, due to memory constraints, you might not have a choice :)

Brumal answered 9/7, 2010 at 13:51 Comment(5)
You may be right about BSXFUN. It will still have memory issues, but I believe it usually does slightly better than using REPMAT.Kairouan
The thing I like about bsxfun is that in the 2010a and 2010b versions it will natively multithread your code for improved performance without too much intervention on your part.Plott
@JudoWill: That's great! I've been looking for a clear case against repmat --- do you have any documentation regarding it?Brumal
Perhaps this link: mathworks.com/support/solutions/en/data/1-4PG4AN/… , as you can see, multithreading only kicks in for large enough matrices.Lachrymal
As one of the more recent answers points out, Matlab R2016b appears to have added broadcasting as a standard feature. (nickhigham.wordpress.com/2016/09/20/…)Benita
B
4

I don't know if this will speed up the code, but subtraction of a scalar from a vector doesn't have memory issues. Since your matrix size is so asymmetrical, the overhead from a for-loop on the short dimension is negligible.

So maybe

matout = matin;
for j = 1:size(matin, 1) %3 in this case
     matout(j,:) = matin(j,:) - vec_to_subtract(j);
end

of course, you could do this in place, but I didn't know if you wanted to preserve the original matrix.

Botvinnik answered 12/7, 2010 at 17:16 Comment(2)
Actually, the for loop is on the large dimension (as I'm substracting a size-3 vector from each column of a size-3*(a lot) array), so that was why I was afraid of the for loop.Redletter
Think about it this way -- divide your array into 3 vectors of size 1xN. then subtract the corresponding scalar from each vector. So the for loop is along the short dimension.Botvinnik
R
0

Actually, it seems that http://www.frontiernet.net/~dmschwarz/genops.html (operator overloading with mex files) does the trick too, even though I haven't tested it yet.

Redletter answered 19/7, 2010 at 13:24 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.