How to search a matrix for all elements of a vector?

I am trying to search an element list for the occurance of nodes and output the elements where the nodes are occuring.
I want to find a fast integrated method, as for loops are just horribly slow.
x_mask=N(:,2) > X(i,1)-X(i,4)/2 & N(:,2)< X(i,1)+X(i,4)/2;
NX=N(x_mask,:);
y_mask=NX(:,3)> X(i,2)-X(i,5)/2 & NX(:,3)< X(i,2)+X(i,5)/2;
NY=NX(y_mask,:);
z_mask=NY(:,4)> X(i,3)-X(i,6)/2 & NY(:,4)< X(i,3)+X(i,6)/2;
NZ=NY(z_mask,:); %NZ is the Vector that contains the nodes 22500x1 of them
%(it also still contains the x,y,z coordinates but those can be ignored)
% i.e.:
% 1 0.849999300000000 0.273165000000000 -0.517777800000000
% 2 0.859999200000000 0.273165700000000 -0.517777800000000
% 3 0.849999500000000 0.223106800000000 -0.395308600000000
% 4 0.859999400000000 0.223107700000000 -0.395308600000000
% 5 0.849999700000000 0.180807400000000 -0.291975300000000
% 8 0.859999600000000 0.180808400000000 -0.291975300000000
% 9 0.849999800000000 0.146298800000000 -0.207777800000000
% 11 0.859999800000000 0.146299700000000 -0.207777800000000
% 13 0.849999900000000 0.119606900000000 -0.142716100000000
% 14 0.859999900000000 0.119607700000000 -0.142716100000000
% 16 0.850000000000000 0.100751900000000 -0.0967901000000000
% 17 0.860000000000000 0.100752600000000 -0.0967901000000000
%...
pow=zeros(length(E),2);
for n=1:length(NZ)
for e=1:length(E)
%E contains the elements-Node table 71300x8 (+ 1 indexing column that can be ignored)
% i.e. 1 57122 57123 57125 57124 71892 71889 71890 71891
% 2 56110 56062 56060 56059 71888 71885 71886 71887
% 3 56176 56172 56165 56171 71884 71881 71882 71883
% 4 55532 55533 55534 55535 71880 71877 71878 71879
% 5 55172 55173 55211 55213 71876 71873 71874 71875
% 6 52416 52411 52412 52414 71872 71869 71870 71871
% 7 56714 56715 56683 56705 71868 71865 71866 71867
% 8 54553 54554 54559 54556 71864 71861 71862 71863
% 9 54906 53303 53304 54917 71860 71857 71858 71859
%....
if(~isempty(find(E(e,2:9)==NZ(n,1))))
pow(e,2)=pow(e,2)+1; %i need to know how many nodes of NZ are part of an element
end
end
end
I am trying to use some sort of find to search the matrix, but as the dimensions do not agree.
Are there functions that can do this? Maybe i should go for tree searching?
Thank you so much for your help!

4 Comments

if you know another post that already answers this question i am happy for a link!
If E is [71300 x 8], this must fail: E(e,2:9).
Do I understand correctly, that pow(k, 2) contains the number of occurences of the elements of NZ in E(:, 2:9)? The current code increases the element in pow by 1 if there is any match in a row of E, but does not care about the number of matchs.
Using length() is dangerous in the general case, because it does not measure a specific dimension, but take the longest one.
Such comments are horrible, if you ask others for help:
%NZ is the Vector that contains the nodes 22500x1 of them
%(it also still contains the x,y,z coordinates but those can be ignored)
For the efficiency of the code it does matter if the arrays are matrices or vectors. With such ambiguous explanations, the readers have to guess how the real input data look like.
yeah there is one more indexing column i omitted, let me fix to make the code consistent
pow(e,2) contains occurances of Nodes in NZ in element E(e,1)
Element E(e,1) is made up from nodes E(e,2:9)

Sign in to comment.

 Accepted Answer

Jan
Jan on 29 Apr 2021
Edited: Jan on 29 Apr 2021
Start with replacing:
if(~isempty(find(E(e,2:9)==NZ(n,1))))
by
if any(E(e, 2:9) == NZ(n,1))
Or even better: %i need to know how many nodes of NZ are part of an element
for n = 1:size(NZ, 1)
for e = 1:size(E, 1)
pow(e, 2) = pow(e, 2) + any(E(e, 2:9) == NZ(n,1));
end
end
Then test, if omitting the inner loop is faster:
for n = 1:size(NZ, 1)
pow(:, 2) = pow(:, 2) + any(E(:, 2:9) == NZ(n), 2);
end
Avoid the repeated indexing in pow(:, 2) by using a temporary variable:
tmp = 0;
EE = E(:, 2:9);
for n = 1:size(NZ, 1)
tmp = tmp + any(EE == NZ(n), 2);
end
pow(:, 2) = tmp;

4 Comments

Yes the functionality of
B=any(A=y,2)
was exactly what i was looking for!
Thank you!
If i could get rid of the outer loop it would be even nicer, but the performance gain is already visisble!
Jan
Jan on 29 Apr 2021
Edited: Jan on 29 Apr 2021
Why do you think that omitting the outer loop is "nicer"? Creating large intermediate arrays is usually a drawback for the run time. In your case it would be a 22500 x 71300 x 8 array, which need 12 GB of RAM.
Before I try it, please explain, if this code really does, what you need: Should pow(i) be increased by 1 if a matching value contains anywhere in the row? Or do the number of occurences count? Are the values of the rows unique? For such cases intersect and histcounts or a fast accumarray approach might be efficient.
Can you provide some example data for NZ and E?
so The code ran and did what i wanted.
I say it would be great if there is no loop, because it still needs to loop through all 22500 nodes, and i need to do this process for every experiment.
I have 8GB RAM so i guess its out of the option.
Currently the code is acceptable, you dont need to try :)
In case you want the challenge:
  • rows of E are unique
  • I need to know how many times any Node from NZ occurs per row of E
  • it is not important what location in row of E it occurs
  • it is important in what row there are how many occurances (0 to 8)
I attached 2 mat files, for ease of use NZ is a bit smaller(only 8600 long) in this sample

Sign in to comment.

More Answers (0)

Categories

Asked:

on 29 Apr 2021

Commented:

on 29 Apr 2021

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!