6

There are mainly two things I would like to research on about here -

  • There are six built-in relational operations for use with bsxfun : @eq (equal), @ne (not-equal), @lt (less-than), @le (less-than or equal), @gt (greater-than) and @ge (greater-than or equal). Lots of times we use them on floating point numbers and being relational operations, they output logical arrays. So, it got me curious, if the inherent expansion with bsxfun when using these relational operations on floating point numbers involve actual replication of input elements and that is precisely my first question.

  • I would also like to know how this memory efficiency issue translates to the anonymous functions when used with bsxfun, again with the case of relational operations.

This is inspired by the runtime/speedup tests performed for Comparing BSXFUN and REPMAT.

Community
  • 1
  • 1
Divakar
  • 218,885
  • 19
  • 262
  • 358
  • Maybe add a link to your previous question and answer about `bsxfun` time performance? – Luis Mendo Apr 22 '15 at 14:41
  • @LuisMendo Actually I wanted to give this a general background, as I think this memory efficiency with bsxfun for relational operations is unique to it and wanted to put focus just on memory part. repmat just acted something to compare against with. Linked it anyway here in the question :) – Divakar Apr 22 '15 at 15:21

1 Answers1

8

Introduction & Test Setup

To perform memory tests to inquire about the points raised in the question, let's define the inputs A and B:

A = rand(M,N)
B = rand(1,N)

Here, M and N are the size parameters and are kept as really large numbers.

I would be using repmat for comparisons as that seems like the closest alternative to bsxfun. So, the idea here to run the bsxfun and repmat equivalent codes and watch out for the bumps in memory usages from the Task Manager (on Windows).

This solution that compared bsxfun and repmat for runtime efficiency led to the conclusions that using relational operations with bsxfun is hugely runtime efficient, so it would be interesting to extend the basis of memory efficiency to the comparisons.

Thus, the bsxfun and repmat equivalents would look something like these -

REPMAT version:  A == repmat(B,size(A,1),1)
BSXFUN version: bsxfun(@eq,A,B))

Results

On running the repmat and then bsxfun codes, the Windows Task Manager showed something like this with the first bump denoting the run for repmat and the next one is for the bsxfun one -

enter image description here

The repmat bump has the same height as that when an actual copy of A is created. This basically shows that repmat makes an actual replication of B and then does the equality check. Since, B is to be replicated to a bigger floating point array, the memory requirements are huge as again shown in the memory graph earlier. On the other hand with bsxfun, from its bump height it seems is not replicating the actual floating point values and that leads to an efficient memory usage.

Now, after converting both A and B to logical arrays, the memory usage bumps changed to this -

enter image description here

Thus, it suggests that repmat was then able to optimize memory, as this time the replication was of logical datatype.

Using anonymous functions with bsxfun: One can experiment a bit with the anonymous functions usage with bsxfun and see if MATLAB shows the same smartness with it in optimizing memory requirements as with the built-in.

So, bsxfun(@eq,A,B) could be replaced by bsxfun(@(k1,k2) k1==k2,A,B). The resultant memory usage with this built-in and anonymous function implementation when operated on floating point input arrays, resulted in a memory graph as shown below -

enter image description here

The plot indicates that the use of anonymous function keeps the memory efficiency as with the built-in, even though the runtime is hampered quite a bit. The test results were similar when other relational operations were used instead.

Conclusions

When working with relational operations on floating-point arrays, it's definitely preferable to use bsxfun over repmat for both runtime and memory efficiency. So, this just proves that there are more reasons to go with bsxfun!

Community
  • 1
  • 1
Divakar
  • 218,885
  • 19
  • 262
  • 358
  • 2
    I'm very glad to read this. You know, we `bsxfun` addicts need excuses for our addiction – Luis Mendo Apr 22 '15 at 14:38
  • I assume this question and answer may have been partly motivated by [this](http://stackoverflow.com/questions/28722723/matlab-bsxfun-no-longer-faster-than-repmat/29753104?noredirect=1#comment47725299_29753104), right? – Luis Mendo Apr 22 '15 at 14:38
  • @LuisMendo Actually that was the coincidence, I got something like this yesterday and wasn't sure whether to make it a new question out of it or add to the my previous question on comparing bsxfun and repmat. I had few comparisons with the floating point operations too, but nothing interesting in them, so just stuck with the relational operations. But yeah, the post and the Sam's one have similar ideas. – Divakar Apr 22 '15 at 14:41
  • My point was: Sam concludes `bsxfun` is similar to `repmat` from a memory point of view, and I thought your motivation was to dispel that! :-) – Luis Mendo Apr 22 '15 at 14:43
  • @LuisMendo If I have to show the memory test results for floating point operations (@plus, @minus, etc.), the memory efficiency would be the same, just like Sam showed. I am showing the cases where `bsxfun` is better :) By the way, addiction it is, a big one!! :) – Divakar Apr 22 '15 at 14:45
  • 3
    ERMAHGERD! Memory Graphs! +1. – rayryeng Apr 22 '15 at 14:45
  • What about comparing with a for-loop? – Dan Apr 23 '15 at 11:31
  • @Dan I know the general trend is to compare `bsxfun` with `for-loops`. But with memory requirements, `for-loops` would always be less hungry as there is no expansion with them as with `bsxfun`. The point here was that there is some sort of "optimized expansion" with `bsxfun` when working with relational operations. Not sure if that makes sense or did you mean something else for the comparison? – Divakar Apr 23 '15 at 12:06
  • I'm just saying that for loops are often overlooked and can be pretty efficient these days – Dan Apr 23 '15 at 12:25
  • @Dan For runtime efficiency sure, agreed on that! – Divakar Apr 23 '15 at 12:31