Efficient way of finding numbers from one matrix in another, not using for loops

1 次查看(过去 30 天)
I have always been shown how to do this using for loops whilst at University, but with a large number of rows, the current for loop takes 10 minutes and there are a lot more implementation steps going forward which will use a similar technique, which would take hours
I have the following code, the first part with the help of the MATLAB community. All files are attached.
clear
clc
ElementFibreTensor = dlmread('ElementResultsUnedited.txt','',3,0); %Fibre Orientation @ Nodes. Read text file, first few lines not needed
fmt1 = '"TET4{%f%*f%*f%*f%*f%*s%*f%*f%f%f%f%f}"'; % note the ignored fields! Star after % is ignore
opt1 = {'HeaderLines',4,'CollectOutput',true}; %First four lines of text not required
[fid1,msg1] = fopen('NodeNosatElementsUnedited.txt','rt'); %Opens file
assert(fid1>=3,msg1) %Checks if file can open, if not message will pop up.
NodesatElements = textscan(fid1,fmt1,opt1{:}); %Reads File line by line
fclose(fid1); %Closes file
NodesatElements = NodesatElements{1}; %Display Data
[numRows1,numCols1] = size(ElementFibreTensor); %Size of array
for i = 1:numRows1
TempVar1 = ElementFibreTensor(i,1); %Collate ElementIDs at Elements ONLY assoicated with Fibre Orientation Tensor
FindLoc1 = find(NodesatElements(:,1) == TempVar1); %Collate Node Numbers at Elements ONLY assoicated with Fibre Orientation Tensor
ElementNodes(i,:) = NodesatElements(FindLoc1,:);
%[ElementID, Nodes 1-4 associated with ElementID]
end
I am particularly looking to simplify how I use the for loop. What I am currently doing is asking MATLAB to look at the first columnt of ElementMesh ID's (from one file) and trying to find the nodes numbers associated with the particular Element ID. There are over a quarter of a million Element ID's, but I don't know how I would do this without a for loop, I haven't so far come across any functions to do this. As a similar method will be used in the future to find co-ordinates, I thought it would be useful to solve now and understand a new way of performing the action.

采纳的回答

Stephen23
Stephen23 2020-1-1
编辑:Stephen23 2020-1-1
Your code's slowness is partly due to the fact that you are expanding the output array ElementNodes on each loop iteration: this forces MATLAB to move the entire array in memory on each loop iteration, which is very inefficient. You can avoid this by preallocating the output array before the loop, e.g.:
ElementNodes = nan(numRows1,size(NodesatElements,2));
for i = 1:numRows1
...
ElementNodes(i,:) = ...
end
However probably the fastest solution is to use ismember's two outputs:
[idx,idy] = ismember(ElementFibreTensor(:,1),NodesatElements(:,1));
ElementNodes2 = NodesatElements(idy(idx),:);
Compare the run times:
Elapsed time is 656.365 seconds. % Your code...
Elapsed time is 252.188 seconds. % ... with preallocated output array.
Elapsed time is 0.0380042 seconds. % Using ISMEMBER.
You can use isequal to compare the outputs of the different methods.
  3 个评论
Stephen23
Stephen23 2020-1-1
"...as it only finds the lowest index."
Your own code assumes exactly one matching value on each loop iteration (the indexing into ElementNodes makes this clear, as your code will throw an error if there are zero/multiple matches), so your comment is rather moot: if there is always exactly one match for one value (like in your code) then the "lowest" and the "highest" indices (and indeed all the indices in between...) are one and the same: the index of that one match. So why would it matter?
The ismember code is not exactly equivalent because it can return zero/multiple matches, but as this is not the case in your code, nor in your data. If you have data where that can occur, you need to decide if that is appropriate or not (and then what steps might be needed to handle it).

请先登录,再进行评论。

更多回答(0 个)

类别

Help CenterFile Exchange 中查找有关 Loops and Conditional Statements 的更多信息

产品


版本

R2019b

Community Treasure Hunt

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

Start Hunting!

Translated by