An n-by-n square logical matrix can be represented by a cell vector of n elements where the kth element corresponds to the kth row of the matrix. Each element of the cell vector is a row vector of positive integers in increasing order representing th

3 views (last 30 days)
I don't exactly understand what the question is asking here, despite reading it over and over multiple times. Is the input the nxn matrix, or the cell row vector with logical values? Would this simply contain 0's and 1's? If someone could please explain the overall goal of the question that would be great. Thanks in advance!
  5 Comments
Guillaume
Guillaume on 5 Sep 2017
Considering that it can be done with exactly 3 lines of code (1st line: initialise the matrix, 2nd line: repelem the rows indices using a cellfun(@numel), 3rd line: allocate true to the matrix using sub2ind, the row indices from line 2 and the cell array converted to a vector), I have to concur with James: show us what you've done.

Sign in to comment.

Accepted Answer

Stephen23
Stephen23 on 5 Sep 2017
Edited: Stephen23 on 5 Sep 2017
The question introduces the idea that data can be compressed by storing meta-data about the data: in this case, rather than storing a whole large logical array, the indices of any true elements are stored. There are many possible ways that the indices could be achieved (e.g. linear indexing, row+column indexing, etc), but the question's author decided to encode the logical array by storing only the columns explicitly and the rows implicitly.
As an aside, note that the MATLAB sparse data class does something similar, by storing non-zero locations. It is only efficient if the number of elements being encoded is relatively small.
You can solve your task quite simply:
>> C = cell(1,100);
>> C(10) = [20,75];
>> M = logiunpack(C);
>> [row,col] = find(M)
row =
10
10
col =
20
75
>>
Where the function is:
function X = logiunpack(C)
X = false(numel(C));
for k = 1:numel(C)
X(k,C{k}) = true;
end
end
  7 Comments
Stephen23
Stephen23 on 22 Jan 2018
Edited: Stephen23 on 22 Jan 2018
@Paul Murphy: Expanding an array within a loop is usually quite inefficient, and it is highly recommended to preallocate the cell array before the loop, exactly in the same way that you should always preallcoate a numeric array before a loop. Given that you know how big the cell array will be (it has as many cells as the input matrix has rows) this is trivial to do.
Your use of for to loop over the columns of Y is innovative... but personally I would avoid this "feature" as its behavior changes unexpectedly depending on the dimensions of the input array. It would be more robust to specify the row index explicitly.
So with that in mind, all you need is this:
M = false(100);
M(10,[20,75]) = true; % our sample matrix
C = cell(1,size(M,1));
for k = 1:size(M,1)
C{k} = find(M(k,:));
end
>> C{10}
ans =
20 75
Note that a 1x0 array is empty according to MATLAB (e.g. when tested by isempty), so this fulfills the specification according to the original question posted above. If you really want to exclude those 1x0 arrays then use a temporary variable and check it:
C = cell(1,size(M,1));
for k = 1:size(M,1)
tmp = find(M(k,:));
if tmp % if all values in tmp>0
C{k} = tmp;
end
end
Paul Murphy
Paul Murphy on 23 Jan 2018
Hi Stephen, thank you for the reply! I am going to take some time to go over this in detail as a lot of my codes are very slow due to inefficient use of loops.

Sign in to comment.

More Answers (1)

champions2015
champions2015 on 5 Sep 2017
Edited: champions2015 on 5 Sep 2017
Thanks Stephen! I applied your code which helped me understand what the function was doing, and what the question was asking! I tried making my own code from there so it's not exactly the same as yours! Thanks again!

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!