29
$\begingroup$

Fixed in 10.1.0.

Consider the following function, which generates uniformly random points on the surface of the 2-sphere:

randSphere[] := Block[{z = RandomReal[{-1, 1}, 3]},
    If[Total[z^2] > 1, randSphere[], Normalize[z]]]

I can use this function to generate a Table of 249 points:

Table[randSphere[], {249}] (* works fine *)

but mysteriously, changing 249 to 250 consistently crashes the kernel. I am running Mathematica 10.0.2 on Windows. What's going on here? It's worth noting that I can also generate 249 pairs of points with no problems:

Table[{randSphere[], randSphere[]}, {249}] (* also works fine *)

and I can even generate 249 Tables of 249 points:

Table[Table[randSphere[], {249}], {249}] (* still fine *)

but changing any instance of 249 to 250 in each of the above examples crashes the kernel again.

$\endgroup$
  • 3
    $\begingroup$ Reproduced in 10.0.2 OS X. Table will attempt to auto-compile its first argument starting at 250, which is certainly related to the crash. The CompileOptions setting from SystemOptions controls this. $\endgroup$ – Szabolcs Dec 30 '14 at 18:13
  • 2
    $\begingroup$ Reproduced in v9.0.1 as well. This crash is almost certainly related to the recursive call in randSphere. The workaround is to get rid of that (use a While[... > 1, (* recompute *)] sort of thing). Compile doesn't support recursive calls. I'm tagging this as a bug, please report it to support at wolfram.com. $\endgroup$ – Szabolcs Dec 30 '14 at 18:15
  • 2
    $\begingroup$ Reported as a bug. $\endgroup$ – Daniel Lichtblau Dec 30 '14 at 19:41
  • 2
    $\begingroup$ @MichaelE2 Your simpler example indeed runs afoul of the same underlying problem. $\endgroup$ – Daniel Lichtblau Dec 30 '14 at 19:44
  • 5
    $\begingroup$ @MichaelE2 By the way, your formulation will have a separate but possibly related issue in that the (weak) type inferencing mechanism in Compile will not know what is getting returned. The variant below makes this explicit, and has the pleasant side effect of circumventing the crash.ff = Compile[{}, randSphere[], {{_randSphere,_Real,1}}]; Table[ff[],{250}] I do not understand how this manages to evade the crash. Which is weird, since I now know what causes said crash. One of those mysteries. $\endgroup$ – Daniel Lichtblau Dec 30 '14 at 20:57
25
$\begingroup$

I can reproduce this on OS X in M10.0.2 and M9.0.1, so it looks like a bug. Please report it to Wolfram support.

Table will automatically try to compile its argument above a table length threshold. This threshold is 250 by default and can be set to a different value using SetSystemOptions["CompileOptions" -> "TableCompileLength" -> ...]. It seems the crash happens only when Table compiles its argument.

The randSphere function is recursive but Compile doesn't support recursion. My guess is that the crash is related to this.

I recommend eliminating the recursion as a workaround:

randSphere[] := Module[{z},
  While[True,
   z = RandomReal[{-1, 1}, 3];
   If[Total[z^2] <= 1, Return@Normalize[z]]
   ]
  ]

This version won't crash.

$\endgroup$
  • 5
    $\begingroup$ We are aware of this issue. I don't have an ETA for when it will be fixed, though. $\endgroup$ – Stefan R Dec 30 '14 at 19:43
  • 1
    $\begingroup$ @StefanR Out of curiosity, is the problem really related to the recursion? $\endgroup$ – Szabolcs Dec 30 '14 at 20:04
  • 4
    $\begingroup$ Yes, it's related to the recursion. Not the actual running of the recursion, but in the preprocessing. $\endgroup$ – Daniel Lichtblau Dec 31 '14 at 0:18
2
$\begingroup$

As an alternative, you can use the following function to generate pseudo-random points on the sphere:

PointOnTwoSphere[] := Module[
  {z, phi, rho, x, y},
  z = RandomReal[{-1, 1}];
  phi = RandomReal[{0, 2*Pi}];
  rho = Sqrt[1 - z^2];
  x = rho * Cos[phi];
  y = rho * Sin[phi];
  {x, y, z}
]

This algorithm, due to Marsaglia, has the virtue that it does not throw away any points.

$\endgroup$
0
$\begingroup$

Not a solution but worth noting.

enter image description here enter image description here

ParallelTable[randSphere[], {250}]

Does seem to work.

I dont know about its limit, but eventually, it crashed (as expected for "big" data). enter image description here

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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