Evaluation control in Compile[]

635 views
Skip to first unread message

Ben

unread,
May 30, 2011, 6:33:58 AM5/30/11
to
I'd like to compile a function that estimates (assuming a spherical
earth) the length of a degree of longitude at any particular
latitude. Here's how I write it up and test its speed:

In[1]:= radiusOfEarth=6378100.;
latitudeDegreeLength=2*Pi*radiusOfEarth/360
Out[2]= 111319.
In[3]:= X=Table[RandomReal[{0,90}],{100000}];
In[4]:=
GetLongitudeDegreeLength=Compile[{latitude},latitudeDegreeLength*Cos[latitude
Degree]]
Out[4]= CompiledFunction[{latitude},latitudeDegreeLength Cos[latitude
=B0],-CompiledCode-]
In[5]:= Timing[Map[GetLongitudeDegreeLength,X];]
Out[5]:= {0.312,Null}

Since the values of "latitudeDegreeLength" and "Degree" are constant,
I'd prefer to use numerical approximations in the definition so the
compiled code doesn't have to request the values of these global
variables at runtime. Like this:

In[6]:= GetLongitudeDegreeLength=Compile[{latitude},
111318.*Cos[0.0174532925 latitude]]
Out[6]:= CompiledFunction[{latitude},111318. Cos[0.0174533 latitude],-
CompiledCode-]
In[7]:= Timing[Map[GetLongitudeDegreeLength,X];]
Out[7]:= {0.031,Null}

Is there any way to tell Mathematica that I'd like these symbols to be
evaluated before the compilation so that I don't have to copy and
paste the numerical values into the definition?

Thanks.

Albert Retey

unread,
May 30, 2011, 7:48:12 AM5/30/11
to

there are several, but for this case I think With is probably the clearest:

radiusOfEarth=6378100.;
With[{latitudeDegreeLength=2*Pi*radiusOfEarth/360,deg=N[Degree]},
GetLongitudeDegreeLength=Compile[{latitude},
latitudeDegreeLength*Cos[latitude*deg]]
]

hth,

albert

Ben

unread,
May 31, 2011, 7:46:02 AM5/31/11
to

Thank you!

Szabolcs Horvát

unread,
May 31, 2011, 7:49:03 AM5/31/11
to
Dear MathGroup members,

After reading this question, I started wondering if there is any way to
receive warnings that there might be something "wrong" with a compiled
function (e.g. that Mathematica might drop back to standard evaluation
instead of running compiled code).

CCodeGenerate[] does issue some warnings:

CCodeGenerate[GetLongitudeDegreeLength, "fun"]

CCodeGenerate::wmreq: "The expression
Function[{latitude},latitudeDegreeLength] requires Mathematica to be
evaluated. The function will be generated but can be expected to fail
with a nonzero error code when executed"

Is there a way to get some similar warnings from Compile[]? It is not
obvious and intuitive that using an e.g. elsewhere defined constant
might slow down a compiled function to non-compiled speed.

GetLongitudeDegreeLength =
Function[{latitude}, latitudeDegreeLength*Cos[latitude Degree]]
Timing[Map[GetLongitudeDegreeLength,X];]

is only 1.5 slower on my machine than the compiled version (with
non-inlined constants). (I know that Map can auto-compile its argument,
but setting SetSystemOptions["CompileOptions" -> "MapCompileLength" ->
Infinity] doesn't seem to change anything here, so I assume that the
timing is valid for the uncompiled case)

Szabolcs Horvát

unread,
Jun 1, 2011, 4:30:16 AM6/1/11
to
On 2011.05.30. 12:33, Ben wrote:

After reading up a bit more on Compile[] based on Oliver's replies, I
came across another possible solution, which you might find interesting:

GetLongitudeDegreeLength =
Compile[{{latitude, _Integer, 0}},
latitudeDegreeLength*Cos[latitude Degree],
CompilationOptions -> {"InlineExternalDefinitions" -> True}]


This is documented at ref/CompilationOptions and
Compile/tutorial/Operation

-- Szabolcs

Oliver Ruebenkoenig

unread,
Jun 1, 2011, 4:34:31 AM6/1/11
to
On Tue, 31 May 2011, Szabolcs Horv=E1t wrote:

> Dear MathGroup members,
>
> After reading this question, I started wondering if there is any way to
> receive warnings that there might be something "wrong" with a compiled
> function (e.g. that Mathematica might drop back to standard evaluation
> instead of running compiled code).
>
> CCodeGenerate[] does issue some warnings:
>
> CCodeGenerate[GetLongitudeDegreeLength, "fun"]
>
> CCodeGenerate::wmreq: "The expression
> Function[{latitude},latitudeDegreeLength] requires Mathematica to be
> evaluated. The function will be generated but can be expected to fail
> with a nonzero error code when executed"
>
> Is there a way to get some similar warnings from Compile[]? It is not
> obvious and intuitive that using an e.g. elsewhere defined constant
> might slow down a compiled function to non-compiled speed.
>
> GetLongitudeDegreeLength =
> Function[{latitude}, latitudeDegreeLength*Cos[latitude Degree]]
> Timing[Map[GetLongitudeDegreeLength,X];]
>
> is only 1.5 slower on my machine than the compiled version (with
> non-inlined constants). (I know that Map can auto-compile its argument,
> but setting SetSystemOptions["CompileOptions" -> "MapCompileLength" ->
> Infinity] doesn't seem to change anything here, so I assume that the
> timing is valid for the uncompiled case)
>

>> Thanks.
>>
>
>
>

Hi,

does this help?

f[x_] := x + 1
f1 = Compile[{{x, _Integer, 0}}, f[x]]

f1[1]


<< "CompiledFunctionTools`"

CompilePrint[f1]

System`SetSystemOptions[
"CompileOptions" -> "CompileReportExternal" -> True];

f2 = Compile[{{x, _Integer, 0}}, f[x]]

Oliver

Szabolcs Horvát

unread,
Jun 1, 2011, 4:34:42 AM6/1/11
to
2011/5/31 Oliver Ruebenkoenig <rueb...@wolfram.com>:
>
> Hi,
>
> does this help?
>
> f[x_] :== x + 1
> f1 == Compile[{{x, _Integer, 0}}, f[x]]

>
> f1[1]
>
>
> << "CompiledFunctionTools`"
>
> CompilePrint[f1]
>
> System`SetSystemOptions[
> =C2 "CompileOptions" -> "CompileReportExternal" -> True];
>
> f2 == Compile[{{x, _Integer, 0}}, f[x]]
>

Thank you, that's exactly what I've been looking for (I think)!

Reply all
Reply to author
Forward
0 new messages