{"id":157,"date":"2008-10-13T15:14:34","date_gmt":"2008-10-13T20:14:34","guid":{"rendered":"https:\/\/blogs.mathworks.com\/loren\/2008\/10\/13\/vectorizing-the-notion-of-colon\/"},"modified":"2018-01-08T15:21:45","modified_gmt":"2018-01-08T20:21:45","slug":"vectorizing-the-notion-of-colon","status":"publish","type":"post","link":"https:\/\/blogs.mathworks.com\/loren\/2008\/10\/13\/vectorizing-the-notion-of-colon\/","title":{"rendered":"Vectorizing the Notion of Colon (:)"},"content":{"rendered":"<div xmlns:mwsh=\"https:\/\/www.mathworks.com\/namespace\/mcode\/v1\/syntaxhighlight.dtd\" class=\"content\">\r\n   <introduction>\r\n      <p>The other day, one of my MathWorks buddies, Peter, asked me if I knew any tricks for vectorizing the notion of the <a href=\"https:\/\/www.mathworks.com\/help\/releases\/R2008b\/techdoc\/ref\/colon.html\">colon (<tt>:<\/tt>) operator<\/a>. For me, this sort of inquiry sometimes has an effect similar to waving a flag in front of a bull!  The challenge was on.\r\n      <\/p>\r\n      <p>I know people have posted methods in the past on the <a>MathWorks newsgroup<\/a>. I quickly had a few more ideas and implemented them.\r\n      <\/p>\r\n   <\/introduction>\r\n   <h3>Contents<\/h3>\r\n   <div>\r\n      <ul>\r\n         <li><a href=\"#1\">Problem Statement<\/a><\/li>\r\n         <li><a href=\"#2\">Solution Variants<\/a><\/li>\r\n         <li><a href=\"#3\">Test the Solutions<\/a><\/li>\r\n         <li><a href=\"#7\">Look at the Algorithms<\/a><\/li>\r\n         <li><a href=\"#8\">Use a for Loop<\/a><\/li>\r\n         <li><a href=\"#10\">Use sprintf and eval<\/a><\/li>\r\n         <li><a href=\"#11\">Use arrayfun - Method 1<\/a><\/li>\r\n         <li><a href=\"#13\">Use arrayfun - Method 2<\/a><\/li>\r\n         <li><a href=\"#15\">Use Run-Length Decoding Idea<\/a><\/li>\r\n         <li><a href=\"#17\">Other Methods?<\/a><\/li>\r\n      <\/ul>\r\n   <\/div>\r\n   <h3>Problem Statement<a name=\"1\"><\/a><\/h3>\r\n   <p>Suppose I have matching pairs of integers depicting the starting and stopping indices for selecting points from another vector.\r\n        I've shown in other <a href=\"https:\/\/blogs.mathworks.com\/loren\/category\/Indexing\">posts<\/a> that vectorizing the indexing can have tremendous performance benefits for your code.  What I'd like to do is create one\r\n      full list of indices so I ultimately only index into the data vector once.\r\n   <\/p>\r\n   <h3>Solution Variants<a name=\"2\"><\/a><\/h3>\r\n   <p>Here are a few ways to solve the problem.<\/p>\r\n   <div>\r\n      <ul>\r\n         <li>Build up the array of indices, looping (<a href=\"https:\/\/www.mathworks.com\/help\/releases\/R2008b\/techdoc\/ref\/for.html\"><tt>for<\/tt><\/a>) over each pair, one at a time.\r\n         <\/li>\r\n         <li>Write the indices to a string and have MATLAB evaluate the various : expressions.<\/li>\r\n         <li>Use <a href=\"https:\/\/www.mathworks.com\/help\/releases\/R2008b\/techdoc\/ref\/arrayfun.html\"><tt>arrayfun<\/tt><\/a> (two algorithms) as the engine for creating the output.\r\n         <\/li>\r\n         <li>Modify the idea of run-length decoding, inspired by Peter Acklam's run length decoder. MathWorks Peter used this as a basis for the rld-based algorithm.\r\n         <\/li>\r\n      <\/ul>\r\n   <\/div>\r\n   <h3>Test the Solutions<a name=\"3\"><\/a><\/h3>\r\n   <p>Let's prove that the solutions all get the same answers first before delving into the algorithm details.  I'll give a vector\r\n      of starting indices followed by a vector of ending indices.  If an ending value is smaller than a starting value, that pair\r\n      is effectively skipped. Duplicate starting points are allowed.\r\n   <\/p><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">starts = [1 7 7 15 17];\r\nends = [3 8 6 15 19];\r\nexpectedAnswer = [1 2 3 7 8 15 17 18 19];<\/pre><p>Round up the files to run.<\/p><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">d = dir(<span style=\"color: #A020F0\">'coloncat*.m'<\/span>);\r\nd.name<\/pre><pre style=\"font-style:oblique\">ans =\r\ncoloncatarrf1.m\r\nans =\r\ncoloncatarrf2.m\r\nans =\r\ncoloncatfor.m\r\nans =\r\ncoloncatrld.m\r\nans =\r\ncoloncatstr.m\r\n<\/pre><p>Run each file with the test data.<\/p><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\"><span style=\"color: #0000FF\">for<\/span> k = 1:length(d)\r\n    func = str2func(d(k).name(1:end-2));\r\n    outputs{k} = func(starts, ends);\r\n<span style=\"color: #0000FF\">end<\/span><\/pre><p>Validate that all the methods calculated the expected results.<\/p><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">rightAnswers = isequal(expectedAnswer,outputs{:})<\/pre><pre style=\"font-style:oblique\">rightAnswers =\r\n     1\r\n<\/pre><h3>Look at the Algorithms<a name=\"7\"><\/a><\/h3>\r\n   <p>Let's look at the variety of algorithms and coding techniques I used. If you look at the first chunk of code in each file,\r\n      you will see they are algorithmically identical - checking for sequences that have length of at least one (1) and deleting\r\n      the other entries.  What we really want to compare are the lines that follow that section.\r\n   <\/p>\r\n   <h3>Use a for Loop<a name=\"8\"><\/a><\/h3>\r\n   <p>This is perhaps the most straightforward method.<\/p><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">dbtype <span style=\"color: #A020F0\">coloncatfor<\/span><\/pre><pre style=\"font-style:oblique\">\r\n1     function x = coloncatfor(start, stop)\r\n2     % COLONCAT Concatenate colon expressions\r\n3     %    X = COLONCAT(START,STOP) returns a vector containing the values\r\n4     %    [START(1):STOP(1) START(2):STOP(2) START(END):STOP(END)].\r\n5     \r\n6     len = stop - start + 1;\r\n7     \r\n8     % keep only sequences whose length is positive\r\n9     pos = len &gt; 0;\r\n10    start = start(pos);\r\n11    stop = stop(pos);\r\n12    len = len(pos);\r\n13    if isempty(len)\r\n14        x = [];\r\n15        return;\r\n16    end\r\n17    \r\n18    % find end and beginning indices for each chunk\r\n19    partialLength = cumsum(len);\r\n20    cumStart = [1 partialLength(1:end-1)+1];\r\n21    \r\n22    % preallocate output\r\n23    % then loop through start\/stop pairs, in order, and fill\r\n24    numtot = sum(len);\r\n25    x = zeros(1,numtot);\r\n26    for k = 1:length(start)\r\n27        x(cumStart(k):partialLength(k)) = start(k):stop(k);\r\n28    end\r\n<\/pre><p>After culling the <tt>start<\/tt> and <tt>stop<\/tt> indices, I calculate where each successive sequence ends (<tt>partialLength<\/tt>) and where they each begin (<tt>cumStart<\/tt>).  I next preallocate the output array to its final size. And finally, as I loop through the matched pairs of <tt>start<\/tt> and <tt>stop<\/tt> values, I generate the colon sequence and fill these values into the correct output locations.\r\n   <\/p>\r\n   <h3>Use sprintf and eval<a name=\"10\"><\/a><\/h3>\r\n   <p>This method uses <a href=\"https:\/\/www.mathworks.com\/help\/releases\/R2008b\/techdoc\/ref\/sprintf.html\"><tt>sprintf<\/tt><\/a> which allows me to gather all of the index start and stop values into a string without looping.  I use <a href=\"https:\/\/www.mathworks.com\/help\/releases\/R2008b\/techdoc\/ref\/eval.html\"><tt>eval<\/tt><\/a> evaluate the string, thereby computing the output.\r\n   <\/p><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">dbtype <span style=\"color: #A020F0\">coloncatstr<\/span><\/pre><pre style=\"font-style:oblique\">\r\n1     function x = coloncatstr(start, stop)\r\n2     % COLONCAT Concatenate colon expressions\r\n3     %    X = COLONCAT(START,STOP) returns a vector containing the values\r\n4     %    [START(1):STOP(1) START(2):STOP(2) START(END):STOP(END)].\r\n5     \r\n6     len = stop - start + 1;\r\n7     \r\n8     % keep only sequences whose length is positive\r\n9     pos = len &gt; 0;\r\n10    start = start(pos);\r\n11    stop = stop(pos);\r\n12    len = len(pos);\r\n13    if isempty(len)\r\n14        x = [];\r\n15        return;\r\n16    end\r\n17    \r\n18    % create list of indices for : and evaluate\r\n19    indices = [start; stop];\r\n20    list = sprintf('%d:%d ',indices);\r\n21    x = eval(['[', list, ']']);\r\n<\/pre><h3>Use arrayfun - Method 1<a name=\"11\"><\/a><\/h3>\r\n   <p>The next two methods use <a href=\"https:\/\/www.mathworks.com\/help\/releases\/R2008b\/techdoc\/ref\/arrayfun.html\"><tt>arrayfun<\/tt><\/a> to do the work. Here's the first approach.\r\n   <\/p><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">dbtype <span style=\"color: #A020F0\">coloncatarrf1<\/span><\/pre><pre style=\"font-style:oblique\">\r\n1     function x = coloncatarrf1(start, stop)\r\n2     % COLONCAT Concatenate colon expressions\r\n3     %    X = COLONCAT(START,STOP) returns a vector containing the values\r\n4     %    [START(1):STOP(1) START(2):STOP(2) START(END):STOP(END)].\r\n5     \r\n6     len = stop - start + 1;\r\n7     \r\n8     % keep only sequences whose length is positive\r\n9     pos = len &gt; 0;\r\n10    start = start(pos);\r\n11    stop = stop(pos);\r\n12    len = len(pos);\r\n13    if isempty(len)\r\n14        x = [];\r\n15        return;\r\n16    end\r\n17    \r\n18    % put entries into a cell array for later use by arrayfun\r\n19    cstart = num2cell(start);\r\n20    cstop = num2cell(stop);\r\n21    vals = arrayfun(@(x,y){x{1}:y{1}},cstart,cstop);\r\n22    x = [vals{:}];\r\n\r\n<\/pre><p>Place the <tt>start<\/tt> and <tt>stop<\/tt> values into cell arrays to feed to <tt>arrayfun<\/tt>.  The entries for the two arrays act in pairs, and the function that I have <tt>arrayfun<\/tt> apply places in a cell array the sequence of values between the numbers in the paired cells.  Finally, take all the output\r\n      cells in the cell array and string out the values into a single numeric vector.\r\n   <\/p>\r\n   <h3>Use arrayfun - Method 2<a name=\"13\"><\/a><\/h3>\r\n   <p>Here's the second approach using <tt>arrayfun<\/tt>.  It involves a <tt>for<\/tt> loop as well.\r\n   <\/p><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">dbtype <span style=\"color: #A020F0\">coloncatarrf2<\/span><\/pre><pre style=\"font-style:oblique\">\r\n1     function x = coloncatarrf2(start, stop)\r\n2     % COLONCAT Concatenate colon expressions\r\n3     %    X = COLONCAT(START,STOP) returns a vector containing the values\r\n4     %    [START(1):STOP(1) START(2):STOP(2) START(END):STOP(END)].\r\n5     \r\n6     len = stop - start + 1;\r\n7     \r\n8     % keep only sequences whose length is positive\r\n9     pos = len &gt; 0;\r\n10    start = start(pos);\r\n11    stop = stop(pos);\r\n12    len = len(pos);\r\n13    if isempty(len)\r\n14        x = [];\r\n15        return;\r\n16    end\r\n17    \r\n18    % Find unique sequence lengths\r\n19    uniqlens = unique(len);\r\n20    \r\n21    % preallocate space for cell outputs of arrayfun\r\n22    chunks = cell(1,length(len));\r\n23    \r\n24    % Now loop over the lengths, being sure to place the \r\n25    % outputs in the right positions.\r\n26    for ilen = uniqlens(:)'\r\n27        idxlen = find(len==ilen);\r\n28        chunks(idxlen) = arrayfun(@(xx,yy)xx:yy,...\r\n29            start(idxlen),stop(idxlen),'UniformOutput',false);\r\n30    end\r\n31    % reassemble chunks into output\r\n32    x = [chunks{:}];\r\n\r\n<\/pre><p>The concept here is to loop over sequences that have the same length.  At most, this <tt>for<\/tt> loop is the same length as the number of values in the initial <tt>start<\/tt> vector.  If the length of the inputs is long, however, it might be advantageous to loop over sequences that generate the\r\n      same length (commensurate size) output.  Placing the output into cells allows me to not worry that I might be intermingling\r\n      output vectors of different sizes.  Once all the output sequences are collected in the cell array, I flatten it into a vector\r\n      the same way I did with method 1.\r\n   <\/p>\r\n   <h3>Use Run-Length Decoding Idea<a name=\"15\"><\/a><\/h3>\r\n   <p>Here's an algorithm based on the idea of run-length decoding.<\/p><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">dbtype <span style=\"color: #A020F0\">coloncatrld<\/span><\/pre><pre style=\"font-style:oblique\">\r\n1     function x = coloncatrld(start, stop)\r\n2     % COLONCAT Concatenate colon expressions\r\n3     %    X = COLONCAT(START,STOP) returns a vector containing the values\r\n4     %    [START(1):STOP(1) START(2):STOP(2) START(END):STOP(END)].\r\n5     \r\n6     % Based on Peter Acklam's code for run length decoding.\r\n7     len = stop - start + 1;\r\n8     \r\n9     % keep only sequences whose length is positive\r\n10    pos = len &gt; 0;\r\n11    start = start(pos);\r\n12    stop = stop(pos);\r\n13    len = len(pos);\r\n14    if isempty(len)\r\n15        x = [];\r\n16        return;\r\n17    end\r\n18    \r\n19    % expand out the colon expressions\r\n20    endlocs = cumsum(len);  \r\n21    incr = ones(1, endlocs(end));  \r\n22    jumps = start(2:end) - stop(1:end-1);  \r\n23    incr(endlocs(1:end-1)+1) = jumps;\r\n24    incr(1) = start(1);\r\n25    x = cumsum(incr);\r\n\r\n<\/pre><p>The idea is to expand the colon sequences out.  I know the lengths of each sequence so I know the starting points in the output\r\n      array.  Fill the values after the start values with 1s.  Then I figure out how much to jump from the end of one sequence to\r\n      the beginning of the next one. If there are repeated start values, the jumps might be negative.  Once this array is filled,\r\n      the output is simply the cumulative sum or <a href=\"https:\/\/www.mathworks.com\/help\/releases\/R2008b\/techdoc\/ref\/cumsum.html\"><tt>cumsum<\/tt><\/a> of the sequence.\r\n   <\/p>\r\n   <h3>Other Methods?<a name=\"17\"><\/a><\/h3>\r\n   <p>These methods I've shown, for vectorizing the notion of the colon operator, are ones that came very quickly.  I haven't spent\r\n      concerted time looking for other algorithms though I am positive some others, including some clever ones, probably exist.\r\n       Can you help me and provide other possible algorithmic ideas? Please post them <a href=\"https:\/\/blogs.mathworks.com\/loren\/?p=157#respond\">here<\/a>.\r\n   <\/p><script language=\"JavaScript\">\r\n<!--\r\n\r\n    function grabCode_5302f9ed50114135a28aab46cda75bd0() {\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='5302f9ed50114135a28aab46cda75bd0 ' + '##### ' + 'SOURCE BEGIN' + ' #####';\r\n        t2='##### ' + 'SOURCE END' + ' #####' + ' 5302f9ed50114135a28aab46cda75bd0';\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 = 'Loren Shure';\r\n        copyright = 'Copyright 2008 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_5302f9ed50114135a28aab46cda75bd0()\"><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.7<br><\/p>\r\n<\/div>\r\n<!--\r\n5302f9ed50114135a28aab46cda75bd0 ##### SOURCE BEGIN #####\r\n%% Vectorizing the Notion of Colon (:)\r\n% The other day, one of my MathWorks buddies, \r\n% <https:\/\/www.mathworks.com\/matlabcentral\/fileexchange\/loadAuthor.do?objectId=1093801&objectType=author Peter>, \r\n% asked me if I knew any tricks for vectorizing the notion of the \r\n% <https:\/\/www.mathworks.com\/help\/releases\/R2008b\/techdoc\/ref\/colon.html colon (|:|) operator>.\r\n% For me, this sort of inquiry sometimes has an effect similar to waving a \r\n% flag in front of a bull!  The challenge was on.  \r\n%\r\n% I know people have\r\n% posted methods in the past on the \r\n% <http:\/\/newsreader.mathworks.com MathWorks newsgroup>. \r\n% I quickly had a few more ideas and implemented them.\r\n%% Problem Statement\r\n% Suppose I have matching pairs of integers depicting the starting and\r\n% stopping indices for selecting points from another vector.   I've shown\r\n% in other <https:\/\/blogs.mathworks.com\/loren\/category\/Indexing posts> that\r\n% vectorizing the indexing can have tremendous performance benefits for\r\n% your code.  What I'd like to do is create one full list of indices so I\r\n% ultimately only index into the data vector once.\r\n%% Solution Variants\r\n% Here are a few ways to solve the problem.\r\n%\r\n% * Build up the array of indices, looping \r\n% (<https:\/\/www.mathworks.com\/help\/releases\/R2008b\/techdoc\/ref\/for.html |for|>) \r\n% over each pair, one at a time.\r\n% * Write the indices to a string and have MATLAB evaluate the various :\r\n% expressions.\r\n% * Use \r\n% <https:\/\/www.mathworks.com\/help\/releases\/R2008b\/techdoc\/ref\/arrayfun.html |arrayfun|> \r\n% (two algorithms) as the engine for creating the output.\r\n% * Modify the idea of run-length decoding, inspired by \r\n% <http:\/\/home.online.no\/~pjacklam\/ Peter Acklam>'s \r\n% <http:\/\/home.online.no\/~pjacklam\/matlab\/software\/util\/matutil\/obsolete\/rldecode.m run length decoder>.\r\n% MathWorks Peter used this as a basis for the rld-based algorithm.\r\n%\r\n%% Test the Solutions\r\n% Let's prove that the solutions all get the same answers first before\r\n% delving into the algorithm details.  I'll give a vector of starting\r\n% indices followed by a vector of ending indices.  If an ending value is\r\n% smaller than a starting value, that pair is effectively skipped.\r\n% Duplicate starting points are allowed.\r\nstarts = [1 7 7 15 17];\r\nends = [3 8 6 15 19];\r\nexpectedAnswer = [1 2 3 7 8 15 17 18 19];\r\n%%\r\n% Round up the files to run.\r\nd = dir('coloncat*.m');\r\nd.name\r\n%%\r\n% Run each file with the test data.\r\nfor k = 1:length(d)\r\n    func = str2func(d(k).name(1:end-2));\r\n    outputs{k} = func(starts, ends);\r\nend\r\n%%\r\n% Validate that all the methods calculated the expected results.\r\nrightAnswers = isequal(expectedAnswer,outputs{:})\r\n%% Look at the Algorithms\r\n% Let's look at the variety of algorithms and coding techniques I used.  \r\n% If you look at the first chunk of code in each file, you\r\n% will see they are algorithmically identical - checking for sequences that\r\n% have length of at least one (1) and deleting the other entries.  What we\r\n% really want to compare are the lines that follow that section.\r\n%% Use a for Loop\r\n% This is perhaps the most straightforward method.\r\ndbtype coloncatfor\r\n%%\r\n% After culling the |start| and |stop| indices, I calculate where each\r\n% successive sequence ends (|partialLength|) and where they each begin\r\n% (|cumStart|).  I next preallocate the output array to its final size.\r\n% And finally, as I loop through the matched pairs of |start| and |stop|\r\n% values, I generate the colon sequence and fill these values into the\r\n% correct output locations.\r\n%% Use sprintf and eval\r\n% This method uses \r\n% <https:\/\/www.mathworks.com\/help\/releases\/R2008b\/techdoc\/ref\/sprintf.html |sprintf|>\r\n% which allows me to gather all of the index start and stop values into a\r\n% string without looping.  I use\r\n% <https:\/\/www.mathworks.com\/help\/releases\/R2008b\/techdoc\/ref\/eval.html |eval|>\r\n% evaluate the string, thereby computing the output.\r\ndbtype coloncatstr\r\n%% Use arrayfun - Method 1\r\n% The next two methods use\r\n% <https:\/\/www.mathworks.com\/help\/releases\/R2008b\/techdoc\/ref\/arrayfun.html |arrayfun|>\r\n% to do the work. Here's the first approach.\r\ndbtype coloncatarrf1\r\n%%\r\n% Place the |start| and |stop| values into cell arrays to feed to\r\n% |arrayfun|.  The entries for the two arrays act in pairs, and the function\r\n% that I have |arrayfun| apply places in a cell array the sequence of\r\n% values between the numbers in the paired cells.  Finally, take all the\r\n% output cells in the cell array and string out the values into a single\r\n% numeric vector.\r\n%% Use arrayfun - Method 2\r\n% Here's the second approach using |arrayfun|.  It involves a |for| loop as\r\n% well.\r\ndbtype coloncatarrf2\r\n%%\r\n% The concept here is to loop over sequences that have the same length.  At\r\n% most, this |for| loop is the same length as the number of values in the\r\n% initial |start| vector.  If the length of the inputs is long, however, it\r\n% might be advantageous to loop over sequences that generate the same length\r\n% (commensurate size) output.  Placing the output into cells allows me to\r\n% not worry that I might be intermingling output vectors of different\r\n% sizes.  Once all the output sequences are collected in the cell array, I\r\n% flatten it into a vector the same way I did with method 1.\r\n%% Use Run-Length Decoding Idea\r\n% Here's an algorithm based on the idea of run-length decoding.\r\ndbtype coloncatrld\r\n%%\r\n% The idea is to expand the colon sequences out.  I know the lengths of\r\n% each sequence so I know the starting points in the output array.  Fill\r\n% the values after the start values with 1s.  Then I figure out how much\r\n% to jump from the end of one sequence to the beginning of the next one.\r\n% If there are repeated start values, the jumps might be negative.  Once\r\n% this array is filled, the output is simply the cumulative sum or \r\n% <https:\/\/www.mathworks.com\/help\/releases\/R2008b\/techdoc\/ref\/cumsum.html |cumsum|>\r\n% of the sequence.\r\n%% Other Methods?\r\n% These methods I've shown, for vectorizing the notion of the colon\r\n% operator, are ones that came very quickly.  I haven't spent concerted\r\n% time looking for other algorithms though I am positive some others,\r\n% including some clever ones, probably exist.  Can you help me and provide\r\n% other possible algorithmic ideas? Please post them\r\n% <https:\/\/blogs.mathworks.com\/loren\/?p=157#respond here>.\r\n\r\n\r\n\r\n##### SOURCE END ##### 5302f9ed50114135a28aab46cda75bd0\r\n-->","protected":false},"excerpt":{"rendered":"<p>\r\n   \r\n      The other day, one of my MathWorks buddies, Peter, asked me if I knew any tricks for vectorizing the notion of the colon (:) operator. For me, this sort of inquiry sometimes has an... <a class=\"read-more\" href=\"https:\/\/blogs.mathworks.com\/loren\/2008\/10\/13\/vectorizing-the-notion-of-colon\/\">read more >><\/a><\/p>","protected":false},"author":39,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[4,8,12],"tags":[],"_links":{"self":[{"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/posts\/157"}],"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=157"}],"version-history":[{"count":3,"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/posts\/157\/revisions"}],"predecessor-version":[{"id":2566,"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/posts\/157\/revisions\/2566"}],"wp:attachment":[{"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/media?parent=157"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/categories?post=157"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/tags?post=157"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}