RE: Illumination or obfuscation?

*To*: mathgroup at smc.vnet.net*Subject*: [mg43976] RE: [mg43943] Illumination or obfuscation?*From*: "Wolf, Hartmut" <Hartmut.Wolf at t-systems.com>*Date*: Thu, 16 Oct 2003 04:16:11 -0400 (EDT)*Sender*: owner-wri-mathgroup at wolfram.com

>-----Original Message----- >From: Steven T. Hatton [mailto:hattons at globalsymmetry.com] To: mathgroup at smc.vnet.net >Sent: Wednesday, October 15, 2003 10:59 AM >To: mathgroup at smc.vnet.net >Subject: [mg43976] [mg43943] Illumination or obfuscation? > > >To an experienced Mathematica user, is the following snippet clear, and easy >to understand, or simply an exercise in obfuscation? Assume I already have >px,py and m[] lying around. > >px = {1, 0}; >py = {0, 1}; > >m[th_] := {{Cos[th], Sin[th]}, {-Sin[th], Cos[th]}} > >crossPoint[p_, th_:0, L_:0.5] := > Arrow[##,HeadLength -> 0.015]&@@#&/@(p+#.m[th]&/@{-#, #}&/@(L{px, py})) > To begin at the end, I'd express that function as In[19]:= Arrow[p - L m[-th].#, p + L m[-th].#, HeadLength -> 0.015] & /@ {px, py} Out[19]= {Arrow[{p1 - L Cos[th], p2 - L Sin[th]}, {p1 + L Cos[th], p2 + L Sin[th]}, HeadLength -> 0.015], Arrow[{p1 + L Sin[th], p2 - L Cos[th]}, {p1 - L Sin[th], p2 + L Cos[th]}, HeadLength -> 0.015]} which involves only one function, here applied to (i.e. mapped over a list of) two (elementary) vectors px, and py, and that generates an Arrow 2 L times the length of each elementary input vector, turned about an angle -th[eta] and translated to point p (such that the mid of the vector is at p). This for clarity, but of course not optimal for performance. To do that move only the result of the calculation L m[-th].p<i> to Arrow. There are several ways to do that, if you want to do it by function application it's: In[17]:= Arrow[p - #, p + #, HeadLength -> 0.015] &[L m[-th].#] & /@ {px, py} The real question, of course, is how to deal with such a thing when it hits your nose. The recipe is simple: work from the inside out. First define everything: In[4]:= p = {p1, p2}; In[5]:= m[th_] := {{Cos[th], Sin[th]}, {-Sin[th], Cos[th]}} (a rotation matrix, my fantasy of m) Now gradually follow the calculation, step by step: In[6]:= (L{px, py}) Out[6]= {{L, 0}, {0, L}} (vectors scaled to L) In[7]:= {-#, #} & /@ (L{px, py}) Out[7]= {{{-L, 0}, {L, 0}}, {{0, -L}, {0, L}}} (two pairs of opposite vectors) In[8]:= (p + #.m[th] & /@ {-#, #} & /@ (L{px, py})) Out[8]= {{{p1 - L Cos[th], p2 - L Sin[th]}, (* from px *) {p1 + L Cos[th], p2 + L Sin[th]}}, {{p1 + L Sin[th], p2 - L Cos[th]}, (* from py *) {p1 - L Sin[th], p2 + L Cos[th]}}} (each turned by -th, and translated to p) In[10]:= # & /@ (p + #.m[th] & /@ {-#, #} & /@ (L{px, py})) Out[10]= {{{p1 - L Cos[th], p2 - L Sin[th]}, {p1 + L Cos[th], p2 + L Sin[th]}}, {{p1 + L Sin[th], p2 - L Cos[th]}, {p1 - L Sin[th], p2 + L Cos[th]}}} (as you see this wouldn't change anything, just mapping an identity, but it is used in conjuction with another f[##,...]& @@ #& So each pair of vectors is taken (the lists at level 1) and f[##,...] Apply-ed to that, which just means, that the pair of vectors is inserted as a Sequence (at place ##) into f : In[12]:= Arrow[##, HeadLength -> 0.015] & @@ # & /@ (p + #.m[th] & /@ {-#, #} & /@ (L{px, py})) Out[12]= {Arrow[{p1 - L Cos[th], p2 - L Sin[th]}, {p1 + L Cos[th], p2 + L Sin[th]}, HeadLength -> 0.015], Arrow[{p1 + L Sin[th], p2 - L Cos[th]}, {p1 - L Sin[th], p2 + L Cos[th]}, HeadLength -> 0.015]} Or as you might see, the same structure as above, but "List[" at level 1 is replaced by "Arrow[" and "]" (right terminating side) by ", HeadLength -> 0.015]" Further we now conclude, that this is old code from version 3.0, because today we would use instead In[13]:= Arrow[##, HeadLength -> 0.015] & @@@ (p + #.m[th] & /@ {-#, #} & /@ (L{px, py})) This is the analysis. If you don't like it, just resynthesize. So, to make it better understandable one idea is to group calculation differently, that is: first use one input vector to build the function, and _then_ map that over both input vetors. Also don't map over and over basically the same same structure (three times above, once is enough). So, just shift the calculations into the final place, such you will quickly arrive at In[19] (I replaced #.m[th] by m[-th].#, thus assuming m is orthogonal and m[-th] is the inverse of m[th], but this is completely unessential, just following my habits). Done that, you may again pull out common calculation to reach at In[17], for instance. -- Hartmut Wolf