2

I have an array A=[1,2] and B=[5,6]
I want to generate an array C=[1*1,2*2,5*5,6*6,1*2,1*5,1*6,2*5,2*6,5*6]
That is all the possible combinations (ab is equal to ba and hence only 1 of them should be on the resultant C array).

Does matlab have an inbuilt function I can use to achieve this?
Can you help me?

Phantômaxx
  • 37,901
  • 21
  • 84
  • 115
gambit
  • 35
  • 4
  • 1
    What if you have A=[2,4] B=[3,6] - should 12 appear twice (3*4,6*2) or only once? – amit Mar 23 '15 at 08:00
  • How does *2 arrays* come into play here? It seems it doesn't matter which elements are in which array. It should be the same as choosing 2 elements from `[A,B]`. – knedlsepp Mar 26 '15 at 13:12

4 Answers4

3

Two approaches with bsxfun could be suggested here.

Approach #1

%// Form a concatenated array
AB = [A(:) ; B(:)]

%// Get pairwise multiplications between all elements
allvals = bsxfun(@times,AB,AB.') %//'

%// Discard the repeated ones for the final output
C = allvals(bsxfun(@le,[1:numel(AB)]',1:numel(AB)))

Approach #2

%// Form a concatenated array
AB = [A(:) ; B(:)]

%// Get "non-repeated" pairwise indices
[Y,X] = find(bsxfun(@le,[1:numel(AB)]',1:numel(AB))) %//'

%// Elementwise multiplications across all such pairs for final output
C = AB(X).*AB(Y)

The second one is based on Fastest solution to list all pairs of n integers and is less memory hungry than the first approach.

Community
  • 1
  • 1
Divakar
  • 218,885
  • 19
  • 262
  • 358
2

An alternative is to use pdist (from the Statistics Toolbox) with an anonymous function:

AB = [A(:); B(:)];
C = [AB.'.^2 pdist(AB, @(x,y) x*y)];
Luis Mendo
  • 110,752
  • 13
  • 76
  • 147
  • Good thinking on this! Did some quick tests and this one is the fastest for really large arrays! – Divakar Mar 23 '15 at 16:52
  • @Divakar Thanks! In recent versions of Matlab `pdist` uses a mex file to do the actual computations; that must be (part of) the reason – Luis Mendo Mar 23 '15 at 21:07
  • 1
    Well, my tests state that my Approach #1 `bsxfun` performs really well until numel(A) is `2000` i.e. numel(AB) is `4000`, after which I am guessing the heavy memory requirements of `bsxfun` kicks in and then `pdist` starts to shine thereafter. Not seeing a clear winner! – Divakar Mar 23 '15 at 21:14
1

Try the following code:

%merge
AB = [A(:) ; B(:)]
%multiply to get all combinations
C=AB*AB'
%delete everything below the first diagonal
C=C(triu(true(numel(AB))));
kenorb
  • 155,785
  • 88
  • 678
  • 743
Daniel
  • 36,610
  • 3
  • 36
  • 69
0

It doesn't add much to the question that you are using two vectors. You just want the product of every n choose 2 combination of the concatenation x = [A(:); B(:)].

prod(x(nchoosek(1:numel(x), 2)), 2)
knedlsepp
  • 6,065
  • 3
  • 20
  • 41