how to build sequential cell rows
Mostrar comentarios más antiguos
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 !)
Respuesta aceptada
Más respuestas (3)
Andrei Bobrov
el 9 de Jul. de 2016
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 comentarios
Star Strider
el 9 de Jul. de 2016
Andrei, you never cease to amaze me!
+1
Image Analyst
el 9 de Jul. de 2016
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
el 10 de Jul. de 2016
Image Analyst
el 9 de Jul. de 2016
Editada: Image Analyst
el 9 de Jul. de 2016
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 comentario
Image Analyst
el 9 de Jul. de 2016
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)
el 9 de Jul. de 2016
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)
Categorías
Más información sobre Creating and Concatenating Matrices en Centro de ayuda y File Exchange.
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!