sum of matrix omitting one dimension

조회 수: 8(최근 30일)
Rafael Schwarzenegger
Rafael Schwarzenegger 2017년 11월 2일
댓글: Stephen23 2017년 11월 2일
Hi, I would like to ask how I could sum over a n dimensional matrix except one dimension, so the output is a vector. The ndims are not known in forehand. The summation is giving always a vector. (In my case a marginal pdf in statistics). Something like sum(K(:) except i-th dimension)
The best in a cyclus ( ndims not known).
For example having matrix K, the sums would be [6 22], [12 16], [10 18]
K(:,:,1) =
0 1
2 3
K(:,:,2) =
4 5
6 7
  댓글 수: 3
Rafael Schwarzenegger
Rafael Schwarzenegger 2017년 11월 2일
Yeah 22, thank you.
I have as an input a m^n matrix and as and output n vectors of the length m.

댓글을 달려면 로그인하십시오.

채택된 답변

Stephen23
Stephen23 2017년 11월 2일
편집: Stephen23 2017년 11월 2일
Here is one very simple way:
>> d = 3; % dimension
>> v = 1:ndims(K);
>> v([1,d]) = v([d,1]);
>> s = sum(reshape(permute(K,v),size(K,d),[]),2)
s =
6
22
It works by swapping the first and the desired dimension, then reshaping so that all trailing dimensions are reduced to one. The sum is then trivially along each row.
Note that the method I show here also has the significant advantage that it does not create any variables with copies of the data from the input array: this will be important for scaling to larger input arrays. Also note that slow and complex arrayfun or cellfun are not required for this task!
  댓글 수: 4
Stephen23
Stephen23 2017년 11월 2일
@Rafael Schwarzenegger: the dimensions of the input array are automatically measured using ndims(K).

댓글을 달려면 로그인하십시오.

추가 답변(1개)

Cedric Wannaz
Cedric Wannaz 2017년 11월 2일
Here is one way, but there is probably a simpler approach:
buffer = arrayfun(@(k) permute(KL, circshift(1:ndims(KL), k-1)), 1:ndims(KL), 'UniformOutput', false) ;
s = cellfun(@(M) sum(reshape(M, [], size(M,2))), buffer, 'UniformOutput', false) ;
where s is a cell array of sum vectors.
EDIT : I won't have time, but maybe you can see how dimensions work with SHIFTDIM and understand how to have the outputs ordered as needed:
buffer = arrayfun(@(k) shiftdim(KL, k-1), 1:ndims(KL), 'UniformOutput', false) ;
s = cellfun(@(M) sum(reshape(M, [], size(M,2))), buffer, 'UniformOutput', false) ;
PS : you'll have to test whether it really does what you need. The approach is based on the fact that MATLAB reads memory column first
  댓글 수: 4
Rafael Schwarzenegger
Rafael Schwarzenegger 2017년 11월 2일
@Cedric Wannaz: Thank you anyway.

댓글을 달려면 로그인하십시오.

Community Treasure Hunt

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

Start Hunting!

Translated by