-1

I have a matrix M and a cell X as shown below. A contains unique column vectors of M(1:3,:). A is introduced only to explain what I want, this is not an initial data.

I try to modify the program below so that instead of finding the column vectors of A(1:3,:) whose corresponding values in M(4,:) are not part of one of the vectors of the cell X (and obviously not equal to one of these vectors). Now, I want to find the column vectors of A(1:3,:) whose corresponding values in M(4,:) contains at least one vector of the cell X (or equal to one of these vectors). For the example, the result should be:

out =

        622   1007
        124    552
         88   2010

The code that I would like to modify:

 M = [1007  1007  4044  1007  4044  1007  5002 5002 5002 622 622;
       552   552   300   552   300   552   431  431  431 124 124; 
      2010  2010  1113  2010  1113  2010  1100 1100 1100  88  88;
         7    12    25    15    12    30     2   10   55  32  12];

A = [1007  4044  5002  622;
      552   300   431  124;
     2010  1113  1100   88];

A contains unique column vectors of M(1:3,:)

 X = {[2 5 68 44],[2 10 55 9 17],[1 55 6 7 8 9],[32 12],[30 12 15]};

[C,~, subs] = unique(M(1:3,:)','rows');

A4 = accumarray(subs(:),M(4,:).',[],@(x) {x});

idxC = true(size(A4));
NX = numel(X);
for ii = 1:length(A4)
    for jj = 1:NX
        xj = X{jj};
        issubset = true;
        for A4i=A4{ii}.'
            if ~ismember(A4i, xj)
                issubset = false;
                break;
            end;
        end;
        if issubset
            idxC(ii) = false;
            break;
        end;
    end;
end;


out = C(idxC,:).';

There are two shortcuts. One, if any element of an A4{ii} is not found in X{jj}, don't test the remaining parts of A4{ii}, start over with the next jj. Secondly, if all elements of an A4{ii} are found in any X{jj}, don't test the remaining values of jj, remove that A4{ii} already.

>> out

out =

    1007        4044
     552         300
    2010        1113

I tried this code, it gives the right result but I do not know if it is correct:

M = [1007  1007  4044  1007  4044  1007  5002 5002 5002 622 622;
      552   552   300   552   300   552   431  431  431 124 124; 
     2010  2010  1113  2010  1113  2010  1100 1100 1100  88  88;
        7    12    25    15    12    30     2   10   55  32  12];


 X = {[2 5 68 44],[2 10 55 9 17],[1 55 6 7 8 9],[32 12],[30 12 15]};



[C,~, subs] = unique(M(1:3,:)','rows');

A4 = accumarray(subs(:),M(4,:).',[],@(x) {x});


idxC = false(size(A4));
NX = numel(X);

for jj = 1:NX
     for ii = 1:length(A4)
        A4i=A4{ii};

        issubset = false;
        for xj = X{jj}.'
            if ismember(xj,A4i)
               issubset = true;
               break;
            end;
        end;
        if issubset
            idxC(ii) = true;
            break;
        end;
    end;
end;


out = C(idxC,:).';

out =

         622        1007
         124         552
          88        2010
bzak
  • 563
  • 1
  • 8
  • 21
  • 4
    "I want to modify the program below..." Okay, have you attempted to modify the program? If so, where have you gotten stuck? As your question is currently written, it seems that you are just asking Stackoverflow to write your code for you. – beaker Aug 02 '15 at 00:50
  • @beaker: I do not program every day, even for questions that you think are easy, I can have difficulty to solve them. – bzak Aug 02 '15 at 10:20
  • 1
    It's not about succeeding, it's about trying. – Ikaros Aug 04 '15 at 06:15
  • 1
    Explaining what you don't want is sometimes usefull, but usually not enough to let people help you easily. Please include something like this in your problem description: I have variables M, A, and X as shown below. M is a variable that contains ..., A is a variable that contains ...., X is a variable that contains ... .What I am trying to achieve is ... , I have tried this by doing ... (It seems like you already tried to do this a bit in the first paragraph but it is just very confusing) – Dennis Jaheruddin Aug 04 '15 at 09:43

2 Answers2

0

Here's my way to do it. Before reading it, keep in mind that it may not be the fastest/trickiest way to do it.

%Extracting the values of M(4,:) as blocks (I kept your way to do it)
[C, ~, subs] = unique(M(1:3,:)','rows');    
A4 = accumarray(subs(:),M(4,:).',[],@(x) {x});

%Finding which A4 elements contains at least a vector of x
containsX = arrayfun(@(it)cellfun(@(x)all(ismember(x,A4{it})),X),1:length(A4),'UniformOutput',0)';

%Converting containsX into array so I can use `any`
containsX_array = cell2mat(containsX);

%Extracting the elements of A concerned
out = A(:,find(ismember(A',C(any(containsX_array,2),1:3),'rows')));

I did run it on some examples and it seems to work without problems.

%TEST :

M = [1007  1007  4044  1007  4044  1007  5002 5002 5002 622 622;
       552   552   300   552   300   552   431  431  431 124 124; 
      2010  2010  1113  2010  1113  2010  1100 1100 1100  88  88;
         7    12    25    15    12    30     2   10   55  32  12];

A = [1007  4044  5002  622;
      552   300   431  124;
     2010  1113  1100   88];

X = {[2 5 68 44],[2 10 55 9 17],[1 55 6 7 8 9],[32 12],[30 12 15]};

>> out

out =

        1007         622
         552         124
        2010          88
Ikaros
  • 1,048
  • 11
  • 19
0
M = [1007  1007  4044  1007  4044  1007  5002 5002 5002 622 622;
      552   552   300   552   300   552   431  431  431 124 124; 
     2010  2010  1113  2010  1113  2010  1100 1100 1100  88  88;
        7    12    25    15    12    30     2   10   55  32  12];


 X = {[2 5 68 44],[2 10 55 9 17],[1 55 6 7 8 9],[32 12],[30 12 15]};



[C,~, subs] = unique(M(1:3,:)','rows');

A4 = accumarray(subs(:),M(4,:).',[],@(x) {x});


idxC = false(size(A4));
NX = numel(X);

for jj = 1:NX
     for ii = 1:length(A4)
        A4i=A4{ii};

        issubset = false;
        for xj = X{jj}.'
            if ismember(xj,A4i)
               issubset = true;
               break;
            end;
        end;
        if issubset
            idxC(ii) = true;
            break;
        end;
    end;
end;


out = C(idxC,:).';

out =

         622        1007
         124         552
          88        2010
bzak
  • 563
  • 1
  • 8
  • 21