www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - How to generate a random number from system clock as seed

reply Eric P626 <ericp lariennalibrary.com> writes:
I managed to create a random number generator using the following 
code:

~~~
auto rng = Random(42);
//....
uniform(0,10,rng);
~~~

Now I want to seed the generator using system time. I looked at 
Date & time functions/classes and systime functions/classes. The 
problem is that they all require a time zone. But I don't need a 
time zone since there is no time zone. I just want the number of 
seconds elapsed since jan 1st 1970. In other words, the internal 
system clock value.
Jun 08
next sibling parent Salih Dincer <salihdb hotmail.com> writes:
On Saturday, 8 June 2024 at 13:19:30 UTC, Eric P626 wrote:
 I just want the number of seconds elapsed since jan 1st 1970. 
 In other words, the internal system clock value.
#unix #time SDB79
Jun 08
prev sibling next sibling parent reply monkyyy <crazymonkyyy gmail.com> writes:
On Saturday, 8 June 2024 at 13:19:30 UTC, Eric P626 wrote:
 I managed to create a random number generator using the 
 following code:

 ~~~
 auto rng = Random(42);
 //....
 uniform(0,10,rng);
 ~~~

 Now I want to seed the generator using system time. I looked at 
 Date & time functions/classes and systime functions/classes. 
 The problem is that they all require a time zone. But I don't 
 need a time zone since there is no time zone. I just want the 
 number of seconds elapsed since jan 1st 1970. In other words, 
 the internal system clock value.
rng is an optional parameter, `uniform(0,100).writeln;` alone works; the docs not telling you that is really bad the docs/api for std.time/random are bad if you need something specif Id suggest doing it yourself, but if you want to use std.time anyway the magic word I think is "localtime"(Ive pounded my head into those auto generated docs and had to dive deep to find such estoric knowledge) if you need a spefic random number from a spefic timestamp, Id suggest making a rng function from scratch and using clibs time stuff
Jun 08
next sibling parent reply Nick Treleaven <nick geany.org> writes:
On Saturday, 8 June 2024 at 16:09:04 UTC, monkyyy wrote:
 rng is an optional parameter, `uniform(0,100).writeln;` alone 
 works; the docs not telling you that is really bad
They do tell you:
 urng 	(optional) random number generator to use; if not 
 specified, defaults to rndGen
That overload is used in the 2nd example. https://dlang.org/phobos/std_random.html#.uniform
Jun 08
parent reply monkyyy <crazymonkyyy gmail.com> writes:
On Saturday, 8 June 2024 at 20:53:02 UTC, Nick Treleaven wrote:
 On Saturday, 8 June 2024 at 16:09:04 UTC, monkyyy wrote:
 rng is an optional parameter, `uniform(0,100).writeln;` alone 
 works; the docs not telling you that is really bad
They do tell you:
 urng 	(optional) random number generator to use; if not 
 specified, defaults to rndGen
That overload is used in the 2nd example. https://dlang.org/phobos/std_random.html#.uniform
generate is a very rare function and do novices understand lamdas?
Jun 08
parent reply Eric P626 <ericp lariennalibrary.com> writes:
On Saturday, 8 June 2024 at 21:04:16 UTC, monkyyy wrote:
 generate is a very rare function and do novices understand 
 lamdas?
Yes I know lamdas, but try not to use them. I am not very picky about the exact source of time, I just want a different integer every time I run the program. But while looking at the doc, it seemed complicated because I required time zones, and I could not get the entire time stamp as a single integer.
Jun 09
parent monkyyy <crazymonkyyy gmail.com> writes:
On Sunday, 9 June 2024 at 07:11:22 UTC, Eric P626 wrote:
 On Saturday, 8 June 2024 at 21:04:16 UTC, monkyyy wrote:
 generate is a very rare function and do novices understand 
 lamdas?
Yes I know lamdas, but try not to use them. I am not very picky about the exact source of time, I just want a different integer every time I run the program. But while looking at the doc, it seemed complicated because I required time zones, and I could not get the entire time stamp as a single integer.
Im not sure exactly why it automagically works, but it does work, the defualt rng is time seeded somehow
 I am not exactly sure what the exclamation points stand for in 
 the first line of code.
templates its a simplification but assume function headers have two parts, a compile time part and a runtime part thats from c; while it trys to fill in the compile time part implicitly if theres no information and your passing a type in, you use ! to fill the compile time header
Jun 09
prev sibling parent reply Joseph Rushton Wakeling <joseph.wakeling webdrake.net> writes:
On Saturday, 8 June 2024 at 16:09:04 UTC, monkyyy wrote:
 rng is an optional parameter, `uniform(0,100).writeln;` alone 
 works; the docs not telling you that is really bad
The docs do tell you that `rng` is an optional parameter of `uniform`: https://dlang.org/phobos/std_random.html#uniform However, there are often good reasons to want to pass a specific RNG: you may want to pick the specific RNG algorithm, and you may want to be able to know exactly how it was seeded, e.g. if you want to be able to reproduce the same results. I assume that Eric's use case may reflect that.
Jun 09
parent Eric P626 <ericp lariennalibrary.com> writes:
On Sunday, 9 June 2024 at 13:20:09 UTC, Joseph Rushton Wakeling 
wrote:
 On Saturday, 8 June 2024 at 16:09:04 UTC, monkyyy wrote:
 rng is an optional parameter, `uniform(0,100).writeln;` alone 
 works; the docs not telling you that is really bad
The docs do tell you that `rng` is an optional parameter of
I don't need anything fancy. Most of the time, it's for video games, so I want to make sure the numbers are always shuffled. Here it's for maze generation, so I wan each maze to be unique. Eventually, I would like to use a fixed seed generator, so that I can generate the same maze over and over again if necessary. I guess, in that case, I could create a generator. I found the the simplest way to implement this is not to define any seed or generator and simply call: ~~~ uniform(0,2) ~~~ with the range you want. It was a bit counter intuitive because most languages have a ```rand()``` function. But I prefer specifying a range. Thanks again.
Jun 09
prev sibling next sibling parent reply drug007 <drug2004 bk.ru> writes:
On 08.06.2024 16:19, Eric P626 wrote:
 I managed to create a random number generator using the following code:
 
 ~~~
 auto rng = Random(42);
 //....
 uniform(0,10,rng);
 ~~~
 
 Now I want to seed the generator using system time. I looked at Date & 
 time functions/classes and systime functions/classes. The problem is 
 that they all require a time zone. But I don't need a time zone since 
 there is no time zone. I just want the number of seconds elapsed since 
 jan 1st 1970. In other words, the internal system clock value.
 
```d import std; void main() { { auto rng = Random(42); auto result = generate!(() => uniform(0, 10, rng))().take(7); // the same random numbers sequence assert (result.equal([2, 7, 6, 4, 6, 5, 0])); } { const seed = castFrom!long.to!uint(Clock.currStdTime); auto rng = Random(seed); auto result = generate!(() => uniform(0, 10, rng))().take(7); // new random numbers sequence every time result.writeln; } } ```
Jun 08
next sibling parent Salih Dincer <salihdb hotmail.com> writes:
On Saturday, 8 June 2024 at 18:25:20 UTC, drug007 wrote:
 
 ```d
     {
         const seed = castFrom!long.to!uint(Clock.currStdTime);
         auto rng = Random(seed);
         auto result = generate!(() => uniform(0, 10, 
 rng))().take(7);
 	// new random numbers sequence every time
         result.writeln;
     }
 ```
If UnixTime is desired, it is sufficient to have currTime.toUnixTime instead of currStdTime. It will not reset until January 19, 2038. ```d auto seed = to!uint(Clock.currTime.toUnixTime); ``` SDB 79
Jun 08
prev sibling parent reply Eric P626 <ericp lariennalibrary.com> writes:
On Saturday, 8 June 2024 at 18:25:20 UTC, drug007 wrote:
 ~~~
     {
         const seed = castFrom!long.to!uint(Clock.currStdTime);
         auto rng = Random(seed);
         auto result = generate!(() => uniform(0, 10, 
 rng))().take(7);
 	// new random numbers sequence every time
         result.writeln;
     }
 }
 ~~~
I managed to use this piece of code and it worked. ~~~ uint seed = castFrom!long.to!uint(Clock.currStdTime); auto rng = Random(seed); ~~~ I am not exactly sure what the exclamation points stand for in the first line of code. Probably, defining a type to class ```castFrom``` and function ```to```. But I get the idea that it just cast long to uint since ```Random``` requires an unsigned int. I assume from this line of code that C casting like ```(uint)varname``` would not work.
Jun 09
parent reply drug007 <drug2004 bk.ru> writes:
On 09.06.2024 16:37, Eric P626 wrote:
 On Saturday, 8 June 2024 at 18:25:20 UTC, drug007 wrote:
 ~~~
     {
         const seed = castFrom!long.to!uint(Clock.currStdTime);
         auto rng = Random(seed);
         auto result = generate!(() => uniform(0, 10, rng))().take(7);
     // new random numbers sequence every time
         result.writeln;
     }
 }
 ~~~
I managed to use this piece of code and it worked. ~~~ uint seed = castFrom!long.to!uint(Clock.currStdTime); auto rng = Random(seed); ~~~ I am not exactly sure what the exclamation points stand for in the first line of code. Probably, defining a type to class ```castFrom``` and function ```to```. But I get the idea that it just cast long to uint since ```Random``` requires an unsigned int > I assume from this line of code that C casting like ```(uint)varname``` would not work.
`CastFrom!long` is a template instantiation. The instantiated template converts from `long` to `uint`. It is useful in meta-programming but here you can safely use other forms like c style cast: ```d const seed = cast(uint) Clock.currStdTime; ``` or ``` const seed = to!uint(Clock.currStdTime & 0xFFFF); ``` here we need to use the `0xFFFF` mask, because `to!uint` throws a conversion positive overflow when the value of `Clock.currStdTime` exceeds the value of `uint.max`. But I don't like this variant and I don't recommend it.
Jun 09
parent Eric P626 <ericp lariennalibrary.com> writes:
On Sunday, 9 June 2024 at 23:31:47 UTC, drug007 wrote:
 ```d
     const seed = cast(uint) Clock.currStdTime;
 ```
Casting like this looks nice. It fits my type of thinking.
Jun 10
prev sibling next sibling parent Joseph Rushton Wakeling <joseph.wakeling webdrake.net> writes:
On Saturday, 8 June 2024 at 13:19:30 UTC, Eric P626 wrote:
 Now I want to seed the generator using system time.
Just to be clear, do you _specifically_ want to use the system time, or are you aiming to use the system time to generate different seeds for each run? If the latter you might prefer to use the `unpredictableSeed()` function from `std.random`: https://dlang.org/phobos/std_random.html#unpredictableSeed That may use a variety of different methods to generate the seed, depending on the capabilities of the system, but one of the fallback options (which is actually the original implementation IIRC) uses a pseudo-random transformation of values derived from the thread ID, the process ID, and the current time in ticks as reported by the system's monotonic clock. A benefit of that is that it means that different threads in the same app, and different apps, are guaranteed to get _different_ random seeds if started at the same time. The preferred alternatives to that use different mechanisms, but should all have the same desired property of guaranteeing that different threads get different random seeds. But FWIW, if current time in ticks is valid for your use-case, `cast(ulong) MonoTime.currTime.ticks` should do. Hope that helps! Best wishes, -- Joe
Jun 09
prev sibling parent Steven Schveighoffer <schveiguy gmail.com> writes:
On Saturday, 8 June 2024 at 13:19:30 UTC, Eric P626 wrote:
 I managed to create a random number generator using the 
 following code:

 ~~~
 auto rng = Random(42);
 //....
 uniform(0,10,rng);
 ~~~

 Now I want to seed the generator using system time. I looked at 
 Date & time functions/classes and systime functions/classes. 
 The problem is that they all require a time zone. But I don't 
 need a time zone since there is no time zone. I just want the 
 number of seconds elapsed since jan 1st 1970. In other words, 
 the internal system clock value.
I'm not sure if anyone said it explicitly, but `uniform(0, 10)` uses the default RNG [`rndGen`](https://dlang.org/phobos/std_random.html#rndGen), which is already properly seeded with an unpredictable seed: Global random number generator used by various functions in this module whenever no generator is specified. It is allocated per-thread and initialized to an unpredictable value for each thread. So unless you are explicitly doing something like saving the seed for future playback, I'd leave it off. -Steve
Jun 10