
AMDG Justinas V. D. wrote:
2010.04.09 23:46, Steven Watanabe rašė:
What exactly would this constructor do? It looks to me as though, if it jest set the initial state, then (for a one-dimensional generator) the effective result would be as though you xor'ed the initial state with the normal values of the generator.
This could used, for example, to initialize nextq to specific values that nextq would be unlikely to acquire otherwise. This scenario is admittedly a little bit contrived.
I guess my point was that since the sequences produced with different seeds will be strongly correlated, I don't see that it really matters. On the other hand, this behavior should make it pretty easy to show that you'll still get a low-discrepency sequence if you use a different seed, so at least it's safe. (I'm not absolutely certain that this is true, since I haven't worked through the math)
Finally, since the algorithm does a lot of bit-twiddling, would uint32_t be more appropriate than int?
You mean those typedefs of niederreiter_base2? Does not really matter. You could, for example instantiate template class niederreiter_base2 like this: niederreiter_base2<long, D, 1, (1 << 63)> gen; [1]
long is not guaranteed to be 64 bits (I know that it isn't on some systems). int is not guaranteed to be 32 bits, either. If you rely on the number of bits, then you should use uint32_t or int32_t.
Scaling down to the [0, 1]^D unit hypercube you would get more precision this way. (Of course, you could use uint32_t, too, and the typedef would look like this: niederreiter_base2<uint32_t, D, 1, (1U << 32) /*!*/> [2], but g++ complains about left shift count >= width of type, and spits out a warning in the instantiation site.) I think this option could be best left to users, who know what they want.
I do find it odd that you use (1 << 31) which is a negative number. I'd prefer it if you used <uint32_t, D, 1, ((uint32_t)1 << 31)>
Speaking of discard member function, I improved it in a way that makes more sense to me. According to the draft, discard(z) ought to behave as if z consecutive operator() invocations were executed. I refined this to be Dimension*z, so discard(z) now actually discards z consecutive s-dimensional vectors (s = Dimension). In 1-dimensional case the behaviour is the same as dictated by the standard.
I'm not sure that this is a good idea. If you want discard to operate on a whole vector, then shouldn't operator() return a whole vector too? I'm guessing that returning a vector from operator() would make using the generator more inconvenient. In Christ, Steven Watanabe