Re: Thread vs MapThread with Compiled functions
- To: mathgroup at smc.vnet.net
- Subject: [mg115142] Re: Thread vs MapThread with Compiled functions
- From: Leonid Shifrin <lshifr at gmail.com>
- 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: http://www.mathprogramming-intro.org/book/node481.html 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 Listable attribute: 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. Regards, Leonid On Sat, Jan 1, 2011 at 12:26 PM, Eric Michielssen <emichiel at eecs.umich.edu>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 > > > > >