2
votes

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]
2
You can construct the wanted matrices by going through the original matrix in a for loop, checking if the element is <>0 and saving the thus selected numbers in vectors.Karlo

2 Answers

1
votes

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
1
votes

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