Skip to main content

random - Why doesn't SeedRandom work here?


From the docs on SeedRandom,



SeedRandom[] resets the generator, using as a seed the time of day and certain attributes of the current Wolfram System session.




This means that every time I use SeedRandom[] without an argument, I should get a new sequence of random numbers. (Note: When evaluating the code in this post, make sure to wait a few seconds between evaluations to ensure that the seed taken from the system timer is different.)


Indeed, evaluating


BlockRandom[
SeedRandom[]; RandomInteger[10, 10]
]

multiple times gives different results.


But now try setting the generation method and evaluate this in a new kernel:


Table[

BlockRandom[
Pause[2]; SeedRandom[Method -> "Congruential"]; RandomInteger[10, 10]
],
{4}
]

{{9, 5, 2, 8, 6, 5, 6, 4, 2, 3},
{1, 4, 7, 4, 8, 0, 9, 5, 3, 6},
{1, 4, 7, 4, 8, 0, 9, 5, 3, 6},
{1, 4, 7, 4, 8, 0, 9, 5, 3, 6}}


After the second evaluation, it keeps returning the same sequence of numbers. Why?


This does not happen if evaluating the same outside of BlockRandom.




To try to get to the bottom of this, we can try to define our own random number generator and see how Mathematica calls it. I took the Blum-Blum-Shub example from the documentation and added Print commands to the initialization, seeding and generation functions to see how it is being called under the hood. Performing the same experiment as above (BlockRandom[SeedRandom[Method -> BlumBlumShub]; RandomInteger[10, 10]]) shows that the generator is called only the very first time. After that it is not re-seeded and cached results are being returned.


Experimenting with this and trying to find out how many numbers are cached shows some weird things again: generating 100 numbers instead of 10 calls the generator every time, yet the results returned are still the same every time. The threshold at which the generator is being called seems to depend on many details, I couldn't find out what exactly. It is unusual that although all 100 numbers seem to be cached, the generator is still invoked every time (why?).


These observations about caching bring up an important question:


Does the generator framework assume that two user-defined objects that are equal at the Mathematica level (== or ===) truly have the same internal state? I was implementing a generator in C and the Mathematica side generator object is nothing more than a handle to a C-side data structure (a managed library expression).




Update



There's an internal function called Random`GetRandomState[]. This returns something more than just the generator object. Example:


BlockRandom[
SeedRandom[Method -> BlumBlumShub];
RandomInteger[10, 10];
Random`GetRandomState[]
]

Random`GeneratorState[{BlumBlumShub, {}},
{{1389677191105303686723527819391197837920730913355627310599292454172523542012932098584330324866567942749879326659731493946935471621493571, 24, 7, 5},
{BlumBlumShub[1606938044258990275541964487092870409276299325644596228407321, 7, 127, 1268550763627358771726516777152512424855599645376602106716491], 7, 1, None}}

]

What is notable here is that the result is entirely determined by the parameters in RandomInteger[10, 10]. Changing it to RandomInteger[10, 100] changes the result predictably, changing it back changes the result back too.


This suggests that the RNG framework does work with the internal state of user defined generators, and perhaps caches it. That would mean that it is not safe to store the state somewhere else (e.g. in a C data structure).


This seems to contradict the documentation, which says,



A generator object is of the form gsym[data] where gsym is the symbol that identifies the generator and to which rules are attached. data is effectively private to the top-level evaluations associated with the generator definitions.



(Emphasis by me.)





Link to Wolfram Community question.




Comments

Popular posts from this blog

plotting - Filling between two spheres in SphericalPlot3D

Manipulate[ SphericalPlot3D[{1, 2 - n}, {θ, 0, Pi}, {ϕ, 0, 1.5 Pi}, Mesh -> None, PlotPoints -> 15, PlotRange -> {-2.2, 2.2}], {n, 0, 1}] I cant' seem to be able to make a filling between two spheres. I've already tried the obvious Filling -> {1 -> {2}} but Mathematica doesn't seem to like that option. Is there any easy way around this or ... Answer There is no built-in filling in SphericalPlot3D . One option is to use ParametricPlot3D to draw the surfaces between the two shells: Manipulate[ Show[SphericalPlot3D[{1, 2 - n}, {θ, 0, Pi}, {ϕ, 0, 1.5 Pi}, PlotPoints -> 15, PlotRange -> {-2.2, 2.2}], ParametricPlot3D[{ r {Sin[t] Cos[1.5 Pi], Sin[t] Sin[1.5 Pi], Cos[t]}, r {Sin[t] Cos[0 Pi], Sin[t] Sin[0 Pi], Cos[t]}}, {r, 1, 2 - n}, {t, 0, Pi}, PlotStyle -> Yellow, Mesh -> {2, 15}]], {n, 0, 1}]

plotting - Plot 4D data with color as 4th dimension

I have a list of 4D data (x position, y position, amplitude, wavelength). I want to plot x, y, and amplitude on a 3D plot and have the color of the points correspond to the wavelength. I have seen many examples using functions to define color but my wavelength cannot be expressed by an analytic function. Is there a simple way to do this? Answer Here a another possible way to visualize 4D data: data = Flatten[Table[{x, y, x^2 + y^2, Sin[x - y]}, {x, -Pi, Pi,Pi/10}, {y,-Pi,Pi, Pi/10}], 1]; You can use the function Point along with VertexColors . Now the points are places using the first three elements and the color is determined by the fourth. In this case I used Hue, but you can use whatever you prefer. Graphics3D[ Point[data[[All, 1 ;; 3]], VertexColors -> Hue /@ data[[All, 4]]], Axes -> True, BoxRatios -> {1, 1, 1/GoldenRatio}]

plotting - Mathematica: 3D plot based on combined 2D graphs

I have several sigmoidal fits to 3 different datasets, with mean fit predictions plus the 95% confidence limits (not symmetrical around the mean) and the actual data. I would now like to show these different 2D plots projected in 3D as in but then using proper perspective. In the link here they give some solutions to combine the plots using isometric perspective, but I would like to use proper 3 point perspective. Any thoughts? Also any way to show the mean points per time point for each series plus or minus the standard error on the mean would be cool too, either using points+vertical bars, or using spheres plus tubes. Below are some test data and the fit function I am using. Note that I am working on a logit(proportion) scale and that the final vertical scale is Log10(percentage). (* some test data *) data = Table[Null, {i, 4}]; data[[1]] = {{1, -5.8}, {2, -5.4}, {3, -0.8}, {4, -0.2}, {5, 4.6}, {1, -6.4}, {2, -5.6}, {3, -0.7}, {4, 0.04}, {5, 1.0}, {1, -6.8}, {2, -4.7}, {3, -1.