Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

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.]

output reads

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).

share|improve this question

1 Answer 1

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.

share|improve this answer
    
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 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 at 14:27

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.