Discover MakerZone

MATLAB and Simulink resources for Arduino, LEGO, and Raspberry Pi

Learn more

Discover what MATLAB® can do for your career.

Opportunities for recent engineering grads.

Apply Today

Thread Subject:
vectorization speed

Subject: vectorization speed

From: Jeff

Date: 6 Oct, 2013 01:05:09

Message: 1 of 3


I'm trying to convert some Pascal code for handling a matrix and have tried various ways of "vectorizing" it for MatLab. I was surprised to find that execution was always faster with a straight loop translation than with any of my vectorizing attempts. Since I'm pretty new to MatLab, I wonder if there are
better ways to vectorize, and I would appreciate any tips.

Here is code for a simplified version of the sort of loop I want:

% Loop Version:
function myoutput=speedtst0(myinput)
    myoutput = zeros(size(myinput));
    for i=1:numel(myinput)
        if myinput(i)<=0
             % leave output as zero
        elseif myinput(i)>=10
             myoutput(i)=1
        else
             myoutput(i)=0.1*myinput(i);
        end
    end
end

Below are three different ways I've tried to vectorize that. In all the tests I have run, the different vectorized versions take about the same amount of time (measured with tic/toc), but the loop version takes only about half as much time. So, my question is whether there are better ways to vectorize this sort of loop?

% 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

% Vectorized Version 2:
function myoutput=speedtst2(myinput)
    myoutput = zeros(size(myinput));
    myoutput(find(myinput>=10)) = 1;
    myoutput(myinput>0&myinput<10) = 0.1*myinput(myinput>0&myinput<10);
end

% Vectorized Version 3:
function myoutput=speedtst3(myinput)
    myoutput = zeros(size(myinput));
    myoutput(myinput>=10) = 1;
    myoutput(myinput>0&myinput<10) = 0.1*myinput(myinput>0&myinput<10);
end

Thanks for any tips.

Subject: vectorization speed

From: dpb

Date: 6 Oct, 2013 14:18:19

Message: 2 of 3

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.

--

Subject: vectorization speed

From: Bruno Luong

Date: 7 Oct, 2013 06:31:05

Message: 3 of 3

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

Not sure about speed, it can be achieve by single line (do we need a function for that ?)

res = max(min(0.1*x, 1), 0)

Bruno

Tags for this Thread

No tags are associated with this thread.

What are tags?

A tag is like a keyword or category label associated with each thread. Tags make it easier for you to find threads of interest.

Anyone can tag a thread. Tags are public and visible to everyone.

Contact us