1

i use matlab and need to combine two 2-dimensional matrices, so that the resulting rows are combinations of the rows from the input matrices concatenated together.

I tried ndgrid, but this creates ALL possible combinations. I need the input rows to stay together to create the output.

Here is an example:

I got:

  a= [1 2 3
      4 5 6];

  b= [7 8
      9 10];

I need:

needed = [1 2 3 7 8
          1 2 3 9 10
          4 5 6 7 8
          4 5 6 9 10];

I would prefer to do this without loops if possible

Jennes
  • 13
  • 3

3 Answers3

2

Here's an adaptation of yuk's answer using find:

[ib, ia] = find(true(size(b, 1), size(a, 1)));
needed = [a(ia(:), :), b(ib(:), :)];

This should be much faster than using kron and repmat.

Benchmark

a = [1 2 3; 4 5 6];
b = [7 8; 9 10];

tic
for k = 1:1e3
    [ib, ia] = find(true(size(b, 1), size(a, 1)));
    needed = [a(ia(:), :), b(ib(:), :)];
end
toc

tic
for k = 1:1e3
    needed = [kron(a, ones(size(b,1),1)), repmat(b, [size(a, 1), 1])];
end
toc

The results:

Elapsed time is 0.030021 seconds.
Elapsed time is 0.17028 seconds.
Community
  • 1
  • 1
Eitan T
  • 32,660
  • 14
  • 72
  • 109
  • @Jennes Yes, indeed. If you still have any question about the specific usage of `find` in this answer, I'll be more than glad to explain it. – Eitan T Jul 22 '13 at 13:30
1

Use a Kronecker product for a and repmat for b:

[kron(a, ones(size(b,1),1)), repmat(b, [size(a, 1), 1])]

ans =

     1     2     3     7     8
     1     2     3     9    10
     4     5     6     7     8
     4     5     6     9    10
Dan
  • 45,079
  • 17
  • 88
  • 157
-1

It gives the desired result but you might need something else then array_merge if you have duplicated items.

$a = array(array(1, 2, 3), array(4, 5, 6));
$b = array(array(7, 8), array(9, 10));

$acc = array_reduce($a, function ($acc, $r) use ($b) {
  foreach ($b as $br) {
    $acc []= array_merge($r, $br);
  }

  return $acc;
}, array());

var_dump($acc);

Edit: Sorry I've just noticed the "without loops" section. You can change the foreach to array_reduce to.

erdeszt
  • 799
  • 5
  • 12