www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Is continuously seeding a random number generator performance

reply "Jeroen Bollen" <jbinero gmail.com> writes:
D provides a set of Random Number Generators in std.random. I am 
writing an application which would create a 2D map of noise. To 
do this though, I'll have to calculate the same random numbers 
over and over again. (I cannot store them, that'd take a horrible 
amount of RAM. )

Is it good to re-seed a generator for every coordinate, will this 
be performance intensive? Is there maybe way to easily implement 
Generator.at(uint x) in D?
Jan 02 2014
next sibling parent "monarch_dodra" <monarchdodra gmail.com> writes:
On Thursday, 2 January 2014 at 20:38:10 UTC, Jeroen Bollen wrote:
 D provides a set of Random Number Generators in std.random. I 
 am writing an application which would create a 2D map of noise. 
 To do this though, I'll have to calculate the same random 
 numbers over and over again. (I cannot store them, that'd take 
 a horrible amount of RAM. )
AFAIK, the costliest part of seeding a generator is generating the "random seed". After that, once you have the seed, it shouldn't be too expensive. That said, it depends on each generator of course. In any case, performance wise, it shouldn't be too expensive (if you use the same seed). That said, it sounds like what you want to do though is to simply "save" the range. PRNG's have the "save" primitive you can use. Just use that.
 Is it good to re-seed a generator for every coordinate, will 
 this be performance intensive? Is there maybe way to easily 
 implement Generator.at(uint x) in D?
*This* comment is confusing me. What do you mean by "re-seed"? You mean a random seed? Once seeded, you shouldn't have to re-seed a PRNG: It'll generate random numbers forever. Or do you mean "re-seed" in the sense "reset"? Because if you do that, then you'll have the same numbers for each coordinates...?
Jan 02 2014
prev sibling next sibling parent reply "Frustrated" <c1514843 drdrb.com> writes:
On Thursday, 2 January 2014 at 20:38:10 UTC, Jeroen Bollen wrote:
 D provides a set of Random Number Generators in std.random. I 
 am writing an application which would create a 2D map of noise. 
 To do this though, I'll have to calculate the same random 
 numbers over and over again. (I cannot store them, that'd take 
 a horrible amount of RAM. )

 Is it good to re-seed a generator for every coordinate, will 
 this be performance intensive? Is there maybe way to easily 
 implement Generator.at(uint x) in D?
I believe you fail to understand how the RNG's work. You supply a seed(a value) and they generate a deterministic sequence off that value that is pseudo-random relative to each other.. If you re-seed the generator every time you are not doing anything but wasting cycles since the new element will be random, but the same as using the next element in the sequence in the first case. e.g., seed(k); for(i = 1..10) print(rnd(i)); and for(i = 1..10) { seed(time); print(rnd(i)); } will both produce random sequences of numbers(and random sequences of numbers are "identically random". The nice thing about the first case is that you can save the seed once time and produce the exact same sequence... which would save you memory. In the second case you would have to record every seed to recover the sequence.
Jan 02 2014
next sibling parent reply "Chris Cain" <clcain uncg.edu> writes:
On Thursday, 2 January 2014 at 22:01:01 UTC, monarch_dodra wrote:
 *This* comment is confusing me. What do you mean by "re-seed"? 
 You mean a random seed? Once seeded, you shouldn't have to 
 re-seed a PRNG: It'll generate random numbers forever. Or do 
 you mean "re-seed" in the sense "reset"? Because if you do 
 that, then you'll have the same numbers for each coordinates...?
And... On Friday, 3 January 2014 at 01:01:21 UTC, Frustrated wrote:
 If you re-seed the generator every time you are not doing 
 anything but wasting cycles since the new element will be 
 random, but the same as using the next element in the sequence 
 in the first case.

 ...snip..

 The nice thing about the first case is that you can save the 
 seed once time and produce the exact same sequence... which 
 would save you memory. In the second case you would have to 
 record every seed to recover the sequence.
I think you both misunderstand what he wants to do. He's generating a 2D noise map, apparently of arbitrarily large size. Let's say his 2D map was 4 billion x 4 billion elements long and each element needs to have a range of 0-255 (so, 1 byte). Obviously storing such a large noise map in memory is not feasible. But if you were able to instead take an x and y coordinate and regenerate the information when it becomes necessary, then storing all of those positions would be unnecessary. Instead of storing 16,000,000,000,000,000,000 bytes (completely infeasible), you could store the bounds of map (8 bytes) and generate the part of the map you need at any one moment in time (which may need perhaps a ~2000x2000 portion or 4MB at a time, depending on what he's doing). So, it sounds like the OP is using the x and y coords for a seed to generate a single number and he was curious to whether it costs too much to reseed like this for every point. To the OP: FWIW, I'm under the impression that this is a fairly common strategy, but usually when I've seen this used more than one number is generated at a time. You can still do this, in this case. For example, divide x by 10 and generate 10 elements (column wise) in the noise map each time and it reduces the number of reseeds by a factor of 10. Some effort might be wasted, but as long as you need a decent chunk of the noise map at any one point in time, this should work out pretty well in practice. My biggest concern with this approach is that you must take care that your usage of seeding with x and y coordinates does not cause repeated elements to occur. For instance, using `Random rng = Random(x + y);` will _not_ work properly (unless you want strange mirroring down the diagonal in your noise map). There's numerous landmines to avoid when doing something like this. Some approaches may not be perfect, but depending on what you're doing they may be sufficient, however.
Jan 02 2014
parent reply "monarch_dodra" <monarchdodra gmail.com> writes:
On Friday, 3 January 2014 at 01:43:09 UTC, Chris Cain wrote:
 So, it sounds like the OP is using the x and y coords for a 
 seed to generate a single number and he was curious to whether 
 it costs too much to reseed like this for every point.

 FWIW, I'm under the impression that this is a fairly common 
 strategy, but usually when I've seen this used more than one 
 number is generated at a time.
I *thought* he wanted to do something like that, but was surprised by the fact he wanted to reseed *per* element...
 You can still do this, in this case. For example, divide x by 
 10 and generate 10 elements (column wise) in the noise map each 
 time and it reduces the number of reseeds by a factor of 10. 
 Some effort might be wasted, but as long as you need a decent 
 chunk of the noise map at any one point in time, this should 
 work out pretty well in practice.

 My biggest concern with this approach is that you must take 
 care that your usage of seeding with x and y coordinates does 
 not cause repeated elements to occur. For instance, using 
 `Random rng = Random(x + y);` will _not_ work properly (unless 
 you want strange mirroring down the diagonal in your noise 
 map). There's numerous landmines to avoid when doing something 
 like this. Some approaches may not be perfect, but depending on 
 what you're doing they may be sufficient, however.
The approach I'd take here is to eagerly generate a "uint[X / 1000][Y / 1000]" grid, that holds randomly generated numbers, to be used as seeds for individual 1000*1000 blocks of the noise map. I don't know how good that is though in terms of correlation...? Or, even better, to create a single generator of type "Gen", and store a "Gen[X / 1000][Y / 1000]": EG: the generator, with a "checkpoint" every 1_000_000 elements. This should reduce correlation down to 0. AFAIK, all generators above the "linear congruential generator" have a period above 10^12, so this approach should be fine. The only issue with such an approach might be the size of the PRNG's themselves: XOrShift, for example, is only a few bytes big, so that's fine. But MT is about 700B, which is a hefty amount to chug along.
Jan 03 2014
parent reply "Jeroen Bollen" <jbinero gmail.com> writes:
On Friday, 3 January 2014 at 10:06:27 UTC, monarch_dodra wrote:
 On Friday, 3 January 2014 at 01:43:09 UTC, Chris Cain wrote:
 So, it sounds like the OP is using the x and y coords for a 
 seed to generate a single number and he was curious to whether 
 it costs too much to reseed like this for every point.

 FWIW, I'm under the impression that this is a fairly common 
 strategy, but usually when I've seen this used more than one 
 number is generated at a time.
I *thought* he wanted to do something like that, but was surprised by the fact he wanted to reseed *per* element...
 You can still do this, in this case. For example, divide x by 
 10 and generate 10 elements (column wise) in the noise map 
 each time and it reduces the number of reseeds by a factor of 
 10. Some effort might be wasted, but as long as you need a 
 decent chunk of the noise map at any one point in time, this 
 should work out pretty well in practice.

 My biggest concern with this approach is that you must take 
 care that your usage of seeding with x and y coordinates does 
 not cause repeated elements to occur. For instance, using 
 `Random rng = Random(x + y);` will _not_ work properly (unless 
 you want strange mirroring down the diagonal in your noise 
 map). There's numerous landmines to avoid when doing something 
 like this. Some approaches may not be perfect, but depending 
 on what you're doing they may be sufficient, however.
The approach I'd take here is to eagerly generate a "uint[X / 1000][Y / 1000]" grid, that holds randomly generated numbers, to be used as seeds for individual 1000*1000 blocks of the noise map. I don't know how good that is though in terms of correlation...? Or, even better, to create a single generator of type "Gen", and store a "Gen[X / 1000][Y / 1000]": EG: the generator, with a "checkpoint" every 1_000_000 elements. This should reduce correlation down to 0. AFAIK, all generators above the "linear congruential generator" have a period above 10^12, so this approach should be fine. The only issue with such an approach might be the size of the PRNG's themselves: XOrShift, for example, is only a few bytes big, so that's fine. But MT is about 700B, which is a hefty amount to chug along.
I already considered this, but the problem is, I need to smoothen the noise, and to do that I need all surrounding 'checkpoints' too. This means that it'll have to load in 5 at a time.
Jan 03 2014
parent reply "monarch_dodra" <monarchdodra gmail.com> writes:
On Friday, 3 January 2014 at 13:30:09 UTC, Jeroen Bollen wrote:
 I already considered this, but the problem is, I need to 
 smoothen the noise, and to do that I need all surrounding 
 'checkpoints' too. This means that it'll have to load in 5 at a 
 time.
I don't see that as a problem. Just because you can load sub-regions at once, doesn't mean you are limited to only loading one at a time.
Jan 03 2014
parent reply "Jeroen Bollen" <jbinero gmail.com> writes:
On Friday, 3 January 2014 at 13:42:19 UTC, monarch_dodra wrote:
 On Friday, 3 January 2014 at 13:30:09 UTC, Jeroen Bollen wrote:
 I already considered this, but the problem is, I need to 
 smoothen the noise, and to do that I need all surrounding 
 'checkpoints' too. This means that it'll have to load in 5 at 
 a time.
I don't see that as a problem. Just because you can load sub-regions at once, doesn't mean you are limited to only loading one at a time.
That still means that out of 5 million pixels loaded, only 1 million 4 thousand will be used. I guess I can recycle them though.
Jan 03 2014
parent reply "monarch_dodra" <monarchdodra gmail.com> writes:
On Friday, 3 January 2014 at 17:41:48 UTC, Jeroen Bollen wrote:
 On Friday, 3 January 2014 at 13:42:19 UTC, monarch_dodra wrote:
 On Friday, 3 January 2014 at 13:30:09 UTC, Jeroen Bollen wrote:
 I already considered this, but the problem is, I need to 
 smoothen the noise, and to do that I need all surrounding 
 'checkpoints' too. This means that it'll have to load in 5 at 
 a time.
I don't see that as a problem. Just because you can load sub-regions at once, doesn't mean you are limited to only loading one at a time.
That still means that out of 5 million pixels loaded, only 1 million 4 thousand will be used. I guess I can recycle them though.
You could also do a "subdivision" approach: First, a table that contains seeds for 1Kx1K blocks... However each seed is designed to seed 10000 new seeds, to generate 10x10 blocks (for example). This way, you can first load your big 1Kx1K block, and then 400 10x10 blocks. Seems reasonable to me. I don't know exactly how big your data is, so your mileage may vary. Depending on your algorithm, you may have to adapt the numbers, or even amount of subdivisions.
Jan 03 2014
parent reply "Jeroen Bollen" <jbinero gmail.com> writes:
On Friday, 3 January 2014 at 18:23:23 UTC, monarch_dodra wrote:
 On Friday, 3 January 2014 at 17:41:48 UTC, Jeroen Bollen wrote:
 On Friday, 3 January 2014 at 13:42:19 UTC, monarch_dodra wrote:
 On Friday, 3 January 2014 at 13:30:09 UTC, Jeroen Bollen 
 wrote:
 I already considered this, but the problem is, I need to 
 smoothen the noise, and to do that I need all surrounding 
 'checkpoints' too. This means that it'll have to load in 5 
 at a time.
I don't see that as a problem. Just because you can load sub-regions at once, doesn't mean you are limited to only loading one at a time.
That still means that out of 5 million pixels loaded, only 1 million 4 thousand will be used. I guess I can recycle them though.
You could also do a "subdivision" approach: First, a table that contains seeds for 1Kx1K blocks... However each seed is designed to seed 10000 new seeds, to generate 10x10 blocks (for example). This way, you can first load your big 1Kx1K block, and then 400 10x10 blocks. Seems reasonable to me. I don't know exactly how big your data is, so your mileage may vary. Depending on your algorithm, you may have to adapt the numbers, or even amount of subdivisions.
What generator would be most fitting for this? The Documentation says the "MersenneTwisterEngine" is an 'overall' good one. I decided to go with blocks of 32*32, which all require to be filled with an unsigned byte.
Jan 03 2014
parent reply "Jeroen Bollen" <jbinero gmail.com> writes:
Also where is UIntType defined?
Jan 04 2014
parent reply "Jeroen Bollen" <jbinero gmail.com> writes:
On Saturday, 4 January 2014 at 20:16:31 UTC, Jeroen Bollen wrote:
 Also where is UIntType defined?
Alright, turns out it was just a template. One more question though, I have my Engine set to have 'ulong' as a seed through the template, which means that it'll also return 'ulong' as a result. Is there a way to have it take 'ulong' as a seed, and output 'ubyte'? Divisions for every result would be expensive, and shifting the output wouldn't return a uniform distribution.
Jan 04 2014
parent reply "bearophile" <bearophileHUGS lycos.com> writes:
Jeroen Bollen:

 Divisions for every result would be expensive, and shifting
 the output wouldn't return a uniform distribution.
If the ulong is uniform, then every of its ubytes is uniform. So "& ubyte.max" could suffice. If that's not good enough for you, then you can xor together the eight ubytes of the ulong with some masking & shifts :-) Bye, bearophile
Jan 04 2014
parent "Jeroen Bollen" <jbinero gmail.com> writes:
On Saturday, 4 January 2014 at 21:48:02 UTC, bearophile wrote:
 Jeroen Bollen:

 Divisions for every result would be expensive, and shifting
 the output wouldn't return a uniform distribution.
If the ulong is uniform, then every of its ubytes is uniform. So "& ubyte.max" could suffice. If that's not good enough for you, then you can xor together the eight ubytes of the ulong with some masking & shifts :-) Bye, bearophile
Oops yeah sorry, I was thinking there is more chance to get a small number and thus more chance for there being zeros up front, but actually there is as much chance due there being as many numbers started with 1 as with 0. Thanks for the help. :D
Jan 04 2014
prev sibling parent reply "Andrea Fontana" <nospam example.com> writes:
On Friday, 3 January 2014 at 01:01:21 UTC, Frustrated wrote:
 On Thursday, 2 January 2014 at 20:38:10 UTC, Jeroen Bollen 
 wrote:
 [...]
 e.g.,

 seed(k);
 for(i = 1..10)
 print(rnd(i));

 and

 for(i = 1..10)
 {
 seed(time);
 print(rnd(i));
 }

 will both produce random sequences of numbers(and random 
 sequences of numbers are "identically random".
 [...]
The second example is error-prone. If "time" var doesn't change between cycle, it's not random at all.
Jan 03 2014
parent "Frustrated" <c1514843 drdrb.com> writes:
On Friday, 3 January 2014 at 13:39:41 UTC, Andrea Fontana wrote:
 On Friday, 3 January 2014 at 01:01:21 UTC, Frustrated wrote:
 On Thursday, 2 January 2014 at 20:38:10 UTC, Jeroen Bollen 
 wrote:
 [...]
 e.g.,

 seed(k);
 for(i = 1..10)
 print(rnd(i));

 and

 for(i = 1..10)
 {
 seed(time);
 print(rnd(i));
 }

 will both produce random sequences of numbers(and random 
 sequences of numbers are "identically random".
 [...]
The second example is error-prone. If "time" var doesn't change between cycle, it's not random at all.
Wrong, in this example I'm using rnd(i) as having a seed i. Obviously, I'm not using i as an interval. i still changes per iteration of the loop so rnd still changes. (if I did not seed the rnd I would not have used rnd(i) but rnd;) i.e., for(i = 1..10) { seed(time); print(rnd(i)); } and for(i = 1..10) { seed(time); print(rnd); } are different but my example could easily have been written as for(i = 1..10) { seed(time+i); print(rnd); } which may be more obvious. The point of writing it the first way was to try to make it more clear about actually changing the seed vs the ith random number. (the seed changes the sequence of random numbers to another sequence but rnd returns the ith value in the sequence which is ultimately cyclical)
Jan 15 2014
prev sibling parent reply "marcpmichel" <marc.p.michel gmail.com> writes:
On Thursday, 2 January 2014 at 20:38:10 UTC, Jeroen Bollen wrote:
 Is it good to re-seed a generator for every coordinate, will 
 this be performance intensive? Is there maybe way to easily 
 implement Generator.at(uint x) in D?
http://www.valion-game.com/337/noise-functions-to-generate-landscapes/ I successfully implemented a D version of the above for my toy voxel engine project. I will be happy to share it ( it's currently not uploaded anywhere ).
Jan 13 2014
parent reply "Jeroen Bollen" <jbinero gmail.com> writes:
How do you correctly create a MersenneTwisterEngine with a ulong 
as seed?
Jan 15 2014
next sibling parent reply "Frustrated" <c1514843 drdrb.com> writes:
On Wednesday, 15 January 2014 at 21:00:57 UTC, Jeroen Bollen 
wrote:
 How do you correctly create a MersenneTwisterEngine with a 
 ulong as seed?
If you are trying to create a very large 2D noise generator, this is how you do it, and you can any degree of smoothness you want: Create a 2D RNG. e.g., RND2D(x,y) { seed(S + x + N*y); return rand; } You could use this to generate your whole map very predictably up to the seed length(at some point it will repeat because of the finite size of the seed). If you have any degree of smoothness you do not want to use this per point unless you do want to have some "noise" which could be controlled by weighting the RND2D function so intergrid points are not so random: RND2D(x,y, xS, yS) { s = RND2D(x,y) sm1m1 = RND2D((int)(x/xS) - 1, (int)(y / yS - 1)); sm1m1 = RND2D((int)(x/xS) - 1, (int)(y / yS + 1)); ... return interpolate(s, x, y, sm1m1, sm1p1, ...); } where interpolate returns the modified seed that is partially based on the seed at the point x,y and partially an interpolation value between the sub grid points. Anyways, now that you have your RND2D you don't ever have to pre-generate your noise. Obviously it is more computationally expensive though. I guess this was the function you were looking for before if I now understand what you are trying to do?
Jan 15 2014
parent "Jeroen Bollen" <jbinero gmail.com> writes:
On Wednesday, 15 January 2014 at 21:23:03 UTC, Frustrated wrote:
 Anyways, now that you have your RND2D you don't ever have to 
 pre-generate your noise. Obviously it is more computationally 
 expensive though.
Thing is, the image is finite so I figured it'd be best to pre-generate a set of seeds, and then when I need a certain chunk of pixels simply quickly generate that one, like already suggested in this topic.
Jan 16 2014
prev sibling parent reply "Jeroen Bollen" <jbinero gmail.com> writes:
On Wednesday, 15 January 2014 at 21:00:57 UTC, Jeroen Bollen 
wrote:
 How do you correctly create a MersenneTwisterEngine with a 
 ulong as seed?
This question still isn't answered by the way.
Jan 17 2014
parent reply "Jeroen Bollen" <jbinero gmail.com> writes:
On Friday, 17 January 2014 at 19:00:29 UTC, Jeroen Bollen wrote:
 On Wednesday, 15 January 2014 at 21:00:57 UTC, Jeroen Bollen 
 wrote:
 How do you correctly create a MersenneTwisterEngine with a 
 ulong as seed?
This question still isn't answered by the way.
Come on, surely someone knows how to. I've already tried the obvious, but it doesn't work. MersenneTwisterEngine!(ulong, 32, 624, 397, 31, 0x9908b0df, 11, 7, 0x9d2c5680, 15, 0xefc60000, 18) rndEngine; rndEngine = MersenneTwisterEngine(seed); "shift by 32 is outside the range 0..31" "static assert (false && 4022730752LU <= 0LU) is false" "instantiated from here: MersenneTwisterEngine!(ulong, 32, 624, 397, 31, 2567483615u, 11, 7, 2636928640u, 15, 4022730752u, 18)"
Jan 21 2014
parent reply "monarch_dodra" <monarchdodra gmail.com> writes:
On Tuesday, 21 January 2014 at 17:13:39 UTC, Jeroen Bollen wrote:
 On Friday, 17 January 2014 at 19:00:29 UTC, Jeroen Bollen wrote:
 On Wednesday, 15 January 2014 at 21:00:57 UTC, Jeroen Bollen 
 wrote:
 How do you correctly create a MersenneTwisterEngine with a 
 ulong as seed?
This question still isn't answered by the way.
Come on, surely someone knows how to. I've already tried the obvious, but it doesn't work. MersenneTwisterEngine!(ulong, 32, 624, 397, 31, 0x9908b0df, 11, 7, 0x9d2c5680, 15, 0xefc60000, 18) rndEngine; rndEngine = MersenneTwisterEngine(seed); "shift by 32 is outside the range 0..31" "static assert (false && 4022730752LU <= 0LU) is false" "instantiated from here: MersenneTwisterEngine!(ulong, 32, 624, 397, 31, 2567483615u, 11, 7, 2636928640u, 15, 4022730752u, 18)"
Is that your actual code? "MersenneTwisterEngine(seed)" is not valid code, you have to provide the template arguments. In any case, that's a bug. Please file a report for it, and I'll give it a full fix. For a local fix, you can replace the incriminating line (random.d:550): /// Largest generated value. enum UIntType max = w == UIntType.sizeof * 8 ? UIntType.max : (1u << w) - 1; By: /// Largest generated value. enum UIntType max = UIntType.max >> (UIntType.sizeof * 8 - w); I think that's all that's required. PS: If you want to generate longs, you also need to set the "w" variable (wordSize) from 32 to 64, or you'll still just be generating 32 bits worth of randomness. I also recommend you use an alias (and alignment), such as: alias Mt19937UL = MersenneTwisterEngine!(ulong, 64, 624, 397, 31, 0x9908b0df, 11, 7, 0x9d2c5680, 15, 0xefc60000, 18); auto rndEngine = Mt19937UL(seed);
Jan 21 2014
parent reply "Jeroen Bollen" <jbinero gmail.com> writes:
On Tuesday, 21 January 2014 at 17:51:44 UTC, monarch_dodra wrote:
 On Tuesday, 21 January 2014 at 17:13:39 UTC, Jeroen Bollen 
 wrote:
 On Friday, 17 January 2014 at 19:00:29 UTC, Jeroen Bollen 
 wrote:
 On Wednesday, 15 January 2014 at 21:00:57 UTC, Jeroen Bollen 
 wrote:
 How do you correctly create a MersenneTwisterEngine with a 
 ulong as seed?
This question still isn't answered by the way.
Come on, surely someone knows how to. I've already tried the obvious, but it doesn't work. MersenneTwisterEngine!(ulong, 32, 624, 397, 31, 0x9908b0df, 11, 7, 0x9d2c5680, 15, 0xefc60000, 18) rndEngine; rndEngine = MersenneTwisterEngine(seed); "shift by 32 is outside the range 0..31" "static assert (false && 4022730752LU <= 0LU) is false" "instantiated from here: MersenneTwisterEngine!(ulong, 32, 624, 397, 31, 2567483615u, 11, 7, 2636928640u, 15, 4022730752u, 18)"
Is that your actual code? "MersenneTwisterEngine(seed)" is not valid code, you have to provide the template arguments. In any case, that's a bug. Please file a report for it, and I'll give it a full fix. For a local fix, you can replace the incriminating line (random.d:550): /// Largest generated value. enum UIntType max = w == UIntType.sizeof * 8 ? UIntType.max : (1u << w) - 1; By: /// Largest generated value. enum UIntType max = UIntType.max >> (UIntType.sizeof * 8 - w); I think that's all that's required. PS: If you want to generate longs, you also need to set the "w" variable (wordSize) from 32 to 64, or you'll still just be generating 32 bits worth of randomness. I also recommend you use an alias (and alignment), such as: alias Mt19937UL = MersenneTwisterEngine!(ulong, 64, 624, 397, 31, 0x9908b0df, 11, 7, 0x9d2c5680, 15, 0xefc60000, 18); auto rndEngine = Mt19937UL(seed);
That is my actual code.
Jan 21 2014
parent reply "Jeroen Bollen" <jbinero gmail.com> writes:
On Tuesday, 21 January 2014 at 17:51:44 UTC, monarch_dodra
 Is that your actual code? "MersenneTwisterEngine(seed)" is not 
 valid code, you have to provide the template arguments.
I meant to answer to this by the way, sorry. (in need of edit feature :P )
Jan 21 2014
parent "monarch_dodra" <monarchdodra gmail.com> writes:
On Tuesday, 21 January 2014 at 19:00:32 UTC, Jeroen Bollen wrote:
 On Tuesday, 21 January 2014 at 17:51:44 UTC, monarch_dodra
 Is that your actual code? "MersenneTwisterEngine(seed)" is not 
 valid code, you have to provide the template arguments.
I meant to answer to this by the way, sorry. (in need of edit feature :P )
https://d.puremagic.com/issues/show_bug.cgi?id=11960 Now resolved fixed.
Jan 30 2014