Jonas
Jonas

Reputation: 318

Modify large cell array to find certain rows that meet a condition in MATLAB

I have a cellmatrix that I want to analyse for certain rows in MATLAB. My own solution is pretty bad (see bottom), so I thought someone could give me a hint on how to improve it. I'm pretty sure, I just have to reshape the cell array somehow, but I'm not too sure how to do that.

I have one cell with logical array entries:

TheCell{with N-rows cell}(Logical Array with varying length, but max 24 entries)

For example:

TheCell{1} = [0,1,0,1,0,0,0,0,0,1,0]
TheCell{2} = [0,0,0,0]
...
TheCell{9} = [0,1,0,0,0,0,0]

Moreover, I have one matrix called Problem that tells me at which rows in "TheCell" I'm interested in (the Problem matrix has stored some certain row indexes of TheCell):

Problem(with M-rows)

For example:

Problem = [3,5,9]

I want to find all cell entries(indexes) of TheCell, where a "1" appears in either of the following positions,:

Critical = [1;2;3;4;5;6]

So for example in row Problem(3), i.e. TheCell{9} the conditions is met at Critical(2), since:

TheCell{Problem(3)}(Critical(2)) == 1

Thus I can make a new entry in my solution matrix:

Solution(counter) = Problem(3)

Finally, I have implemented this in a bad solution, not really efficient.

Critical = [1;2;3;4;5;6];
Solution = [];
counter = 1;
for i = 1:length(Problem)
   Row = Problem(i);
   b = length(TheCell{Row})
   for k = 1:length(Critical)
        if k > b
           break;
        end  
        if TheCell{Row}(Critical(k))==1
            Solution(counter) = Row;
            counter = counter+1;
            break;
        end
    end
end

Upvotes: 4

Views: 119

Answers (1)

Dan
Dan

Reputation: 45752

Critical = 6;
find(cellfun(@(x)any(x(1:min(Critical,end))), TheCell))

or if Critical won't always be consecutive numbers starting from 1 then

Critical = [2,4,5];
find(cellfun(@(x)any(x(min(Critical,end))), TheCell))

If you have control over how TheCell is created, you can probably get a far more efficient solution by not using a cell array but rather padding the ends of each row with false.

For example

TheMatrix = false(9,24);

%// You would generate this more sensibly in your process
TheMatrix(1,1:11) = [0,1,0,1,0,0,0,0,0,1,0]
TheMatrix(2,1:4) = [0,0,0,0]
...
TheMatrix(9,1:7) = [0,1,0,0,0,0,0]

Then the solution is:

find(any(TheMatrix(:,Critical),2))

Upvotes: 3

Related Questions