Kris
Kris

Reputation: 2123

Matlab vectorisation of loop "tracking value increments"

I have been breaking my head about trying to optimise a matlab script that needs to process quite long arrays.

Basically, there are 2 arrays: AbsoluteTimeTag and Channel.

AbsoluteTimeTag will hold int values signifying time that are recorded using a 16 bit counter. Since the counter is limited to 2^16 values it will often roll over during the course of the measurement. Channel registers this and when it does, bitand(Channel,2048) will evaluate true.

How these arrays are generated is out of my control and the overflow markers occur "in sync" with the data coming in.

It is now easy to reconstruct the absolute time by doing:

AbsoluteTimeTag(i) = NoOfOverflows * 65536 + TimeTag(i);

In a loop:

for i=1:NumberOfRecords

    %Running through all records, if we meet anything other than an
    %overflow record, we van just calculate its absolute time based on
    %current overflow count and its timetag.
    AbsoluteTimeTag(i) = NoOfOverflows * 65536 + TimeTag(i);

    % We are running through all records so if we encounter an overflow
    % (signified by bitand(..., 2048), we add 1 to the overflow count.
    if bitand(Channel(i),2048)
        NoOfOverflows = NoOfOverflows + 1;
    end;
end;

I have been really breaking my head on how to potentially vectorise this (since Matlab is pretty bad at loops). So far however, I do not see the light for some reason.

Problem is that the number of overflows up to a certain record index along AbsoluteTimeTag can change as you walk the vector from start to end.

I do not know how I could express "count all occurrences of overflow up to this point" in a vectored operation.

Can somebody comment on whether or not this might be feasible at all?

EDIT

Example data would look like this:

TimeTag (each element is an event for which time is counted un a 2^3 register for simplicity):

[ 01 03 04 07 xx 02 03 04 05 xx 01 03 04 07 xx ... ]

overflow:

[ 00 00 00 00 01 00 00 00 00 01 00 00 00 00 01 ... ]

Which would need to yield

[ 01 03 04 07 xx 10 11 12 13 xx 17 19 20 23 xx ... ]

The reason xx is there is because originally, all records, both the events and the overflows are in one large uint32 array where each record holds different types of info on the different bits. The xx locations can undergo any operation but they are further meaningless when considering the TimeTag records. I have a logical array keeping track of what locations hold actual meaningful data.

Upvotes: 1

Views: 89

Answers (1)

Divakar
Divakar

Reputation: 221664

"count all occurrences of ... to this point" in a vectored operation would be best expressed as cumsum.

Assuming NoOfOverflows is initialized as zero before the start of the loop and AbsoluteTimeTag, Timetag have NumberOfRecords as their number of elements , see if this works for you -

%// Get the overflow for all Channel entries in one go
bitand_all = bitand(Channel,2048)~=0; 

%// AbsoluteTimeTag appears to be a cumsum of overflows plus Timetag
AbsoluteTimeTag = [0 ; cumsum(bitand_all(1:end-1).*65536)]+ TimeTag;

%// Get the count of overflows as NoOfOverflows
NoOfOverflows = sum(bitand_all);

Upvotes: 1

Related Questions