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 - How to draw lines between specified dots on ListPlot?

I would like to create a plot where I have unconnected dots and some connected. So far, I have figured out how to draw the dots. My code is the following: ListPlot[{{1, 1}, {2, 2}, {3, 3}, {4, 4}, {1, 4}, {2, 5}, {3, 6}, {4, 7}, {1, 7}, {2, 8}, {3, 9}, {4, 10}, {1, 10}, {2, 11}, {3, 12}, {4,13}, {2.5, 7}}, Ticks -> {{1, 2, 3, 4}, None}, AxesStyle -> Thin, TicksStyle -> Directive[Black, Bold, 12], Mesh -> Full] I have thought using ListLinePlot command, but I don't know how to specify to the command to draw only selected lines between the dots. Do have any suggestions/hints on how to do that? Thank you. Answer One possibility would be to use Epilog with Line : ListPlot[ {{1, 1}, {2, 2}, {3, 3}, {4, 4}, {1, 4}, {2, 5}, {3, 6}, {4, 7}, {1, 7}, {2, 8}, {3, 9}, {4, 10}, {1, 10}, {2, 11}, {3, 12}, {4, 13}, {2.5, 7}}, Ticks -> {{1, 2, 3, 4}, None}, AxesStyle -> Thin, TicksStyle -> Directive[Black, Bold, 12], Mesh -> Full, Epilog -> { Line[ ...

equation solving - Invert and fit implicitly defined curve

I need to fit an implicitly defined curve. I thought I could get some data out of Solve , and then using FindFit . Therefore, I would like to find the relation the parametric curve defined by $F(x,y)=0$: Solve[-(1/2) + 1/2 (0.41202 BesselK[0, 0.1 Sqrt[x^2 + y^2]] + (0.101483 x BesselK[1, 0.1 Sqrt[x^2 + y^2]])/Sqrt[x^2 + y^2]) == 0, y] But I can't get an output: Solve was unable to solve the system with inexact coefficients or the system obtained by direct rationalization of inexact numbers present in the system. Since many of the methods used by Solve require exact input, providing Solve with an exact version of the system may help. >> Edit: In particular, I would like to fit the data coming from the curve with the expression of another curve, and not with a function $f(x)$. In particular, since this clearly looks like a cardioid , I would like it to fit to something like it. What other strategies could I try?

dynamic - How can I make a clickable ArrayPlot that returns input?

I would like to create a dynamic ArrayPlot so that the rectangles, when clicked, provide the input. Can I use ArrayPlot for this? Or is there something else I should have to use? Answer ArrayPlot is much more than just a simple array like Grid : it represents a ranged 2D dataset, and its visualization can be finetuned by options like DataReversed and DataRange . These features make it quite complicated to reproduce the same layout and order with Grid . Here I offer AnnotatedArrayPlot which comes in handy when your dataset is more than just a flat 2D array. The dynamic interface allows highlighting individual cells and possibly interacting with them. AnnotatedArrayPlot works the same way as ArrayPlot and accepts the same options plus Enabled , HighlightCoordinates , HighlightStyle and HighlightElementFunction . data = {{Missing["HasSomeMoreData"], GrayLevel[ 1], {RGBColor[0, 1, 1], RGBColor[0, 0, 1], GrayLevel[1]}, RGBColor[0, 1, 0]}, {GrayLevel[0], GrayLevel...