How expanding 2 columns matrix (with each row having edges of a specific range) into a vector without for loop?
2 views (last 30 days)
Show older comments
Hi
I have a two column and 4 rows (4X2)matrix. Each row contains the begining (value in 1st column) and the end (value in 2nd column) of a spesific range of indexes a data file. The ranges length are NOT the same. I would like to add all the indexes that fall within each range (row) and add all the indexes in one vector to be used later for data manipulation. One way to do it is using a for-loop that goes through each row and create the indexes in between and save them in a new vector that contain all indexes as in the example below:
% Each row in the matrix rangeEdges contains the begining & end of a spesific range of indexes
rangeEdges = [1,10; 20,25; 40,60; 65,71]
for ixi=1: size(rangeEdges,1)
allIndexes = [allIndexes,[rangeEdges(ixi,1):1:rangeEdges(ixi,2)]];
end
The code above will results into the vector allIndexes below:
allIndexes =
Columns 1 through 15
1 2 3 4 5 6 7 8 9 10 20 21 22 23 24
Columns 16 through 30
25 40 41 42 43 44 45 46 47 48 49 50 51 52 53
Columns 31 through 44
54 55 56 57 58 59 60 65 66 67 68 69 70 71
This would works fine if I do not have too many rows (ranges). But in my case, the matrix rangeEdges sometims has millions of rows and the for-loop will need extremely long time to execute (hours). The previous process is to do operations on only one data file, and I have thousands of data files. So it is practically impossible to do it with for-loop.
My question: is there a way to do the above mentioned process and get vector allIndexes without using a for-loop?
Thanks!
0 Comments
Accepted Answer
Athul Prakash
on 27 Jan 2020
Hey,
Here's something I came up with, you may try it out to determine if it works with your data.
It's not very straightforward, but the idea is to use 'cumsum' (doc is linked below) to come up with a vector of logical indices, which should be suitable for you, even though you have asked for vector indices.
tempVar = zeros(rangeEdges(end,2), 1, 'uint8'); % create a temp vector of length = last index in rangeEdges
tempVar(rangeEdges(:,1))=1; % set 1 for all the start points of the ranges.
tempVar(rangeEdges(:,2)+1)=-1; %set -1 for all the end points of the ranges (offset by 1 because that's how cumsum works)
% Now temp is a vector of 1's and -1's at the start and end points of our required ranges.
allIndices = cumsum(tempVar); % creates 1's in the required ranges, 0's everywhere else.
allIndices = logical(allIndices); % converts the type to logical, so that we can plug this in for indexing.
Hope it helps.
More Answers (0)
See Also
Categories
Find more on Multidimensional Arrays in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!