<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <link>http://www.mathworks.com/matlabcentral/newsreader/view_thread/251757</link>
    <title>MATLAB Central Newsreader - vectorizing challenge</title>
    <description>Feed for thread: vectorizing challenge</description>
    <language>en-us</language>
    <copyright>&amp;copy;1994-2012 by MathWorks, Inc.</copyright>
    <webmaster>webmaster@mathworks.com</webmaster>
    <generator>MATLAB Central Newsreader</generator>
    <docs>http://blogs.law.harvard.edu/tech/rss</docs>
    <ttl>60</ttl>
    <image>
      <title>MathWorks</title>
      <url>http://www.mathworks.com/images/membrane_icon.gif</url>
    </image>
    <item>
      <pubDate>Wed, 20 May 2009 00:08:01 -0400</pubDate>
      <title>vectorizing challenge</title>
      <link>http://www.mathworks.com/matlabcentral/newsreader/view_thread/251757#651057</link>
      <author>Heywood </author>
      <description>Hi all,&lt;br&gt;
&lt;br&gt;
I'm having a hard time trying to vectorize the following code. Suppose I have a vector of interest V, and a reference vector R which is monotonically increasing (it's actually a cumulative distribution function). Both vectors contain only real numbers, except that I've modified R by tacking on -Inf at the beginning and +Inf at the end (the reason for which is hopefully obvious from the code below).&lt;br&gt;
&lt;br&gt;
For each element of V, I want to find the first element of R that is greater than or equal to it.&lt;br&gt;
&lt;br&gt;
To do this with a FOR loop is trivial (and yes, I realize the two lines in the loop can be combined into one; writing it this way just for clarity):&lt;br&gt;
&lt;br&gt;
result = zeros(1,length(V));&lt;br&gt;
for kk = 1:length(V);&lt;br&gt;
&amp;nbsp;&amp;nbsp;ind = find( V(kk) &amp;lt;= R, 1, 'first' );&lt;br&gt;
&amp;nbsp;&amp;nbsp;result(kk) = R(ind);&lt;br&gt;
end;&lt;br&gt;
&lt;br&gt;
But when V is very large, this is slow. Can anyone think of a clean way to 'vectorize' the FIND command?&lt;br&gt;
&lt;br&gt;
Thanks very much in advance!&lt;br&gt;
&lt;br&gt;
HJ</description>
    </item>
    <item>
      <pubDate>Wed, 20 May 2009 01:13:20 -0400</pubDate>
      <title>Re: vectorizing challenge</title>
      <link>http://www.mathworks.com/matlabcentral/newsreader/view_thread/251757#651059</link>
      <author>Doug Schwarz</author>
      <description>In article &amp;lt;guvhl1$qif$1@fred.mathworks.com&amp;gt;,&lt;br&gt;
&amp;nbsp;&quot;Heywood &quot; &amp;lt;heywoodj123@yahoo.com&amp;gt; wrote:&lt;br&gt;
&lt;br&gt;
&amp;gt; Hi all,&lt;br&gt;
&amp;gt; &lt;br&gt;
&amp;gt; I'm having a hard time trying to vectorize the following code. Suppose I have &lt;br&gt;
&amp;gt; a vector of interest V, and a reference vector R which is monotonically &lt;br&gt;
&amp;gt; increasing (it's actually a cumulative distribution function). Both vectors &lt;br&gt;
&amp;gt; contain only real numbers, except that I've modified R by tacking on -Inf at &lt;br&gt;
&amp;gt; the beginning and +Inf at the end (the reason for which is hopefully obvious &lt;br&gt;
&amp;gt; from the code below).&lt;br&gt;
&amp;gt; &lt;br&gt;
&amp;gt; For each element of V, I want to find the first element of R that is greater &lt;br&gt;
&amp;gt; than or equal to it.&lt;br&gt;
&amp;gt; &lt;br&gt;
&amp;gt; To do this with a FOR loop is trivial (and yes, I realize the two lines in &lt;br&gt;
&amp;gt; the loop can be combined into one; writing it this way just for clarity):&lt;br&gt;
&amp;gt; &lt;br&gt;
&amp;gt; result = zeros(1,length(V));&lt;br&gt;
&amp;gt; for kk = 1:length(V);&lt;br&gt;
&amp;gt;   ind = find( V(kk) &amp;lt;= R, 1, 'first' );&lt;br&gt;
&amp;gt;   result(kk) = R(ind);&lt;br&gt;
&amp;gt; end;&lt;br&gt;
&amp;gt; &lt;br&gt;
&amp;gt; But when V is very large, this is slow. Can anyone think of a clean way to &lt;br&gt;
&amp;gt; 'vectorize' the FIND command?&lt;br&gt;
&amp;gt; &lt;br&gt;
&amp;gt; Thanks very much in advance!&lt;br&gt;
&amp;gt; &lt;br&gt;
&amp;gt; HJ&lt;br&gt;
&lt;br&gt;
How about this?&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;% Create some sample data.&lt;br&gt;
&amp;nbsp;&amp;nbsp;dist = rand(1,10);&lt;br&gt;
&amp;nbsp;&amp;nbsp;R = [0,cumsum(dist)];&lt;br&gt;
&amp;nbsp;&amp;nbsp;R = R/R(end);&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;% Find result.&lt;br&gt;
&amp;nbsp;&amp;nbsp;n = length(R);&lt;br&gt;
&amp;nbsp;&amp;nbsp;V = rand(1,100);&lt;br&gt;
&amp;nbsp;&amp;nbsp;k = interp1(R,0:n,V);&lt;br&gt;
&amp;nbsp;&amp;nbsp;result = R(ceil(k) + 1);&lt;br&gt;
&lt;br&gt;
You are still finding the appropriate interval, but it's done &lt;br&gt;
efficiently inside interp1.&lt;br&gt;
&lt;br&gt;
-- &lt;br&gt;
Doug Schwarz&lt;br&gt;
dmschwarz&amp;ieee,org&lt;br&gt;
Make obvious changes to get real email address.</description>
    </item>
    <item>
      <pubDate>Wed, 20 May 2009 01:30:20 -0400</pubDate>
      <title>Re: vectorizing challenge</title>
      <link>http://www.mathworks.com/matlabcentral/newsreader/view_thread/251757#651061</link>
      <author>Matt </author>
      <description>&quot;Heywood &quot; &amp;lt;heywoodj123@yahoo.com&amp;gt; wrote in message &amp;lt;guvhl1$qif$1@fred.mathworks.com&amp;gt;...&lt;br&gt;
&amp;gt; Hi all,&lt;br&gt;
&amp;gt; &lt;br&gt;
&amp;gt; I'm having a hard time trying to vectorize the following code. Suppose I have a vector of interest V, and a reference vector R which is monotonically increasing (it's actually a cumulative distribution function). Both vectors contain only real numbers, except that I've modified R by tacking on -Inf at the beginning and +Inf at the end (the reason for which is hopefully obvious from the code below).&lt;br&gt;
&amp;gt; &lt;br&gt;
&amp;gt; For each element of V, I want to find the first element of R that is greater than or equal to it.&lt;br&gt;
------&lt;br&gt;
&lt;br&gt;
This one is probably not as efficient as Doug's, but is nice and compact&lt;br&gt;
&lt;br&gt;
[dummy,inds] = max(  bsxfun(@ge,R(:),V(:).')   );&lt;br&gt;
Result = R(inds);</description>
    </item>
    <item>
      <pubDate>Wed, 20 May 2009 07:04:02 -0400</pubDate>
      <title>Re: vectorizing challenge</title>
      <link>http://www.mathworks.com/matlabcentral/newsreader/view_thread/251757#651090</link>
      <author>Bruno Luong</author>
      <description>&quot;Heywood &quot; &amp;lt;heywoodj123@yahoo.com&amp;gt; wrote in message &amp;lt;guvhl1$qif$1@fred.mathworks.com&amp;gt;...&lt;br&gt;
&lt;br&gt;
&amp;gt; result = zeros(1,length(V));&lt;br&gt;
&amp;gt; for kk = 1:length(V);&lt;br&gt;
&amp;gt;   ind = find( V(kk) &amp;lt;= R, 1, 'first' );&lt;br&gt;
&amp;gt;   result(kk) = R(ind);&lt;br&gt;
&amp;gt; end;&lt;br&gt;
&lt;br&gt;
If speed is your main concern, don't use INTERP1 (slow), use HISTC or FIND_IDX on FEX&lt;br&gt;
&lt;br&gt;
&lt;a href=&quot;http://www.mathworks.com/matlabcentral/fileexchange/23049&quot;&gt;http://www.mathworks.com/matlabcentral/fileexchange/23049&lt;/a&gt;&lt;br&gt;
&lt;br&gt;
Bruno</description>
    </item>
    <item>
      <pubDate>Wed, 20 May 2009 09:17:16 -0400</pubDate>
      <title>Re: vectorizing challenge</title>
      <link>http://www.mathworks.com/matlabcentral/newsreader/view_thread/251757#651113</link>
      <author>Jos </author>
      <description>Doug Schwarz &amp;lt;see@sig.for.address.edu&amp;gt; wrote in message &amp;lt;see-FBBAFE.21132019052009@news.frontiernet.net&amp;gt;...&lt;br&gt;
&amp;gt; In article &amp;lt;guvhl1$qif$1@fred.mathworks.com&amp;gt;,&lt;br&gt;
&amp;gt;  &quot;Heywood &quot; &amp;lt;heywoodj123@yahoo.com&amp;gt; wrote:&lt;br&gt;
&amp;gt; &lt;br&gt;
&amp;gt; &amp;gt; Hi all,&lt;br&gt;
&amp;gt; &amp;gt; &lt;br&gt;
&amp;gt; &amp;gt; I'm having a hard time trying to vectorize the following code. Suppose I have &lt;br&gt;
&amp;gt; &amp;gt; a vector of interest V, and a reference vector R which is monotonically &lt;br&gt;
&amp;gt; &amp;gt; increasing (it's actually a cumulative distribution function). Both vectors &lt;br&gt;
&amp;gt; &amp;gt; contain only real numbers, except that I've modified R by tacking on -Inf at &lt;br&gt;
&amp;gt; &amp;gt; the beginning and +Inf at the end (the reason for which is hopefully obvious &lt;br&gt;
&amp;gt; &amp;gt; from the code below).&lt;br&gt;
&amp;gt; &amp;gt; &lt;br&gt;
&amp;gt; &amp;gt; For each element of V, I want to find the first element of R that is greater &lt;br&gt;
&amp;gt; &amp;gt; than or equal to it.&lt;br&gt;
&amp;gt; &amp;gt; &lt;br&gt;
&amp;gt; &amp;gt; To do this with a FOR loop is trivial (and yes, I realize the two lines in &lt;br&gt;
&amp;gt; &amp;gt; the loop can be combined into one; writing it this way just for clarity):&lt;br&gt;
&amp;gt; &amp;gt; &lt;br&gt;
&amp;gt; &amp;gt; result = zeros(1,length(V));&lt;br&gt;
&amp;gt; &amp;gt; for kk = 1:length(V);&lt;br&gt;
&amp;gt; &amp;gt;   ind = find( V(kk) &amp;lt;= R, 1, 'first' );&lt;br&gt;
&amp;gt; &amp;gt;   result(kk) = R(ind);&lt;br&gt;
&amp;gt; &amp;gt; end;&lt;br&gt;
&amp;gt; &amp;gt; &lt;br&gt;
&amp;gt; &amp;gt; But when V is very large, this is slow. Can anyone think of a clean way to &lt;br&gt;
&amp;gt; &amp;gt; 'vectorize' the FIND command?&lt;br&gt;
&amp;gt; &amp;gt; &lt;br&gt;
&amp;gt; &amp;gt; Thanks very much in advance!&lt;br&gt;
&amp;gt; &amp;gt; &lt;br&gt;
&amp;gt; &amp;gt; HJ&lt;br&gt;
&amp;gt; &lt;br&gt;
&amp;gt; How about this?&lt;br&gt;
&amp;gt; &lt;br&gt;
&amp;gt;   % Create some sample data.&lt;br&gt;
&amp;gt;   dist = rand(1,10);&lt;br&gt;
&amp;gt;   R = [0,cumsum(dist)];&lt;br&gt;
&amp;gt;   R = R/R(end);&lt;br&gt;
&amp;gt; &lt;br&gt;
&amp;gt;   % Find result.&lt;br&gt;
&amp;gt;   n = length(R);&lt;br&gt;
&amp;gt;   V = rand(1,100);&lt;br&gt;
&amp;gt;   k = interp1(R,0:n,V);&lt;br&gt;
&amp;gt;   result = R(ceil(k) + 1);&lt;br&gt;
&amp;gt; &lt;br&gt;
&amp;gt; You are still finding the appropriate interval, but it's done &lt;br&gt;
&amp;gt; efficiently inside interp1.&lt;br&gt;
&amp;nbsp;&lt;br&gt;
or&lt;br&gt;
&lt;br&gt;
[dummy, k2] = histc(V,R) &lt;br&gt;
result2 = R(k2+1) ;&lt;br&gt;
&lt;br&gt;
Jos</description>
    </item>
    <item>
      <pubDate>Wed, 20 May 2009 13:08:01 -0400</pubDate>
      <title>Re: vectorizing challenge</title>
      <link>http://www.mathworks.com/matlabcentral/newsreader/view_thread/251757#651164</link>
      <author>Heywood </author>
      <description>&amp;gt; [dummy, k2] = histc(V,R) &lt;br&gt;
&amp;gt; result2 = R(k2+1) ;&lt;br&gt;
&amp;gt; &lt;br&gt;
&amp;gt; Jos&lt;br&gt;
&lt;br&gt;
Hi Doug, Matt, Bruno, and Jos,&lt;br&gt;
&lt;br&gt;
Thanks for all the suggestions! I learned a lot from all your ideas (I'd never seen bsxfun before, and only vaguely remembered interp1). Ultimately Jos's suggestion was the simplest and did the trick -- resulting in a ~20X speedup in execution time!&lt;br&gt;
&lt;br&gt;
Thanks again everyone.&lt;br&gt;
&lt;br&gt;
Cheers,&lt;br&gt;
&lt;br&gt;
Heywood</description>
    </item>
  </channel>
</rss>

