Reputation: 35
I have a Matrix of size M by N in which each row has some zero entries. I want to create M row vectors such that each of the vector contains the non zero elements of each row. For example if I have the following Matrix
A=[0 0 0 5;0 0 4 6;0 1 2 3;9 10 2 3]
I want four different row vectors of the following form
[5]
[4 6]
[1 2 3]
[9 10 2 3]
Upvotes: 2
Views: 144
Reputation: 112759
This can be done with accumarray
using an anonymous function as fourth input argument. To make sure that the results are in the same order as in A
, the grouping values used as first input should be sorted. This requires using (a linearized version of) A
transposed as second input.
ind = repmat((1:size(A,2)).',1,size(A,2)).';
B = A.';
result = accumarray(ind(:), B(:), [], @(x){nonzeros(x).'});
With A = [0 0 0 5; 0 0 4 6; 0 1 2 3; 9 10 2 3];
this gives
result{1} =
5
result{2} =
4 6
result{3} =
1 2 3
result{4} =
9 10 2 3
Upvotes: 1
Reputation: 8401
Since Matlab doesn't support non-rectangular double
arrays, you'll want to settle on a cell
array. One quick way to get the desired output is to combine arrayfun
with logical indexing:
nonZeroVectors = arrayfun(@(k) A(k,A(k,:)~=0),1:size(A,1),'UniformOutput',false);
I used the ('UniformOutput'
,false
) name-value pair for the reasons indicated in the documentation (I'll note that the pair ('uni'
,0
) also works, but I prefer verbosity). This input produces a cell array with the entries
>> nonZerosVectors{:}
ans =
5
ans =
4 6
ans =
1 2 3
ans =
9 10 2 3
Upvotes: 1