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 !)

 采纳的回答

Actually, you can do it without a loop:
B = [23 25
24 28
30 32];
A = cellfun(@(x) {x(:,1):x(:,2)}, mat2cell(B,ones(size(B,1),1),size(B,2)));
celldisp(A) % Display Results (Delete Later)
A{1} =
23 24 25
A{2} =
24 25 26 27 28
A{3} =
30 31 32
EDIT To create a function version:
fillin = @(X) cellfun(@(x) {x(:,1):x(:,2)}, mat2cell(X,ones(size(X,1),1),size(X,2)));
A = fillin(B)
celldisp(A) % Display Results (Delete Later)
The output is the same as above.

2 个评论

works perfectly,
however i would really appreciate helping me understand this part ...> mat2cell(B,ones(size(B,1),1),size(B,2))
Thank you.
The mat2cell function partitions numeric matrices into a cell array of cells. The number of rows in the resulting cell is defined by the second argument, and the number of columns by the third. (The sum of the dimensions have to equal the dimensions of the argument array.) Specific to your ‘B’ matrix, these are [1; 1; 1] and 2 respectively, so the cell array it creates are three (1x2) cells. The easiest way to see what it does is to run this:
Q = mat2cell(B,ones(size(B,1),1),size(B,2))
celldisp(Q)
The cellfun function then applies the anonymous function (the first argument to cellfun) to each of these in turn, producing ‘B’.
The ‘fillin’ function is just an anonymous function implementation of the same code.

请先登录,再进行评论。

更多回答(3 个)

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 个评论

Andrei, you never cease to amaze me!
+1
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.
so .. after trying all proposed answers .. apparently @imageanalyst and @Andreibobrov's approach by departing from cell structure solution is the fastest
thank you all for your kind contributions

请先登录,再进行评论。

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 个评论

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.

请先登录,再进行评论。

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!

Translated by