4
$\begingroup$

Lets say I have the following input:

rn={
 {1, 1.1, 1.5},
 {5, 6, 6.1, 7},
 {8, 8, 12, 12, 12.5, 13}
}

This input has the dimensions of {3, 4, 6}.

I want to get each of the elements from each of the three lists, and add them to each of the elements of another list, for all possibilities, such as I would get a list that is 3 * 4 * 6 = 72 long.

I know that I can do this manually such that:

{
 rn[[1, 1]] + rn[[2, 1]] + rn[[3, 1]],
 rn[[1, 1]] + rn[[2, 1]] + rn[[3, 2]],
 rn[[1, 1]] + rn[[2, 1]] + rn[[3, 3]],
 rn[[1, 1]] + rn[[2, 1]] + rn[[3, 4]],
 rn[[1, 1]] + rn[[2, 1]] + rn[[3, 5]],
 rn[[1, 1]] + rn[[2, 1]] + rn[[3, 6]],
 rn[[1, 1]] + rn[[2, 2]] + rn[[3, 1]],
 rn[[1, 1]] + rn[[2, 2]] + rn[[3, 2]],
 rn[[1, 1]] + rn[[2, 2]] + rn[[3, 3]],
 rn[[1, 1]] + rn[[2, 2]] + rn[[3, 4]],
 rn[[1, 1]] + rn[[2, 2]] + rn[[3, 5]],
 rn[[1, 1]] + rn[[2, 2]] + rn[[3, 6]],
 rn[[1, 1]] + rn[[2, 3]] + rn[[3, 1]],
 rn[[1, 1]] + rn[[2, 3]] + rn[[3, 2]],
 rn[[1, 1]] + rn[[2, 3]] + rn[[3, 3]],
 rn[[1, 1]] + rn[[2, 3]] + rn[[3, 4]],
 rn[[1, 1]] + rn[[2, 3]] + rn[[3, 5]],
 rn[[1, 1]] + rn[[2, 3]] + rn[[3, 6]],
 rn[[1, 1]] + rn[[2, 4]] + rn[[3, 1]],
 rn[[1, 1]] + rn[[2, 4]] + rn[[3, 2]],
 rn[[1, 1]] + rn[[2, 4]] + rn[[3, 3]],
 rn[[1, 1]] + rn[[2, 4]] + rn[[3, 4]],
 rn[[1, 1]] + rn[[2, 4]] + rn[[3, 5]],
 rn[[1, 1]] + rn[[2, 4]] + rn[[3, 6]],
 rn[[1, 2]] + rn[[2, 1]] + rn[[3, 1]],
 rn[[1, 2]] + rn[[2, 1]] + rn[[3, 2]],
 rn[[1, 2]] + rn[[2, 1]] + rn[[3, 3]],
 rn[[1, 2]] + rn[[2, 1]] + rn[[3, 4]],
 rn[[1, 2]] + rn[[2, 1]] + rn[[3, 5]],
 rn[[1, 2]] + rn[[2, 1]] + rn[[3, 6]],
 rn[[1, 2]] + rn[[2, 2]] + rn[[3, 1]],
 rn[[1, 2]] + rn[[2, 2]] + rn[[3, 2]],
 rn[[1, 2]] + rn[[2, 2]] + rn[[3, 3]],
 rn[[1, 2]] + rn[[2, 2]] + rn[[3, 4]],
 rn[[1, 2]] + rn[[2, 2]] + rn[[3, 5]],
 rn[[1, 2]] + rn[[2, 2]] + rn[[3, 6]],
 rn[[1, 2]] + rn[[2, 3]] + rn[[3, 1]],
 rn[[1, 2]] + rn[[2, 3]] + rn[[3, 2]],
 rn[[1, 2]] + rn[[2, 3]] + rn[[3, 3]],
 rn[[1, 2]] + rn[[2, 3]] + rn[[3, 4]],
 rn[[1, 2]] + rn[[2, 3]] + rn[[3, 5]],
 rn[[1, 2]] + rn[[2, 3]] + rn[[3, 6]],
 rn[[1, 2]] + rn[[2, 4]] + rn[[3, 1]],
 rn[[1, 2]] + rn[[2, 4]] + rn[[3, 2]],
 rn[[1, 2]] + rn[[2, 4]] + rn[[3, 3]],
 rn[[1, 2]] + rn[[2, 4]] + rn[[3, 4]],
 rn[[1, 2]] + rn[[2, 4]] + rn[[3, 5]],
 rn[[1, 2]] + rn[[2, 4]] + rn[[3, 6]],
 rn[[1, 3]] + rn[[2, 1]] + rn[[3, 1]],
 rn[[1, 3]] + rn[[2, 1]] + rn[[3, 2]],
 rn[[1, 3]] + rn[[2, 1]] + rn[[3, 3]],
 rn[[1, 3]] + rn[[2, 1]] + rn[[3, 4]],
 rn[[1, 3]] + rn[[2, 1]] + rn[[3, 5]],
 rn[[1, 3]] + rn[[2, 1]] + rn[[3, 6]],
 rn[[1, 3]] + rn[[2, 2]] + rn[[3, 1]],
 rn[[1, 3]] + rn[[2, 2]] + rn[[3, 2]],
 rn[[1, 3]] + rn[[2, 2]] + rn[[3, 3]],
 rn[[1, 3]] + rn[[2, 2]] + rn[[3, 4]],
 rn[[1, 3]] + rn[[2, 2]] + rn[[3, 5]],
 rn[[1, 3]] + rn[[2, 2]] + rn[[3, 6]],
 rn[[1, 3]] + rn[[2, 3]] + rn[[3, 1]],
 rn[[1, 3]] + rn[[2, 3]] + rn[[3, 2]],
 rn[[1, 3]] + rn[[2, 3]] + rn[[3, 3]],
 rn[[1, 3]] + rn[[2, 3]] + rn[[3, 4]],
 rn[[1, 3]] + rn[[2, 3]] + rn[[3, 5]],
 rn[[1, 3]] + rn[[2, 3]] + rn[[3, 6]],
 rn[[1, 3]] + rn[[2, 4]] + rn[[3, 1]],
 rn[[1, 3]] + rn[[2, 4]] + rn[[3, 2]],
 rn[[1, 3]] + rn[[2, 4]] + rn[[3, 3]],
 rn[[1, 3]] + rn[[2, 4]] + rn[[3, 4]],
 rn[[1, 3]] + rn[[2, 4]] + rn[[3, 5]],
 rn[[1, 3]] + rn[[2, 4]] + rn[[3, 6]]
 }

gives the answer:

{14, 14, 18, 18, 18.5, 19, 15, 15, 19, 19, 19.5, 20, 15.1, 15.1, \
19.1, 19.1, 19.6, 20.1, 16, 16, 20, 20, 20.5, 21, 14.1, 14.1, 18.1, \
18.1, 18.6, 19.1, 15.1, 15.1, 19.1, 19.1, 19.6, 20.1, 15.2, 15.2, \
19.2, 19.2, 19.7, 20.2, 16.1, 16.1, 20.1, 20.1, 20.6, 21.1, 14.5, \
14.5, 18.5, 18.5, 19., 19.5, 15.5, 15.5, 19.5, 19.5, 20., 20.5, 15.6, \
15.6, 19.6, 19.6, 20.1, 20.6, 16.5, 16.5, 20.5, 20.5, 21., 21.5}

But there must be an easier way to do this using something like Tuples[], Table[], Sum[], Permutations[] so that I can give it a list that has any number of sub-lists, and sub lists that are of any length.

$\endgroup$
11
$\begingroup$

Total[Tuples@rn, {2}]

should do.

For cases where a very large number of tuples would be generated,

Fold[Total[Tuples[{##}], {2}] &, rn]

will generally be even quicker, and exhibit considerably lower memory pressure, to the point that it can be an order of magnitude faster because it can avoid paging if RAM gets low. If the ordering of the output is not important, sorting your $rn$ so that smaller lists are first (just a simple rn=Sort@rn) will increase the latter's performance even more.

| improve this answer | |
$\endgroup$
  • 3
    $\begingroup$ A slower alternative is Outer[Total[{##}] &, Sequence @@ rn] // Flatten $\endgroup$ – Bob Hanlon Sep 27 at 19:01
  • $\begingroup$ Your code works quickly: rn = Table[ {1, 2}, {n, 1, 23} ]; { Timing[Total[Tuples@rn, {2}] // Length][[1]], Timing[Fold[Total[Tuples[{##}], {2}] &, rn] // Length][[1]], Timing[Distribute[foo @@ rn, List, foo, List, Plus] // Length][[1]], Timing[Flatten@Outer[Plus, ## & @@ rn] // Length][[1]], Timing[Activate@Tuples[Inactive[Plus] @@ rn] // Length][[1]], Timing[Activate@Tuples[Inactive[Plus] @@ rn] // Length][[1]], Timing[Outer[Plus, Apply[Sequence, rn]] // Length][[1]] } ={0.796875, 0.421875, 14.6094, 13.7656, 18.375, 18.3594, 13.875} $\endgroup$ – Robjobbob Oct 2 at 1:40
5
$\begingroup$

Few additional alternatives:

Distribute[foo @@ rn, List, foo, List, Plus]

Flatten @ Outer[Plus, ## & @@ rn]

Activate @ Tuples[Inactive[Plus] @@ rn]
| improve this answer | |
$\endgroup$
1
$\begingroup$

I see kglr got here first, but in a different format:

Outer[Plus, Apply[Sequence, rn]] // TableForm

| improve this answer | |
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.