Re: Compiled function changes somehow.
- To: mathgroup at smc.vnet.net
- Subject: [mg78609] Re: Compiled function changes somehow.
- From: Bill Rowe <readnewsciv at sbcglobal.net>
- Date: Thu, 5 Jul 2007 04:06:35 -0400 (EDT)
On 7/4/07 at 5:40 AM, ncc1701zzz at gmail.com (Nacho) wrote: >I have been playing with Compile to accelerate some simple code and >I have found some differences that I cannot explain. >The standard/compiled code is as follows: >standard[max_] := >Table[n/m, {n, 1, max}, {m, 1, max}] // N // Flatten; >compiled = >Compile[{{max, _Integer}}, Table[n/m, {n, 1, max}, {m, 1, max}] // N >// Flatten]; Note, you do not need to use N in the compiled code since the output of numeric operations with compiled code will be a machine precision number. >So I can do the same calculations with both codes: >In[19]:= standardresult = standard[1000]; // Timing >Out[19]= {2.969, Null} >In[20]:= compiledresult = compiled[1000]; // Timing >Out[20]= {0.422, Null} > > >The second is much faster, as expected. But are the results the >same? Apparently, yes: >In[21]:= standardresult == compiledresult >Out[21]= True >In[22]:= standardresult === compiledresult >Out[22]= True Despite this last result, the output from both functions is not the same. The issue is when values are converted to machine precision. With the compiled version, values are converted to machine precision then the division occurs. With the standard version the rational value is converted to machine precision and the results are not quite the same. Also, with the standard version Mathematica will first reduce the rational to canonical form by eliminating common factors. So, integral multiples of a rational will be converted to the same machine precision number with the standard version. This will not be always true for the compiled version. =46irst, changing your code to eliminate the Flatten and N operations standard[max_] := Table[n/m, {n, max}, {m, max}] compiled = Compile[{{max, _Integer}}, Table[n/m, {n, max}, {m, max}]]; and generating a somewhat smaller test sample standardResult = standard[100]; compiledResult = compiled[100]; base on In[5]:= Union[Head /@ Flatten[compiledResult]] Out[5]= {Real} it is clear N isn't needed for the compiled code In[6]:= Length@ Union[Flatten@compiledResult, SameTest -> (Equal @@ {##} &)] Out[6]= 6087 In[7]:= Length@Union[Flatten@compiledResult] Out[7]= 6256 In[8]:= Length@Union[Flatten@standardResult] Out[8]= 6087 In[9]:= Length@Union[Flatten@standardResult // N] Out[9]= 6087 So, simply changing Union to use Equal as SameTest resolves the discrepancy=