how to build sequential cell rows
Afficher commentaires plus anciens
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 !)
Réponse acceptée
Plus de réponses (3)
Andrei Bobrov
le 9 Juil 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 commentaires
Star Strider
le 9 Juil 2016
Andrei, you never cease to amaze me!
+1
Image Analyst
le 9 Juil 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
le 10 Juil 2016
Image Analyst
le 9 Juil 2016
Modifié(e) : Image Analyst
le 9 Juil 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 commentaire
Image Analyst
le 9 Juil 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)
le 9 Juil 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)
Catégories
En savoir plus sur Creating and Concatenating Matrices dans Centre d'aide et File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!