<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <link>http://www.mathworks.com/matlabcentral/newsreader/view_thread/235533</link>
    <title>MATLAB Central Newsreader - help vectorizing a FOR loop</title>
    <description>Feed for thread: help vectorizing a FOR loop</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>Thu, 04 Sep 2008 14:51:01 -0400</pubDate>
      <title>help vectorizing a FOR loop</title>
      <link>http://www.mathworks.com/matlabcentral/newsreader/view_thread/235533#598695</link>
      <author>GG </author>
      <description>Hi Experts, &lt;br&gt;
&lt;br&gt;
I'm hoping someone can help me vectorize the following &lt;br&gt;
code. The tricky part is that bin_width is a function of &lt;br&gt;
the loop-index i.&lt;br&gt;
&lt;br&gt;
for i = 1:1:10000&lt;br&gt;
&amp;nbsp;&amp;nbsp;smoothline(i) = mean(data(i-bin_width(i)/2:i+bin_width&lt;br&gt;
(i)/2)&lt;br&gt;
end&lt;br&gt;
&lt;br&gt;
This code is just a sliding-window average to smooth-out a &lt;br&gt;
noisy data array. The smoothed line is created at each &lt;br&gt;
data point by looking at bin_width(i)/2 datapoints ahead &lt;br&gt;
and bin_width(i)/2 datapoints behind, and taking the mean &lt;br&gt;
of all this data. Then it steps to the next datapoint and &lt;br&gt;
repeats with a new bin_width(i) value.&lt;br&gt;
&lt;br&gt;
Thanks in advance, -GG</description>
    </item>
    <item>
      <pubDate>Thu, 04 Sep 2008 15:05:44 -0400</pubDate>
      <title>Re: help vectorizing a FOR loop</title>
      <link>http://www.mathworks.com/matlabcentral/newsreader/view_thread/235533#598701</link>
      <author>Walter Roberson</author>
      <description>GG wrote:&lt;br&gt;
&amp;nbsp;&lt;br&gt;
&amp;gt; I'm hoping someone can help me vectorize the following &lt;br&gt;
&amp;gt; code. The tricky part is that bin_width is a function of &lt;br&gt;
&amp;gt; the loop-index i.&lt;br&gt;
&lt;br&gt;
&amp;gt; for i = 1:1:10000&lt;br&gt;
&amp;gt;   smoothline(i) = mean(data(i-bin_width(i)/2:i+bin_width&lt;br&gt;
&amp;gt; (i)/2)&lt;br&gt;
&amp;gt; end&lt;br&gt;
&lt;br&gt;
&amp;gt; This code is just a sliding-window average to smooth-out a &lt;br&gt;
&amp;gt; noisy data array. The smoothed line is created at each &lt;br&gt;
&amp;gt; data point by looking at bin_width(i)/2 datapoints ahead &lt;br&gt;
&amp;gt; and bin_width(i)/2 datapoints behind, and taking the mean &lt;br&gt;
&amp;gt; of all this data. Then it steps to the next datapoint and &lt;br&gt;
&amp;gt; repeats with a new bin_width(i) value.&lt;br&gt;
&lt;br&gt;
cumsum() the data. Suppose we call that csdata.&lt;br&gt;
Then the mean &quot;around&quot; point i is&lt;br&gt;
(csdata(i+bin_width(i)/2) - csdata(i-bin_width(i)/2)) / (bin_width(i)+1)&lt;br&gt;
&lt;br&gt;
Then provided that bin_width is vectorized, the transformed&lt;br&gt;
expression should be vectorizable:&lt;br&gt;
&lt;br&gt;
csdata = cumsum(data);&lt;br&gt;
maxi = 10000;&lt;br&gt;
bw = bin_width(1:maxi);&lt;br&gt;
idxhigh = (1:maxi) + bw/2;&lt;br&gt;
idxlow = (1:maxi) - bw/2;&lt;br&gt;
smoothline = (csdata(idxhigh) - csdata(idxlow)) ./ (bw+1);&lt;br&gt;
&lt;br&gt;
&lt;br&gt;
-- &lt;br&gt;
Q = quotation(rand);&lt;br&gt;
if isempty(Q); error('Quotation server filesystem problems')&lt;br&gt;
else sprintf('%s',Q), end</description>
    </item>
    <item>
      <pubDate>Fri, 05 Sep 2008 03:49:02 -0400</pubDate>
      <title>Re: help vectorizing a FOR loop</title>
      <link>http://www.mathworks.com/matlabcentral/newsreader/view_thread/235533#598796</link>
      <author>GG </author>
      <description>Hi Walter,&lt;br&gt;
&lt;br&gt;
Thanks SOOOOOOO much for your reply. Your code speeds up &lt;br&gt;
my function a factor of 153 times! That's amazing. &lt;br&gt;
&lt;br&gt;
Just two small corrections I found in reducing it to &lt;br&gt;
practice that perhaps will save others a little time....&lt;br&gt;
&lt;br&gt;
csdata = cumsum(data);&lt;br&gt;
maxi = 10000;&lt;br&gt;
bw = bin_width(1:maxi);&lt;br&gt;
idxhigh = (1:maxi) + bw/2;&lt;br&gt;
&lt;br&gt;
% idxlow = (1:maxi) - bw/2; &lt;br&gt;
idxlow = (1:maxi) - bw/2 -1;  % this -1 is needed keep ...&lt;br&gt;
% starting datapt of sliding window in the average ...&lt;br&gt;
% calculation&lt;br&gt;
&lt;br&gt;
% smoothline = (csdata(idxhigh) - csdata(idxlow)) ./ &lt;br&gt;
(bw+1);&lt;br&gt;
smoothline = (csdata(idxhigh) - csdata(idxlow)) ./ (bw'+1);&lt;br&gt;
% I needed to replace bw with bw' to get dimensions right&lt;br&gt;
&lt;br&gt;
Thanks a million! -GG</description>
    </item>
    <item>
      <pubDate>Fri, 05 Sep 2008 15:18:02 -0400</pubDate>
      <title>Re: help vectorizing a FOR loop</title>
      <link>http://www.mathworks.com/matlabcentral/newsreader/view_thread/235533#598907</link>
      <author>GG </author>
      <description>I have another loop maybe someone can help me with as well. I'm not too optimistic that it can be vectorized but I thought I'd post it as I wouldn't have expected the previous loop above to have been vectorized and I was wrong.&lt;br&gt;
&lt;br&gt;
It is a variation of what's above... instead of a centered-sliding window average, this loop is a backward-looking sliding window average. The window size for averaging increases with frequency. The tricky thing is this data has a lot of noise (some noise shoots up quite high, which I call spurs). I identify the spurs (if they're above some threshold level) and don't use them when I calculate the mean_line as I step through the data. The data is in array 'd'.&lt;br&gt;
&lt;br&gt;
dx=1:20000;&lt;br&gt;
bin_width = round(0.2*sqrt(dx)) - 2;  % makes bin_width&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;% increase w/freq&lt;br&gt;
bin_width(1:2)=0;   % prevents negative bin_width&lt;br&gt;
first_data = 1:1:length(bin_width); % initialize array&lt;br&gt;
first_data = first_data - bin_width +1; % index of 1st &lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;% datapt in window for avg'g&lt;br&gt;
mean_line(4) = 1e-5;      %give starting pt&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br&gt;
for i = 5:1:10000  &lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;threshold(i) = 2 * mean_line(i-1);   &lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if (d(i) &amp;gt; threshold(i))  % identifies spurs&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;spurs = [spurs, i];                  &lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;end&lt;br&gt;
&lt;br&gt;
% Next, calc the avg by summing all data pts in &lt;br&gt;
% window (including spurs), then subtract the spur &lt;br&gt;
% data, then divide this by the number of non-spur &lt;br&gt;
% data points (which were used to compute this avg).&lt;br&gt;
&lt;br&gt;
running_spurs = spurs(find(spurs &amp;gt;= first_data(i))); &lt;br&gt;
% finds spurs in window for avg'g&lt;br&gt;
&lt;br&gt;
mean_line(i) = (sum(d(first_data(i):i)) -  ...&lt;br&gt;
&amp;nbsp;&amp;nbsp;sum(d(running_spurs))) /(bin_width(i)- ...&lt;br&gt;
&amp;nbsp;&amp;nbsp;sum(running_spurs&amp;gt;=first_data(i)));  %% computes avg &lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br&gt;
end&lt;br&gt;
&lt;br&gt;
Thanks in advance, -GG</description>
    </item>
  </channel>
</rss>

