Chris Gordon-Smith wrote:
[color=blue]
> Kai-Uwe Bux wrote:
>[color=green]
>> Chris Gordon-Smith wrote:
>> [snip][color=darkred]
>>> How about this as an alternative:-
>>>
>>> Create a class that has an internal cache of random numbers. Initialise
>>> the cache at construction time by calling rand() repeatedly. Then use a
>>> class method to supply random numbers as and when they are required.
>>> When the last random number in the cache is reached, re-initialise the
>>> cache using the last random number in the cache as the seed for
>>> srand(seed).
>>>
>>> I think that this approach should enable my simulation code to be
>>> isolated from the effects of other parts of the program (eg library
>>> code) calling rand(), and it does not need a new random number generator
>>> to be implemented.[/color]
>>
>> The rule of thumb is to seed once and only once.
>>
>> Therefore, I would be worried about the quality of the RNG resulting from
>> your method. Let me illustrate this using the period as a rough measure
>> of quality. Assuming that your library comes with a good RNG, its
>> internal state is very likely much more than just some 32 bits from a
>> seed. Since the internal state is finite, the sequence of random number
>> eventually will cycle. The internal state can be considered as the
>> current position within that cycle. What you suggest is to reseed
>> periodically. Now, you construct a new internal state from the 32-bit
>> seed (I am assuming here that unsigned long is 32 bits, but in any case
>> it is probably much less than the internal state of your libraries RNG).
>> That means that at the reseeding points not all possible positions in the
>> cycle are possible targets for your jump. Thus, your operation will very
>> likely reduce the period of the RNG quite a bit. I would guess you ca get
>> at most a period of length:
>>
>> cache_size * 2^bitlength(seed)
>>
>> This period is very likely much smaller than the original period. And,
>> the actual period you get could be much smaller than the upper bound
>> given above.
>>
>> Also, keep in mind D. Knuth's warning: "... random number should not be
>> generated with a method chosen at random. Some theory should be used."
>> Very likely, the RNG in your library was designed using some reasonable
>> mathematics to make sure that the results are decent. Your proposed
>> method will break the theory and can result in poor quality. My
>> understanding is that examples of such side-effects abound.
>>
>> For more qualified answers, you might try:
>>
>> sci.crypt.random-numbers
>>
>> or some other more appropriate source.
>>
>>
>> Best
>>
>> Kai-Uwe Bux
>>
>> ps.: I still think you would be better off looking into boost.[/color]
>
> Thanks for this comprehensive answer. Despite my reluctance to start using
> a new library, I suspect that you and Cy Edmunds are probably right. If
> the cycle time is at the theoretical maximum you mention above that is
> probably good enough for my purposes. The worry is that it could perhaps
> be much less.[/color]
I've now implemented my own version of rand(), based on the idea of holding
a cache of 10,000 random numbers as described above.
I've tested it by calling it one thousand million times and writing out the
value of the random number taken from the cache whenever it lies in the
range 100000000 to 100000050.
I have included the output below. As you can see, the sequence repeats
itself four times, which means that the sequence repeats roughly every 250
million calls to my random function.
This is good enough for my purposes.
Current_Seq_Val = 100000028
Current_Seq_Val = 100000026
Current_Seq_Val = 100000038
Current_Seq_Val = 100000034
Current_Seq_Val = 100000003
Current_Seq_Val = 100000003
Current_Seq_Val = 100000028
Current_Seq_Val = 100000026
Current_Seq_Val = 100000038
Current_Seq_Val = 100000034
Current_Seq_Val = 100000003
Current_Seq_Val = 100000003
Current_Seq_Val = 100000028
Current_Seq_Val = 100000026
Current_Seq_Val = 100000038
Current_Seq_Val = 100000034
Current_Seq_Val = 100000003
Current_Seq_Val = 100000003
Current_Seq_Val = 100000028
Current_Seq_Val = 100000026
Current_Seq_Val = 100000038
Current_Seq_Val = 100000034
Current_Seq_Val = 100000003
Current_Seq_Val = 100000003
Current_Seq_Val = 100000028
Current_Seq_Val = 100000026
Current_Seq_Val = 100000038
--
Chris Gordon-Smith
London
http://www.simsoup.info