- Made the random number generator serializable

- Fixed a bug in the random number generator where setting the seed back to ""
   didn't result in the object going back to it's initial state.

--HG--
extra : convert_revision : svn%3Afdd8eb12-d10e-0410-9acb-85c331704f74/trunk%403746
This commit is contained in:
Davis King 2010-07-17 14:24:41 +00:00
parent fcf61e2f42
commit e324486483
3 changed files with 96 additions and 4 deletions

View File

@ -96,6 +96,24 @@ namespace dlib
result_type operator()();
friend void serialize(
const mersenne_twister& item,
std::ostream& out
)
{
serialize(item.x, out);
serialize(item.i, out);
}
friend void deserialize(
mersenne_twister& item,
std::istream& in
)
{
deserialize(item.x, in);
deserialize(item.i, in);
}
private:
void twist(int block);

View File

@ -8,6 +8,8 @@
#include "rand_kernel_abstract.h"
#include "mersenne_twister.h"
#include "../is_kind.h"
#include <iostream>
#include "../serialize.h"
namespace dlib
{
@ -61,12 +63,23 @@ namespace dlib
)
{
seed = value;
uint32 s = 0;
for (std::string::size_type i = 0; i < seed.size(); ++i)
// make sure we do the seeding so that using a seed of "" gives the same
// state as calling this->clear()
if (value.size() != 0)
{
s = (s*37) + static_cast<uint32>(seed[i]);
uint32 s = 0;
for (std::string::size_type i = 0; i < seed.size(); ++i)
{
s = (s*37) + static_cast<uint32>(seed[i]);
}
mt.seed(s);
}
mt.seed(s);
else
{
mt.seed();
}
// prime the generator a bit
for (int i = 0; i < 10000; ++i)
mt();
@ -98,6 +111,23 @@ namespace dlib
exchange(seed, item.seed);
}
friend void serialize(
const rand_kernel_1& item,
std::ostream& out
)
{
serialize(item.mt, out);
serialize(item.seed, out);
}
friend void deserialize(
rand_kernel_1& item,
std::istream& in
)
{
deserialize(item.mt, in);
deserialize(item.seed, in);
}
private:
mt19937 mt;

View File

@ -153,6 +153,50 @@ namespace
sout.str("");
// make sure the things can serialize right
{
r.clear();
r2.clear();
for (int i =0; i < 1000; ++i)
r.get_random_32bit_number();
ostringstream sout;
serialize(r, sout);
istringstream sin(sout.str());
deserialize(r2, sin);
for (int i =0; i < 1000; ++i)
{
DLIB_TEST(r.get_random_32bit_number() == r2.get_random_32bit_number());
}
}
// make sure calling clear() and set_seed("") do the same thing
{
r.clear();
r2.set_seed("");
rand r3;
DLIB_TEST(r.get_seed() == r2.get_seed());
DLIB_TEST(r.get_seed() == r3.get_seed());
for (int i =0; i < 1000; ++i)
{
const uint32 num1 = r.get_random_32bit_number();
const uint32 num2 = r2.get_random_32bit_number();
const uint32 num3 = r3.get_random_32bit_number();
DLIB_TEST( num1 == num2);
DLIB_TEST( num1 == num3);
}
}
}