MathGroup Archive 2003

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

Search the Archive

Re: Thread[...] does not seem to work as advertised

  • To: mathgroup at smc.vnet.net
  • Subject: [mg43304] Re: Thread[...] does not seem to work as advertised
  • From: bobhanlon at aol.com (Bob Hanlon)
  • Date: Sun, 24 Aug 2003 04:55:00 -0400 (EDT)
  • References: <bi7mrm$p0h$1@smc.vnet.net>
  • Sender: owner-wri-mathgroup at wolfram.com

fcntimes[v1_, v2_]:=h[v1 v2]

fcndot[v1_, v2_]:=g[v1 . v2]

fcndot[#[[1]],#[[2]]]&/@Transpose[{{a1,a2},{b1,b2}}]

{g[a1 . b1], g[a2 . b2]}

Inner[fcndot, {a1,a2}, {b1,b2}, List]

{g[a1 . b1], g[a2 . b2]}

Thread[h[{a1,a2},{b1,b2}]] /. h :>fcndot

{g[a1 . b1], g[a2 . b2]}


Bob Hanlon

In article <bi7mrm$p0h$1 at smc.vnet.net>, "lwi" <none at nowhere.com> wrote:

<< Try this:

In[1]:=
fcntimes[v1_, v2_]:=h[v1 v2]

In[2]:=
fcndot[v1_, v2_]:=g[v1 . v2]

In[3]:=
Thread[fcntimes[{a1,a2},{b1,b2}]]

Out[3]=
{h[a1 b1],h[a2 b2]}

This is the expected result.

In[4]:=
Thread[fcndot[{a1,a2},{b1,b2}]]

Out[4]=
g[a1 b1+a2 b2]

This is not expected. (or at least not what I expected!) The expected result
was
{g[a1 . b1], g[a2 . b2]}, the result of threading "fcndot" over the lists in
the arguments (as per documentation).

Tracing shows what happened: (I have inserted spaces and line breaks in the
output to improve readability)

In[5]:=
Trace[Thread[fcndot[{a1,a2},{b1,b2}]]]

Out[5]=
{{ fcndot[{a1,a2},{b1,b2}],
   g[{a1,a2}.{b1,b2}],
   {{a1,a2}.{b1,b2}, a1 b1+a2 b2},
   g[a1 b1+a2 b2]
  },
 Thread[g[a1 b1+a2 b2]],
 g[a1 b1+a2 b2]
}

"Thread" is actually being applied *after* its argument evaluates. Since in
this case "fcndot" had a Dot[] function buried inside it that knew what to
do with vector arguments, it effectively consumed the lists before they were
presented to Thread. The behavior occurs because the argument of Thread is
evaluated first, before "threading" takes place.

Compare with:

In[6]:=
Trace[Thread[fcntimes[{a1, a2},{b1,b2}]]]

Out[6]=
{{ fcntimes[{a1,a2},{b1,b2}],
   h[{a1,a2} {b1,b2}],
   {{a1,a2} {b1,b2}, {a1 b1,a2 b2}},
   h[{a1 b1,a2 b2}]
 },
 Thread[h[{a1 b1,a2 b2}]],
 {h[a1 b1],h[a2 b2]}
}

Again, "Thread" is actually being applied to h[...], not to fcntimes[...],
but this time the list is not consumed by h[...] so it is available to be
presented to Thread. Although the sequence of evaluation is not what one
might expect, for this function it makes no difference to the result.

Finally, for comparison,

In[7]:=
fcntimes[{a1, a2},{b1,b2}]

Out[7]=
h[{a1 b1, a2 b2}]

which is the expected result for Times when given vectors as its arguments,
and

In[8]:=
fcndot[{a1, a2},{b1,b2}]

Out[8]=
g[a1 b1+a2 b2]

which is identical to the result when the function was wrapped with
Thread[...], but is the expected result in this case.

Conclusion: Thread[f[{a,b},{c,d}] might return {f[a,c], f[b,d]} or it might
return something else again, depending on the definition of f! But this is
not what seems to be implied by the documentation of Thread.

Shouldn't Thread have non-standard evaluation so that its performance
conforms to the documentation?

And, what is the idiom to use when you need to apply Dot[...] to a list of
lists? (In other words, since Thread doesn't do the trick, how do I get the
result I need, {g[a1.b1], g[a2.b2]}?)


  • Prev by Date: Re: SoBig Virus and the Mathematica mailing list and newsgroup
  • Next by Date: RE: Simplification of radicals
  • Previous by thread: Re: Numerical Integration of Large Expression
  • Next by thread: SphericalPlot3D & RealTime3D