MathGroup Archive 1999

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

Search the Archive

Re: Unexpected behavior with Thread

  • To: mathgroup at smc.vnet.net
  • Subject: [mg21103] Re: [mg21073] Unexpected behavior with Thread
  • From: Hartmut Wolf <hwolf at debis.com>
  • Date: Fri, 17 Dec 1999 01:21:03 -0500 (EST)
  • Organization: debis Systemhaus
  • References: <199912130451.XAA16292@smc.vnet.net>
  • Sender: owner-wri-mathgroup at wolfram.com

Joel Cannon schrieb:
> 
> I have encountered an unexpected behavior when using Thread. I have a
> function getTorque that I am trying to Thread over two lists. When I
> Thread getTorque over the lists, it does not work. However, If I
> thread a function "f" over the same lists, and then make the
> transformation f->getTorque, it works as it should. Here is what it
> looks like. Apologies for the output with all the formatting
> commands. I have not been able to get rid of it. The functions and
> lists are at the bottom of this post.
> 
> *********************************************
> Here is what happens when I Thread the function getTorque.
> 
> In[95]:= getTorque[rwheels, fwheels, 0] // Thread
> 
> Dot::"dotsh": "Tensors \!\({\(\({1, 0, 0}\)\), \(\({0, 1, 0}\)\), \(\({0, 0, \
> 1}\)\)}\) and \!\({\(\({\(\(\(\(-mu\)\)\\ n1\)\), 0, n1}\)\), \
> \(\({\(\(\(\(-mu\)\)\\ n2\)\), 0, n2}\)\)}\) have incompatible shapes."
> 
> Out[95]=
> \!\({CrossProduct[{w\/2,
>         0, \(-zcm\)}, {{1, 0, 0}, {0, 1, 0}, {0, 0, 1}} . {{\(-mu\)\ n1, 0,
>             n1}, {\(-mu\)\ n2, 0, n2}}],
>     CrossProduct[{\(-\(w\/2\)\),
>         0, \(-zcm\)}, {{1, 0, 0}, {0, 1, 0}, {0, 0, 1}} . {{\(-mu\)\ n1, 0,
>             n1}, {\(-mu\)\ n2, 0, n2}}]}\)
> 
> **************************************************
> Here I thread the undefined function "f" and /. f->getTorque
> 
> In[110]:=
> (f[rwheels, fwheels, 0] // Thread) /. f -> getTorque
> 
> Out[110]=
> \!\({{0, \(-\(\(n1\ w\)\/2\)\) + mu\ n1\ zcm,
>       0}, {0, \(n2\ w\)\/2 + mu\ n2\ zcm, 0}}\)°
> 
> *****************************************************************
> For reference, here are the  functions and the lists that I am
> threading over.
> 
> getTorque[rbody_, fspace_, psi_] := CrossProduct[rbody, roty[-psi] . fspace]
> 
> roty[t_] := {{Cos[t], 0, Sin[t]}, {0, 1, 0}, {-Sin[t], 0, Cos[t]}}
> 
> rwheels = {{w/2, 0, -zcm}, {-w/2, 0, -zcm}}
> 
> fwheels = {{-(mu*n1), 0, n1}, {-(mu*n2), 0, n2}}
> ****************************************************
> 
> Thanks to anyone who can help.
> 
> ------------------------------------------------------------------------------
> Joel W. Cannon                   |   (724)223-6146
> Physics Department               |
> Washington and Jefferson College |
> Washington, PA 15301             |
> 
> 
Dear Joel,

you do have a solution, namely your In[110] above, howerver a little bit
more convenient is:

In[64]:= Thread[Hold[getTorque][rwheels, fwheels, 0]] // ReleaseHold
Out[64]=
   {CrossProduct[{w/2, 0, -zcm}, {-mu n1, 0, n1}], 
    CrossProduct[{-w/2, 0, -zcm}, {-mu n2, 0, n2}]}

(which is essentially the same, except that you dispense with the
undefined symbol f).

Also MapThread will do:

In[75]:= MapThread[getTorque2, {rwheels, fwheels, {0, 0}}]
Out[75]=
   {CrossProduct[{w/2, 0, -zcm}, {-mu n1, 0, n1}], 
    CrossProduct[{-w/2, 0, -zcm}, {-mu n2, 0, n2}]}

but perhaps you'll dislike the list which you now must substitute for
your phi argument.

To understand what Thread does in your case, observe

In[76]:= Attributes[Thread]
Out[76]= {Protected}

So Thread evaluates it's arguments (and it need's to do so, else it
couldn't work). So your In[95] above is equivalent with

  CrossProduct[rwheels, roty[-psi].fwheels] // Thread

and now it becomes clear what happens. The thread-list comes across with
Dot, which will evaluate before threading over fwheels is done. It will
run into the error and then threading is done over rwheels (only). You
can avoid this if you take a different head for threading:


In[144]:= ClearAll[getTorque]
In[145]:=
getTorque[rbody_, fspace_, psi_] := 
  CrossProduct[rbody, Thread[roty[-psi].fspace, h]]

In[146]:= Thread[getTorque[h @@ rwheels, h @@ fwheels, 0], h]
Out[146]=
  h[CrossProduct[{w/2, 0, -zcm}, {-mu n1, 0, n1}], 
    CrossProduct[{-w/2, 0, -zcm}, {-mu n2, 0, n2}]]

h is nothing but a container for threading (which Dot can't
misconstrue). And getTorque still works for scalar arguments:


In[147]:=
getTorque[rwheels[[1]], fwheels[[1]], 0]
Out[147]=
 CrossProduct[{w2, 0, -zcm}, {-mu n1, 0, n1}]

My recommendation however is to use Thread with Hold, ReleaseHold!

Kind regards, Hartmut


  • Prev by Date: [Fwd: Graphics3D[] objects clipping & PlotRange]
  • Next by Date: Re: Q: efficient in-place list element replacement?
  • Previous by thread: Unexpected behavior with Thread
  • Next by thread: Reading data.