How to vectorize the following code for matrix insertion?
이전 댓글 표시
I have an nxn matrix A and a 3xm array g. In general, n will be large, so A will be pre-allocated,
I want to carry out the following insertion, where I pick index pairs from the first two rows of g and values from the last row of g, in order to form a 2x2 matrix which I insert in A:
for i = 1:m
A(g(1:2,i),g(1:2,i)) = g(3,i)*[1 2; 3 4];
end
Note that [1 2; 3 4] is some fixed matrix of different size from A. The purpose of the above code is to insert the matrix [1 2; 3 4] , scaled by g(3,i), into the matrix A at position A(g(1:2,i),g(1:2,i)).
Is there any way to vectorize this code? For example, I tried the following (ugly) solution, but it doesn't work:
A(g(1:2,:),g(1:2,:)) = [1*g(3,:) 2*g(3,:);3*g(3,:) 4*g(3,:)];
Any suggestions?
댓글 수: 4
The "nxn matrix A" is the "[1 2;3 4]" in your code? Is n==2 in all cases?
Please post a minimal working example. The less the readers have to invent by their own, the more likely do their suggestions match your needs.
Is K pre-allocated? If not, the iterative growing might be the bottleneck, not the actual code.
Jordan Tryggvesson
2021년 5월 11일
J. Alex Lee
2021년 5월 11일
You might look into "sparse", which has well-defined syntax for making such insertions, not even limited to contiguous sub-matrices. No idea if it will be faster though
Jordan Tryggvesson
2021년 5월 11일
편집: Jordan Tryggvesson
2021년 5월 11일
채택된 답변
추가 답변 (1개)
David Goodmanson
2021년 5월 11일
편집: David Goodmanson
2021년 5월 11일
Hi Jordan,
Here is one method. Whether or not it is faster than the for loop method is another question. The code does exactly the same as your code, inserting elements into A. Consequently any elements of A that are nonzero (from previous actions of the for loop) get overwritten. The elements are not added.
% make up some data
N = 100;
A = zeros(N,N);
m = 88;
g = randi(N,3,2*m);
% eliminate instances where g(1:2,k) is a repeated index
irep = (g(1,:)-g(2,:))==0;
g(:,irep) = [];
g = g(:,1:m);
% original
for k = 1:m
A(g(1:2,k),g(1:2,k)) = g(3,k)*[1 2; 3 4];
end
% vectorized
A1 = zeros(N,N);
ga = g(1:2,:);
gb = g(3,:);
sub1 = [ga(1,:); ga; ga(2,:)];
sub2 = [ga; ga];
ind = sub2ind([N N],sub1,sub2);
A1(ind) = [1 2 3 4]'*gb;
max(abs(A-A1),[],'all') % should be zero
카테고리
도움말 센터 및 File Exchange에서 Matrix Indexing에 대해 자세히 알아보기
제품
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!