1

If B=[1; 2] and A=[B B B...(n times B)], how to obtain the matrix C corresponding to all the possible combinations between the column vectors of A .i.e. I want to get the combinations between n copies of the same vector.

For example, for n=3:

A =
     1     1     1
     2     2     2

So, C can be obtained using the function from File Exchange 'allcomb(varargin)':

C=allcomb(A(:,1),A(:,2),A(:,3))
C =
     1     1     1
     1     1     2
     1     2     1
     1     2     2
     2     1     1
     2     1     2
     2     2     1
     2     2     2

In my case n is variable. How to obtain C for any value of n?

Ghani
  • 23
  • 5
  • 1
    `allcomb` is not a builtin function, it is from File Exchange: [allcomb(varargin)](https://www.mathworks.com/matlabcentral/fileexchange/10064-allcomb-varargin). You should mention this in the question – Eliahu Aaron Nov 18 '19 at 16:30
  • 2
    [Related](https://stackoverflow.com/q/21895335/2586922). Duplicate? – Luis Mendo Nov 18 '19 at 17:39
  • @Luis I thought so too, I don't think the nuance of every input vector being identical makes this question particularly novel... – Wolfie Nov 18 '19 at 17:45
  • @Wolfie I initially marked as dupe, but then un-marked because maybe the real problem here is in generating a comma-separated list of `n` copies of the input vector `B` – Luis Mendo Nov 18 '19 at 17:49

3 Answers3

3

You can put the repetitions in a cell, and use the {:} syntax to put all cell elements as inputs to allcomb

n = 3;
B = [1,2];
A = repmat( {B}, n, 1 );
C = allcomb( A{:} ); % allcomb  is FileExchange.
                     % combvec  is a documented alternative.

Output:

C =
 1     1     1
 1     1     2
 1     2     1
 1     2     2
 2     1     1
 2     1     2
 2     2     1
 2     2     2
Wolfie
  • 27,562
  • 7
  • 28
  • 55
  • Thank you for your answer, @Wolfie . It actually works, but only for limited values of n, as that the length of the B vector i'am using is 100. Is there any other solution ? – Ghani Nov 18 '19 at 17:20
  • 1
    @Ghani That will generate a `100^n` × `n` matrix, and so you quickly run out of memory as `n` is increased. If that's the problem there's not much you can do. Perhaps use `uint8` data type if possible, but that only saves memory by a factor of `8` – Luis Mendo Nov 18 '19 at 17:41
  • 1
    @Ghani If the syntax does what you want then please consider marking this answer as accepted... I'm afraid can't magically reduce the required memory for such a large computation, as outlined by Luis – Wolfie Nov 18 '19 at 17:44
2

Since the alphabets for each of the places is the same, this is really a base conversion. MATLAB only accepts integer bases, but we can use that integer as an index into the alphabet B:

B=[1; 2];
n = 3;
b = numel(B);

for k = 0:(b^n-1)   % loop over all possible combinations
   C(k+1,:) = dec2base(k, b, n);
end
C = C - '0' + 1;   % convert 0..b-1 (in chars) into 1..b (in ints) for indexing
C = B(C);          % index into alphabet B

Results:

>> C
C =

   1   1   1
   1   1   2
   1   2   1
   1   2   2
   2   1   1
   2   1   2
   2   2   1
   2   2   2

The last line of the script doesn't appear to do much in this case because the alphabet happens to be the same range as our indices, but changing the alphabet to B = [7; 14] will correctly result in:

C =

    7    7    7
    7    7   14
    7   14    7
    7   14   14
   14    7    7
   14    7   14
   14   14    7
   14   14   14
beaker
  • 16,331
  • 3
  • 32
  • 49
  • Note that in Octave you can specify the alphabet directly as a vector, which shortens the script by ones step. – beaker Nov 18 '19 at 18:22
0

Funnily enough, allcomb from MATLAB File Exchange seems to be what you want.

allcomb([1; 2],[1; 2], [1; 2])

ans =

     1     1     1
     1     1     2
     1     2     1
     1     2     2
     2     1     1
     2     1     2
     2     2     1
     2     2     2

To do it for any n, simply construct the matrix with:

>> n = 3;
>> repmat(B, 1, n)

ans =

     1     1     1
     2     2     2
mlg556
  • 419
  • 3
  • 13
  • 1
    The OP uses this function in their question, you haven't added any functionality with this answer... They want to avoid the repetition of `[1;2]` as inputs, and repeat it `n` times - as in my answer. – Wolfie Nov 18 '19 at 16:38
  • @mlg556 Unfortunately, i have a long B vector (length(B)=100), the example in my question is just for illustration. 'repmat' seems to work only for limited values of n, in this case. – Ghani Nov 18 '19 at 17:25