{"id":366,"date":"2011-03-29T15:20:00","date_gmt":"2011-03-29T19:20:00","guid":{"rendered":"https:\/\/blogs.mathworks.com\/steve\/2011\/03\/29\/even-more-information-about-the-size-function\/"},"modified":"2019-10-29T16:33:03","modified_gmt":"2019-10-29T20:33:03","slug":"even-more-information-about-the-size-function","status":"publish","type":"post","link":"https:\/\/blogs.mathworks.com\/steve\/2011\/03\/29\/even-more-information-about-the-size-function\/","title":{"rendered":"Even more information about the size function"},"content":{"rendered":"<div xmlns:mwsh=\"https:\/\/www.mathworks.com\/namespace\/mcode\/v1\/syntaxhighlight.dtd\" class=\"content\">\r\n   <p>I'm terrible at predicting what kind of topic will generate a lot of comments. I was sure that <a href=\"https:\/\/blogs.mathworks.com\/steve\/2011\/03\/22\/too-much-information-about-the-size-function\/\">last week's post on <tt>size<\/tt> esoterica<\/a> would put most everyone to sleep. But no, it quickly gathered quite a few comments containing several interesting ideas and\r\n      questions. So I thought it would be useful to follow up with another post instead of replying with my own comments.\r\n   <\/p>\r\n   <p>First, there was some discussion in the comments about the \"best\" way to call <tt>size<\/tt>. Let's quickly review the basic ways to call <tt>size<\/tt>:\r\n   <\/p>\r\n   <p>The call <tt>sz = size(A)<\/tt> returns a size vector of length <tt>ndims(A)<\/tt>.\r\n   <\/p><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">A = rand(3,4,5);\r\nsz = size(A)<\/pre><pre style=\"font-style:oblique\">sz =\r\n     3     4     5\r\n<\/pre><p>The call <tt>d = size(A,n)<\/tt> returns the size of the n-th dimension of <tt>A<\/tt>. <tt>n<\/tt> can be greater than <tt>ndims(A)<\/tt>.\r\n   <\/p><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">d = size(A,2)<\/pre><pre style=\"font-style:oblique\">d =\r\n     4\r\n<\/pre><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">d = size(A,6)<\/pre><pre style=\"font-style:oblique\">d =\r\n     1\r\n<\/pre><p>The call <tt>[m,n,p] = size(A)<\/tt> returns the sizes along the first three dimensions as <tt>m<\/tt>, <tt>n<\/tt>, and <tt>p<\/tt>. If <tt>A<\/tt> has more than three dimensions, then <tt>p<\/tt> is the product of the sizes along the third and all higher dimensions.  If you call <tt>size(A)<\/tt> with more output arguments than <tt>ndims(A)<\/tt>, the value of all the \"extra\" output arguments is 1.\r\n   <\/p><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">[m,n,p] = size(A)<\/pre><pre style=\"font-style:oblique\">m =\r\n     3\r\nn =\r\n     4\r\np =\r\n     5\r\n<\/pre><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">[m,n] = size(A)<\/pre><pre style=\"font-style:oblique\">m =\r\n     3\r\nn =\r\n    20\r\n<\/pre><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">[m,n,p,q,r] = size(A)<\/pre><pre style=\"font-style:oblique\">m =\r\n     3\r\nn =\r\n     4\r\np =\r\n     5\r\nq =\r\n     1\r\nr =\r\n     1\r\n<\/pre><p>So which of these forms is best? I don't think there is a single best choice. I regularly use all three, and my particular\r\n      choice in any one instance depends on how the output of <tt>size<\/tt> is used in the subsequent code. Also, keep in mind that every variable assignment is an opportunity to name something well\r\n      (or not).\r\n   <\/p>\r\n   <p>Sometimes, for example, I just need a size vector to pass to something like <tt>reshape<\/tt>, like this:\r\n   <\/p><pre>   size_in = size(in);\r\n   % work with input as a single column vector\r\n   in = in(:);<\/pre><pre>   ... lots o' code<\/pre><pre>   % reshape output to be the same size as input\r\n   out = reshape(out,size_in);<\/pre><p>Or I might need to refer several times in the code to the number of color-space components in an array, and I don't need other\r\n      information about the size:\r\n   <\/p><pre>   num_components = size(in,3);<\/pre><pre>   for k = 1:num_components\r\n      ... do something interesting with each component\r\n   end<\/pre><p>If I need to refer to the sizes along several dimensions separately in the code, then I'll do something like this in order\r\n      to have readable names:\r\n   <\/p><pre>   [num_rows, num_cols, num_planes] = size(A);<\/pre><p><a href=\"https:\/\/blogs.mathworks.com\/steve\/2011\/03\/22\/too-much-information-about-the-size-function\/#comment-24045\">Jonathan<\/a> didn't want to use the tilde technique I showed because of code portability with older versions of MATLAB:\r\n   <\/p><pre>   [num_rows, num_cols, ~] = size(A);<\/pre><p>I acknowledge that is sometimes a concern, but for any given feature this issue doesn't last forever. MATLAB xUnit Test Framework is by far my post popular contribution to the MATLAB Central File Exchange (147 downloads in the last 30 days), and it requires\r\n      R2008a or later to run. When I started at MathWorks, there were no multidimensional arrays, integer arrays, cell arrays, structs,\r\n      subfunctions, object-oriented programming, function handles, try\/catch, etc.\r\n   <\/p>\r\n   <p><a href=\"https:\/\/blogs.mathworks.com\/steve\/2011\/03\/22\/too-much-information-about-the-size-function\/#comment-24049\">Jo&atilde;o suggested<\/a> that we enhance <tt>size<\/tt> so that the <tt>dim<\/tt> argument can be a vector. For example:\r\n   <\/p><pre>   sz = size(A,1:2);<\/pre><p>I like this idea a lot in principle, but I would personally be cautious about putting it into MATLAB. There are a lot of functions\r\n      that take <tt>dim<\/tt> arguments, and we want them to be as consistent as possible in the way they treat the <tt>dim<\/tt> argument. So making this change to <tt>size<\/tt> has possible implications well beyond <tt>size<\/tt> that we would have to consider.\r\n   <\/p>\r\n   <p>If I think about the size-related code I've written many times for handling multidimensional arrays, I think I'd like to have\r\n      a function that allows me to specify how many elements the output size vector should have. It would work something like this:\r\n   <\/p><pre>   sz = sizen(A,5);  % sz has five elements<\/pre><p>Then, if I'm working with two multidimensional arrays, A and B, and I want size vectors that are guaranteed to be compatible,\r\n      I could do it like this:\r\n   <\/p><pre>   num_dims = max(ndims(A), ndims(B));\r\n   size_A = sizen(A, num_dims);\r\n   size_B = sizen(B, num_dims);<\/pre><p>I could even imagine a <tt>sizes<\/tt> function that would handle that logic for me automatically:\r\n   <\/p><pre>   [size_A, size_B] = sizes(A, B);<\/pre><p>There were other comments that had to do with general multidimensional array manipulation and indexing techniques. I'll explore\r\n      some of those ideas in a future post. While you're waiting, look at the code for <tt>flipdim<\/tt> and see if you can figure out how it works.\r\n   <\/p><script language=\"JavaScript\">\r\n<!--\r\n\r\n    function grabCode_bfb5d3a9199846dd8d800a9d608b1907() {\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='bfb5d3a9199846dd8d800a9d608b1907 ' + '##### ' + 'SOURCE BEGIN' + ' #####';\r\n        t2='##### ' + 'SOURCE END' + ' #####' + ' bfb5d3a9199846dd8d800a9d608b1907';\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        author = 'Steve Eddins';\r\n        copyright = 'Copyright 2011 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 author and copyright lines at the bottom if specified.\r\n        if ((author.length > 0) || (copyright.length > 0)) {\r\n            d.writeln('');\r\n            d.writeln('%%');\r\n            if (author.length > 0) {\r\n                d.writeln('% _' + author + '_');\r\n            }\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      \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_bfb5d3a9199846dd8d800a9d608b1907()\"><span style=\"font-size: x-small;        font-style: italic;\">Get \r\n            the MATLAB code \r\n            <noscript>(requires JavaScript)<\/noscript><\/span><\/a><br><br>\r\n      Published with MATLAB&reg; 7.11<br><\/p>\r\n<\/div>\r\n<!--\r\nbfb5d3a9199846dd8d800a9d608b1907 ##### SOURCE BEGIN #####\r\n%%\r\n% I'm terrible at predicting what kind of topic will generate a lot of\r\n% comments. I was sure that\r\n% <https:\/\/blogs.mathworks.com\/steve\/2011\/03\/22\/too-much-information-about-the-size-function\/\r\n% last week's post on |size| esoterica> would put most everyone to sleep.\r\n% But no, it quickly gathered quite a few comments containing several\r\n% interesting ideas and questions. So I thought it would be useful to\r\n% follow up with another post instead of replying with my own comments.\r\n%\r\n% First, there was some discussion in the comments about the \"best\" way to\r\n% call |size|. Let's quickly review the basic ways to call |size|:\r\n%\r\n% The call |sz = size(A)| returns a size vector of length |ndims(A)|.\r\n\r\nA = rand(3,4,5);\r\nsz = size(A)\r\n\r\n%%\r\n% The call |d = size(A,n)| returns the size of the n-th dimension of |A|.\r\n% |n| can be greater than |ndims(A)|.\r\n\r\nd = size(A,2)\r\n\r\n%%\r\n\r\nd = size(A,6)\r\n\r\n%%\r\n% The call |[m,n,p] = size(A)| returns the sizes along the first three\r\n% dimensions as |m|, |n|, and |p|. If |A| has more than three dimensions,\r\n% then |p| is the product of the sizes along the third and all higher\r\n% dimensions.  If you call |size(A)| with more output arguments than\r\n% |ndims(A)|, the value of all the \"extra\" output arguments is 1.\r\n\r\n[m,n,p] = size(A)\r\n\r\n%%\r\n\r\n[m,n] = size(A)\r\n\r\n%%\r\n\r\n[m,n,p,q,r] = size(A)\r\n\r\n%%\r\n% So which of these forms is best? I don't think there is a single best\r\n% choice. I regularly use all three, and my particular choice in any one\r\n% instance depends on how the output of |size| is used in the subsequent\r\n% code. Also, keep in mind that every variable assignment is an opportunity\r\n% to name something well (or not).\r\n%\r\n% Sometimes, for example, I just need a size vector to pass to something\r\n% like |reshape|, like this:\r\n%\r\n%     size_in = size(in);\r\n%     % work with input as a single column vector\r\n%     in = in(:);\r\n%\r\n%     ... lots o' code\r\n%     \r\n%     % reshape output to be the same size as input\r\n%     out = reshape(out,size_in);\r\n%\r\n% Or I might need to refer several times in the code to the number of\r\n% color-space components in an array, and I don't need other information\r\n% about the size:\r\n%\r\n%     num_components = size(in,3);\r\n%\r\n%     for k = 1:num_components\r\n%        ... do something interesting with each component\r\n%     end\r\n%\r\n% If I need to refer to the sizes along several dimensions separately in the\r\n% code, then I'll do something like this in order to have readable names:\r\n%\r\n%     [num_rows, num_cols, num_planes] = size(A);\r\n%\r\n% <https:\/\/blogs.mathworks.com\/steve\/2011\/03\/22\/too-much-information-about-the-size-function\/#comment-24045\r\n% Jonathan> didn't want to use the tilde technique I showed because of code\r\n% portability with older versions of MATLAB:\r\n%\r\n%     [num_rows, num_cols, ~] = size(A);\r\n%\r\n% I acknowledge that is sometimes a concern, but for any given feature\r\n% this issue doesn't last forever.\r\n% <https:\/\/www.mathworks.com\/matlabcentral\/fileexchange\/22846-matlab-xunit-test-framework\r\n% MATLAB xUnit Test Framework> is by far my post popular contribution to\r\n% the MATLAB Central File Exchange (147 downloads in the last 30 days), and\r\n% it requires R2008a or later to run. When I started at MathWorks, there\r\n% were no multidimensional arrays, integer arrays, cell arrays, structs,\r\n% subfunctions, object-oriented programming, function handles, try\/catch,\r\n% etc.\r\n%\r\n% <https:\/\/blogs.mathworks.com\/steve\/2011\/03\/22\/too-much-information-about-the-size-function\/#comment-24049\r\n% Jo\u00c3\u00a3o suggested> that we enhance |size| so that the |dim| argument can be a\r\n% vector. For example:\r\n%\r\n%     sz = size(A,1:2);\r\n%\r\n% I like this idea a lot in principle, but I would personally be cautious\r\n% about putting it into MATLAB. There are a lot of functions that take\r\n% |dim| arguments, and we want them to be as consistent as possible in the\r\n% way they treat the |dim| argument. So making this change to |size| has\r\n% possible implications well beyond |size| that we would have to consider.\r\n%\r\n% If I think about the size-related code I've written many times for\r\n% handling multidimensional arrays, I think I'd like to have a function that\r\n% allows me to specify how many elements the output size vector should\r\n% have. It would work something like this:\r\n%\r\n%     sz = sizen(A,5);  % sz has five elements\r\n%\r\n% Then, if I'm working with two multidimensional arrays, A and B, and I\r\n% want size vectors that are guaranteed to be compatible, I could do it\r\n% like this:\r\n%\r\n%     num_dims = max(ndims(A), ndims(B));\r\n%     size_A = sizen(A, num_dims);\r\n%     size_B = sizen(B, num_dims);\r\n%\r\n% I could even imagine a |sizes| function that would handle that logic for\r\n% me automatically:\r\n%\r\n%     [size_A, size_B] = sizes(A, B);\r\n%\r\n% There were other comments that had to do with general multidimensional\r\n% array manipulation and indexing techniques. I'll explore some of those\r\n% ideas in a future post. While you're waiting, look at the code for\r\n% |flipdim| and see if you can figure out how it works.\r\n\r\n##### SOURCE END ##### bfb5d3a9199846dd8d800a9d608b1907\r\n-->","protected":false},"excerpt":{"rendered":"<p>\r\n   I'm terrible at predicting what kind of topic will generate a lot of comments. I was sure that last week's post on size esoterica would put most everyone to sleep. But no, it quickly gathered... <a class=\"read-more\" href=\"https:\/\/blogs.mathworks.com\/steve\/2011\/03\/29\/even-more-information-about-the-size-function\/\">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":[460,170,190],"_links":{"self":[{"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/posts\/366"}],"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=366"}],"version-history":[{"count":1,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/posts\/366\/revisions"}],"predecessor-version":[{"id":2291,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/posts\/366\/revisions\/2291"}],"wp:attachment":[{"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/media?parent=366"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/categories?post=366"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/tags?post=366"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}