Path: news.mathworks.com!newsfeed-00.mathworks.com!news.kjsl.com!feeder.erje.net!eu.feeder.erje.net!news.etla.org!aioe.org!.POSTED!not-for-mail
From: <HIDDEN>
Newsgroups: comp.soft-sys.matlab
Subject: Re: vectorization speed
Date: Sun, 06 Oct 2013 09:18:19 -0500
Organization: Aioe.org NNTP Server
Lines: 75
Message-ID: <l2rrfl$7aj$1@speranza.aioe.org>
References: <bb7943ed-370c-4c27-9781-585085c9444f@googlegroups.com>
NNTP-Posting-Host: MwZBok20aqOVGBcJQjCELA.user.speranza.aioe.org
Mime-Version: 1.0
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: 7bit
X-Complaints-To: abuse@aioe.org
User-Agent: Mozilla/5.0 (Windows NT 5.1; rv:12.0) Gecko/20120428 Thunderbird/12.0.1
X-Notice: Filtered by postfilter v. 0.8.2
Xref: news.mathworks.com comp.soft-sys.matlab:803353

On 10/5/2013 8:05 PM, Jeff wrote:
>
...
> have tried various ways of "vectorizing" ... [but] ...
> find ... faster with a straight  loop translation ...
> and I would appreciate  any tips.
>
...

> function myoutput=speedtst0(myinput)
>   myoutput = zeros(size(myinput));
>   for i=1:numel(myinput)
>     if myinput(i)<=0
>       % do nothing
>     elseif myinput(i)>=10
>       myoutput(i)=1
>     else
>       myoutput(i)=0.1*myinput(i);
>     end
>   end
> end
>
> ... I've tried to vectorize that. ... but the loop version takes only
> about half as much time. ...
>
> % Vectorized Version 1:
> function myoutput=speedtst1(myinput)
>      myoutput = zeros(size(myinput));
>      myoutput(find(myinput>=10)) = 1;
>      f=find(myinput>0&myinput<10);
>      myoutput(f) = 0.1*myinput(f);
> end
>
... slightly modified versions of above elided for brevity...

The problem is in this case that the vectorization while it does 
eliminate the direct loop results in the code being as if you wrote the 
original looping version as three separate loops as you have two 
separate logic tests on the entire array; one for >=10, one for the 
[0-10] interval and then the third for the scaling multiplication.

If your case were simply binary, then undoubtedly as the size of the 
array got larger you would see the benefits of vectorizing.  In some 
cases, however, since Matlab doesn't do overall optimization but only on 
each source code line, it can't "see" that it could do all in one pass 
thru the loop but has to do each step as presented.  Sometimes even in 
Matlab a loop _is_ the best alternative.

NB: as an aside -- it probably won't make enough difference to win, but 
you can improve the performance of you versions by eliminating the call 
to find() -- "logical addressing" using the result of the test as the 
addressing array is the same result but eliminates the return of the 
actual array locations which aren't needed here.

That is, instead of

   myoutput(find(myinput>=10)) = 1;

simply

   myoutput(myinput>=10) = 1;


I've not timed it and it may still not beat the loop but you could try

function res=scale(x)
   res=0.1*x;
   res(res<0)=0;
   res=min(res,1);
end

The above works for your specific function because the 0.1*10 --> 1, the 
clipping value.

--