{"id":23,"date":"2006-02-22T00:00:00","date_gmt":"2006-02-22T05:00:00","guid":{"rendered":"https:\/\/blogs.mathworks.com\/loren\/?p=23"},"modified":"2006-03-12T07:57:34","modified_gmt":"2006-03-12T12:57:34","slug":"scalar-expansion-and-more-take-2","status":"publish","type":"post","link":"https:\/\/blogs.mathworks.com\/loren\/2006\/02\/22\/scalar-expansion-and-more-take-2\/","title":{"rendered":"Scalar Expansion and More"},"content":{"rendered":"<style xmlns:mwsh=\"https:\/\/www.mathworks.com\/namespace\/mcode\/v1\/syntaxhighlight.dtd\">\r\n\r\npre.codeinput {\r\n  background: #F9F7F3;\r\n  padding: 10px;\r\n  border: 1px solid rgb(200,200,200);\r\n}\r\n\r\n@media print {\r\n  pre.codeinput {word-wrap:break-word; width:100%;}\r\n} \r\n\r\nspan.keyword {color: #0000FF}\r\nspan.comment {color: #228B22}\r\nspan.string {color: #A020F0}\r\nspan.untermstring {color: #B20000}\r\nspan.syscmd {color: #B28C00}\r\n\r\npre.codeoutput {\r\n  background: #F9F7F3;\r\n  color: #777777;\r\n  padding: 10px;\r\n  border: 1px solid rgb(200,200,200);\r\n}\r\n\r\npre.error {\r\n  color: red;\r\n}\r\n\r\np.footer {\r\n  text-align: right;\r\n  font-size: xx-small;\r\n  font-weight: lighter;\r\n  font-style: italic;\r\n  color: gray;\r\n}\r\n\r\n  <\/style><div xmlns:mwsh=\"https:\/\/www.mathworks.com\/namespace\/mcode\/v1\/syntaxhighlight.dtd\" class=\"content\">\r\n   <introduction>\r\n      <p>Last week I received email from a blog reader asking about extending the meaning of the arithmetic operators to do more than scalar expansion, and instead extend the expansion to singleton dimensions. \r\nIn this post, I discuss the evolution of scalar expansion in MATLAB, talk about possible future designs,\r\n         and open up the discussion to your input.  In that spirit, please add your comments on this topic <a href=\"?p=23#comments\">here<\/a>.\r\n      <\/p>\r\n   <\/introduction>\r\n   <h3>Contents<\/h3>\r\n   <div>\r\n      <ul>\r\n         <li><a href=\"#1\">Scalar Expansion for Arithmetic<\/a><\/li>\r\n         <li><a href=\"#3\">Scalar Expansion for Assignment<\/a><\/li>\r\n         <li><a href=\"#5\">What about More than Scalar Expansion?<\/a><\/li>\r\n         <li><a href=\"#6\">How to Add Constant Values to Each Column of a Matrix<\/a><\/li>\r\n         <li><a href=\"#14\">Four Choices<\/a><\/li>\r\n         <li><a href=\"#16\">Pros and Cons<\/a><\/li>\r\n         <li><a href=\"#18\">Now It's Your Turn<\/a><\/li>\r\n       <\/ul>\r\n   <\/div>\r\n   <h3>Scalar Expansion for Arithmetic<a name=\"1\"><\/a><\/h3>\r\n   <p>In very early versions of MATLAB, you could rely on scalars expanding when you were performing element-wise arithmetic. In\r\n      the following code, for example,\r\n   <\/p><pre class=\"codeinput\">    A = magic(3);\r\n    B = 2;\r\n    C = A + B;\r\n<\/pre><p>the scalar <tt>B<\/tt> is added to each element of <tt>A<\/tt>.\r\n   <\/p>\r\n   <h3>Scalar Expansion for Assignment<a name=\"3\"><\/a><\/h3>\r\n   <p>It wasn't until MATLAB version 5 and the introduction of N-dimensional arrays, that scalar expansion extended to assignment,\r\n      e.g.,\r\n   <\/p><pre class=\"codeinput\">    D(3:5,1:2) = 17\r\n<\/pre><pre class=\"codeoutput\">\r\nD =\r\n\r\n     0     0\r\n     0     0\r\n    17    17\r\n    17    17\r\n    17    17\r\n\r\n<\/pre><p>replacing the need for forming a right-hand side exactly the same size as the left-hand side.<\/p>\r\n   <h3>What about More than Scalar Expansion?<a name=\"5\"><\/a><\/h3>\r\n   <p>Judging from the number of newsgroup posts (see a few at these links:  <a href=\"http:\/\/groups.google.com\/group\/comp.soft-sys.matlab\/browse_frm\/thread\/272e3bacdd55ef80\/b9f9a117765ba065?lnk=st&amp;q=group%3Acomp.soft-sys.matlab+repmat+%22each+column%22&amp;rnum=1#b9f9a117765ba065\">1<\/a>  <a href=\"http:\/\/groups.google.com\/group\/comp.soft-sys.matlab\/browse_frm\/thread\/676588ab53dc0fa\/055f67c9bde40b77?lnk=st&amp;q=group%3Acomp.soft-sys.matlab+repmat+%22each+column%22&amp;rnum=2#055f67c9bde40b77\">2<\/a>  <a href=\"http:\/\/groups.google.com\/group\/comp.soft-sys.matlab\/browse_frm\/thread\/b48f2d33f9d762f3\/c2b391a0c8adae21?lnk=st&amp;q=group%3Acomp.soft-sys.matlab+repmat+%22each+column%22&amp;rnum=3#c2b391a0c8adae21\">3<\/a>  <a href=\"http:\/\/groups.google.com\/group\/comp.soft-sys.matlab\/browse_frm\/thread\/a522ef0dc1943631\/8f92a20733070c54?lnk=st&amp;q=group%3Acomp.soft-sys.matlab+repmat+%22each+column%22&amp;rnum=2#8f92a20733070c54\">4<\/a>  <a href=\"http:\/\/groups.google.com\/group\/comp.soft-sys.matlab\/browse_frm\/thread\/9e7e1f5c091ee313\/4950ee79ce3c67e0?lnk=st&amp;q=group%3Acomp.soft-sys.matlab+repmat+%22each+column%22&amp;rnum=3#4950ee79ce3c67e0\">5<\/a> ), there is a lot of interest in having way to express calculations concisely that don't involve scalars or arrays that match\r\n      completely but for which there is a reasonable interpretation, for example, calculating <kbd>A - mean(A)<\/kbd> where <kbd>A<\/kbd> is a matrix.  \r\n   <\/p>\r\n   <h3>How to Add Constant Values to Each Column of a Matrix<a name=\"6\"><\/a><\/h3>\r\n   <p>Let's suppose we want to add a constant value to each column of a matrix. Here are some ways we might do it today, all of which require at least some temporary extra memory from MATLAB.  If the matrix is large, then the temporary of the second variable will also be large, and may consume a substantial additional amount of memory.<\/p><pre class=\"codeinput\">row = 1:4;\r\nmat = [magic(3) (10:12)']\r\n<\/pre><pre class=\"codeoutput\">\r\nmat =\r\n\r\n     8     1     6    10\r\n     3     5     7    11\r\n     4     9     2    12\r\n\r\n<\/pre><p>Loop over columns of matrix, adding a scalar value to each one<\/p><pre class=\"codeinput\">out = mat;\r\n<span class=\"keyword\">for<\/span> c = 1:length(row)\r\n    out(:,c) = out(:,c) + row(c);\r\n<span class=\"keyword\">end<\/span>\r\n<\/pre><p>Expand the rows into a larger matrix the size of <tt>mat<\/tt> 3 different ways.\r\n   <\/p>\r\n   <p>The first way is via indexing into the row vector, a technique known as Tony's trick because a customer, Tony, showed it to\r\n      me at the ICASSP conference in Albuquerque in 1990\r\n   <\/p><pre class=\"codeinput\">out1 = mat + row(ones(1,size(mat,1)),:);\r\n<\/pre><p>The second way it to use <tt>repmat<\/tt> which essentially uses Tony's trick in most cases.\r\n   <\/p><pre class=\"codeinput\">out2 = mat + repmat(row, size(mat,1),1);\r\n<\/pre><p>The third variant is to use an outer product to duplicate the rows.<\/p><pre class=\"codeinput\">out3 = mat + ones(size(mat,1),1) * row;\r\n<\/pre><p>Let's make sure our answers are all the same.<\/p><pre class=\"codeinput\">isequal(out,out1,out2,out3)\r\n<\/pre><pre class=\"codeoutput\">\r\nans =\r\n\r\n     1\r\n\r\n<\/pre><p>Doug Schwarz, a longtime MATLAB user, has developed a <a href=\"http:\/\/www.frontiernet.net\/~dmschwarz\/genops.html\">library of generalized operators<\/a> which could also be used to solve this class of problem (and more).\r\n   <\/p>\r\n   <h3>Four Choices<a name=\"14\"><\/a><\/h3>\r\n   <p>There are four alternatives I can think of for dealing with expansion beyond scalars.<\/p>\r\n   <div>\r\n      <ol>\r\n         <li>Keep the status quo since there are already many ways to accomplish what users want.<\/li>\r\n         <li>Create new functions to flexibly deal with combining different size arrays for elementwise (and perhaps matrix) operations.<\/li>\r\n         <li>Change the basic operators in MATLAB such as <tt>+<\/tt> to accomodate commensurate but not identically sized arrays.\r\n         <\/li>\r\n         <li>Invent new operator notation to accomodate the sort of binary elementwise operations we've discussed so far.<\/li>\r\n      <\/ol>\r\n   <\/div>\r\n   <h3>Pros and Cons<a name=\"16\"><\/a><\/h3>\r\n   <p>Each of the above ideas has pros and cons.  We've talked to some users in the past about this topic and their reactions generally\r\n      fell into three buckets:\r\n   <\/p>\r\n   <div>\r\n      <ul>\r\n         <li>loved the idea of changing the meaning of the elementwise operators so, for example, row+column would do an \"outer\" sum.<\/li>\r\n         <li>hated the idea of changing the meaning of existing operators, for reasons of both readability and backward compatibility.<\/li>\r\n         <li>indifferent (this was, by far, the smallest group!).<\/li>\r\n      <\/ul>\r\n   <\/div>\r\n   <h3>Now It's Your Turn<a name=\"18\"><\/a><\/h3>\r\n   <p>Now it's your turn to chime in.  Please leave your thoughts on this topic <a href=\"?p=23#comments\">here<\/a>.\r\n   <\/p>\r\n    <p class=\"footer\"><br>\r\n      Published with MATLAB&reg; 7.2<br><\/p>\r\n<\/div>\r\n<!--\r\n##### SOURCE BEGIN #####\r\n%% Scalar Expansion (and more?) \r\n% This is an open mike(*) post in which I discuss the evolution of scalar\r\n% expansion in MATLAB, talk about possible future designs, and open up the\r\n% discussion to your input.  In that spirit, please add your comments on\r\n% this topic <?p=22#comments here>.\r\n\r\n\r\n%% Scalar Expansion for Arithmetic\r\n% In very early versions of MATLAB, you could rely on scalars expanding when you were performing element-wise arithmetic. In the following code, for example,\r\n    A = magic(3);\r\n    B = 2;\r\n    C = A + B;\r\n%%\r\n% the scalar |B| is added to each element of |A|.  \r\n\r\n%% Scalar Expansion for Assignment\r\n% It wasn't until MATLAB\r\n% version 5 and the introduction of N-dimensional arrays, that scalar expansion extended to assignment, e.g.,\r\n    D(3:5,1:2) = 17\r\n%%\r\n% replacing the need for forming a right-hand side exactly the same size\r\n% as the left-hand side.\r\n\r\n%% What about More than Scalar Expansion?\r\n% Judging from the number of newsgroup posts (see a few at these links:\r\n%  <http:\/\/groups.google.com\/group\/comp.soft-sys.matlab\/browse_frm\/thread\/272e3bacdd55ef80\/b9f9a117765ba065?lnk=st&q=group%3Acomp.soft-sys.matlab+repmat+%22each+column%22&rnum=1#b9f9a117765ba065 1>\r\n%  <http:\/\/groups.google.com\/group\/comp.soft-sys.matlab\/browse_frm\/thread\/676588ab53dc0fa\/055f67c9bde40b77?lnk=st&q=group%3Acomp.soft-sys.matlab+repmat+%22each+column%22&rnum=2#055f67c9bde40b77 2>\r\n%  <http:\/\/groups.google.com\/group\/comp.soft-sys.matlab\/browse_frm\/thread\/b48f2d33f9d762f3\/c2b391a0c8adae21?lnk=st&q=group%3Acomp.soft-sys.matlab+repmat+%22each+column%22&rnum=3#c2b391a0c8adae21 3>\r\n%  <http:\/\/groups.google.com\/group\/comp.soft-sys.matlab\/browse_frm\/thread\/a522ef0dc1943631\/8f92a20733070c54?lnk=st&q=group%3Acomp.soft-sys.matlab+repmat+%22each+column%22&rnum=2#8f92a20733070c54 4>\r\n%  <http:\/\/groups.google.com\/group\/comp.soft-sys.matlab\/browse_frm\/thread\/9e7e1f5c091ee313\/4950ee79ce3c67e0?lnk=st&q=group%3Acomp.soft-sys.matlab+repmat+%22each+column%22&rnum=3#4950ee79ce3c67e0 5>\r\n% ), there is a lot of interest in having way to express calculations\r\n% concisely that don't involve scalars or arrays that match completely but\r\n% for which there is a reasonable interpretation.   \r\n%% How to Add Constant Values to Each Column of a Matrix\r\n% Let's suppose we want to add a constant value to each column of a matrix.\r\n% Here are some ways we might do it today.\r\nrow = 1:4;\r\nmat = [magic(3) (10:12)']\r\n%%\r\n% Loop over columns of matrix, adding a scalar value to each one\r\nout = mat;\r\nfor c = 1:length(row)\r\n    out(:,c) = out(:,c) + row(c);  \r\nend\r\n%% \r\n% Expand the rows into a larger matrix the size of |mat| 3 different ways.\r\n%%\r\n% The first way is via indexing into the row vector, a technique known as\r\n% Tony's trick because a customer, Tony, showed it to me at the ICASSP\r\n% conference in Albuquerque in 1990\r\nout1 = mat + row(ones(1,size(mat,1)),:);\r\n\r\n%%\r\n% The second way it to use |repmat| which essentially uses Tony's trick in\r\n% most cases.\r\nout2 = mat + repmat(row, size(mat,1),1);\r\n\r\n%%\r\n% The third variant is to use an outer product to duplicate the rows.\r\nout3 = mat + ones(size(mat,1),1) * row;\r\n\r\n%%\r\n% Let's make sure our answers are all the same.\r\nisequal(out,out1,out2,out3)\r\n\r\n%%\r\n% Doug Schwarz, a longtime MATLAB user, has developed a \r\n% <http:\/\/www.frontiernet.net\/~dmschwarz\/genops.html library of generalized operators>\r\n% which could also be used to solve this class of problem (and more).\r\n\r\n%% Four Choices\r\n% There are four alternatives I can think of for dealing with expansion\r\n% beyond scalars.\r\n%%\r\n% * Keep the status quo since there are already many ways to accomplish\r\n% what users want.\r\n% * Create new functions to flexibly deal with combining different size\r\n% arrays for elementwise (and perhaps matrix) operations.\r\n% * Create change the basic operators in MATLAB such as |+| to accomodate\r\n% commensurate but not identically sized arrays.\r\n% * Invent new operator notation to accomodate the sort of binary\r\n% elementwise operations we've discussed so far.\r\n%% Pros and Cons\r\n% Each of the above ideas has pros and cons.  We've talked to some users in\r\n% the past about this topic and their reactions generally fell into three\r\n% buckets:\r\n%%\r\n% * loved the idea of changing the meaning of the elementwise operators so,\r\n% for example, row+column would do an \"outer\" sum.\r\n% * hated the idea of changing the meaning of existing operators, for\r\n% reasons of both readability and backward compatibility.\r\n% * indifferent (this was, by far, the smallest group!).\r\n%% Now It's Your Turn\r\n% Now it's your turn to chime in.  Please leave your thoughts on this\r\n% topic <?p=22#comments here>.\r\n\r\n\r\n\r\n##### SOURCE END #####\r\n-->","protected":false},"excerpt":{"rendered":"<p>\r\n\r\npre.codeinput {\r\n  background: #F9F7F3;\r\n  padding: 10px;\r\n  border: 1px solid rgb(200,200,200);\r\n}\r\n\r\n@media print {\r\n  pre.codeinput {word-wrap:break-word; width:100%;}\r\n} \r\n\r\nspan.keyword... <a class=\"read-more\" href=\"https:\/\/blogs.mathworks.com\/loren\/2006\/02\/22\/scalar-expansion-and-more-take-2\/\">read more >><\/a><\/p>","protected":false},"author":39,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[10,7,12],"tags":[],"_links":{"self":[{"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/posts\/23"}],"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=23"}],"version-history":[{"count":0,"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/posts\/23\/revisions"}],"wp:attachment":[{"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/media?parent=23"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/categories?post=23"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/tags?post=23"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}