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.

This code shown below works well for n<=10, if n>11, Mathematica gives the message

CompiledFunction::cfne: Numerical error encountered; proceeding with uncompiled evaluation. >>.

So compilation failed, my questions is: How can I make it compilable?

cf = Compile[{{n, _Integer}}, 
   With[{c = Table[j + i*I, {i, -1.2, 1.2, .006015}, {j, -1.8, 0.6, .006015}]},
        Exp[-Abs@Nest[#^2 + c &, c, n]]]];
share|improve this question
4  
Well to be fair, those numbers are in underflow territory... a "straightforward" way (but terribly slow) would be to use exact arithmetic (but you can't use Compile). –  rm -rf May 22 '13 at 15:46
2  
I don't think compiling failed. The message means that the function, which works in machine precision, detected an underflow condition and decided to continue with the more accurate symbolic version. –  Sjoerd C. de Vries May 22 '13 at 15:46
5  
You can set a value as the infinity and for everything greater you set the Exp to zero. I assume that you are studying something about Julia sets so the divergence area is not the one that you are mainly interested at. –  Spawn1701D May 22 '13 at 19:10
    
How about RuntimeOptions -> "Speed" ? –  Jacob Akkerboom May 24 '13 at 16:32
add comment

2 Answers 2

up vote 5 down vote accepted
+50

The main error is that the numbers get too large in the Nest call, greater than is possible to represent as machine reals/complexes, and you get overflow. Here I just cap them at a large number 10^10, but small enough that Exp won't underflow.

cf = Compile[{{n, _Integer}}, 
   With[{c = Table[j + i*I, {i, -1.2, 1.2, .006015}, {j, -1.8, 0.6, .006015}]}, 
    Exp[-Abs @ Nest[Map[If[Norm[#] > 1.`*^10, 1.`*^10, #] &, #^2 + c, {2}] &, c, n]]],
   RuntimeOptions -> "Speed"];

Same idea, but somewhat faster:

cf = Compile[{{n, _Integer}}, 
   With[{c = Table[j + i*I, {i, -1.2, 1.2, .006015}, {j, -1.8, 0.6, .006015}]},
     Exp[-Abs @
       Nest[With[{u = UnitStep[1.`*^10 - Abs[#]]}, u # + (1 - u) 1.`*^10] &[#^2 + c] &,
        c, n]]], 
   RuntimeOptions -> "Speed"]
share|improve this answer
add comment

Here we stop the iteration before the values get small enough to cause the underflow errors.

cf = Compile[{{n, _Integer}},
       Table[Exp[-Abs@NestWhile[#^2 + j + i*I &, j + i*I, Abs[#] < 10. &, 1, n]], 
       {i, -1.2, 1.2, .006015}, {j, -1.8, 0.6, .006015}]];

Instead of Nest it uses NestWhile and the condition is Abs[#] < 10. & so it iterates up to n times, but stops iterating if the argument gets larger than 10, which means Exp[-Abs[10]] is getting small. You might want to change this value. The other change was to not use With and the c variable; the reason for this change (using Table instead) is that the test didn't like having a whole matrix of values passed to it.

share|improve this answer
add comment

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.