# Underflow occurred in compilation

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

• 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
• 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
• 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

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


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