Home > Blockchain >  Recursive function to list every element from cell arrays in Matlab
Recursive function to list every element from cell arrays in Matlab

Time:09-08

I am trying to get all possible combinations of elements from an array of vectors. For example, say, I have a cell array

C = {[1 2 3 4 5], [6:13], [14 15]}

then the output should be something like

out = {[1 6 14], [1 6 15], [1 7 14], [1 7 15],....,[5 13 15]}

I tried to use a recursive function to implement this, but the code below doesn't seem to work. How can I obtain the list of all these combinations?

function [out,i] = permuteTest2(a,i,N,l,out)
    if nargin == 0
        a={[1 2],[4 5],[7 8]};
        N = length(a);
        i = 1;
        out = [];
    end
    if i == N
        out = [out, a{i}(l)];
        return;
    else
        for k=i:N
            L = length(a{k});
            for l=1:L
                out =[out a{k}(l)];
                [out,i] =permuteTest2(a, i 1, N,l,out);
            end
        end
    end

CodePudding user response:

Say you have a cell array C with N vectors in it. To get all combinations of one element from each vector, you need to combine each element from the first vector with all combinations of the remaining vectors:

function combs = all_combinations(C)
   a = C{1};
   b = all_combinations(C(2:end));
   % ... get all the combinations of a and b here

If C has only one element, then all combinations is just that element (let's convert it to a cell array with one number in each cell, to match the expected output format):

function combs = all_combinations(C)
   a = C{1};
   if numel(C) == 1
      combs = num2cell(a);
      return;
   end
   b = all_combinations(C(2:end));
   % ... get all the combinations of a and b here

This takes care of the recursive part. Now all we need to do is find all combinations of the two sets a and b:

function combs = all_combinations(C)
   a = C{1};
   if numel(C) == 1
      combs = num2cell(a);
      return;
   end
   b = all_combinations(C(2:end));
   combs = cell(numel(a), numel(b));
   for ii = 1:numel(a)
      for jj = 1:numel(b)
         combs{ii, jj} = [a(ii), b{jj}];
      end
   end
   combs = combs(:);

To understand the answer above, it is important to track which elements are cell arrays and which are not, and how we index cell arrays ({} to extract an element from the array, () to index parts of the cell array, creating a new cell array).

I also used numel everywhere instead of length. numel is more efficient, and allows the code above to work equally well if instead of vectors you input arrays with more than one dimension.

A more robust function would test the input C to be a cell array with at least one element, and it would test each of the elements of this cell array to be a numeric array (or vector).

  • Related