how to build sequential cell rows
이전 댓글 표시
2-column matrix .. left column has min. values .. right column has max. values .. for example B =
23 25
24 28
30 32
then i would like to generate the following
A =
23 24 25
24 25 26 27 28
30 31 32
the solution that worked is by using a for loop and assigning each row's solution into a new row of a cell
A{j} = B(j,1):B(j,2)
.. however i was hoping for a smarter solution to cut down the computatinoal time (it is a very large matrix !)
채택된 답변
추가 답변 (3개)
Andrei Bobrov
2016년 7월 9일
a = [23 25
24 28
30 32];
n = max(diff(a,1,2) + 1);
b = ones(size(a,1),n);
b(:,1) = a(:,1);
z = cumsum(b,2);
out = z.*bsxfun(@le,z,a(:,2));
댓글 수: 3
Star Strider
2016년 7월 9일
Andrei, you never cease to amaze me!
+1
Image Analyst
2016년 7월 9일
I initially thought of this too, but then decided to go with logical indexing rather than linear indexing like this. Not totally sure which indexing method is faster when it comes time to use it. But Andrei certainly is the master of the powerful one-liners.
Tarek Mohamed
2016년 7월 10일
Image Analyst
2016년 7월 9일
편집: Image Analyst
2016년 7월 9일
Cell arrays are very inefficient and take up a lot of memory and are slow. Perhaps you could be faster just to make up a logical matrix where you have max(B(:)) columns and you just set the column "true" if it's in the range. Wouldn't that work? For example:
B=[...
23 25
24 28
30 32]
A = false(size(B, 1), max(B(:))); % Initialize
for row = 1 : size(B, 1)
A(row, B(row,1):B(row, 2)) = true;
end
A % Display in command window.
This could be very much faster.
댓글 수: 1
Image Analyst
2016년 7월 9일
You said B was very large, so let's compare the memory used and times for a cell array versus a simple logical array:
B = randi(30, 1000000, 2);
tic;
A = false(size(B, 1), max(B(:))); % Initialize
for row = 1 : size(B, 1)
A(row, B(row,1):B(row, 2)) = true;
end
toc
whos A
% Cell array
tic;
A2 = cellfun(@(x) {x(:,1):x(:,2)}, mat2cell(B,ones(size(B,1),1),size(B,2)));
toc;
% celldisp(A2)
whos A2
So, for a million rows in B:
Elapsed time is 0.823932 seconds.
Name Size Bytes Class Attributes
A 1000000x30 30000000 logical
Elapsed time is 14.638256 seconds.
Name Size Bytes Class Attributes
A2 1000000x1 156065952 cell
The cell array method is nearly 20 times slower to create the matrix (almost 15 seconds vs. less than a second).
And, even though the cell array has only a million "elements" instead of 30 million elements like the logical array, the cell array uses up 5 times as much memory (156 megabytes vs. 30) for 1/30th the number of elements.
And that's just to create the array. When it comes time to use it, it will again be slower. With a logical matrix, you can use logical indexing which is very fast. Extracting indexes from a cell array and then indexing over those will be slower.
Jos (10584)
2016년 7월 9일
Arrayfun seems easier than the cellfun/mat2cell approach:
B = [23 25
24 28
30 32];
A = arrayfun(@(k) B(k,1):B(k,2), 1:size(B,1), 'un', 0)
카테고리
도움말 센터 및 File Exchange에서 Creating and Concatenating Matrices에 대해 자세히 알아보기
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!