MathGroup Archive 2007

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

Search the Archive

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=


  • Prev by Date: Re: Rotable Graphics and ViewPoint
  • Next by Date: Re: V6: ListPlot memory requeriments
  • Previous by thread: Re: Compiled function changes somehow.
  • Next by thread: Re: Compiled function changes somehow.