4
$\begingroup$

I would like to know what is the most efficient to implement the following computation. Given three lists

    a = {a_1,a_2, a_3, …, a_n}
    b = {b_1,b_2, b_3, …, b_n}
    c = {c_1,c_2, c_3, …, c_n} 

and a function $f(x_1,x_2,x_3)$, obtain

     f(a_1,b_1,c_1)   f(a_1,b_1,c_2)   .....   f(a_1,b_1,c_n)  
     f(a_2,b_2,c_1)   f(a_2,b_2,c_2)   .....   f(a_2,b_2,c_n) 
     .....            .....            .....   .....
     f(a_n,b_n,c_1)   f(a_n,b_n,c_2)   .....   f(a_n,b_n,c_n) 

I cannot find a solution not using For.

$\endgroup$
6
$\begingroup$

Another possibility is to use the 3-arg version of Thread. With Sjoerd's example:

n = 3;
l1 = Array[a,n];
l2 = Array[b,n];
l3 = Array[c,n];

Using Thread:

Thread /@ Thread[f[l1, l2, l3], List, 2]

{{f[a[1], b[1], c[1]], f[a[1], b[1], c[2]], f[a[1], b[1], c[3]]}, {f[a[2], b[2], c[1]], f[a[2], b[2], c[2]], f[a[2], b[2], c[3]]}, {f[a[3], b[3], c[1]], f[a[3], b[3], c[2]], f[a[3], b[3], c[3]]}}

$\endgroup$
1
  • $\begingroup$ Super-fast and very elegant, but does not work if f is already defined to generate a result. In this case you'll need something like Thread /@ Thread[Inactive[f][l1, l2, l3], List, 2] // Activate. $\endgroup$ – Roman Apr 27 '19 at 7:13
7
$\begingroup$

Here's one way to do it with Outer:

n = 3;
l1 = Array[a, n];
l2 = Array[b, n];
l3 = Array[c, n];

Outer[
  f[#1[[1]], #1[[2]], #2] &,
  Transpose @ {l1, l2},
  l3,
  1
]

Out[25]= {{f[a[1], b[1], c[1]], f[a[1], b[1], c[2]], f[a[1], b[1], c[3]]}, {f[a[2], b[2], c[1]], f[a[2], b[2], c[2]], f[a[2], b[2], c[3]]}, {f[a[3], b[3], c[1]], f[a[3], b[3], c[2]], f[a[3], b[3], c[3]]}}

$\endgroup$
1
  • 2
    $\begingroup$ Or Outer[f[Sequence @@ #1, #2] &, Transpose@{l1, l2}, l3, 1] so you don't need to unravel #1 manually. $\endgroup$ – Roman Apr 26 '19 at 22:01
6
$\begingroup$
a = {a1, a2, a3, a4, a5};
b = {b1, b2, b3, b4, b5};
c = {c1, c2, c3, c4, c5};

Table[f[a[[j]], b[[j]], c[[k]]], {j, 1, 5}, {k, 1, 5}]

enter image description here

$\endgroup$
2
$\begingroup$

Another way with Curry and Through.

Through /@ Apply[Curry[f, {2, 3, 1}] /@ c] /@ Transpose@{a, b}

Mathematica graphics

Hope this helps.

$\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.