In the mathematica document "tutorial/CompilingWolframLanguageExpressions"
1
It says about how to set return type of a called function you used in Compile
.
Clear[com]
com[i_] := Binomial[2 i, i]
test=Compile[{x, {i, _Integer}}, x^com[i], {{com[_], _Integer}}]
From the above example, we can see that because the com
function evaluates to integer, so we set {{com[_], _Integer}}
to let Compile
know the return type of com
.
But if you inspect it further
Needs["CompiledFunctionTools`"]
CompilePrint[test]
You can see there is MainEvaluate
when calling function com
.
So, I don't understand the meaning of this example in the document. If a compiled function has a MainEvaluate
process, then I think compiling it is just nonsense, for it won't speed up things, right?
2
Then I came up with another question, it is also mentioned in the same document page. If we compile Sqrt
as below
sqrtcom1 = Compile[{{x, _Real}}, Sqrt[x]]
we will run into problems if we evaluate sqrtom1[-1.]
, it will give errors like
CompiledFunction::cfn: Numerical error encountered at instruction 1; proceeding with uncompiled evaluation. >>
This is because the return type of Sqrt
is assumed to be real by default. This can be see from
In[20]:= ToCompiledProcedure[sqrtcom1][[4]]
Out[20]= CompiledResult[Register[Real, 1]]
So, theoretically we could solve this by
sqrtcom2 = Compile[{{x, _Real}}, Sqrt[x], {{Sqrt[_], _Complex}}]
But this is not working!! ToCompiledProcedure[sqrtcom2][[4]]
still gives CompiledResult[Register[Real, 1]]
and sqrtcom2
still gives errors.
Why is it not working?
_Complex
, e.g.In[53]:= sqrtcom1 = Compile[{{x, _Complex}}, Sqrt[x]]; sqrtcom1[-1.1] Out[54]= 0. + 1.04880884817 I
$\endgroup$_Complex
works. So just as halirutan says in the link provided by Jason B. " one of the situations where the third argument of Compile is required is when your compiled code needs to make a MainEvaluate call". Can I safely change the word "one of" as "only one"? Is there any other situations? $\endgroup$RepeatedTiming
on the root of -4 and found uncompiledSqrt
fastest, followed bysqrtHal
andsqrtHal2
accepting real input, thensqrtcom1
accepting complex input, andsqrtcom3
involving aMainEvaluate
call. Curiously,sqrtHal
was slightly faster thansqrtHal2
, but it became clear when I looked atCompilePrint
thatsqrtHal2
involves an additional complex addition inx + 0. I
, whichsqrtHal
lacks. $\endgroup$sqrtcom2
doesn't work, it seems, as you may already suspect,Compile
ignores the third argument for supported functions. Only when a function requires aMainEvaluate
call doesCompile
look at the third argument for the function's return type. I think the answer by @JasonB supports this conjecture. $\endgroup$