Reputation: 563
This question is more complex than my previous question because here V is a cell
M
is a matrix 4x2000000
composed of several submatrix Ai such that Ai(1:3,j) is the same vector for j = 1,...,size(Ai,2)
. and Ai(4,j)
are values between 1
and 100
.
V = {V1,V2,...,Vn} (V1 or V2 or ...Vn)
V1,V2,... and Vn
have different sizes.
my goal is to eliminate all sub-matrix Ai
of M
, if Ai(4,:)
does not contain all the values of V1 or V2 or ...Vn
.
The only initial data for this problem are M
and V
I wanted to use a for loop with the answer of the question here, but I noticed that the calculation time increases with the size of V.
Example:
M = [1022 3001 4451 1022 1022 3001 1022 3001 3001 1022 1055 1055 1055 1055 1055 1055;
112 45 10 112 112 45 11 45 99 112 11 11 11 11 11 11;
500 11 55 500 500 11 88 11 1 500 45 45 45 45 45 45;
2 6 3 5 71 2 2 71 5 88 8 15 21 94 10 33]
A1 = [1022 1022 1022 1022;
112 112 112 112;
500 500 500 500;
2 5 71 88]
A2 = [3001 3001 3001;
45 45 45;
11 11 11;
6 2 71]
A3 = [4451;
10;
55;
3]
A4 = [1055 1055 1055 1055 1055 1055;
11 11 11 11 11 11;
45 45 45 45 45 45;
8 15 21 94 10 33]
A5 =[3001;
99;
1;
5]
if V = {[2 71],[3],[15 94 33 10]}
The expected output (order of columns is not important):
[1022 1022 1022 1022 3001 3001 3001 4451 1055 1055 1055 1055 1055 1055;
112 112 112 112 45 45 45 10 11 11 11 11 11 11;
500 500 500 500 11 11 11 55 45 45 45 45 45 45;
2 5 71 88 6 2 71 3 8 15 21 94 10 33]
Upvotes: 0
Views: 43
Reputation: 221624
See if this works for you -
%// ID columns of M based on the uniquenes of the first thre rows
[~,~,idx] = unique(M(1:3,:).','rows') %//'
%// Lengths of each V cell
lens = cellfun('length',V)
%// Setup ID array for use with ACCUMARRAY later on
id = zeros(1,sum(lens))
id(cumsum(lens(1:end-1))+1) = 1
id = cumsum(id)+1
%// Collect all cells of V as a 1D numeric array
Vn = [V{:}]
%// Counts of number of elements for each cell/groups of V
counts_V = histc(id,1:numel(V))
%// Function handle to detect for if the input would satisfy the crietria
%// of all its values belong to either V1 or V2 or ...Vn
func1 = @(x) any(counts_V == histc(id(ismember(Vn,x)),1:numel(V)))
%// For each ID in "idx", see if it satisfies the above mentioned criteria
matches = accumarray(idx(:),M(4,:)',[], func1 ) %//'
%// Use the "detections" for selecting the valid columns from M
out = M(:,ismember(idx,find(matches)))
Upvotes: 1