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

functions - Get leading series expansion term?

Given a function f[x] , I would like to have a function leadingSeries that returns just the leading term in the series around x=0 . For example: leadingSeries[(1/x + 2)/(4 + 1/x^2 + x)] x and leadingSeries[(1/x + 2 + (1 - 1/x^3)/4)/(4 + x)] -(1/(16 x^3)) Is there such a function in Mathematica? Or maybe one can implement it efficiently? EDIT I finally went with the following implementation, based on Carl Woll 's answer: lds[ex_,x_]:=( (ex/.x->(x+O[x]^2))/.SeriesData[U_,Z_,L_List,Mi_,Ma_,De_]:>SeriesData[U,Z,{L[[1]]},Mi,Mi+1,De]//Quiet//Normal) The advantage is, that this one also properly works with functions whose leading term is a constant: lds[Exp[x],x] 1 Answer Update 1 Updated to eliminate SeriesData and to not return additional terms Perhaps you could use: leadingSeries[expr_, x_] := Normal[expr /. x->(x+O[x]^2) /. a_List :> Take[a, 1]] Then for your examples: leadingSeries[(1/x + 2)/(4 + 1/x^2 + x), x] leadingSeries[Exp[x], x] leadingSeries[(1/x + 2 + (1 - 1/x...

How to thread a list

I have data in format data = {{a1, a2}, {b1, b2}, {c1, c2}, {d1, d2}} Tableform: I want to thread it to : tdata = {{{a1, b1}, {a2, b2}}, {{a1, c1}, {a2, c2}}, {{a1, d1}, {a2, d2}}} Tableform: And I would like to do better then pseudofunction[n_] := Transpose[{data2[[1]], data2[[n]]}]; SetAttributes[pseudofunction, Listable]; Range[2, 4] // pseudofunction Here is my benchmark data, where data3 is normal sample of real data. data3 = Drop[ExcelWorkBook[[Column1 ;; Column4]], None, 1]; data2 = {a #, b #, c #, d #} & /@ Range[1, 10^5]; data = RandomReal[{0, 1}, {10^6, 4}]; Here is my benchmark code kptnw[list_] := Transpose[{Table[First@#, {Length@# - 1}], Rest@#}, {3, 1, 2}] &@list kptnw2[list_] := Transpose[{ConstantArray[First@#, Length@# - 1], Rest@#}, {3, 1, 2}] &@list OleksandrR[list_] := Flatten[Outer[List, List@First[list], Rest[list], 1], {{2}, {1, 4}}] paradox2[list_] := Partition[Riffle[list[[1]], #], 2] & /@ Drop[list, 1] RM[list_] := FoldList[Transpose[{First@li...

front end - keyboard shortcut to invoke Insert new matrix

I frequently need to type in some matrices, and the menu command Insert > Table/Matrix > New... allows matrices with lines drawn between columns and rows, which is very helpful. I would like to make a keyboard shortcut for it, but cannot find the relevant frontend token command (4209405) for it. Since the FullForm[] and InputForm[] of matrices with lines drawn between rows and columns is the same as those without lines, it's hard to do this via 3rd party system-wide text expanders (e.g. autohotkey or atext on mac). How does one assign a keyboard shortcut for the menu item Insert > Table/Matrix > New... , preferably using only mathematica? Thanks! Answer In the MenuSetup.tr (for linux located in the $InstallationDirectory/SystemFiles/FrontEnd/TextResources/X/ directory), I changed the line MenuItem["&New...", "CreateGridBoxDialog"] to read MenuItem["&New...", "CreateGridBoxDialog", MenuKey["m", Modifiers-...