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 Ansichten (letzte 30 Tage)
Ältere Kommentare anzeigen
champions2015
am 4 Sep. 2017
Kommentiert: Paul Murphy
am 23 Jan. 2018
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 Kommentare
James Tursa
am 5 Sep. 2017
What have you done so far? What specific problems are you having with your code?
Guillaume
am 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.
Akzeptierte Antwort
Stephen23
am 5 Sep. 2017
Bearbeitet: Stephen23
am 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 Kommentare
Stephen23
am 22 Jan. 2018
Bearbeitet: Stephen23
am 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
am 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.
Weitere Antworten (1)
Siehe auch
Kategorien
Mehr zu Matrix Indexing finden Sie in Help Center und File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!