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:
Help Vectorizing For Loop

Subject: Help Vectorizing For Loop

From: Darrell

Date: 28 Oct, 2010 19:18:03

Message: 1 of 5

I was looking over some help information regarding vectorizing a for loop, however I am stumped as to how to implement vectorizng for the loop I have attached below.

I am working with a vector of footages, increasing linearly by one foot increments until the mile is complete. Then, the footage counter resets to zero, and the next mile is counted up. The catch: each "mile" may be a different length.

I've tested this for loop, and it does the job right. However, it is slow as molasses.
I was thinking that maybe somehow I could use a logical vector to help?

Thanks for any insight,
DK

%% Create a Footage Channel
% This will take the footage channel and join each mile together into a
% continuous string of feet.

% Initialize an "add on"
add = 0;

% Start at the second entry, and go through the entire footage channel.
for n=2:length(data{1,10})
    
    % footage will rise linearly in one-foot increments until a new mile is
    % marked, and the footage will be reset to zero.
    
    % if the n-th value is less than the one preceding it, this is treated
    % as the beginning of a new mile.
    if data{1,10}(n) < data{1,10}(n-1)
        % if the above is true, take our original add length, and tack-on
        % the largest value that the previous mile obtained.
        % The plus-one foot takes care of not duplicating a footage.
        add = add + data{1,10}(n-1)+1;
    end
    
    % create the next footage entry by adding the footage data and the
    % add-on footage that was calculated.
    footage(n) = data{1,10}(n)+add;
end

Subject: Help Vectorizing For Loop

From: Sean

Date: 28 Oct, 2010 19:41:03

Message: 2 of 5

"Darrell " <darrell@railsciences.com> wrote in message <iaci9b$du7$1@fred.mathworks.com>...
> I was looking over some help information regarding vectorizing a for loop, however I am stumped as to how to implement vectorizng for the loop I have attached below.
>
> I am working with a vector of footages, increasing linearly by one foot increments until the mile is complete. Then, the footage counter resets to zero, and the next mile is counted up. The catch: each "mile" may be a different length.
>
> I've tested this for loop, and it does the job right. However, it is slow as molasses.
> I was thinking that maybe somehow I could use a logical vector to help?
>
> Thanks for any insight,
> DK
>
> %% Create a Footage Channel
> % This will take the footage channel and join each mile together into a
> % continuous string of feet.
>
> % Initialize an "add on"
> add = 0;
>
> % Start at the second entry, and go through the entire footage channel.
> for n=2:length(data{1,10})
>
> % footage will rise linearly in one-foot increments until a new mile is
> % marked, and the footage will be reset to zero.
>
> % if the n-th value is less than the one preceding it, this is treated
> % as the beginning of a new mile.
> if data{1,10}(n) < data{1,10}(n-1)
> % if the above is true, take our original add length, and tack-on
> % the largest value that the previous mile obtained.
> % The plus-one foot takes care of not duplicating a footage.
> add = add + data{1,10}(n-1)+1;
> end
>
> % create the next footage entry by adding the footage data and the
> % add-on footage that was calculated.
> footage(n) = data{1,10}(n)+add;
> end

One of the reasons it's slow is because you don't preallocate footage. I.e.
footage = zeros(1,length(data{1,10}));


Without sample data it's really hard to test, but this is something along the lines of what you want:
%
ddiff = (diff(data{1,10}(:))>0);
addspan(ddiff) = data{1,10}(ddiff);
add = sum(addspan)+sum(ddiff);
footage(2:end) = data{1,10}(2:length(data))+cumsum(addspan);

Subject: Help Vectorizing For Loop

From: Darrell

Date: 28 Oct, 2010 20:29:04

Message: 3 of 5

Sean -

Thank you for your help. In previous versions of this, preallocating didn't help so I omitted it. After adding it back in, it certainly reduced the computation time.

As for the code you offered, I appreciate the insight into vectorization, however it did not run right-off-the-bat. There was a matrix size mismatch on the last line. I'm working with what you presented, and hopefully I can get it rolling.

Your help is greatly appreciated!

Thanks,
Darrell

Subject: Help Vectorizing For Loop

From: Sean

Date: 28 Oct, 2010 20:41:06

Message: 4 of 5

"Darrell " <darrell@railsciences.com> wrote in message <iacmeg$c47$1@fred.mathworks.com>...
> Sean -
>
> Thank you for your help. In previous versions of this, preallocating didn't help so I omitted it. After adding it back in, it certainly reduced the computation time.
>
> As for the code you offered, I appreciate the insight into vectorization, however it did not run right-off-the-bat. There was a matrix size mismatch on the last line. I'm working with what you presented, and hopefully I can get it rolling.
>
> Your help is greatly appreciated!
>
> Thanks,
> Darrell

You're welcome.

The problem is:

footage(2:end) = data{1,10}(2:length(data))+cumsum(addspan);
cumsum(addspan)
will be 1 element longer than
data{1,10}(2:length(data))

Since you don't want the last element of addspan because 'add' in your for-loop only goes to n-1; simply try this and get back to me:
footage(2:end) = data{1,10}(2:length(data))+cumsum(addspan(1:end-1));

-Sean

Subject: Help Vectorizing For Loop

From: Sean

Date: 28 Oct, 2010 20:47:04

Message: 5 of 5

This should be:
> footage(2:end) = data{1,10}(2:end)+cumsum(addspan(1:end-1));

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