# Determine types of input, output and internal variables in compiled functions

I am trying to speedup the computation of a longer function using Compile. For illustration consider the following short example:

procTest = Compile[{{x, _Real}},
res = Log[-x];
Im[res]
];


The input and output are both real valued. But Mathematica Compile seems to assume that this means that it can use the real Log function inside the routine. At least the following commands

procTest[-1.]
procTest[1.]


0
CompiledFunction::cfse:  Compiled expression 0. + 3.14159 I should be a machine-size real number.
CompiledFunction::cfex:  Could not complete external evaluation at instruction 2; proceeding with uncompiled evaluation.
3.141592653589793


Of course I can change the type _Real to _Complex which makes this example work, but the output is then a complex quantity with zero imaginary part. Is there a way to tell Compile that it should assume real input and outputs, but complex quantities can appear inside the function? If not, can I convert the output type from complex to real? I am worried about the output type because it seems to confuse other parts of my computation (not sure, but probably FindRoot tries to perform a complex root search if the arguments are not reals).

-

This seems to be a problem with the type-inferencer of Compile. Here is one way around this:

procTest =
Compile[{{x, _Real}},
Module[{res = 0 * I},
res = -x;
res = Log[res];
Im[res]]];


In which case, both test cases work all right.

-
Of course, the intermediate variable res should be localized in a Module anyway. By incorporating res=0*I, you're essentially declaring res to be Complex. Is that correct? If so, I would have expected 0.0*I to make more sense. I guess that Module has the attribute HoldAll so that it sees the I anyway. – Mark McClure Mar 7 '14 at 14:11
@MarkMcClure My guess is that the type-inferencer inside Compile introspects internal Module anyway, and has its own means to determine the type, so I did not feel it necessary to use 0.0 * I - but in general you are probably right, 0.0 I should be safer. – Leonid Shifrin Mar 7 '14 at 14:27