# Combining lists of 2D points

Posted 10 years ago
5872 Views
|
6 Replies
|
6 Total Likes
|
 Hi all,I'm trying to solve a somewhat simple problem, but I'm using it as a proxy to better understand the Map/Thread/MapThread aspects of the language, ....I have 2 lists that I want to combine/add. The list elements are 2D points, but the lists could be arbitrarily long i.e.aa = {{Ax, Ay}, {Bx, By}, {Cx, Cy}}bb = {{x1, y1}, {x2, y2}, {x3, y3}, {x4, y4},{x5, y5}}and I want to combine the lists to get an output that is :out = {{Ax + x1, Ay + y1}, {Ax + x2, Ay + y2}, {Ax + x3, Ay + y3}, {Ax + x4,Ay + y4}, {Bx + x1, By + y1}, {Bx + x2, By + y2}, {Bx + x3,By + y3}, {Bx + x4, By + y4}, {Cx + x1, Cy + y1}, {Cx + x2,Cy + y2}, {Cx + x3, Cy + y3}, {Cx + x4, Cy + y4}}I can do this with a Table command, i.e.In[1]:= out = Flatten[Table[u + v, {u, aa}, {v, bb}], 1]Out[1]= {{Ax + x1, Ay + y1}, {Ax + x2, Ay + y2}, {Ax + x3, Ay + y3}, {Ax + x4, Ay + y4}, {Bx + x1, By + y1}, {Bx + x2, By + y2}, {Bx + x3, By + y3}, {Bx + x4, By + y4}, {Cx + x1, Cy + y1}, {Cx + x2, Cy + y2}, {Cx + x3, Cy + y3}, {Cx + x4, Cy + y4}}However, I was trying to figure out how this could be done using a Map/Thread/MapThread based approach. I got as far as:In[2]:= Map[aa[[1]] + # &, bb]Out[2]= {{Ax + x1, Ay + y1}, {Ax + x2, Ay + y2}, {Ax + x3,Ay + y3}, {Ax + x4, Ay + y4}}orIn[3]:= gg[arg1_, arg2_] := Map[arg1 + # &, arg2]In[4]:= gg[aa[[1]], bb]Out[4]= {{Ax + x1, Ay + y1}, {Ax + x2, Ay + y2}, {Ax + x3, Ay + y3}, {Ax + x4, Ay + y4}}But taking it the next step and having the function take in a list of points aa instead of just one has been problematic (that is without ending up with an unwieldy, messy pit of code). I think part of my problem is that the function Plus acting on a list just gives back the list, i.e.In[5]:= Plus[{a, b, c}]Out[5]= {a, b, c}Thanks of any words of wisdom, and happy new year to all.
6 Replies
Sort By:
Posted 10 years ago
 You are absolutly correct in the observation, that the generic variable # inside (# + # &) has no way of knowing the first # comes from the outside Map and the second # comes from the inside Map. This inside and outside indexing is already handeled for you by Table, but still you have to set up the variables to be distinguishable using u and v, in Table[u + v, {u, aa}, {v, bb}], for example. The same thing can be done for a pure function, if you replace the function signifier & with the raw head Function.Map[Function[{u}, Map[u + # &, bb]], aa]Map[Function[{u}, Map[Function[{v}, u + v], bb]], aa]
Posted 10 years ago
 Thank you all, this was very helpful. The Plus@@@Tuples was the approach that I had originally wanted to translate from "gray-matter" language into mathematica language. Didn't realize the correspondence was quite so literal
Posted 10 years ago
 Your function gg already maps over bb, so map that over aa.out === Join @@ Map[gg[#, bb] &, aa] out === Flatten[gg[#, bb] & /@ aa, 1]Tupels and Outer is a better way to go for your exampel problem. To get Thread to work with items of different level depth and length, it is tricky.out === Flatten[ Function[{a, b}, Map[Plus[a, #] &, b]] @@@ (Thread[{aa, b}] /. b -> bb), 1]In the above example the operation being applied to the result of Thread you already designated as, ggout === Flatten[gg @@@ (Thread[{aa, b}] /. b -> bb), 1]
Posted 10 years ago
 Concise approaches are:you could use the Tuples function to get the combinations and then, simply, Apply the Plus function:Plus @@@ Tuples[{aa, bb}] Or, as Frank suggested, the outer function with a fourth argument for the level specification, and then flattening:Flatten[Outer[Plus,aa,bb, 1],1]I Hope this helps T Saab..
Posted 10 years ago
 I think what you want is Outer[Plus, aa, bb] and then Flatten to get to the level of nesting you want.
Posted 10 years ago
 P.S. Christopher, if I may ask a related question re. your first suggstion:gg[arg1_, arg2_] := Map[arg1 + # &, arg2]Map[gg[#, bb] &, aa] In a sense this looks like a 2-level deep set of pure functions. I was wondering if this can be done in 1 step, i.e.replace the # in (Map[gg[#, bb] &, aa]) with (Map[gg[#, bb] &, aa] )Map[ Map[#L1 + #L2 &, bb] &, aa]#L1 and #L2 are meant to represent the arguments passed to the different levels of pure function. Is that possible in the mathematica syntax?