MathGroup Archive 2011

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

Search the Archive

Re: Thread vs MapThread with Compiled functions

  • To: mathgroup at
  • Subject: [mg115142] Re: Thread vs MapThread with Compiled functions
  • From: Leonid Shifrin <lshifr at>
  • Date: Sun, 2 Jan 2011 04:55:57 -0500 (EST)

Hi Eric,

The problem is that Thread evaluates its argument, while in MapThread the format
of the function is such that the function is separated from the arguments
and so no unwanted evaluation of this type can take place.

Here is one workaround:

Block[{myadd}, Thread[myadd[x1t, x2t]]]

{0.388655, 0.829089, 0.975558, 0.526135}

By using Block, we make <myadd> forget its definition inside  Block, and
this effectively
changes the order of evaluation - it is first threaded as a general head,
and then evaluated,
already after the evaluation leaves the Block (dynamic) scope.

Here is an alternative way to do this, without using the Block trick:

In[16]:= With[{x1 = x1t, x2 = x2t},
 Thread[Unevaluated[myadd[x1, x2]]]]

Out[16]= {0.388655, 0.829089, 0.975558, 0.526135}

The bottom line is that this is not a problem of Compile, but a general
property of the standard
evaluation in Mathematica, and Thread in particular. I discussed exactly
this problem here:

Regarding Compile, there are a few ways to simplify things in your case. One
is to
define the function to work with lists from the start:

In[17]:= myaddList =
  Compile[{{x1, _Real, 1}, {x2, _Real, 1}}, x1 + x2];

In[18]:= myaddList[x1t, x2t]

Out[18]= {0.388655, 0.829089, 0.975558, 0.526135}

Another is to use the new capability of Mathematica 8 Compile and define the run-time

In[21]:= myaddL =
  Compile[{{x1, _Real}, {x2, _Real}}, x1 + x2,
   RuntimeAttributes -> Listable];

In[22]:= myaddL[x1t, x2t]

Out[22]= {0.388655, 0.829089, 0.975558, 0.526135}

The latter option becomes more relevant for the function body which does not
by itself automatically
thread over lists (unlike in this example), and in the context of
parallelizing  for multi-core PCs.

Hope  this helps.


On Sat, Jan 1, 2011 at 12:26 PM, Eric Michielssen
<emichiel at>wrote:

> All,
> It seems like I can MapThread with a compiled function, but not Thread w/o
> Mathematica complaining... Any explanation?
> myadd = Compile[{{x1, _Real}, {x2, _Real}}, x1 + x2];
> x1t = Table[RandomReal[], {i, 1, 4}];
> x2t = Table[RandomReal[], {i, 1, 4}];
> MapThread[myadd, {x1t, x2t}]  (** Works, see below **)
> Thread[myadd[x1t, x2t]] (** Minor (?) trouble, see below **)
> Out[1591]= {0.987826, 0.739118, 0.483543, 1.03504}
> During evaluation of In[1587]:= CompiledFunction::cfsa: Argument
> {0.0803627,0.64419,0.240207,0.35777} at position 1 should be a machine-size
> real number. >>
> Out[1592]= {0.987826, 0.739118, 0.483543, 1.03504}   (** Still goes through
> despite complaint... **)
> Eric Michielssen

  • Prev by Date: Re: Manually culling a list
  • Next by Date: Import, ReadList, and Unicode
  • Previous by thread: Thread vs MapThread with Compiled functions
  • Next by thread: Re: Manually culling a list