comparing columns between differently sized matrices
古いコメントを表示
Hi, I am writing a finite element analysis code in MATLAB using tetrahedral elements. In the formulation of the problem, I have a 3xM surface connectivity matrix containing global node numbers and I have a 4xN volume connectivity matrix where M is the number of surfaces and N is the number of elements (M≠N). Each column in the surface connectivity matrix represents the surface number and each column in the volume connectivity matrix represents the element number. I need to compare each column of the 3xM surface connectivity matrix to each column of the 4xN volume connectivity matrix to determine which element number corresponds to each surface. Example matrices are given below.
surface connectivity matrix (3xM)
1 4 4 1
3 1 7 4
2 2 2 7
Volume connectivity matrix (4xN)
1 1 1 1 3 4
4 8 7 7 2 7
7 3 8 9 8 2
2 2 2 8 10 10
As can be seen in this example surface #1 corresponds to element #2, surface #2 corresponds to element #1, surface #3 corresponds to elements #1 and #6 (this surface is shared between two elements) etc. To complicate matters, the global node ordering for the surfaces is different than the ordering for the element numbers, but the ordering doesn’t matter. I can perform the comparison using a for loop (looping M times) and searching the entire 4xN matrix during each loop iteration, but since M and N are >10^5, the computation time is unreasonable. Is there a way to perform this comparison operation in a vectorized way to avoid loops?
回答 (2 件)
Fangjun Jiang
2011 年 9 月 29 日
SCM=[1 4 4 1
3 1 2 4
2 2 7 7];
VCM=[1 1 1 1 3 4
4 8 7 7 2 7
7 3 8 9 8 2
2 2 2 8 10 10];
M=size(SCM,2);
N=size(VCM,2);
CORRESP=false(M,N);
for k=1:M
for j=1:N
CORRESP(k,j)=all(ismember(SCM(:,k),VCM(:,j)));
end
end
CORRESP =
0 1 0 0 0 0
1 0 0 0 0 0
1 0 0 0 0 1
1 0 0 0 0 0
It shows surface #1 corresponds to element #2, surface #2 corresponds to element #1, surface #3 corresponds to elements #1 and #6, surface #4 corresponds to elements #1.
2 件のコメント
Joel
2011 年 9 月 29 日
Fangjun Jiang
2011 年 9 月 29 日
Can you show your code so we understand how the loop is done?
Joel
2011 年 9 月 29 日
6 件のコメント
Fangjun Jiang
2011 年 9 月 29 日
Not using a for-loop doesn't necessarily mean fast. There are many factor can impact the efficiency. In your code, double() and sum() seem to be unnecessary. You can use all() for that. I hope you pre-allocate elem.
Again, show your actual code so others can point out any place that can be improved. There are many examples on this forum that the best approach is application dependent.
Joel
2011 年 9 月 29 日
Fangjun Jiang
2011 年 9 月 29 日
So your algorithm is to compare the whole VCM matrix(4xN) with each column of SCM matrix(3xM) at a time, the result b is also a 4xN matrix. You then check if any of the b column sums to 3.
When N is large (10^5), I think this might not be efficient. I think you agree that my double-loop algorithm works too. Why don't you time both to see the difference. I'll probably do it too when I have spare time.
Jan
2011 年 9 月 29 日
SUM operates on LOGICAL arrays, so there is no need to cast to DOUBLE in "b=double(ismember( ..."
Joel
2011 年 9 月 29 日
Fangjun Jiang
2011 年 9 月 30 日
Now I thought it more, I think your approach is probably most efficient. I can't think of any other ways. Don't be obsessed with "no-loop". The loop in new versions of MATLAB is very efficient. There are functions like cellfun(), arrayfun(), bxsfun() etc that can be used to eliminate the loop but I don't think there will be a good use for your case.
If you are still interested in improving the efficiency of your code, many other experts can probably point out other areas to improve if you post your code.
カテゴリ
ヘルプ センター および File Exchange で Matrix Indexing についてさらに検索
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!