410 lines
11 KiB
C++
410 lines
11 KiB
C++
|
// Copyright (C) 2006 Davis E. King (davis@dlib.net)
|
||
|
// License: Boost Software License See LICENSE.txt for the full license.
|
||
|
|
||
|
|
||
|
#include <sstream>
|
||
|
#include <string>
|
||
|
#include <cstdlib>
|
||
|
#include <ctime>
|
||
|
#include <cmath>
|
||
|
#include <dlib/rand.h>
|
||
|
#include <dlib/compress_stream.h>
|
||
|
#include <dlib/hash.h>
|
||
|
|
||
|
#include "tester.h"
|
||
|
|
||
|
namespace
|
||
|
{
|
||
|
|
||
|
using namespace test;
|
||
|
using namespace dlib;
|
||
|
using namespace std;
|
||
|
|
||
|
logger dlog("test.rand");
|
||
|
|
||
|
void check_bpp (
|
||
|
const std::string str
|
||
|
)
|
||
|
{
|
||
|
istringstream rdata;
|
||
|
ostringstream sout;
|
||
|
rdata.str(str);
|
||
|
double compressed_size;
|
||
|
compress_stream::kernel_1a cs1;
|
||
|
compress_stream::kernel_2a cs2;
|
||
|
|
||
|
compress_stream_kernel_1<
|
||
|
entropy_encoder_model_kernel_5<257,entropy_encoder::kernel_1a,4000000,4>,
|
||
|
entropy_decoder_model_kernel_5<257,entropy_decoder::kernel_1a,4000000,4>,
|
||
|
crc32::kernel_1a
|
||
|
> cs3;
|
||
|
|
||
|
|
||
|
print_spinner();
|
||
|
|
||
|
rdata.clear();
|
||
|
rdata.seekg(0);
|
||
|
sout.clear();
|
||
|
sout.str("");
|
||
|
cs1.compress(rdata,sout);
|
||
|
compressed_size = sout.str().size();
|
||
|
compressed_size *= 8;
|
||
|
compressed_size /= str.size();
|
||
|
DLIB_TEST_MSG(compressed_size >= 8, "order 0 bps: " << compressed_size);
|
||
|
dlog << LINFO << "order 0: " << compressed_size;
|
||
|
|
||
|
print_spinner();
|
||
|
|
||
|
rdata.clear();
|
||
|
rdata.seekg(0);
|
||
|
sout.clear();
|
||
|
sout.str("");
|
||
|
cs2.compress(rdata,sout);
|
||
|
compressed_size = sout.str().size();
|
||
|
compressed_size *= 8;
|
||
|
compressed_size /= str.size();
|
||
|
DLIB_TEST_MSG(compressed_size >= 8, "order 1 bps: " << compressed_size);
|
||
|
dlog << LINFO << "order 1: " << compressed_size;
|
||
|
|
||
|
print_spinner();
|
||
|
|
||
|
rdata.clear();
|
||
|
rdata.seekg(0);
|
||
|
sout.clear();
|
||
|
sout.str("");
|
||
|
cs3.compress(rdata,sout);
|
||
|
compressed_size = sout.str().size();
|
||
|
compressed_size *= 8;
|
||
|
compressed_size /= str.size();
|
||
|
DLIB_TEST_MSG(compressed_size >= 8, "order 4 bps: " << compressed_size);
|
||
|
dlog << LINFO << "order 4: " << compressed_size;
|
||
|
|
||
|
}
|
||
|
|
||
|
template <
|
||
|
typename rand
|
||
|
>
|
||
|
void rand_test (
|
||
|
)
|
||
|
/*!
|
||
|
requires
|
||
|
- rand is an implementation of rand/rand_kernel_abstract.h
|
||
|
is instantiated with int
|
||
|
ensures
|
||
|
- runs tests on rand for compliance with the specs
|
||
|
!*/
|
||
|
{
|
||
|
|
||
|
ostringstream seed;
|
||
|
seed << (unsigned int)time(0);
|
||
|
|
||
|
ostringstream sout;
|
||
|
|
||
|
|
||
|
rand r, r2;
|
||
|
DLIB_TEST(r.get_seed() == "");
|
||
|
r.set_seed(seed.str());
|
||
|
|
||
|
DLIB_TEST(r.get_seed() == seed.str());
|
||
|
r.clear();
|
||
|
DLIB_TEST(r.get_seed() == "");
|
||
|
swap(r,r2);
|
||
|
DLIB_TEST(r.get_seed() == "");
|
||
|
r.set_seed(seed.str());
|
||
|
DLIB_TEST(r.get_seed() == seed.str());
|
||
|
swap(r,r2);
|
||
|
DLIB_TEST(r2.get_seed() == seed.str());
|
||
|
DLIB_TEST(r.get_seed() == "");
|
||
|
swap(r,r2);
|
||
|
DLIB_TEST(r.get_seed() == seed.str());
|
||
|
DLIB_TEST(r2.get_seed() == "");
|
||
|
|
||
|
print_spinner();
|
||
|
unsigned long size = 100000;
|
||
|
for (unsigned long i = 0; i < size; ++i)
|
||
|
{
|
||
|
uint32 ch = r.get_random_32bit_number();
|
||
|
sout.write((char*)&ch,4);
|
||
|
}
|
||
|
|
||
|
check_bpp(sout.str());
|
||
|
sout.clear();
|
||
|
sout.str("");
|
||
|
|
||
|
print_spinner();
|
||
|
for (unsigned long i = 0; i < size; ++i)
|
||
|
{
|
||
|
uint16 ch = r.get_random_16bit_number();
|
||
|
sout.write((char*)&ch,2);
|
||
|
}
|
||
|
|
||
|
check_bpp(sout.str());
|
||
|
sout.clear();
|
||
|
sout.str("");
|
||
|
|
||
|
print_spinner();
|
||
|
for (unsigned long i = 0; i < size; ++i)
|
||
|
{
|
||
|
unsigned char ch = r.get_random_8bit_number();
|
||
|
sout.write((char*)&ch,1);
|
||
|
}
|
||
|
|
||
|
check_bpp(sout.str());
|
||
|
sout.clear();
|
||
|
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();
|
||
|
r.get_random_gaussian();
|
||
|
}
|
||
|
|
||
|
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());
|
||
|
DLIB_TEST(std::abs(r.get_random_gaussian() - r2.get_random_gaussian()) < 1e-14);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
// 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);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
template <typename rand_type>
|
||
|
void test_normal_numbers(
|
||
|
rand_type& rnd
|
||
|
)
|
||
|
{
|
||
|
print_spinner();
|
||
|
dlog << LINFO << "test normality";
|
||
|
double cnt1 = 0; // num <= -1.2
|
||
|
double cnt2 = 0; // num <= -0.5
|
||
|
double cnt3 = 0; // num <= 0
|
||
|
double cnt4 = 0; // num <= 0.5
|
||
|
double cnt5 = 0; // num <= 1.2
|
||
|
|
||
|
const unsigned long total = 1000000;
|
||
|
for (unsigned long i = 0; i < total; ++i)
|
||
|
{
|
||
|
const double r = rnd.get_random_gaussian();
|
||
|
if (r <= -1.2) cnt1 += 1;
|
||
|
if (r <= -0.5) cnt2 += 1;
|
||
|
if (r <= 0) cnt3 += 1;
|
||
|
if (r <= 0.5) cnt4 += 1;
|
||
|
if (r <= 1.2) cnt5 += 1;
|
||
|
}
|
||
|
|
||
|
cnt1 /= total;
|
||
|
cnt2 /= total;
|
||
|
cnt3 /= total;
|
||
|
cnt4 /= total;
|
||
|
cnt5 /= total;
|
||
|
|
||
|
dlog << LINFO << "cnt1: "<< cnt1;
|
||
|
dlog << LINFO << "cnt2: "<< cnt2;
|
||
|
dlog << LINFO << "cnt3: "<< cnt3;
|
||
|
dlog << LINFO << "cnt4: "<< cnt4;
|
||
|
dlog << LINFO << "cnt5: "<< cnt5;
|
||
|
|
||
|
DLIB_TEST(std::abs(cnt1 - 0.11507) < 0.001);
|
||
|
DLIB_TEST(std::abs(cnt2 - 0.30854) < 0.001);
|
||
|
DLIB_TEST(std::abs(cnt3 - 0.5) < 0.001);
|
||
|
DLIB_TEST(std::abs(cnt4 - 0.69146) < 0.001);
|
||
|
DLIB_TEST(std::abs(cnt5 - 0.88493) < 0.001);
|
||
|
|
||
|
}
|
||
|
|
||
|
void test_gaussian_random_hash()
|
||
|
{
|
||
|
print_spinner();
|
||
|
dlog << LINFO << "test_gaussian_random_hash()";
|
||
|
double cnt1 = 0; // num <= -1.2
|
||
|
double cnt2 = 0; // num <= -0.5
|
||
|
double cnt3 = 0; // num <= 0
|
||
|
double cnt4 = 0; // num <= 0.5
|
||
|
double cnt5 = 0; // num <= 1.2
|
||
|
|
||
|
const unsigned long total = 1000000;
|
||
|
for (unsigned long i = 0; i < total; ++i)
|
||
|
{
|
||
|
const double r = gaussian_random_hash(i,0,0);
|
||
|
if (r <= -1.2) cnt1 += 1;
|
||
|
if (r <= -0.5) cnt2 += 1;
|
||
|
if (r <= 0) cnt3 += 1;
|
||
|
if (r <= 0.5) cnt4 += 1;
|
||
|
if (r <= 1.2) cnt5 += 1;
|
||
|
}
|
||
|
for (unsigned long i = 0; i < total; ++i)
|
||
|
{
|
||
|
const double r = gaussian_random_hash(0,i,0);
|
||
|
if (r <= -1.2) cnt1 += 1;
|
||
|
if (r <= -0.5) cnt2 += 1;
|
||
|
if (r <= 0) cnt3 += 1;
|
||
|
if (r <= 0.5) cnt4 += 1;
|
||
|
if (r <= 1.2) cnt5 += 1;
|
||
|
}
|
||
|
for (unsigned long i = 0; i < total; ++i)
|
||
|
{
|
||
|
const double r = gaussian_random_hash(0,0,i);
|
||
|
if (r <= -1.2) cnt1 += 1;
|
||
|
if (r <= -0.5) cnt2 += 1;
|
||
|
if (r <= 0) cnt3 += 1;
|
||
|
if (r <= 0.5) cnt4 += 1;
|
||
|
if (r <= 1.2) cnt5 += 1;
|
||
|
}
|
||
|
|
||
|
cnt1 /= total*3;
|
||
|
cnt2 /= total*3;
|
||
|
cnt3 /= total*3;
|
||
|
cnt4 /= total*3;
|
||
|
cnt5 /= total*3;
|
||
|
|
||
|
dlog << LINFO << "cnt1: "<< cnt1;
|
||
|
dlog << LINFO << "cnt2: "<< cnt2;
|
||
|
dlog << LINFO << "cnt3: "<< cnt3;
|
||
|
dlog << LINFO << "cnt4: "<< cnt4;
|
||
|
dlog << LINFO << "cnt5: "<< cnt5;
|
||
|
|
||
|
DLIB_TEST(std::abs(cnt1 - 0.11507) < 0.001);
|
||
|
DLIB_TEST(std::abs(cnt2 - 0.30854) < 0.001);
|
||
|
DLIB_TEST(std::abs(cnt3 - 0.5) < 0.001);
|
||
|
DLIB_TEST(std::abs(cnt4 - 0.69146) < 0.001);
|
||
|
DLIB_TEST(std::abs(cnt5 - 0.88493) < 0.001);
|
||
|
}
|
||
|
|
||
|
void test_uniform_random_hash()
|
||
|
{
|
||
|
print_spinner();
|
||
|
dlog << LINFO << "test_uniform_random_hash()";
|
||
|
double cnt1 = 0; // num <= 0.2
|
||
|
double cnt2 = 0; // num <= 0.4
|
||
|
double cnt3 = 0; // num <= 0.6
|
||
|
double cnt4 = 0; // num <= 0.8
|
||
|
double cnt5 = 0; // num <= 1.0
|
||
|
|
||
|
double min_val = 10;
|
||
|
double max_val = 0;
|
||
|
|
||
|
const unsigned long total = 1000000;
|
||
|
for (unsigned long i = 0; i < total; ++i)
|
||
|
{
|
||
|
const double r = uniform_random_hash(i,0,0);
|
||
|
min_val = min(r,min_val);
|
||
|
max_val = max(r,max_val);
|
||
|
|
||
|
if (r <= 0.2) cnt1 += 1;
|
||
|
if (r <= 0.4) cnt2 += 1;
|
||
|
if (r <= 0.6) cnt3 += 1;
|
||
|
if (r <= 0.8) cnt4 += 1;
|
||
|
if (r <= 1.0) cnt5 += 1;
|
||
|
}
|
||
|
for (unsigned long i = 0; i < total; ++i)
|
||
|
{
|
||
|
const double r = uniform_random_hash(0,i,0);
|
||
|
min_val = min(r,min_val);
|
||
|
max_val = max(r,max_val);
|
||
|
|
||
|
if (r <= 0.2) cnt1 += 1;
|
||
|
if (r <= 0.4) cnt2 += 1;
|
||
|
if (r <= 0.6) cnt3 += 1;
|
||
|
if (r <= 0.8) cnt4 += 1;
|
||
|
if (r <= 1.0) cnt5 += 1;
|
||
|
}
|
||
|
for (unsigned long i = 0; i < total; ++i)
|
||
|
{
|
||
|
const double r = uniform_random_hash(0,0,i);
|
||
|
min_val = min(r,min_val);
|
||
|
max_val = max(r,max_val);
|
||
|
|
||
|
if (r <= 0.2) cnt1 += 1;
|
||
|
if (r <= 0.4) cnt2 += 1;
|
||
|
if (r <= 0.6) cnt3 += 1;
|
||
|
if (r <= 0.8) cnt4 += 1;
|
||
|
if (r <= 1.0) cnt5 += 1;
|
||
|
}
|
||
|
|
||
|
cnt1 /= total*3;
|
||
|
cnt2 /= total*3;
|
||
|
cnt3 /= total*3;
|
||
|
cnt4 /= total*3;
|
||
|
cnt5 /= total*3;
|
||
|
|
||
|
dlog << LINFO << "cnt1: "<< cnt1;
|
||
|
dlog << LINFO << "cnt2: "<< cnt2;
|
||
|
dlog << LINFO << "cnt3: "<< cnt3;
|
||
|
dlog << LINFO << "cnt4: "<< cnt4;
|
||
|
dlog << LINFO << "cnt5: "<< cnt5;
|
||
|
dlog << LINFO << "min_val: "<< min_val;
|
||
|
dlog << LINFO << "max_val: "<< max_val;
|
||
|
|
||
|
DLIB_TEST(std::abs(cnt1 - 0.2) < 0.001);
|
||
|
DLIB_TEST(std::abs(cnt2 - 0.4) < 0.001);
|
||
|
DLIB_TEST(std::abs(cnt3 - 0.6) < 0.001);
|
||
|
DLIB_TEST(std::abs(cnt4 - 0.8) < 0.001);
|
||
|
DLIB_TEST(std::abs(cnt5 - 1.0) < 0.001);
|
||
|
DLIB_TEST(std::abs(min_val - 0.0) < 0.001);
|
||
|
DLIB_TEST(std::abs(max_val - 1.0) < 0.001);
|
||
|
}
|
||
|
|
||
|
class rand_tester : public tester
|
||
|
{
|
||
|
public:
|
||
|
rand_tester (
|
||
|
) :
|
||
|
tester ("test_rand",
|
||
|
"Runs tests on the rand component.")
|
||
|
{}
|
||
|
|
||
|
void perform_test (
|
||
|
)
|
||
|
{
|
||
|
dlog << LINFO << "testing kernel_1a";
|
||
|
rand_test<dlib::rand>();
|
||
|
rand_test<dlib::rand>();
|
||
|
|
||
|
dlib::rand rnd;
|
||
|
test_normal_numbers(rnd);
|
||
|
test_gaussian_random_hash();
|
||
|
test_uniform_random_hash();
|
||
|
}
|
||
|
} a;
|
||
|
|
||
|
}
|
||
|
|
||
|
|