I have the following three lists:

kr = {{8, 8, 19, 3, 3}, {8, 8, 21, 3, 3}, {8, 8, 23, 3, 3}};
Rk = {{8., 3, 4, 5, 6}, {8., 4, 5, 6, 7}, {8., 5, 6, 7, 8}};
qsum = {{320, 270, 120, 140, 170}, {320, 280, 120, 150, 190}, {320, 290, 120, 160, 210}};


When I use

MapThread[#1 + #2 + #3 &, {Take[#, {3, -2}] & /@ kr, Take[#, {4, -1}] & /@ Rk, Take[#, {3, -2}] & /@ qsum}]


It shows the output {{144., 149.}, {147., 160.}, {150., 171.}}

which is perfectly fine, but using the function floExct in the MapThread as

floExct[n_, ku_, qr_] := Min[100*ku, (2500*n) - qr];
MapThread[ floExct[#1, #2, #3] &, {Take[#, {3, -2}] & /@ kr, Take[#, {4, -1}] & /@ Rk, Take[#, {3, -2}] & /@ qsum}]


gives me

{500., 600., 700.}


{{a,b},{c,d},{e,f}};


What am I missing?

• You are aware that the function Min returns a single scalar value? Apr 4, 2014 at 17:02
• I understand that the function floExct will return 1 value, but it should be evaluated 6 times and needs to give 6 values. Apr 4, 2014 at 17:04
• The dimensions of the list MapThread is being applied to is {3,3,2}, so you would expect only three results. Apr 4, 2014 at 17:14
• Take[#, {3, -2}] & /@ kr->{{19, 3}, {21, 3}, {23, 3}}, Take[#, {4, -1}] & /@ Rk->{{5, 6}, {6, 7}, {7, 8}} and Take[#, {3, -2}] & /@ qsum->{{120, 140}, {120, 150}, {120, 160}} so I would expect the result to be in the {{a,b},{c,d},{e,f}} format Apr 4, 2014 at 17:21
• Try this MapThread[floExct, {Take[#, {3, -2}] & /@ kr, Take[#, {4, -1}] & /@ Rk, Take[#, {3, -2}] & /@ qsum}, 2]
– Aky
Apr 4, 2014 at 17:31

As was initially mentioned in the comments, you can use the levelspec argument of MapThread to get the behavior you were expecting, but you can also set your floExct function to have the Listable attribute. This is why Plus works well for your first example snippet.

In[11]:= floExct[n_, ku_, qr_] := Min[100*ku, (2500*n) - qr];
SetAttributes[floExct, Listable];
floExct[#1, #2, #3] &, {Take[#, {3, -2}] & /@ kr,
Take[#, {4, -1}] & /@ Rk, Take[#, {3, -2}] & /@ qsum}]

Out[13]= {{500, 600}, {600, 700}, {700, 800}}

• Thanks for the answer and the neat trick to make custom functions as listable. Apr 8, 2014 at 17:48

I suppose it wouldn't hurt to add a bit of explanation here.

Plus is Listable, which is why Plus[{a, b}, {c, d}] evaluates to {Plus[a, c], Plus[b, d]} (it automatically threads over lists in its arguments). In fact, you did not need to use MapThread at all:

Plus[Take[#, {3, -2}] & /@ kr, Take[#, {4, -1}] & /@ Rk,
Take[#, {3, -2}] & /@ qsum] (* {{144, 149}, {147, 160}, {150, 171}} *)


On the other hand, Min flattens any lists in its arguments, eg. Min[{a, b}, {c, d}] evaluates to Min[a, b, c, d], not {Min[a, c], Min[b, d]}

Now, generally speaking, MapThread[func, {{p1, q1}, {p2, q2}}] == {func[p1, p2], func[q1, q2]}

Consider that p1, p2, q1 and q2 could themselves be lists, eg. p1 = {a1, b1}, p2 = {a2, b2}, q1 = {m1, n1}, q2 = {m2, n2}; The third argument of MapThread determines at which level of the list you want the threading to happen.

With the levelspec = 1 (default), MapThread[func, {{p1, q1}, {p2, q2}}] == {func[{a1, b1}, {a2, b2}], func[{m1, n1}, {m2, n2}]}, mentally replacing func with Min (and recalling its flattening behaviour) explains why the output isn't what you desire.

OTOH, MapThread[func, {{p1, q1}, {p2, q2}}, 2], which is the same as MapThread[func, {{{a1, b1}, {m1, n1}}, {{a2, b2}, {m2, n2}}}, 2], evaluates to {{func[a1, a2], func[b1, b2]}, {func[m1, m2], func[n1, n2]}}. If you mentally replace func with Min (or your floExct) you'll see this is the expression you want.

I'm afraid I haven't been able to express myself clearly (perhaps someone could polish it?), but hopefully the reader will be able to connect any missing links.

• Got it...Thanks. Apr 8, 2014 at 17:47