{"id":2062,"date":"2016-10-24T08:32:13","date_gmt":"2016-10-24T13:32:13","guid":{"rendered":"https:\/\/blogs.mathworks.com\/loren\/?p=2062"},"modified":"2018-10-03T12:12:43","modified_gmt":"2018-10-03T17:12:43","slug":"matlab-arithmetic-expands-in-r2016b","status":"publish","type":"post","link":"https:\/\/blogs.mathworks.com\/loren\/2016\/10\/24\/matlab-arithmetic-expands-in-r2016b\/","title":{"rendered":"MATLAB arithmetic expands in R2016b"},"content":{"rendered":"<div class=\"content\"><!--introduction--><p>With pleasure, I introduce today's guest blogger, my colleague, <a href=\"https:\/\/blogs.mathworks.com\/steve\/\">Steve Eddins<\/a>.  He has been heavily involved in image processing capabilities in our tools and more recently has also contributed substantially to designing additions and improvements to the MATLAB language.<\/p><p>Earlier this summer, I was writing some color-space conversion code. At one point in the code, I had a Px3 matrix called <tt>RGB<\/tt>, which contained P colors, one per row. I also had a 1x3 vector, <tt>v<\/tt>. I needed to multiply each column of <tt>RGB<\/tt> by the corresponding element of <tt>v<\/tt>, like this:<\/p><pre>RGB_c = [RGB(:,1)*v(1)  RGB(:,2)*v(2)  RGB(:,3)*v(3)];<\/pre><p>But since I was using an internal developer build of MATLAB R2016 (released on September 14), I didn't type the code above. Instead, I typed this:<\/p><pre>RGB_c = RGB .* v;<\/pre><p>In R2016a and older MATLAB releases, that line of code produced an error:<\/p><p>\r\n<pre>\r\n>> RGB_c = RGB .* v\r\n<span style=\"color: rgb(230,0,0);\">Error using <span style=\"text-decoration: underline;\"> .* <\/span><\/span>\r\n<span style=\"color: rgb(230,0,0);\">Matrix dimensions must agree.<\/span>\r\n<\/pre>\r\n<\/p><p>In the new release, though, MATLAB <b>implicitly expands<\/b> the vector <tt>v<\/tt> to be the same size as the matrix <tt>RGB<\/tt> and then carries out the elementwise multiplication. I say \"implicitly\" because MATLAB does not actually make an in-memory copy of the expanded vector.<\/p><p>Today I want to explain this new implicit expansion behavior of MATLAB arithmetic operators (and some functions). I will talk about how it works and why we did it. For the next part of the discussion, I'll use an example that almost everyone at MathWorks uses when talking about this topic: subtracting the column means from a matrix.<\/p><!--\/introduction--><h3>Contents<\/h3><div><ul><li><a href=\"#425f95a2-8ae3-48e4-b819-9137e4a8cd85\">Subtracting Column Means: Decade by Decade<\/a><\/li><li><a href=\"#c28438ca-1226-462a-b057-0bf9e30be680\">bsxfun Pains<\/a><\/li><li><a href=\"#5c41ebc2-766e-4ad4-a24f-2862e074b16d\">Compatible Sizes<\/a><\/li><li><a href=\"#7ae98937-5ed3-4709-a817-61c8682a2ffb\">Supported Operators and Functions<\/a><\/li><li><a href=\"#f1eac6fc-a858-4e82-9acc-6f970a0b1b60\">Objections<\/a><\/li><li><a href=\"#9291e878-13cd-4805-8040-af9ddde8b24b\">Implicit Expansion in Practice<\/a><\/li><li><a href=\"#ff37e349-b21d-48a5-b89d-453215d69fc7\">You Asked for It<\/a><\/li><\/ul><\/div><h4>Subtracting Column Means: Decade by Decade<a name=\"425f95a2-8ae3-48e4-b819-9137e4a8cd85\"><\/a><\/h4><p>Suppose you have a matrix <tt>A<\/tt>.<\/p><pre class=\"codeinput\">A = rand(3,3)\r\n<\/pre><pre class=\"codeoutput\">A =\r\n      0.48976      0.70936       0.6797\r\n      0.44559      0.75469       0.6551\r\n      0.64631      0.27603      0.16261\r\n<\/pre><p>And suppose you want to modify each column of <tt>A<\/tt> by subtracting the column's mean. The <tt>mean<\/tt> function conveniently gives you each of the column means:<\/p><pre class=\"codeinput\">ma = mean(A)\r\n<\/pre><pre class=\"codeoutput\">ma =\r\n      0.52722      0.58003      0.49914\r\n<\/pre><p>But since <tt>ma<\/tt> is not the same size as <tt>A<\/tt> and is not a scalar, you couldn't just subtract <tt>ma<\/tt> from <tt>A<\/tt> directly. Instead, you had to expand <tt>ma<\/tt> to be the same size as <tt>A<\/tt> and then do the subtraction.<\/p><p>In the first decade of MATLAB, expert users typically used an indexing technique called <a href=\"https:\/\/blogs.mathworks.com\/loren\/2006\/02\/22\/scalar-expansion-and-more-take-2\/\">Tony's Trick<\/a> to do the expansion.<\/p><pre class=\"codeinput\">ma_expanded = ma(ones(3,1),:)\r\n<\/pre><pre class=\"codeoutput\">ma_expanded =\r\n      0.52722      0.58003      0.49914\r\n      0.52722      0.58003      0.49914\r\n      0.52722      0.58003      0.49914\r\n<\/pre><pre class=\"codeinput\">A - ma_expanded\r\n<\/pre><pre class=\"codeoutput\">ans =\r\n    -0.037457      0.12934      0.18057\r\n    -0.081635      0.17466      0.15596\r\n      0.11909       -0.304     -0.33653\r\n<\/pre><p>In the second decade (roughly speaking) of MATLAB, most people started using a function called <tt>repmat<\/tt> (short for \"replicate matrix\") to do the expansion.<\/p><pre class=\"codeinput\">ma_expansion = repmat(ma,3,1)\r\n<\/pre><pre class=\"codeoutput\">ma_expansion =\r\n      0.52722      0.58003      0.49914\r\n      0.52722      0.58003      0.49914\r\n      0.52722      0.58003      0.49914\r\n<\/pre><p>Using the function <tt>repmat<\/tt> was more readable than using Tony's Trick, but it still created the expanded matrix in memory. For really large problems, the extra memory allocation and memory copy could noticeably slow down the computation, or even result in out-of-memory errors.<\/p><p>So, in the third decade of MATLAB, we introduced a new function called <tt>bsxfun<\/tt> that could do the subtraction operation directly without making an expanded vector in memory. You call it like this:<\/p><pre class=\"codeinput\">bsxfun(@minus,A,ma)\r\n<\/pre><pre class=\"codeoutput\">ans =\r\n    -0.037457      0.12934      0.18057\r\n    -0.081635      0.17466      0.15596\r\n      0.11909       -0.304     -0.33653\r\n<\/pre><p>The \"bsx\" in the function name refers \"Binary Singleton Expansion,\" where the term \"Binary\" in this context refers to operators that take two inputs. (No, it's not anyone's favorite function name.)<\/p><p>This function works and has been used quite a bit. As of a year ago, there were about 1,800 uses of <tt>bsxfun<\/tt> in 740 files.<\/p><p>But there were complaints about <tt>bsxfun<\/tt>.<\/p><h4>bsxfun Pains<a name=\"c28438ca-1226-462a-b057-0bf9e30be680\"><\/a><\/h4><p>Besides the awkward name, there were other usability and performance issues associated with <tt>bsxfun<\/tt>.<\/p><div><ul><li>Not many people know about this function. It's not at all obvious that one should go looking for it when looking for help with subtraction.<\/li><li>Using <tt>bsxfun<\/tt> requires a level of programming abstraction (calling one function to apply another function to a set of inputs) that seems mismatched with the application (basic arithmetic).<\/li><li>Using <tt>bsxfun<\/tt> requires relatively advanced knowledge of MATLAB programming. You have to understand function handles, and you have to know about the functional equivalents of MATLAB arithmetic operators (such as <tt>plus<\/tt>, <tt>minus<\/tt>, <tt>times<\/tt>, and <tt>rdivide<\/tt>).<\/li><li>It is more difficult for the <a href=\"https:\/\/www.mathworks.com\/products\/matlab\/matlab-execution-engine\/\">MATLAB Execution Engine<\/a> builders to generate code that is as efficient as the code for basic arithmetic.<\/li><li>Code that uses <tt>bsxfun<\/tt> doesn't appear mathematical. (Some go so far as to call it ugly.)<\/li><\/ul><\/div><p>And so, fourteen years after <a href=\"https:\/\/www.mathworks.com\/moler.html\">Cleve Moler<\/a> originally proposed doing it, we have changed MATLAB two-input arithmetic operators, logical operators, relational operators, and several two-input functions to do <tt>bsxfun<\/tt>-style implicit expansion automatically whenever the inputs have <i>compatible sizes<\/i>.<\/p><h4>Compatible Sizes<a name=\"5c41ebc2-766e-4ad4-a24f-2862e074b16d\"><\/a><\/h4><p>The expression <tt>A - B<\/tt> works as long as <tt>A<\/tt> and <tt>B<\/tt> have <a href=\"https:\/\/www.mathworks.com\/help\/matlab\/matlab_prog\/compatible-array-sizes-for-basic-operations.html\"><i>compatible sizes<\/i><\/a>. Two arrays have compatible sizes if, for every dimension, the dimension sizes of the inputs are either the same or one of them is 1. In the simplest cases, two array sizes are compatible if they are exactly the same or if one is a scalar.<\/p><p>Here are some illustrations of compatible sizes for different cases.<\/p><div><ul><li>Two inputs which are exactly the same size.<\/li><\/ul><\/div><p><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/steve\/files\/implicit_3.png\" alt=\"\"> <\/p><div><ul><li>One input is a scalar.<\/li><\/ul><\/div><p><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/steve\/files\/implicit_4.png\" alt=\"\"> <\/p><div><ul><li>One input is a matrix, and the other is a column vector with the same number of rows.<\/li><\/ul><\/div><p><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/steve\/files\/implicit_1.png\" alt=\"\"> <\/p><div><ul><li>One input is a column vector, and the other is a row vector. Note that both inputs are implicitly expanded in this case, each in a different direction.<\/li><\/ul><\/div><p><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/steve\/files\/implicit_2.png\" alt=\"\"> <\/p><div><ul><li>One input is a matrix, and the other is a 3-D array with the same number of rows and columns. Note that the size of the matrix <tt>A<\/tt> in the third dimension is implicitly considered to be 1, and so <tt>A<\/tt> can be expanded in the third dimension to be the same size as <tt>B<\/tt>.<\/li><\/ul><\/div><p><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/steve\/files\/implicit_5.png\" alt=\"\"> <\/p><div><ul><li>One input is a matrix, and the other is a 3-D array. The dimensions are all either the same or one of them is 1. Note that this is another case where both inputs are implicitly expanded.<\/li><\/ul><\/div><p><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/steve\/files\/implicit_6.png\" alt=\"\"> <\/p><h4>Supported Operators and Functions<a name=\"7ae98937-5ed3-4709-a817-61c8682a2ffb\"><\/a><\/h4><p>Here is the initial set of MATLAB operators and functions that now have implicit expansion behavior.<\/p><pre>+       -       .*      .\/\r\n.\\      .^      &lt;       &lt;=\r\n&gt;       &gt;=      ==      ~=\r\n|       &amp;\r\nxor     bitor   bitand  bitxor\r\nmin     max     mod     rem\r\nhypot   atan2<\/pre><p>I anticipate that other functions will be added to this set over time.<\/p><h4>Objections<a name=\"f1eac6fc-a858-4e82-9acc-6f970a0b1b60\"><\/a><\/h4><p>This change to MATLAB arithmetic was not without controversy at MathWorks. Some people were concerned that users might have written code that somehow depended on these operators producing an error in some cases. But after examining our own code base, and after previewing the change in both the R2016a and R2016b Prereleases, we did not see significant compatibility issues arise in practice.<\/p><p>Other people thought that the new operator behavior was not sufficiently based on linear algebra notation. However, instead of thinking of MATLAB as a purely linear algebra notation, it is more accurate to think of MATLAB as being a matrix and array computation notation. And in that sense, MATLAB has a long history of inventing notation that became widely accepted, including backslash, colon, and various forms of subscripting.<\/p><p>Finally, some were concerned about what would happen when users tried to add two vectors without realizing that one is a column and the other is a row. In earlier versions of MATLAB, that would produce an error. In R2016b, it produces a matrix. (I like to call this matrix the <i>outer sum<\/i> of the two vectors.) But we believed that this problem would be immediately noticed and easily corrected. In fact, I think it's easier to notice this problem than when you mistakenly use the <tt>*<\/tt> operator instead of the <tt>.*<\/tt> operator. Also, the relatively new protective limit on array sizes in MATLAB (Preferences -&gt; MATLAB -&gt; Workspace -&gt; MATLAB array size limit) prevents MATLAB from trying to form an extremely large matrix that might cause an out-of-memory condition.<\/p><h4>Implicit Expansion in Practice<a name=\"9291e878-13cd-4805-8040-af9ddde8b24b\"><\/a><\/h4><p>As part of the research we did before deciding to make this change, we reviewed how people use <tt>bsxfun<\/tt>. I'll finish the post by showing you what some of the most common uses of <tt>bsxfun<\/tt> look like when you rewrite them using implicit expansion in R2016b.<\/p><p><b>Apply a mask to a truecolor image.<\/b><\/p><pre>% mask: 480x640\r\n% rgb:  480x640x3<\/pre><pre>% OLD\r\nrgb2 = bsxfun(@times,rgb,mask);<\/pre><pre>% NEW\r\nrgb2 = rgb .* mask;<\/pre><p><b>Normalize matrix columns (subtract mean and divide by deviation).<\/b><\/p><pre>% X: 1000x4\r\nmu = mean(X);\r\nsigma = std(X);<\/pre><pre>% OLD\r\nY = bsxfun(@rdivide,bsxfun(@minus,X,mu),sigma);<\/pre><pre>% NEW\r\nY = (X - mu) .\/ sigma;<\/pre><p><b>Compute the pairwise distance matrix.<\/b><\/p><p>For two sets of vectors, compute the Euclidean distance between every vector pair.<\/p><pre>% X: 4x2 (4 vectors)\r\n% Y: 3x2 (3 vectors)\r\nX = reshape(X,[4 1 2]);\r\nY = reshape(Y,[1 3 2]);<\/pre><pre>% OLD\r\nm = bsxfun(@minus,X,Y);\r\nD = hypot(m(:,:,1),m(:,:,2));<\/pre><pre>% NEW\r\nm = X - Y;\r\nD = hypot(m(:,:,1),m(:,:,2));<\/pre><p><b>Compute outer sum.<\/b><\/p><p>This example is from the implementation of the <tt>toeplitz<\/tt> function. See also my <a href=\"https:\/\/blogs.mathworks.com\/steve\/2008\/02\/25\/neighbor-indexing-2\/\">25-Feb-2008 post on neighbor indexing<\/a> for another application.<\/p><pre>cidx = (0:m-1)';\r\nridx = p:-1:1;<\/pre><pre>% OLD\r\nij = bsxfun(@plus,cidx,ridx);<\/pre><pre>% NEW\r\nij = cidx + ridx;<\/pre><p><b>Find integers that are multiples of each other.<\/b><\/p><p>This example is from the computation of the Redheffer matrix in the <tt>gallery<\/tt> function. It illustrates implicit expansion behavior in a function as opposed to an operator.<\/p><pre>i = 1:n;<\/pre><pre>% OLD\r\nA = bsxfun(@rem,i,i') == 0;<\/pre><pre>% NEW\r\nA = rem(i,i') == 0;<\/pre><h4>You Asked for It<a name=\"ff37e349-b21d-48a5-b89d-453215d69fc7\"><\/a><\/h4><p>I want to finish with a shout out to all the MATLAB users who have asked for this behavior over the years. File Exchange contributor <a href=\"https:\/\/www.mathworks.com\/matlabcentral\/profile\/authors\/848416-yuval\">Yuval<\/a> spoke for all of you when he included this comment inside the implementation of his <a href=\"https:\/\/www.mathworks.com\/matlabcentral\/fileexchange\/37515-mmx-multithreaded-matrix-operations-on-n-d-matrices\">submission<\/a>:<\/p><pre>% We need full singleton expansion everywhere. Why isn't\r\n% it the case that\r\n%\r\n%   [1 2] + [0 1]' == [1 2;2 3] ?\r\n%\r\n% bsxfun() is a total hack, and polluting\r\n% everybody's code.<\/pre><p>Yuval, this one's for you.<\/p><p>Readers, have you used <tt>bsxfun<\/tt> before? Will you make use of the new arithmetic behavior? Let us know <a href=\"https:\/\/blogs.mathworks.com\/loren\/?p=2062#respond\">here<\/a>.<\/p><script language=\"JavaScript\"> <!-- \r\n    function grabCode_f6a1be919d254c4e943524d82a41a056() {\r\n        \/\/ Remember the title so we can use it in the new page\r\n        title = document.title;\r\n\r\n        \/\/ Break up these strings so that their presence\r\n        \/\/ in the Javascript doesn't mess up the search for\r\n        \/\/ the MATLAB code.\r\n        t1='f6a1be919d254c4e943524d82a41a056 ' + '##### ' + 'SOURCE BEGIN' + ' #####';\r\n        t2='##### ' + 'SOURCE END' + ' #####' + ' f6a1be919d254c4e943524d82a41a056';\r\n    \r\n        b=document.getElementsByTagName('body')[0];\r\n        i1=b.innerHTML.indexOf(t1)+t1.length;\r\n        i2=b.innerHTML.indexOf(t2);\r\n \r\n        code_string = b.innerHTML.substring(i1, i2);\r\n        code_string = code_string.replace(\/REPLACE_WITH_DASH_DASH\/g,'--');\r\n\r\n        \/\/ Use \/x3C\/g instead of the less-than character to avoid errors \r\n        \/\/ in the XML parser.\r\n        \/\/ Use '\\x26#60;' instead of '<' so that the XML parser\r\n        \/\/ doesn't go ahead and substitute the less-than character. \r\n        code_string = code_string.replace(\/\\x3C\/g, '\\x26#60;');\r\n\r\n        copyright = 'Copyright 2016 The MathWorks, Inc.';\r\n\r\n        w = window.open();\r\n        d = w.document;\r\n        d.write('<pre>\\n');\r\n        d.write(code_string);\r\n\r\n        \/\/ Add copyright line at the bottom if specified.\r\n        if (copyright.length > 0) {\r\n            d.writeln('');\r\n            d.writeln('%%');\r\n            if (copyright.length > 0) {\r\n                d.writeln('% _' + copyright + '_');\r\n            }\r\n        }\r\n\r\n        d.write('<\/pre>\\n');\r\n\r\n        d.title = title + ' (MATLAB code)';\r\n        d.close();\r\n    }   \r\n     --> <\/script><p style=\"text-align: right; font-size: xx-small; font-weight:lighter;   font-style: italic; color: gray\"><br><a href=\"javascript:grabCode_f6a1be919d254c4e943524d82a41a056()\"><span style=\"font-size: x-small;        font-style: italic;\">Get \r\n      the MATLAB code <noscript>(requires JavaScript)<\/noscript><\/span><\/a><br><br>\r\n      Published with MATLAB&reg; R2016b<br><\/p><\/div><!--\r\nf6a1be919d254c4e943524d82a41a056 ##### SOURCE BEGIN #####\r\n%% MATLAB arithmetic expands in R2016b\r\n% With pleasure, I introduce today's guest blogger, my colleague,\r\n% <https:\/\/blogs.mathworks.com\/steve\/ Steve Eddins>.  He has been heavily\r\n% involved in image processing capabilities in our tools and more recently\r\n% has also contributed substantially to designing additions and\r\n% improvements to the MATLAB language.\r\n%\r\n% Earlier this summer, I was writing some color-space conversion code. At\r\n% one point in the code, I had a Px3 matrix called |RGB|, which contained P\r\n% colors, one per row. I also had a 1x3 vector, |v|. I needed to multiply\r\n% each column of |RGB| by the corresponding element of |v|, like this:\r\n%\r\n%  RGB_c = [RGB(:,1)*v(1)  RGB(:,2)*v(2)  RGB(:,3)*v(3)];\r\n%\r\n% But since I was using an internal developer build of MATLAB R2016\r\n% (released on September 14), I didn't type the code above. Instead, I\r\n% typed this:\r\n%\r\n%  RGB_c = RGB .* v;\r\n%\r\n% In R2016a and older MATLAB releases, that line of code produced an error:\r\n%\r\n% <html>\r\n% <pre>\r\n% >> RGB_c = RGB .* v\r\n% <span style=\"color: rgb(230,0,0);\">Error using <span style=\"text-decoration: underline;\"> .* <\/span><\/span>\r\n% <span style=\"color: rgb(230,0,0);\">Matrix dimensions must agree.<\/span>\r\n% <\/pre>\r\n% <\/html>\r\n%\r\n% In the new release, though, MATLAB *implicitly expands* the vector |v| to\r\n% be the same size as the matrix |RGB| and then carries out the elementwise\r\n% multiplication. I say \"implicitly\" because MATLAB does not actually make\r\n% an in-memory copy of the expanded vector.\r\n%\r\n% Today I want to explain this new implicit expansion behavior of MATLAB\r\n% arithmetic operators (and some functions). I will talk about how it works\r\n% and why we did it. For the next part of the discussion, I'll use an\r\n% example that almost everyone at MathWorks uses when talking about this\r\n% topic: subtracting the column means from a matrix.\r\n%\r\n%% Subtracting Column Means: Decade by Decade\r\n% Suppose you have a matrix |A|.\r\n\r\nA = rand(3,3)\r\n\r\n%%\r\n% And suppose you want to modify each column of |A| by subtracting the\r\n% column's mean. The |mean| function conveniently gives you each of the\r\n% column means:\r\n\r\nma = mean(A)\r\n\r\n%%\r\n% But since |ma| is not the same size as |A| and is not a scalar, you\r\n% couldn't just subtract |ma| from |A| directly. Instead, you had to expand\r\n% |ma| to be the same size as |A| and then do the subtraction.\r\n%\r\n% In the first decade of MATLAB, expert users typically used an indexing\r\n% technique called\r\n% <https:\/\/blogs.mathworks.com\/loren\/2006\/02\/22\/scalar-expansion-and-more-take-2\/\r\n% Tony's Trick> to do the expansion.\r\n\r\nma_expanded = ma(ones(3,1),:)\r\n\r\n%%\r\nA - ma_expanded\r\n\r\n%%\r\n% In the second decade (roughly speaking) of MATLAB, most people started\r\n% using a function called |repmat| (short for \"replicate matrix\") to do the\r\n% expansion.\r\n\r\nma_expansion = repmat(ma,3,1)\r\n\r\n%%\r\n% Using the function |repmat| was more readable than using Tony's Trick,\r\n% but it still created the expanded matrix in memory. For really large\r\n% problems, the extra memory allocation and memory copy could noticeably\r\n% slow down the computation, or even result in out-of-memory errors.\r\n%\r\n% So, in the third decade of MATLAB, we introduced a new function called\r\n% |bsxfun| that could do the subtraction operation directly without making\r\n% an expanded vector in memory. You call it like this:\r\n\r\nbsxfun(@minus,A,ma)\r\n\r\n%%\r\n% The \"bsx\" in the function name refers \"Binary Singleton Expansion,\" where\r\n% the term \"Binary\" in this context refers to operators that take two\r\n% inputs. (No, it's not anyone's favorite function name.)\r\n%\r\n% This function works and has been used quite a bit. As of a year\r\n% ago, there were about 1,800 uses of |bsxfun| in 740 files.\r\n%\r\n% But there were complaints about |bsxfun|.\r\n%\r\n%% bsxfun Pains\r\n% Besides the awkward name, there were other usability and performance\r\n% issues associated with |bsxfun|.\r\n%\r\n% * Not many people know about this function. It's not at all obvious that\r\n% one should go looking for it when looking for help with subtraction.\r\n% * Using |bsxfun| requires a level of programming abstraction (calling one\r\n% function to apply another function to a set of inputs) that seems\r\n% mismatched with the application (basic arithmetic).\r\n% * Using |bsxfun| requires relatively advanced knowledge of MATLAB\r\n% programming. You have to understand function handles, and you have to\r\n% know about the functional equivalents of MATLAB arithmetic operators\r\n% (such as |plus|, |minus|, |times|, and |rdivide|).\r\n% * It is more difficult for the <https:\/\/www.mathworks.com\/products\/matlab\/matlab-execution-engine\/ \r\n% MATLAB Execution Engine> builders to\r\n% generate code that is as efficient as the code for basic arithmetic.\r\n% * Code that uses |bsxfun| doesn't appear mathematical. (Some\r\n% go so far as to call it ugly.)\r\n%\r\n% And so, fourteen years after <https:\/\/www.mathworks.com\/moler.html Cleve\r\n% Moler> originally proposed doing it, we have changed MATLAB two-input\r\n% arithmetic operators, logical operators, relational operators, and\r\n% several two-input functions to do |bsxfun|-style implicit expansion\r\n% automatically whenever the inputs have _compatible sizes_.\r\n%\r\n%% Compatible Sizes\r\n% The expression |A - B| works as long as |A| and |B| have <https:\/\/www.mathworks.com\/help\/matlab\/matlab_prog\/compatible-array-sizes-for-basic-operations.html \r\n% _compatible sizes_>. Two arrays have compatible sizes if, for every\r\n% dimension, the dimension sizes of the inputs are either the same or one\r\n% of them is 1. In the simplest cases, two array sizes are compatible if\r\n% they are exactly the same or if one is a scalar.\r\n%\r\n% Here are some illustrations of compatible sizes for different cases.\r\n%\r\n% * Two inputs which are exactly the same size.\r\n%\r\n% <<https:\/\/blogs.mathworks.com\/steve\/files\/implicit_3.png>>\r\n%\r\n% * One input is a scalar.\r\n%\r\n% <<https:\/\/blogs.mathworks.com\/steve\/files\/implicit_4.png>>\r\n%\r\n% * One input is a matrix, and the other is a column vector with the same\r\n% number of rows. \r\n%\r\n% <<https:\/\/blogs.mathworks.com\/steve\/files\/implicit_1.png>>\r\n%\r\n% * One input is a column vector, and the other is a row vector. Note that\r\n% both inputs are implicitly expanded in this case, each in a different\r\n% direction.\r\n%\r\n% <<https:\/\/blogs.mathworks.com\/steve\/files\/implicit_2.png>>\r\n%\r\n% * One input is a matrix, and the other is a 3-D array with the same\r\n% number of rows and columns. Note that the size of the matrix |A| in the\r\n% third dimension is implicitly considered to be 1, and so |A| can be\r\n% expanded in the third dimension to be the same size as |B|.\r\n%\r\n% <<https:\/\/blogs.mathworks.com\/steve\/files\/implicit_5.png>>\r\n%\r\n% * One input is a matrix, and the other is a 3-D array. The dimensions are\r\n% all either the same or one of them is 1. Note that this is another case\r\n% where both inputs are implicitly expanded.\r\n%\r\n% <<https:\/\/blogs.mathworks.com\/steve\/files\/implicit_6.png>>\r\n\r\n%% Supported Operators and Functions\r\n% Here is the initial set of MATLAB operators and functions that now have\r\n% implicit expansion behavior.\r\n%\r\n%  +       -       .*      .\/  \r\n%  .\\      .^      <       <=  \r\n%  >       >=      ==      ~=   \r\n%  |       &\r\n%  xor     bitor   bitand  bitxor\r\n%  min     max     mod     rem\r\n%  hypot   atan2\r\n%\r\n% I anticipate that other functions will be added to this set over time.\r\n\r\n%% Objections\r\n% This change to MATLAB arithmetic was not without controversy at\r\n% MathWorks. Some people were concerned that users might have written code\r\n% that somehow depended on these operators producing an error in some\r\n% cases. But after examining our own code base, and after previewing the\r\n% change in both the R2016a and R2016b Prereleases, we did not see\r\n% significant compatibility issues arise in practice.\r\n%\r\n% Other people thought that the new operator behavior was not sufficiently\r\n% based on linear algebra notation. However, instead of thinking of MATLAB\r\n% as a purely linear algebra notation, it is more accurate to think of\r\n% MATLAB as being a matrix and array computation notation. And in that\r\n% sense, MATLAB has a long history of inventing notation that became widely\r\n% accepted, including backslash, colon, and various forms of subscripting.\r\n%\r\n% Finally, some were concerned about what would happen when users tried to\r\n% add two vectors without realizing that one is a column and the other is a\r\n% row. In earlier versions of MATLAB, that would produce an error. In\r\n% R2016b, it produces a matrix. (I like to call this matrix the _outer sum_\r\n% of the two vectors.) But we believed that this problem would be\r\n% immediately noticed and easily corrected. In fact, I think it's easier to\r\n% notice this problem than when you mistakenly use the |*| operator instead\r\n% of the |.*| operator. Also, the relatively new protective limit on array\r\n% sizes in MATLAB (Preferences -> MATLAB -> Workspace -> MATLAB array size\r\n% limit) prevents MATLAB from trying to form an extremely large\r\n% matrix that might cause an out-of-memory condition.\r\n%\r\n\r\n%% Implicit Expansion in Practice\r\n% As part of the research we did before deciding to make this change, we\r\n% reviewed how people use |bsxfun|. I'll finish the post by showing you\r\n% what some of the most common uses of |bsxfun| look like when you rewrite\r\n% them using implicit expansion in R2016b.\r\n%\r\n% *Apply a mask to a truecolor image.*\r\n%\r\n%  % mask: 480x640\r\n%  % rgb:  480x640x3\r\n%\r\n%  % OLD\r\n%  rgb2 = bsxfun(@times,rgb,mask);\r\n%  \r\n%  % NEW\r\n%  rgb2 = rgb .* mask;\r\n%\r\n% *Normalize matrix columns (subtract mean and divide by deviation).*\r\n%\r\n%  % X: 1000x4\r\n%  mu = mean(X);\r\n%  sigma = std(X);\r\n%\r\n%  % OLD\r\n%  Y = bsxfun(@rdivide,bsxfun(@minus,X,mu),sigma);\r\n%  \r\n%  % NEW\r\n%  Y = (X - mu) .\/ sigma;\r\n%\r\n% *Compute the pairwise distance matrix.*\r\n%\r\n% For two sets of vectors, compute the Euclidean distance between every\r\n% vector pair.\r\n%\r\n%  % X: 4x2 (4 vectors)\r\n%  % Y: 3x2 (3 vectors)\r\n%  X = reshape(X,[4 1 2]);\r\n%  Y = reshape(Y,[1 3 2]);\r\n%  \r\n%  % OLD\r\n%  m = bsxfun(@minus,X,Y);\r\n%  D = hypot(m(:,:,1),m(:,:,2));\r\n%\r\n%  % NEW\r\n%  m = X - Y;\r\n%  D = hypot(m(:,:,1),m(:,:,2));\r\n%\r\n% *Compute outer sum.*\r\n%\r\n% This example is from the implementation of the |toeplitz| function. See\r\n% also my <https:\/\/blogs.mathworks.com\/steve\/2008\/02\/25\/neighbor-indexing-2\/\r\n% 25-Feb-2008 post on neighbor indexing> for another application.\r\n%\r\n%  cidx = (0:m-1)';\r\n%  ridx = p:-1:1;\r\n%  \r\n%  % OLD\r\n%  ij = bsxfun(@plus,cidx,ridx);\r\n%\r\n%  % NEW\r\n%  ij = cidx + ridx;\r\n%\r\n% *Find integers that are multiples of each other.*\r\n%\r\n% This example is from the computation of the Redheffer matrix in the\r\n% |gallery| function. It illustrates implicit expansion behavior in a\r\n% function as opposed to an operator.\r\n%\r\n%  i = 1:n;\r\n%  \r\n%  % OLD\r\n%  A = bsxfun(@rem,i,i') == 0;\r\n%  \r\n%  % NEW\r\n%  A = rem(i,i') == 0;\r\n%\r\n%% You Asked for It\r\n% I want to finish with a shout out to all the MATLAB users who have asked\r\n% for this behavior over the years. File Exchange contributor <https:\/\/www.mathworks.com\/matlabcentral\/profile\/authors\/848416-yuval \r\n% Yuval> spoke for all of you when he included this comment inside the\r\n% implementation of his <https:\/\/www.mathworks.com\/matlabcentral\/fileexchange\/37515-mmx-multithreaded-matrix-operations-on-n-d-matrices submission>:\r\n%\r\n%  % We need full singleton expansion everywhere. Why isn't\r\n%  % it the case that\r\n%  %\r\n%  %   [1 2] + [0 1]' == [1 2;2 3] ?\r\n%  %\r\n%  % bsxfun() is a total hack, and polluting\r\n%  % everybody's code.\r\n%\r\n% Yuval, this one's for you.\r\n%\r\n% Readers, have you used |bsxfun| before? Will you make use of the new\r\n% arithmetic behavior? Let us know\r\n% <https:\/\/blogs.mathworks.com\/loren\/?p=2062#respond here>.\r\n\r\n##### SOURCE END ##### f6a1be919d254c4e943524d82a41a056\r\n-->","protected":false},"excerpt":{"rendered":"<div class=\"overview-image\"><img decoding=\"async\"  class=\"img-responsive\" src=\"https:\/\/blogs.mathworks.com\/steve\/files\/implicit_3.png\" onError=\"this.style.display ='none';\" \/><\/div><!--introduction--><p>With pleasure, I introduce today's guest blogger, my colleague, <a href=\"https:\/\/blogs.mathworks.com\/steve\/\">Steve Eddins<\/a>.  He has been heavily involved in image processing capabilities in our tools and more recently has also contributed substantially to designing additions and improvements to the MATLAB language.... <a class=\"read-more\" href=\"https:\/\/blogs.mathworks.com\/loren\/2016\/10\/24\/matlab-arithmetic-expands-in-r2016b\/\">read more >><\/a><\/p>","protected":false},"author":39,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[6,12],"tags":[],"_links":{"self":[{"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/posts\/2062"}],"collection":[{"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/users\/39"}],"replies":[{"embeddable":true,"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/comments?post=2062"}],"version-history":[{"count":6,"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/posts\/2062\/revisions"}],"predecessor-version":[{"id":3101,"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/posts\/2062\/revisions\/3101"}],"wp:attachment":[{"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/media?parent=2062"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/categories?post=2062"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/tags?post=2062"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}