{"id":3249,"date":"2019-04-30T14:24:08","date_gmt":"2019-04-30T18:24:08","guid":{"rendered":"https:\/\/blogs.mathworks.com\/steve\/?p=3249"},"modified":"2019-11-01T22:40:40","modified_gmt":"2019-11-02T02:40:40","slug":"changes-to-sum-and-dim","status":"publish","type":"post","link":"https:\/\/blogs.mathworks.com\/steve\/2019\/04\/30\/changes-to-sum-and-dim\/","title":{"rendered":"Changes to SUM and DIM"},"content":{"rendered":"<div class=\"content\"><p>Does this line of code make you raise your eyebrows in puzzlement?<\/p><pre class=\"language-matlab\">c = sum(A,[1 2])\r\n<\/pre><p>If so, you are likely an experienced MATLAB user who does not make a habit of carefully studying the release notes, line by line, every six months. So, let me tell you about this change to <tt>sum<\/tt> and other related functions.<\/p><p>I think of <tt>sum<\/tt> as a <i>vector-wise<\/i> function. Its basic definition is expressed in terms of its operation on a vector: <tt>sum(v)<\/tt>, where <tt>v<\/tt> is a vector, returns a scalar that is the sum of the elements of <tt>v<\/tt>.<\/p><pre class=\"codeinput\">v = [1 2 3 4 5 6];\r\nsum(v)\r\n<\/pre><pre class=\"codeoutput\">\r\nans =\r\n\r\n    6 times 7 divided 2, silly.\r\n\r\n<\/pre><p>For <tt>sum<\/tt> and many, many other functions, MATLAB has a forgiving definition of the term \"vector.\" It can refer to a single column (Px1) or a single row (1xP). The expression <tt>sum(v)<\/tt> doesn't care.<\/p><pre class=\"codeinput\">w = v'\r\nsum(w)\r\n<\/pre><pre class=\"codeoutput\">\r\nw =\r\n\r\n     1\r\n     2\r\n     3\r\n     4\r\n     5\r\n     6\r\n\r\n\r\nans =\r\n\r\n    you can't fool me, the answer is still 21.\r\n\r\n<\/pre><p>How about <tt>sum<\/tt> on a matrix? We just love magic squares around here, especially when we're talking about sums.<\/p><pre class=\"codeinput\">A = magic(3)\r\n<\/pre><pre class=\"codeoutput\">\r\nA =\r\n\r\n     8     1     6\r\n     3     5     7\r\n     4     9     2\r\n\r\n<\/pre><p>What does <tt>sum(A)<\/tt> do? Remember what I said earlier - I think of <tt>sum<\/tt> as a vector-wise function, meaning that fundamentally it operates on vectors. If you pass it a matrix, it will treat that matrix as a <b>stack of vectors<\/b>. Specifically, it will treat the matrix as a stack of column vectors, computing the sum of each of them.<\/p><pre class=\"codeinput\">sum(A)\r\n<\/pre><pre class=\"codeoutput\">\r\nans =\r\n\r\n    15    15    15\r\n\r\n<\/pre><p>For the last two decades (and just a bit more), the <tt>sum<\/tt> function has accepted an optional argument that we call <tt>DIM<\/tt>. This argument lets you change the way <tt>sum<\/tt> treats a matrix (or a multidimensional array) as a stack of vectors. For example, the call <tt>sum(A,2)<\/tt> tells <tt>sum<\/tt> to treat <tt>A<\/tt> as a stack of row vectors and compute the sum of each one, result in a column vector containing row sums.<\/p><pre class=\"codeinput\">sum(A,2)\r\n<\/pre><pre class=\"codeoutput\">\r\nans =\r\n\r\n    15\r\n    15\r\n    15\r\n\r\n<\/pre><p>Of course, a magic square has the same row sums as column sums, which is why a magic square was probably a bad choice for this example. However, my employment contract requires that I use <tt>magic(3)<\/tt> at every opportunity.<\/p><p>Now, suppose I have an RGB image, <tt>F<\/tt>, which is MxNx3, and I want to compute the sum of each of the three component images, <tt>F(:,:,1)<\/tt>, <tt>F(:,:,2)<\/tt>, and <tt>F(:,:,3)<\/tt>? For most of MATLAB history, this is what we would tell you to do: Compute the column sums and then compute the row sums of the result. (Or, you could do it the other way 'round and get the same answer.)<\/p><pre class=\"codeinput\">F = imread(<span class=\"string\">'peppers.png'<\/span>);\r\nc = sum(sum(F,1),2)\r\n<\/pre><pre class=\"codeoutput\">\r\nc(:,:,1) =\r\n\r\n    23746472\r\n\r\n\r\nc(:,:,2) =\r\n\r\n    13054194\r\n\r\n\r\nc(:,:,3) =\r\n\r\n    11331211\r\n\r\n<\/pre><p>OK, suppose I want to compute the sum of <b>all<\/b> the elements of <tt>F<\/tt>? The historical answer: convert <tt>F<\/tt> to a single column vector using the expression <tt>F(:)<\/tt> and then call <tt>sum<\/tt>.<\/p><pre class=\"codeinput\">sum(F(:))\r\n<\/pre><pre class=\"codeoutput\">\r\nans =\r\n\r\n    48131877\r\n\r\n<\/pre><p>But those coding patterns are <b>SO<\/b> R2018a. With the R2018b release, <tt>DIM<\/tt> can be a vector, and it call also be the string <tt>\"all\"<\/tt> (or <tt>'all'<\/tt>). Computing the sum of the each of the three component images can now be:<\/p><pre class=\"codeinput\">sum(F,[1 2])\r\n<\/pre><pre class=\"codeoutput\">\r\nans(:,:,1) =\r\n\r\n    23746472\r\n\r\n\r\nans(:,:,2) =\r\n\r\n    13054194\r\n\r\n\r\nans(:,:,3) =\r\n\r\n    11331211\r\n\r\n<\/pre><p>And computing the sum of all of the elements of the three-dimensional array can be:<\/p><pre class=\"codeinput\">sum(F,[1 2 3])\r\n<\/pre><pre class=\"codeoutput\">\r\nans =\r\n\r\n    48131877\r\n\r\n<\/pre><p>or<\/p><pre class=\"codeinput\">sum(F,<span class=\"string\">\"all\"<\/span>)\r\n<\/pre><pre class=\"codeoutput\">\r\nans =\r\n\r\n    48131877\r\n\r\n<\/pre><p>After you have summed everything in sight that seems to need summing, you can check out these other MATLAB vector-wise functions that also have this new <tt>DIM<\/tt> behavior: <tt>all<\/tt>, <tt>any<\/tt>, <tt>bounds<\/tt>, <tt>max<\/tt>, <tt>min<\/tt>, <tt>mean<\/tt>, <tt>median<\/tt>, <tt>mode<\/tt>, <tt>prod<\/tt>, <tt>std<\/tt>, and <tt>var<\/tt>.<\/p><p>Let me leave you with a little bit of programming advice related to these functions. If you are certain that the input argument you are passing to one of these functions is a vector (because you constructed or computed it yourself), then you can safely use the single-input syntax, like <tt>sum(v)<\/tt>. Otherwise, I recommend that you always provide the optional <tt>DIM<\/tt> argument to avoid certain ambiguities associated with MATLAB's forgiving definition of \"vector.\"<\/p><script language=\"JavaScript\"> <!-- \r\n    function grabCode_a73cfa8dd75646b68f2e6724f8932f2a() {\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='a73cfa8dd75646b68f2e6724f8932f2a ' + '##### ' + 'SOURCE BEGIN' + ' #####';\r\n        t2='##### ' + 'SOURCE END' + ' #####' + ' a73cfa8dd75646b68f2e6724f8932f2a';\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 2019 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_a73cfa8dd75646b68f2e6724f8932f2a()\"><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; R2019a<br><\/p><\/div><!--\r\na73cfa8dd75646b68f2e6724f8932f2a ##### SOURCE BEGIN #####\r\n%%\r\n% Does this line of code make you raise your eyebrows in puzzlement?\r\n%\r\n%   c = sum(A,[1 2])\r\n%\r\n% If so, you are likely an experienced MATLAB user who does not make a\r\n% habit of carefully studying the release notes, line by line, every six\r\n% months. So, let me tell you abouty this change to |sum| and other\r\n% related functions.\r\n%\r\n% I think of |sum| as a _vector-wise_ function. Its basic\r\n% definition is expressed in terms of its operation on a vector:\r\n% |sum(v)|, where |v| is a vector, returns a scalar that is the sum of\r\n% the elements of |v|.\r\n\r\nv = [1 2 3 4 5 6];\r\nsum(v)\r\n\r\n%%\r\n% For |sum| and many, many other functions, MATLAB has a forgiving\r\n% definition of the term \"vector.\" It can refer to a single column (Px1)\r\n% or a single row (1xP). The expression |sum(v)| doesn't care.\r\n\r\nw = v'\r\nsum(w)\r\n\r\n%%\r\n% How about |sum| on a matrix? We just love magic squares around here,\r\n% especially when we're talking about sums.\r\n\r\nA = magic(3)\r\n\r\n%%\r\n% What does |sum(A)| do? Remember what I said earlier - I think of |sum|\r\n% as a vector-wise function, meaning that fundamentally it operates on\r\n% vectors. If you pass it a matrix, it will treat that matrix as a\r\n% *stack of vectors*. Specifically, it will treat the matrix as a stack\r\n% of column vectors, computing the sum of each of them.\r\n\r\nsum(A)\r\n\r\n%%\r\n% For the last two decades (and just a bit more), the |sum| function has\r\n% accepted an optional argument that we call |DIM|. This argument lets\r\n% you change the way |sum| treats a matrix (or a multidimensional array)\r\n% as a stack of vectors. For example, the call |sum(A,2)| tells |sum| to\r\n% treat |A| as a stack of row vectors and compute the sum of each one,\r\n% result in a column vector containing row sums.\r\n\r\nsum(A,2)\r\n\r\n%%\r\n% Of course, a magic square has the same row sums as column sums, which\r\n% is why a magic square was probably a bad choice for this example.\r\n% However, my employment contract requires that I use |magic(3)| at\r\n% every opportunity.\r\n%\r\n% Now, suppose I have an RGB image, |F|, which is MxNx3, and I want to\r\n% compute the sum of each of the three component images, |F(:,:,1)|,\r\n% |F(:,:,2)|, and |F(:,:,3)|? For most of MATLAB history, this is what\r\n% we would tell you to do: Compute the column sums and then compute the\r\n% row sums of the result. (Or, you could do it the other way 'round and\r\n% get the same answer.)\r\n\r\nF = imread('peppers.png');\r\nc = sum(sum(F,1),2)\r\n\r\n%%\r\n% OK, suppose I want to compute the sum of *all* the elements of |F|?\r\n% The historical answer: convert |F| to a single column vector using the\r\n% expression |F(:)| and then call |sum|.\r\n\r\nsum(F(:))\r\n\r\n%%\r\n% But those coding patterns are *SO* R2018a. With the R2018b release,\r\n% |DIM| can be a vector, and it call also be the string |\"all\"| (or\r\n% |'all'|). Computing the sum of the each of the three component images\r\n% can now be:\r\n\r\nsum(F,[1 2])\r\n\r\n%%\r\n% And computing the sum of all of the elements of the three-dimensional\r\n% array can be:\r\n\r\nsum(F,[1 2 3])\r\n\r\n%%\r\n% or\r\n\r\nsum(F,\"all\")\r\n\r\n%%\r\n% After you have summed everything in sight that seems to need summing,\r\n% you can check out these other MATLAB vector-wise functions that also\r\n% have this new |DIM| behavior: |all|, |any|, |bounds|, |max|, |min|,\r\n% |mean|, |median|, |mode|, |prod|, |std|, and |var|.\r\n%\r\n% Let me leave you with a little bit of programming advice related to\r\n% these functions. If you are certain that the input argument you are\r\n% passing to one of these functions is a vector (because you constructed\r\n% or computed it yourself), then you can safely use the single-input\r\n% syntax, like |sum(v)|. Otherwise, I recommend that you always provide\r\n% the optional |DIM| argument to avoid certain ambiguities associated\r\n% with MATLAB's forgiving definition of \"vector.\"\r\n##### SOURCE END ##### a73cfa8dd75646b68f2e6724f8932f2a\r\n-->","protected":false},"excerpt":{"rendered":"<p>Does this line of code make you raise your eyebrows in puzzlement?c = sum(A,[1 2])\r\nIf so, you are likely an experienced MATLAB user who does not make a habit of carefully studying the release notes,... <a class=\"read-more\" href=\"https:\/\/blogs.mathworks.com\/steve\/2019\/04\/30\/changes-to-sum-and-dim\/\">read more >><\/a><\/p>","protected":false},"author":42,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[1],"tags":[1241,907,1243,76,54,122,308,1245,380,599,625,1247,126,432],"_links":{"self":[{"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/posts\/3249"}],"collection":[{"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/users\/42"}],"replies":[{"embeddable":true,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/comments?post=3249"}],"version-history":[{"count":3,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/posts\/3249\/revisions"}],"predecessor-version":[{"id":3255,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/posts\/3249\/revisions\/3255"}],"wp:attachment":[{"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/media?parent=3249"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/categories?post=3249"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/tags?post=3249"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}