How to make and sum up a matrix with upper diagonal direction without for-loop condition [The fastest way!]
1 次查看(过去 30 天)
显示 更早的评论
A = [1 7 13 0 0 0 0 0 ; 2 8 14 0 0 0 0 0; 3 9 15 0 0 0 0 0 ; 4 10 16 0 0 0 0 0; 5 11 17 0 0 0 0 0; 6 12 18 0 0 0 0 0];
A =
1 7 13 0 0 0 0 0
2 8 14 0 0 0 0 0
3 9 15 0 0 0 0 0
4 10 16 0 0 0 0 0
5 11 17 0 0 0 0 0
6 12 18 0 0 0 0 0
B = [1 7 13 0 0 0 0 0 ; 0 2 8 14 0 0 0 0; 0 0 3 9 15 0 0 0; 0 0 0 4 10 16 0 0; 0 0 0 0 5 11 17 0; 0 0 0 0 0 6 12 18];
B=
1 7 13 0 0 0 0 0
0 2 8 14 0 0 0 0
0 0 3 9 15 0 0 0
0 0 0 4 10 16 0 0
0 0 0 0 5 11 17 0
0 0 0 0 0 6 12 18
How to make the B matrix with the fastest way? After making the B matrix, I will column-wisely sum up the B matrix using "sum" function. This process should be fast due to I am going to do 100 times of this processing with the 100 by 300000 matrix.
Please help me out!
0 个评论
采纳的回答
Patrik Ek
2014-4-1
编辑:Patrik Ek
2014-4-1
This is a fully vectorized operation. And it should be quite efficient. Requires making 2 matrices however.
a = [1 2 0 0;3 4 0 0;5 6 0 0]
vertind = mod(find(a)-1,size(a,1))+1;
aind = find(a);
b = aind+(vertind-1)*size(a,1);
z = zeros(size(a));
z(b) = a(aind)
thesum = sum(b)
The operation on a matrix of your size (100x300000) take 0.1 seconds per iteration (creation of a excluded) and the maximal memory consumption (a included) is ~twice the size of a. The catch is that this does not allow values to go from end to 1, but that can be fixed, by some thinking. The method is based on the way create matrix indice, so to say columnwise. so in a 4x3 matrix element (2,1) have index 5.
The solution is 9 times slower than the one supported by Dishant Arora, but that solution does not return the B matrix.
更多回答(3 个)
Dishant Arora
2014-4-1
C = mat2cell(A, ones(1, size(A,1)), size(A,2));
ii = mat2cell(0:size(A,1)-1, 1, ones(1,size(A,1)))';
B = cellfun(@(x,y) circshift(x,[1,y]), C, ii, 'Un', 0);
B = cell2mat(B)
0 个评论
lvn
2014-4-1
Here is one way, which avoids making the B matrix (it directly gives the sum you want, so should be faster on large matrices)
A = [1 7 13 0 0 0 0 0 ; 2 8 14 0 0 0 0 0; 3 9 15 0 0 0 0 0 ; 4 10 16 0 0 0 0 0; 5 11 17 0 0 0 0 0; 6 12 18 0 0 0 0 0];
B = [1 7 13 0 0 0 0 0 ; 0 2 8 14 0 0 0 0; 0 0 3 9 15 0 0 0; 0 0 0 4 10 16 0 0; 0 0 0 0 5 11 17 0; 0 0 0 0 0 6 12 18];
[nrrows,~]=size(A);
C=zeros(1,nrrows+2);
for r=1:nrrows+2
columncounter=max(0,r-nrrows);
for rowcounter=min(r,nrrows):-1:max(1,r-2)
columncounter=columncounter+1;
C(r)=C(r)+A(rowcounter,columncounter);
end
end
C
sum(B)
C =
1 9 24 27 30 33 29 18
ans =
1 9 24 27 30 33 29 18
0 个评论
Andrei Bobrov
2014-4-1
编辑:Andrei Bobrov
2014-4-2
[m,n] = size(A);
B = spdiags(A,0:n-1,m,n);
ADD other way
[m,n] = size(A);
B = zeros(size(A));
ii = reshape(find(A),m,[]);
B(bsxfun(@plus,ii,(0:n-size(ii,2))'*m)) = ii;
or
m = size(A);
n = 3;
[ii,jj] = ndgrid(1:m(1),1:n);
B = zeros(m);
B(sub2ind(m,ii,bsxfun(@plus,jj,(0:m(1)-1)'))) = A(1:m(1),1:n);
另请参阅
类别
在 Help Center 和 File Exchange 中查找有关 Logical 的更多信息
产品
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!