TransWikia.com

Nested lamdas: MapThreading a MapAt lambda

Mathematica Asked on July 30, 2021

Consider a set of (here) 3 series


r`data = Thread[{Range@4, # Range@4}] & /@ (10 Range@3);
(*{
{{1, 10}, {2, 20}, {3, 30}, {4, 40}}, 
{{1, 20}, {2, 40}, {3, 60}, {4, 80}},
{{1, 30}, {2, 60}, {3, 90}, {4, 120}}
}*)

The intent is to divide the second coordinate of each point in each series by some divisor divs[[i]]

r`divs = 10 Range@3;
(*{10, 20, 30}*)

I am currently achieving this as follows

r`f[x_] := #/x &
MapThread[MapAt[r`f@#2, #1, {All, 2}] &, {r`data, r`divs}]
(*{
{{1, 1}, {2, 2}, {3, 3}, {4, 4}},
{{1, 1}, {2, 2}, {3, 3}, {4, 4}},
{{1, 1}, {2, 2}, {3, 3}, {4, 4}}
}*)

How to eliminate r`f in favour of directly nesting the division lambda #/x &, present in the MapAt, inside the MapThread?

In other words how to correctly write something of the kind

MapThread[MapAt[#/#2 &, #1, {All, 2}] &, {r`data, r`divs}]
                ^           
                |
                |
      should refer to second coord of point
             and not r`data[[i]]

Please note that I did go through similar questions (e.g. MapThread on a nested Map) but couldn’t apply their solutions to the present case.

3 Answers

MapThread[MapAt[z [Function] z/#2, #1, {All, 2}] &, {r`data, r`divs}]

or

MapThread[MapAt[Function[z, z/#2], #1, {All, 2}] &, {r`data, r`divs}]

or

MapThread[Function[{x, y}, MapAt[#/y &, x, {All, 2}]], {r`data, r`divs}]
{{{1, 1}, {2, 2}, {3, 3}, {4, 4}}, {{1, 1}, {2, 2}, {3, 3}, {4, 4}}, 
{{1, 1}, {2, 2}, {3, 3}, {4, 4}}}

Alternatively,

Transpose[Transpose[#]/{1, #2}] & @@@ Transpose[{r`data, r`divs}]

MapThread[Transpose[Transpose[#]/{1, #2}] &, {r`data, r`divs}]

MapThread[ReplacePart[#, {i_, 2} :> #[[i, 2]]/#2] &, {r`data, r`divs}]

SubsetMap[Flatten[Partition[#, First[Length /@ r`data]]/r`divs] &, r`data, 
  {All, All, 2}] 

Module[{z = r`data}, z[[All, All, 2]] = z[[All, All, 2]]/r`divs;z]

all give

{{{1, 1}, {2, 2}, {3, 3}, {4, 4}}, {{1, 1}, {2, 2}, {3, 3}, {4, 4}},
 {{1, 1}, {2, 2}, {3, 3}, {4, 4}}} 

And... a Halloween special:

enter image description here

☺[{r`data, r`divs}]
{{{1, 1}, {2, 2}, {3, 3}, {4, 4}}, {{1, 1}, {2, 2}, {3, 3}, {4, 4}}, 
 {{1, 1}, {2, 2}, {3, 3}, {4, 4}}}

Correct answer by kglr on July 30, 2021

By using ReplacePart in place of any mapping function, there is no need to define any function, neither explicitly like your r`f nor as a pure function.

data = Thread[{Range @ 4, # Range @ 4}]& /@ (10 Range @ 3);
divisors = 10 Range @ 3;
ReplacePart[
  data, 
  {i_, j_} :> Module[{m = data[[i, j]]}, m[[2]] = m[[2]]/divisors[[i]]; m]]
{{{1, 1}, {2, 2}, {3, 3}, {4, 4}}, 
 {{1, 1}, {2, 2}, {3, 3}, {4, 4}}, 
 {{1, 1}, {2, 2}, {3, 3}, {4, 4}}}

Answered by m_goldberg on July 30, 2021

In Mathematica version 12.1+ we can use OperatorApplied to inject the outer argument into the inner function:

MapThread[MapAt[OperatorApplied[#/#2&][#2], #1, {All, 2}] &, {r`data, r`divs}]

(*
{{1, 1}, {2, 2}, {3, 3}, {4, 4}},
{{1, 1}, {2, 2}, {3, 3}, {4, 4}},
{{1, 1}, {2, 2}, {3, 3}, {4, 4}}
*)

Curry from version 11.3+ does the same thing but is now considered obsolete. For more details on these and related constructions, see (197168).

Answered by WReach on July 30, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP