Sam
Sam

Reputation: 949

searching on a large database

I have a very large 3D matrix and I need to call some specific patterns with a special configuration from this large matrix. For example, I need a sub-matrixes which their a,b,c,..,h element are equal with a specific value (it is not pattern matching, but I need some patterns that have a specific value)

Is there any solution to find them very fast? One solution, as I know, is to scan the matrix and store its pattern in a database and then use PCA to reducing the size of database, but I am looking for a more accurate method.

For example, suppose that I have a matrix such as I:

    I=[1    0   0   1   0   1   0   1   0
       0    0   0   0   0   0   0   0   0
       0    1   0   0   1   0   0   1   0
       1    0   1   1   0   1   0   1   0
       0    0   0   0   0   0   0   0   0
       1    0   0   0   1   0   1   0   0
       0    0   0   0   0   0   0   0   0
       1    0   1   0   0   0   0   0   1
       0    0   1   0   0   0   0   1   0]

then I have another matrix as below:

    p=[1    0   NaN NaN 1   NaN NaN NaN NaN]

then, I should look in "I" to find the rows which their column 1,2 and 5 is equal to 1,0,1 respectively (in this example, row of 6 is the correct row. But, in the reality, the size of my matrix (I) is very huge (more than billion) and if I use a loop to find those rows, it need a lot of time. I am looking for a fast code or method. Hope it be meaningful now!

Upvotes: 4

Views: 137

Answers (1)

Oli
Oli

Reputation: 16045

If the pattern you are looking for is column-wise, you can do as follow: (If it is not please be more specific in your question, I will modify my answer)

A=randi(10,[11 12 13]); %%% your matrix
p=[2;3;4]; %%% your pattern

m=cell(1,numel(p));
% for each element of the pattern
for i=1:numel(p)
  % find the element of A matching the i-th element of p
  m{i}=find(A==p(i));
  % convert to indices
  [x y z]=ind2sub(size(A),m{i});
  m{i}=[x y z];
  % convert to the position of the first element of the pattern
  m{i}(:,1)=m{i}(:,1)-(i-1);
  % remove when it goes below zero
  m{i}(m{i}(:,1)<=0,:)=[];
end

% accumulate everything to find out where all the elements of the pattern match
numberOfMatching=accumarray(vertcat(m{:}),1,size(A)); 
fullMatchingIndices=find(numberOfMatching==numel(p));
% convert to sub=indices
[x y z]=ind2sub(size(A),fullMatchingIndices);
finalIndices=[x y z];

% check the result
if ~isempty(finalIndices)
  A(finalIndices(1,1)+(0:numel(p)-1),finalIndices(1,2),finalIndices(1,3))
end

As a result, you should obtain the pattern p (if at least one match is foud):

ans =
     2
     3
     4

Upvotes: 1

Related Questions