Message Boards Message Boards

1
|
6815 Views
|
6 Replies
|
6 Total Likes
View groups...
Share
Share this post:

Combining lists of 2D points

Posted 11 years ago
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}}
or
In[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.
POSTED BY: T Saab
6 Replies
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]
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 emoticon
POSTED BY: T Saab
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, gg
out === Flatten[gg @@@ (Thread[{aa, b}] /. b -> bb), 1]
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 BY: Ahmed Mogahed
I think what you want is Outer[Plus, aa, bb] and then Flatten to get to the level of nesting you want.
POSTED BY: Frank Kampas
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?
POSTED BY: T Saab
Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
Attachments
Remove
or Discard

Group Abstract Group Abstract