MathGroup Archive 2003

[Date Index] [Thread Index] [Author Index]

Search the Archive

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


  • Prev by Date: Re: Concentric contours about the centroid, having the same length, and interior to an initial contour.
  • Next by Date: Re: Concentric contours about the centroid, having the same length, and interior to an initial contour.
  • Previous by thread: RE: Illumination or obfuscation?
  • Next by thread: Signals&Systems package